From a9bc395e9852619778025f6b85c7a71306c31170 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Fri, 24 Jan 2025 10:14:26 +0100 Subject: [PATCH] fix: secure bulk transaction (#45386) --- .../purchase_invoice/purchase_invoice_list.js | 16 ++-- .../sales_invoice/sales_invoice_list.js | 16 ++-- .../purchase_order/purchase_order_list.js | 24 +++--- .../supplier_quotation_list.js | 20 +++-- .../doctype/quotation/quotation_list.js | 16 ++-- .../doctype/sales_order/sales_order_list.js | 80 +++++++++++-------- .../delivery_note/delivery_note_list.js | 22 ++--- erpnext/utilities/bulk_transaction.py | 3 + 8 files changed, 120 insertions(+), 77 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js index 031b2341bb6..6bfb48c13d2 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js @@ -45,12 +45,16 @@ frappe.listview_settings["Purchase Invoice"] = { }, onload: function (listview) { - listview.page.add_action_item(__("Purchase Receipt"), () => { - erpnext.bulk_transaction_processing.create(listview, "Purchase Invoice", "Purchase Receipt"); - }); + if (frappe.model.can_create("Purchase Receipt")) { + listview.page.add_action_item(__("Purchase Receipt"), () => { + erpnext.bulk_transaction_processing.create(listview, "Purchase Invoice", "Purchase Receipt"); + }); + } - listview.page.add_action_item(__("Payment"), () => { - erpnext.bulk_transaction_processing.create(listview, "Purchase Invoice", "Payment Entry"); - }); + if (frappe.model.can_create("Payment Entry")) { + listview.page.add_action_item(__("Payment"), () => { + erpnext.bulk_transaction_processing.create(listview, "Purchase Invoice", "Payment Entry"); + }); + } }, }; diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js index 3371a63cca2..ea3ae2b6fab 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js @@ -32,12 +32,16 @@ frappe.listview_settings["Sales Invoice"] = { right_column: "grand_total", onload: function (listview) { - listview.page.add_action_item(__("Delivery Note"), () => { - erpnext.bulk_transaction_processing.create(listview, "Sales Invoice", "Delivery Note"); - }); + if (frappe.model.can_create("Delivery Note")) { + listview.page.add_action_item(__("Delivery Note"), () => { + erpnext.bulk_transaction_processing.create(listview, "Sales Invoice", "Delivery Note"); + }); + } - listview.page.add_action_item(__("Payment"), () => { - erpnext.bulk_transaction_processing.create(listview, "Sales Invoice", "Payment Entry"); - }); + if (frappe.model.can_create("Payment Entry")) { + listview.page.add_action_item(__("Payment"), () => { + erpnext.bulk_transaction_processing.create(listview, "Sales Invoice", "Payment Entry"); + }); + } }, }; diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js index 9a443732569..b308e4bae32 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js @@ -47,16 +47,22 @@ frappe.listview_settings["Purchase Order"] = { listview.call_for_selected_items(method, { status: "Submitted" }); }); - listview.page.add_action_item(__("Purchase Invoice"), () => { - erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Purchase Invoice"); - }); + if (frappe.model.can_create("Purchase Invoice")) { + listview.page.add_action_item(__("Purchase Invoice"), () => { + erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Purchase Invoice"); + }); + } - listview.page.add_action_item(__("Purchase Receipt"), () => { - erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Purchase Receipt"); - }); + if (frappe.model.can_create("Purchase Receipt")) { + listview.page.add_action_item(__("Purchase Receipt"), () => { + erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Purchase Receipt"); + }); + } - listview.page.add_action_item(__("Advance Payment"), () => { - erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Payment Entry"); - }); + if (frappe.model.can_create("Payment Entry")) { + listview.page.add_action_item(__("Advance Payment"), () => { + erpnext.bulk_transaction_processing.create(listview, "Purchase Order", "Payment Entry"); + }); + } }, }; diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js index 99fe24d8770..1a2a514a680 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js @@ -11,12 +11,20 @@ frappe.listview_settings["Supplier Quotation"] = { }, onload: function (listview) { - listview.page.add_action_item(__("Purchase Order"), () => { - erpnext.bulk_transaction_processing.create(listview, "Supplier Quotation", "Purchase Order"); - }); + if (frappe.model.can_create("Purchase Order")) { + listview.page.add_action_item(__("Purchase Order"), () => { + erpnext.bulk_transaction_processing.create(listview, "Supplier Quotation", "Purchase Order"); + }); + } - listview.page.add_action_item(__("Purchase Invoice"), () => { - erpnext.bulk_transaction_processing.create(listview, "Supplier Quotation", "Purchase Invoice"); - }); + if (frappe.model.can_create("Purchase Invoice")) { + listview.page.add_action_item(__("Purchase Invoice"), () => { + erpnext.bulk_transaction_processing.create( + listview, + "Supplier Quotation", + "Purchase Invoice" + ); + }); + } }, }; diff --git a/erpnext/selling/doctype/quotation/quotation_list.js b/erpnext/selling/doctype/quotation/quotation_list.js index ae744b9cba3..b795c3fe0bc 100644 --- a/erpnext/selling/doctype/quotation/quotation_list.js +++ b/erpnext/selling/doctype/quotation/quotation_list.js @@ -12,13 +12,17 @@ frappe.listview_settings["Quotation"] = { }; } - listview.page.add_action_item(__("Sales Order"), () => { - erpnext.bulk_transaction_processing.create(listview, "Quotation", "Sales Order"); - }); + if (frappe.model.can_create("Sales Order")) { + listview.page.add_action_item(__("Sales Order"), () => { + erpnext.bulk_transaction_processing.create(listview, "Quotation", "Sales Order"); + }); + } - listview.page.add_action_item(__("Sales Invoice"), () => { - erpnext.bulk_transaction_processing.create(listview, "Quotation", "Sales Invoice"); - }); + if (frappe.model.can_create("Sales Invoice")) { + listview.page.add_action_item(__("Sales Invoice"), () => { + erpnext.bulk_transaction_processing.create(listview, "Quotation", "Sales Invoice"); + }); + } }, get_indicator: function (doc) { diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js index e48af32a479..cc37bbfe325 100644 --- a/erpnext/selling/doctype/sales_order/sales_order_list.js +++ b/erpnext/selling/doctype/sales_order/sales_order_list.js @@ -63,47 +63,57 @@ frappe.listview_settings["Sales Order"] = { listview.call_for_selected_items(method, { status: "Submitted" }); }); - listview.page.add_action_item(__("Sales Invoice"), () => { - erpnext.bulk_transaction_processing.create(listview, "Sales Order", "Sales Invoice"); - }); + if (frappe.model.can_create("Sales Invoice")) { + listview.page.add_action_item(__("Sales Invoice"), () => { + erpnext.bulk_transaction_processing.create(listview, "Sales Order", "Sales Invoice"); + }); + } - listview.page.add_action_item(__("Delivery Note"), () => { - frappe.call({ - method: "erpnext.selling.doctype.sales_order.sales_order.is_enable_cutoff_date_on_bulk_delivery_note_creation", - callback: (r) => { - if (r.message) { - var dialog = new frappe.ui.Dialog({ - title: __("Select Items up to Delivery Date"), - fields: [ - { - fieldtype: "Date", - fieldname: "delivery_date", - default: frappe.datetime.add_days(frappe.datetime.nowdate(), 1), - }, - ], - }); - dialog.set_primary_action(__("Select"), function (values) { - var until_delivery_date = values.delivery_date; + if (frappe.model.can_create("Delivery Note")) { + listview.page.add_action_item(__("Delivery Note"), () => { + frappe.call({ + method: "erpnext.selling.doctype.sales_order.sales_order.is_enable_cutoff_date_on_bulk_delivery_note_creation", + callback: (r) => { + if (r.message) { + var dialog = new frappe.ui.Dialog({ + title: __("Select Items up to Delivery Date"), + fields: [ + { + fieldtype: "Date", + fieldname: "delivery_date", + default: frappe.datetime.add_days(frappe.datetime.nowdate(), 1), + }, + ], + }); + dialog.set_primary_action(__("Select"), function (values) { + var until_delivery_date = values.delivery_date; + erpnext.bulk_transaction_processing.create( + listview, + "Sales Order", + "Delivery Note", + { + until_delivery_date, + } + ); + dialog.hide(); + }); + dialog.show(); + } else { erpnext.bulk_transaction_processing.create( listview, "Sales Order", - "Delivery Note", - { - until_delivery_date, - } + "Delivery Note" ); - dialog.hide(); - }); - dialog.show(); - } else { - erpnext.bulk_transaction_processing.create(listview, "Sales Order", "Delivery Note"); - } - }, + } + }, + }); }); - }); + } - listview.page.add_action_item(__("Advance Payment"), () => { - erpnext.bulk_transaction_processing.create(listview, "Sales Order", "Payment Entry"); - }); + if (frappe.model.can_create("Payment Entry")) { + listview.page.add_action_item(__("Advance Payment"), () => { + erpnext.bulk_transaction_processing.create(listview, "Sales Order", "Payment Entry"); + }); + } }, }; diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js index 8e4f970e469..87c7982f941 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js @@ -57,16 +57,20 @@ frappe.listview_settings["Delivery Note"] = { } }; - // doclist.page.add_actions_menu_item(__('Create Delivery Trip'), action, false); + if (frappe.model.can_create("Delivery Trip")) { + doclist.page.add_action_item(__("Create Delivery Trip"), action); + } - doclist.page.add_action_item(__("Create Delivery Trip"), action); + if (frappe.model.can_create("Sales Invoice")) { + doclist.page.add_action_item(__("Sales Invoice"), () => { + erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Sales Invoice"); + }); + } - doclist.page.add_action_item(__("Sales Invoice"), () => { - erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Sales Invoice"); - }); - - doclist.page.add_action_item(__("Packaging Slip From Delivery Note"), () => { - erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Packing Slip"); - }); + if (frappe.model.can_create("Packing Slip")) { + doclist.page.add_action_item(__("Packaging Slip From Delivery Note"), () => { + erpnext.bulk_transaction_processing.create(doclist, "Delivery Note", "Packing Slip"); + }); + } }, }; diff --git a/erpnext/utilities/bulk_transaction.py b/erpnext/utilities/bulk_transaction.py index 3046c5bc26e..2aba717482d 100644 --- a/erpnext/utilities/bulk_transaction.py +++ b/erpnext/utilities/bulk_transaction.py @@ -8,6 +8,9 @@ from frappe.utils import get_link_to_form, today @frappe.whitelist() def transaction_processing(data, from_doctype, to_doctype, args=None): + frappe.has_permission(from_doctype, "read", throw=True) + frappe.has_permission(to_doctype, "create", throw=True) + if isinstance(data, str): deserialized_data = json.loads(data) else: