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.
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!
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!!
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 + " " + 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();
}
}
});
},
}
});
Hi @Abai,
Again, I updated the code for the purchase order and override the default list view code.