From bd41a99c8a5c9a8b49174727748ce237a1a87797 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 4 Feb 2022 22:06:56 +0530 Subject: [PATCH] fix: Regenerate packed items on newly mapped doc - Cannot determine action on newly mapped DN that hasnt been inserted - Rows could have been deleted, updated, added, etc. before first save - In this case , reset packing table --- .../stock/doctype/packed_item/packed_item.py | 15 +++++---- .../doctype/packed_item/test_packed_item.py | 31 ++++++++++++++++--- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index e3b5795f4c92..07c2f1f0dd3d 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -27,8 +27,7 @@ def make_packing_list(doc): stale_packed_items_table = get_indexed_packed_items_table(doc) - if not doc.is_new(): - reset = reset_packing_list_if_deleted_items_exist(doc) + reset = reset_packing_list(doc) for item_row in doc.get("items"): if frappe.db.exists("Product Bundle", {"new_item_code": item_row.item_code}): @@ -64,20 +63,24 @@ def get_indexed_packed_items_table(doc): return indexed_table -def reset_packing_list_if_deleted_items_exist(doc): - doc_before_save = doc.get_doc_before_save() +def reset_packing_list(doc): + "Conditionally reset the table and return if it was reset or not." reset_table = False + doc_before_save = doc.get_doc_before_save() if doc_before_save: # reset table if: # 1. items were deleted # 2. if bundle item replaced by another item (same no. of items but different items) - # we maintain list to maintain repeated item rows as well + # we maintain list to track recurring item rows as well items_before_save = [item.item_code for item in doc_before_save.get("items")] items_after_save = [item.item_code for item in doc.get("items")] reset_table = items_before_save != items_after_save else: - reset_table = True # reset if via Update Items (cannot determine action) + # reset: if via Update Items OR + # if new mapped doc with packed items set (SO -> DN) + # (cannot determine action) + reset_table = True if reset_table: doc.set("packed_items", []) diff --git a/erpnext/stock/doctype/packed_item/test_packed_item.py b/erpnext/stock/doctype/packed_item/test_packed_item.py index ed4eecde1da5..5cbaa1ea6699 100644 --- a/erpnext/stock/doctype/packed_item/test_packed_item.py +++ b/erpnext/stock/doctype/packed_item/test_packed_item.py @@ -2,6 +2,7 @@ # License: GNU General Public License v3. See license.txt from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle +from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.stock.doctype.item.test_item import make_item from erpnext.tests.utils import ERPNextTestCase, change_settings @@ -22,7 +23,7 @@ def setUpClass(cls) -> None: qty=2 ) - def test_sales_order_adding_bundle_item(self): + def test_adding_bundle_item(self): "Test impact on packed items if bundle item row is added." so = make_sales_order(item_code = "_Test Product Bundle X", qty=1, do_not_submit=True) @@ -32,7 +33,7 @@ def test_sales_order_adding_bundle_item(self): self.assertEqual(so.packed_items[0].item_code, "_Test Bundle Item 1") self.assertEqual(so.packed_items[0].qty, 2) - def test_sales_order_updating_bundle_item(self): + def test_updating_bundle_item(self): "Test impact on packed items if bundle item row is updated." so = make_sales_order(item_code = "_Test Product Bundle X", qty=1, do_not_submit=True) @@ -49,7 +50,7 @@ def test_sales_order_updating_bundle_item(self): self.assertEqual(len(so.packed_items), 0) - def test_sales_order_recurring_bundle_item(self): + def test_recurring_bundle_item(self): "Test impact on packed items if same bundle item is added and removed." so_items = [] for qty in [2, 4, 6, 8]: @@ -91,7 +92,7 @@ def test_sales_order_recurring_bundle_item(self): self.assertEqual(so.packed_items[3].qty, 12) @change_settings("Selling Settings", {"editable_bundle_item_rates": 1}) - def test_sales_order_bundle_item_cumulative_price(self): + def test_bundle_item_cumulative_price(self): "Test if Bundle Item rate is cumulative from packed items." so = make_sales_order(item_code = "_Test Product Bundle X", qty=2, do_not_submit=True) @@ -102,3 +103,25 @@ def test_sales_order_bundle_item_cumulative_price(self): self.assertEqual(so.items[0].rate, 350) self.assertEqual(so.items[0].amount, 700) + + def test_newly_mapped_doc_packed_items(self): + "Test impact on packed items in newly mapped DN from SO." + so_items = [] + for qty in [2, 4]: + so_items.append({ + "item_code": "_Test Product Bundle X", + "qty": qty, + "rate": 400, + "warehouse": "_Test Warehouse - _TC" + }) + + # create SO with recurring bundle item + so = make_sales_order(item_list=so_items) + + dn = make_delivery_note(so.name) + dn.items[1].qty = 3 # change second row qty for inserting doc + dn.save() + + self.assertEqual(len(dn.packed_items), 4) + self.assertEqual(dn.packed_items[2].qty, 6) + self.assertEqual(dn.packed_items[3].qty, 6) \ No newline at end of file