From 025b2f2922e6af91f54c6a370978f0aa014d51fe Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Fri, 17 Jul 2026 16:52:13 +0530 Subject: [PATCH 1/4] fix: validate buying price list on material request and update item rates on change (cherry picked from commit 18b15f2ca9355c6688b27c6853ea5657aac84109) --- .../material_request/material_request.js | 9 +++-- .../material_request/material_request.py | 38 ++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index e0bbff4cbda..7dab81beba1 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -100,7 +100,10 @@ frappe.ui.form.on("Material Request", { erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype); if (!frm.doc.buying_price_list) { - frm.doc.buying_price_list = frappe.defaults.get_default("buying_price_list"); + const buying_price_list = frappe.defaults.get_default("buying_price_list"); + if (frappe.has_permission("Price List", "read", buying_price_list)) { + frm.set_value("buying_price_list", buying_price_list); + } } }, @@ -287,9 +290,7 @@ frappe.ui.form.on("Material Request", { from_warehouse: item.from_warehouse, warehouse: item.warehouse, doctype: frm.doc.doctype, - buying_price_list: frm.doc.buying_price_list - ? frm.doc.buying_price_list - : frappe.defaults.get_default("buying_price_list"), + buying_price_list: frm.doc.buying_price_list, currency: frappe.defaults.get_default("Currency"), name: frm.doc.name, qty: item.qty || 1, diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 5ed37f34203..0a877612d75 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -18,6 +18,7 @@ from frappe.utils import cint, cstr, flt, get_link_to_form, getdate, new_line_se from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items from erpnext.controllers.buying_controller import BuyingController from erpnext.manufacturing.doctype.work_order.work_order import get_item_details +from erpnext.stock.get_item_details import get_price_list_rate_for from erpnext.stock.stock_balance import get_indented_qty, update_bin_qty from erpnext.subcontracting.doctype.subcontracting_bom.subcontracting_bom import ( get_subcontracting_boms_for_finished_goods, @@ -188,8 +189,43 @@ class MaterialRequest(BuyingController): self.validate_pp_qty() + if self.buying_price_list and not frappe.get_value("Price List", self.buying_price_list, "buying"): + self.buying_price_list = None + if not self.buying_price_list: - self.buying_price_list = frappe.defaults.get_defaults().buying_price_list + buying_price_list = frappe.defaults.get_defaults().buying_price_list + if frappe.has_permission("Price List", "read", buying_price_list): + self.buying_price_list = buying_price_list + + def on_update(self): + if self.buying_price_list and self.has_value_changed("buying_price_list"): + self.update_item_rates() + + def update_item_rates(self): + price_not_uom_dependent = frappe.get_value( + "Price List", self.buying_price_list, "price_not_uom_dependent" + ) + for item in self.items: + rate = get_price_list_rate_for( + frappe._dict( + { + "price_list": self.buying_price_list, + "uom": item.uom, + "transaction_date": self.transaction_date, + "qty": item.qty, + "stock_uom": item.stock_uom, + "price_not_uom_dependent": price_not_uom_dependent, + } + ), + item.item_code, + ) + item.db_set({"rate": flt(rate), "amount": flt(flt(rate) * item.qty, item.precision("amount"))}) + frappe.msgprint( + _("Item rates have been updated based on the selected Buying Price List {0}").format( + self.buying_price_list + ), + alert=True, + ) def validate_pp_qty(self): items_from_pp = [item for item in self.items if item.material_request_plan_item] From c3aea9ca9c4951cc5d41e3caf0dfee7ae56ff245 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Fri, 17 Jul 2026 18:24:15 +0530 Subject: [PATCH 2/4] fix: pass ctx keys get_price_list_rate_for reads, skip rate update on insert update_item_rates passed price_not_uom_dependent, a key get_price_list_rate_for never reads, and omitted conversion_factor, so a stock-UOM price was never converted to the row UOM. The function's (historically misnamed) price_list_uom_dependant ctx key carries the Price List's price_not_uom_dependent value: truthy returns the found rate as-is, falsy multiplies by conversion_factor. Also guard on_update with is_new(): has_value_changed returns True when there is no doc_before_save, so every first save re-wrote item rates. (cherry picked from commit 6dcc0cab3a9cca4d45123995d4ab98e30c6ce052) --- erpnext/stock/doctype/material_request/material_request.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 0a877612d75..0eefd05142b 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -198,7 +198,7 @@ class MaterialRequest(BuyingController): self.buying_price_list = buying_price_list def on_update(self): - if self.buying_price_list and self.has_value_changed("buying_price_list"): + if not self.is_new() and self.buying_price_list and self.has_value_changed("buying_price_list"): self.update_item_rates() def update_item_rates(self): @@ -214,7 +214,8 @@ class MaterialRequest(BuyingController): "transaction_date": self.transaction_date, "qty": item.qty, "stock_uom": item.stock_uom, - "price_not_uom_dependent": price_not_uom_dependent, + "conversion_factor": item.conversion_factor, + "price_list_uom_dependant": price_not_uom_dependent, } ), item.item_code, From aa08f753b4559cefb9c92ac7539fd95c721c8220 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Fri, 17 Jul 2026 21:23:49 +0530 Subject: [PATCH 3/4] fix: dont overwrite rate with 0 if not found (cherry picked from commit 1ef3cd1d3fbb896ed13c65cb04756ef474f1b86d) --- erpnext/stock/doctype/material_request/material_request.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 0eefd05142b..a19f2a8a6ec 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -220,7 +220,9 @@ class MaterialRequest(BuyingController): ), item.item_code, ) - item.db_set({"rate": flt(rate), "amount": flt(flt(rate) * item.qty, item.precision("amount"))}) + if rate is not None: + item.db_set({"rate": flt(rate), "amount": flt(flt(rate) * item.qty, item.precision("amount"))}) + frappe.msgprint( _("Item rates have been updated based on the selected Buying Price List {0}").format( self.buying_price_list From ec0da0f11311db78a602f3ca6563da3a29b3851d Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Fri, 17 Jul 2026 21:24:40 +0530 Subject: [PATCH 4/4] chore: remove unneccessary flt (cherry picked from commit 3a63f61832bc447d40201837a70d43b669e98eac) --- erpnext/stock/doctype/material_request/material_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index a19f2a8a6ec..daebeaa4e1b 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -221,7 +221,7 @@ class MaterialRequest(BuyingController): item.item_code, ) if rate is not None: - item.db_set({"rate": flt(rate), "amount": flt(flt(rate) * item.qty, item.precision("amount"))}) + item.db_set({"rate": rate, "amount": flt(rate * item.qty, item.precision("amount"))}) frappe.msgprint( _("Item rates have been updated based on the selected Buying Price List {0}").format(