From cac907383b9906496b9d8220a9be9bc863bc29ca Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 07:46:21 +0000 Subject: [PATCH] fix: Disallow negative rates in Purchase invoice (backport #54254) (#54393) fix: Disallow negative rates in Purchase invoice (#54254) (cherry picked from commit 23768ae0a5b7b1019aee251c9bd2d81f766e98e3) Co-authored-by: Nishka Gosalia <58264710+nishkagosalia@users.noreply.github.com> --- .../buying_settings/buying_settings.json | 9 ++++++++- .../buying_settings/buying_settings.py | 1 + erpnext/controllers/status_updater.py | 19 +++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 5a0edbdf5d1..3963bbb4959 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -24,6 +24,7 @@ "allow_zero_qty_in_supplier_quotation", "use_transaction_date_exchange_rate", "allow_zero_qty_in_request_for_quotation", + "allow_negative_rates_for_items", "column_break_12", "maintain_same_rate", "allow_multiple_items", @@ -279,6 +280,12 @@ "fieldname": "validate_consumed_qty", "fieldtype": "Check", "label": "Validate Consumed Qty (as per BOM)" + }, + { + "default": "0", + "fieldname": "allow_negative_rates_for_items", + "fieldtype": "Check", + "label": "Allow Negative rates for Items" } ], "grid_page_length": 50, @@ -288,7 +295,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-03-16 13:28:19.432589", + "modified": "2026-04-15 16:07:35.484787", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py index 3634f8a9069..8f358bb364b 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.py +++ b/erpnext/buying/doctype/buying_settings/buying_settings.py @@ -18,6 +18,7 @@ class BuyingSettings(Document): from frappe.types import DF allow_multiple_items: DF.Check + allow_negative_rates_for_items: DF.Check allow_zero_qty_in_purchase_order: DF.Check allow_zero_qty_in_request_for_quotation: DF.Check allow_zero_qty_in_supplier_quotation: DF.Check diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 96ca67c28df..95c25c497bf 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -272,6 +272,12 @@ class StatusUpdater(Document): continue items_to_validate = [] + selling_negative_rate_allowed = frappe.get_single_value( + "Selling Settings", "allow_negative_rates_for_items" + ) + buying_negative_rate_allowed = frappe.get_single_value( + "Buying Settings", "allow_negative_rates_for_items" + ) # get unique transactions to update for d in self.get_all_children(): @@ -281,7 +287,12 @@ class StatusUpdater(Document): if hasattr(d, "qty") and d.qty > 0 and self.get("is_return"): frappe.throw(_("For an item {0}, quantity must be negative number").format(d.item_code)) - if not frappe.get_single_value("Selling Settings", "allow_negative_rates_for_items"): + if ( + not selling_negative_rate_allowed and self.doctype in ["Sales Invoice", "Delivery Note"] + ) or ( + not buying_negative_rate_allowed + and self.doctype in ["Purchase Invoice", "Purchase Receipt"] + ): if hasattr(d, "item_code") and hasattr(d, "rate") and flt(d.rate) < 0: frappe.throw( _( @@ -289,7 +300,11 @@ class StatusUpdater(Document): ).format( frappe.bold(d.item_code), frappe.bold(_("`Allow Negative rates for Items`")), - get_link_to_form("Selling Settings", "Selling Settings"), + get_link_to_form( + "Selling Settings" + if self.doctype in ["Sales Invoice", "Delivery Note"] + else "Buying Settings" + ), ), )