Pop up Showing the list of items in Purchase Order

Hi,
Is it possible to view the list of items in a purchase order or a sales order without selecting that purchase or sales order instead creating an option to view the items list alone on the popup with the help of any button.

@Abai Hi , do you want like this?

Yes @Kiranmai but I want to see the item list in the list page of the purchase or sales order.

Let me explain the scenario, I may have number of purchase or sales order to the same customer or supplier. In a time customer asks me to change that purchase order so everytime I cant open all the PO and see through it. If i can able to see them via popup in the list itself it would be very useful for me to handle that.

Hi @Abai Try this.

Code :

function ButtonFunction(listview) {
    // Create a dialog to prompt user for Purchase Order name
    let d = new frappe.ui.Dialog({
        title: 'Purchase Order Items',
        fields: [
            {
                label: 'Purchase Order Name',
                fieldname: 'po_name',
                fieldtype: 'Link', // Use Data field type to enter Purchase Order Name
                reqd: 1,
                options:'Purchase Order'
            },
            {
                label: 'Items',
                fieldname: 'items_html',
                fieldtype: 'HTML',
            }
        ],
        primary_action_label: 'Fetch Items',
        primary_action: function() {
            let po_name = d.get_value('po_name');

            // Fetch items from the Purchase Order
            frappe.call({
                method: 'frappe.client.get',
                args: {
                    doctype: 'Purchase Order',
                    name: po_name
                },
                callback: function(r) {
                    if (r.message) {
                        // Create the HTML for displaying items
                        let items_html = '<table class="table table-bordered">';
                        items_html += '<tr><th>Item Code</th><th>Item Name</th><th>Quantity</th><th>Rate</th></tr>';
                        r.message.items.forEach(function(item) {
                            items_html += `<tr>
                                <td>${item.item_code}</td>
                                <td>${item.item_name}</td>
                                <td>${item.qty}</td>
                                <td>${item.rate}</td>
                            </tr>`;
                        });
                        items_html += '</table>';

                        // Set the HTML content to the dialog
                        d.fields_dict.items_html.$wrapper.html(items_html);
                    } else {
                        d.fields_dict.items_html.$wrapper.html('<p>No items found.</p>');
                    }
                }
            });
        }
    });

    d.show();
}

frappe.listview_settings['Purchase Order'] = {
    refresh: function(listview) {
        listview.page.add_inner_button("View Items", function() {
            ButtonFunction(listview);
        });
    },
};

Output:

I think it will helps you!

1 Like

Thank You @Kiranmai !!
I’ll try this.

@Abai Okay!

Hi @Kiranmai
Your Code works fine and perfect.
I have made some changes to that according to my need like selecting a purchase order by clicking the select box in PO List and I click view items the items popup will come.


function ButtonFunction(po_name) {
    // Create a dialog to display Purchase Order items
    let d = new frappe.ui.Dialog({
        title: 'Purchase Order Items',
        fields: [
            {
                label: 'Items',
                fieldname: 'items_html',
                fieldtype: 'HTML',
            }
        ],
        primary_action_label: 'Close',
        primary_action: function() {
            d.hide();
        }
    });

    // Fetch items from the selected Purchase Order
    frappe.call({
        method: 'frappe.client.get',
        args: {
            doctype: 'Purchase Order',
            name: po_name
        },
        callback: function(r) {
            if (r.message) {
                // Create the HTML for displaying items
                let items_html = '<table class="table table-bordered">';
                items_html += '<tr><th>Item Code</th><th>Item Name</th><th>Quantity</th><th>Rate</th></tr>';
                r.message.items.forEach(function(item) {
                    items_html += `<tr>
                        <td>${item.item_code}</td>
                        <td>${item.item_name}</td>
                        <td>${item.qty}</td>
                        <td>${item.rate}</td>
                    </tr>`;
                });
                items_html += '</table>';

                // Set the HTML content to the dialog
                d.fields_dict.items_html.$wrapper.html(items_html);
            } else {
                d.fields_dict.items_html.$wrapper.html('<p>No items found.</p>');
            }
        }
    });

    d.show();
}

frappe.listview_settings['Purchase Order'] = {
    refresh: function(listview) {
        listview.page.add_inner_button("View Items", function() {
            let selected_docs = listview.get_checked_items();

            if (selected_docs.length > 0) {
                let po_name = selected_docs[0].name; // Get the name of the first selected Purchase Order
                ButtonFunction(po_name);
            } else {
                frappe.msgprint('Please select a Purchase Order.');
            }
        });
    },
};

Thanks for your help and support!!

1 Like

Hi @Kiranmai,
All of a sudden the above is not working I don’t know what’s the reason ?
I cannot see the view item button.
Can you help me?

@Abai Hii,
See, supplier name name also not visible in list for few of those records.
May be it is effected by any other client/server script.
Check the console for any errors.

Hi @Abai,

You can easily manage it, so please check it.

ListView Client Script:

if (!frappe.listview_settings['Purchase Order']) {
    frappe.listview_settings['Purchase Order'] = {};
}

Object.assign(frappe.listview_settings['Purchase Order'], {
	hide_name_column: true,

	button: {
		show: function (doc) {
			return __("View Items");
		},
		get_label: function () {
			return __("View Items", null, "Access");
		},
		get_description: function (doc) {
			return;
		},
		action: function (doc) {
			frappe.call({
				method: "frappe.client.get",
				args: {
					doctype: "Purchase Order",
					name: doc.name
				},
				callback: function (response) {
					if (response.message) {
						var items = response.message.items;
						var item_table = "<table class='table table-bordered table-condensed' border='1' style='width: 100%;'><tr> \
						<th style='width: 20%;'>Item Code</th> \
						<th style='width: 30%;'>Item Name</th> \
						<th style='width: 15%; text-align: right;'>Qty</th> \
						<th style='width: 15%; text-align: right;'>Rate</th> \
						<th style='width: 20%; text-align: right;'>Amount</th></tr>";
				
						items.forEach(function (item) {
							item_table += "<tr> \
							<td style='width: 20%;'>" + item.item_code + "</td> \
							<td style='width: 30%;'>" + item.item_name + "</td> \
							<td style='width: 15%; text-align: right;'>" + item.qty + "&emsp;" + item.uom + "</td> \
							<td style='width: 15%; text-align: right;'>" + item.rate + "</td> \
							<td style='width: 20%; text-align: right;'>" + item.amount + "</td></tr>";
						});
				
						item_table += "</table>";

						let dialog = new frappe.ui.Dialog({
							title: "Purchase Order Items: " + doc.name,
							size: 'large',
						});

						dialog.$body.html(item_table);
						dialog.show();
					}
				}
			});
		},
	}
});
3 Likes

No @Kiranmai I have covered the supplier names.

I’ll check that and let you know @NCP

Hi @Abai,

Again, I updated the code for the purchase order and override the default list view code.

1 Like

It is working @NCP!
Thanks for giving this.