fix: Disallow negative rates in Purchase invoice (backport #54254) (#54393)

fix: Disallow negative rates in Purchase invoice (#54254)

(cherry picked from commit 23768ae0a5)

Co-authored-by: Nishka Gosalia <58264710+nishkagosalia@users.noreply.github.com>
This commit is contained in:
mergify[bot]
2026-04-19 07:46:21 +00:00
committed by GitHub
parent 7556550158
commit cac907383b
3 changed files with 26 additions and 3 deletions

View File

@@ -24,6 +24,7 @@
"allow_zero_qty_in_supplier_quotation", "allow_zero_qty_in_supplier_quotation",
"use_transaction_date_exchange_rate", "use_transaction_date_exchange_rate",
"allow_zero_qty_in_request_for_quotation", "allow_zero_qty_in_request_for_quotation",
"allow_negative_rates_for_items",
"column_break_12", "column_break_12",
"maintain_same_rate", "maintain_same_rate",
"allow_multiple_items", "allow_multiple_items",
@@ -279,6 +280,12 @@
"fieldname": "validate_consumed_qty", "fieldname": "validate_consumed_qty",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Validate Consumed Qty (as per BOM)" "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, "grid_page_length": 50,
@@ -288,7 +295,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2026-03-16 13:28:19.432589", "modified": "2026-04-15 16:07:35.484787",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Buying Settings", "name": "Buying Settings",

View File

@@ -18,6 +18,7 @@ class BuyingSettings(Document):
from frappe.types import DF from frappe.types import DF
allow_multiple_items: DF.Check allow_multiple_items: DF.Check
allow_negative_rates_for_items: DF.Check
allow_zero_qty_in_purchase_order: DF.Check allow_zero_qty_in_purchase_order: DF.Check
allow_zero_qty_in_request_for_quotation: DF.Check allow_zero_qty_in_request_for_quotation: DF.Check
allow_zero_qty_in_supplier_quotation: DF.Check allow_zero_qty_in_supplier_quotation: DF.Check

View File

@@ -272,6 +272,12 @@ class StatusUpdater(Document):
continue continue
items_to_validate = [] 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 # get unique transactions to update
for d in self.get_all_children(): 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"): 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)) 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: if hasattr(d, "item_code") and hasattr(d, "rate") and flt(d.rate) < 0:
frappe.throw( frappe.throw(
_( _(
@@ -289,7 +300,11 @@ class StatusUpdater(Document):
).format( ).format(
frappe.bold(d.item_code), frappe.bold(d.item_code),
frappe.bold(_("`Allow Negative rates for Items`")), 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"
),
), ),
) )