fix: recompute quotation status and guard state on Update Items

This commit is contained in:
Shllokkk
2026-10-29 00:12:24 +05:30
parent d04f1549e8
commit 44a9739a24
2 changed files with 50 additions and 0 deletions
@@ -4357,6 +4357,19 @@ def update_child_qty_rate(
)
)
# The Quotation form hides Update Items for these states; enforce it server-side too.
if doc.doctype == "Quotation":
if doc.status in ("Lost", "Ordered"):
frappe.throw(
_("Cannot update items of Quotation {0} because it is {1}.").format(
doc.name, _(doc.status)
)
)
if doc.valid_till and getdate(doc.valid_till) < getdate():
frappe.throw(
_("Cannot update items of Quotation {0} because it has expired.").format(doc.name)
)
def validate_workflow_conditions(doc):
workflow = get_workflow_name(doc.doctype)
if not workflow:
@@ -4774,6 +4787,9 @@ def update_child_qty_rate(
elif parent_doctype == "Supplier Quotation":
parent.update_rfq_supplier_status(parent.docstatus.is_submitted(), rfqs_before_update)
elif parent_doctype == "Quotation":
parent.set_status(update=True)
parent.reload()
validate_workflow_conditions(parent)
@@ -1219,6 +1219,40 @@ class TestQuotation(FrappeTestCase):
expired.submit()
self.assertRaises(frappe.ValidationError, make_sales_invoice, expired.name)
def test_quotation_update_items_recomputes_status(self):
from erpnext.stock.doctype.item.test_item import make_item
warehouse = "_Test Warehouse - _TC"
item1 = make_item().item_code
item2 = make_item().item_code
quotation = make_quotation(
item_list=[
{"item_code": item1, "qty": 2, "rate": 100, "warehouse": warehouse},
{"item_code": item2, "qty": 2, "rate": 100, "warehouse": warehouse},
]
)
so = make_sales_order(quotation.name, args={"filtered_children": [quotation.items[0].name]})
so.delivery_date = nowdate()
so.insert()
so.submit()
quotation.reload()
self.assertEqual(quotation.status, "Partially Ordered")
row = quotation.items[0]
trans_items = json.dumps(
[{"item_code": row.item_code, "qty": row.qty, "rate": row.rate, "docname": row.name}]
)
update_child_qty_rate("Quotation", trans_items, quotation.name)
quotation.reload()
self.assertEqual(quotation.status, "Ordered")
row = quotation.items[0]
raised = json.dumps([{"item_code": row.item_code, "qty": 5, "rate": row.rate, "docname": row.name}])
self.assertRaises(frappe.ValidationError, update_child_qty_rate, "Quotation", raised, quotation.name)
test_records = frappe.get_test_records("Quotation")