diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 0de3f15572b..99a65aa7341 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -4730,6 +4730,8 @@ def update_child_qty_rate( if parent_doctype == "Sales Order": make_packing_list(parent) parent.set_gross_profit() + elif parent_doctype == "Quotation": + make_packing_list(parent) frappe.get_doc("Authorization Control").validate_approving_authority( parent.doctype, parent.company, parent.base_grand_total ) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index b5d29eec8eb..8da4306e0f0 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -1253,6 +1253,29 @@ class TestQuotation(FrappeTestCase): 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) + def test_quotation_update_items_rebuilds_bundle_packed_items(self): + from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle + from erpnext.stock.doctype.item.test_item import make_item + + make_item("_Test Product Bundle", {"is_stock_item": 0}) + make_item("_Test Bundle Item 1", {"is_stock_item": 1}) + make_item("_Test Bundle Item 2", {"is_stock_item": 1}) + make_product_bundle("_Test Product Bundle", ["_Test Bundle Item 1", "_Test Bundle Item 2"]) + + quotation = make_quotation(item_code="_Test Product Bundle", qty=1, rate=100) + before = {pi.item_code: pi.qty for pi in quotation.packed_items} + self.assertTrue(before) + + row = quotation.items[0] + trans_items = json.dumps( + [{"item_code": row.item_code, "qty": 3, "rate": row.rate, "docname": row.name}] + ) + update_child_qty_rate("Quotation", trans_items, quotation.name) + + quotation.reload() + after = {pi.item_code: pi.qty for pi in quotation.packed_items} + self.assertEqual(after, {code: qty * 3 for code, qty in before.items()}) + test_records = frappe.get_test_records("Quotation")