From eac7b5d5aaed83217b0a2843d13e75cb94dbb9a0 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 13 Jan 2022 12:15:40 +0530 Subject: [PATCH 1/3] fix: Allow multiple fg in repack entry --- .../stock/doctype/stock_entry/stock_entry.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index d1149ea6a2..486c4c4280 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -738,9 +738,9 @@ class StockEntry(StockController): def validate_finished_goods(self): """ - 1. Check if FG exists - 2. Check if Multiple FG Items are present - 3. Check FG Item and Qty against WO if present + 1. Check if FG exists (mfg, repack) + 2. Check if Multiple FG Items are present (mfg) + 3. Check FG Item and Qty against WO if present (mfg) """ production_item, wo_qty, finished_items = None, 0, [] @@ -753,8 +753,9 @@ class StockEntry(StockController): for d in self.get('items'): if d.is_finished_item: if not self.work_order: + # Independent MFG Entry/ Repack Entry, no WO to match against finished_items.append(d.item_code) - continue # Independent Manufacture Entry, no WO to match against + continue if d.item_code != production_item: frappe.throw(_("Finished Item {0} does not match with Work Order {1}") @@ -767,19 +768,17 @@ class StockEntry(StockController): finished_items.append(d.item_code) - if len(set(finished_items)) > 1: + if not finished_items: frappe.throw( - msg=_("Multiple items cannot be marked as finished item"), - title=_("Note"), - exc=FinishedGoodError + msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name), + title=_("Missing Finished Good"), exc=FinishedGoodError ) if self.purpose == "Manufacture": - if not finished_items: + if len(set(finished_items)) > 1: frappe.throw( - msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name), - title=_("Missing Finished Good"), - exc=FinishedGoodError + msg=_("Multiple items cannot be marked as finished item"), + title=_("Note"), exc=FinishedGoodError ) allowance_percentage = flt( From 3922a39591ad79a44438f3edf28841348a64d74c Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 13 Jan 2022 14:36:21 +0530 Subject: [PATCH 2/3] test: Basic test one item repacked into two - Also run fg validation and fg marking after checking purpose, avoid unnecessary calls --- .../stock/doctype/stock_entry/stock_entry.py | 38 ++++++++++--------- .../doctype/stock_entry/test_stock_entry.py | 35 ++++++++++++++++- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 486c4c4280..a61b3199c0 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -86,8 +86,11 @@ class StockEntry(StockController): self.validate_warehouse() self.validate_work_order() self.validate_bom() - self.mark_finished_and_scrap_items() - self.validate_finished_goods() + + if self.purpose in ("Manufacture", "Repack"): + self.mark_finished_and_scrap_items() + self.validate_finished_goods() + self.validate_with_material_request() self.validate_batch() self.validate_inspection() @@ -706,26 +709,25 @@ class StockEntry(StockController): validate_bom_no(item_code, d.bom_no) def mark_finished_and_scrap_items(self): - if self.purpose in ("Repack", "Manufacture"): - if any([d.item_code for d in self.items if (d.is_finished_item and d.t_warehouse)]): - return + if any([d.item_code for d in self.items if (d.is_finished_item and d.t_warehouse)]): + return - finished_item = self.get_finished_item() + finished_item = self.get_finished_item() - if not finished_item and self.purpose == "Manufacture": - # In case of independent Manufacture entry, don't auto set - # user must decide and set - return + if not finished_item and self.purpose == "Manufacture": + # In case of independent Manufacture entry, don't auto set + # user must decide and set + return - for d in self.items: - if d.t_warehouse and not d.s_warehouse: - if self.purpose=="Repack" or d.item_code == finished_item: - d.is_finished_item = 1 - else: - d.is_scrap_item = 1 + for d in self.items: + if d.t_warehouse and not d.s_warehouse: + if self.purpose=="Repack" or d.item_code == finished_item: + d.is_finished_item = 1 else: - d.is_finished_item = 0 - d.is_scrap_item = 0 + d.is_scrap_item = 1 + else: + d.is_finished_item = 0 + d.is_scrap_item = 0 def get_finished_item(self): finished_item = None diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index b874874adf..c292461824 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -226,9 +226,40 @@ class TestStockEntry(ERPNextTestCase): mtn.cancel() - def test_repack_no_change_in_valuation(self): - company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') + def test_repack_multiple_fg(self): + "Test `is_finsihed_item` for one item repacked into two items." + make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, basic_rate=100) + repack = frappe.copy_doc(test_records[3]) + repack.posting_date = nowdate() + repack.posting_time = nowtime() + + repack.items[0].qty = 100.0 + repack.items[0].transfer_qty = 100.0 + repack.items[1].qty = 50.0 + repack.items[1].basic_rate = 200 + + repack.append("items", { + "conversion_factor": 1.0, + "cost_center": "_Test Cost Center - _TC", + "doctype": "Stock Entry Detail", + "expense_account": "Stock Adjustment - _TC", + "basic_rate": 150, + "item_code": "_Test Item 2", + "parentfield": "items", + "qty": 50.0, + "stock_uom": "_Test UOM", + "t_warehouse": "_Test Warehouse - _TC", + "transfer_qty": 50.0, + "uom": "_Test UOM" + }) + repack.set_stock_entry_type() + repack.insert() + + self.assertEqual(repack.items[1].is_finished_item, 1) + self.assertEqual(repack.items[2].is_finished_item, 1) + + def test_repack_no_change_in_valuation(self): make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100) make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=50, basic_rate=100) From c49dff385a4798e329f0a8390563afee945c7656 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 13 Jan 2022 15:02:59 +0530 Subject: [PATCH 3/3] test: Check for FinishedGoodError if 0 FG in repack entry --- erpnext/stock/doctype/stock_entry/test_stock_entry.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index c292461824..8f5d442d19 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -227,7 +227,7 @@ class TestStockEntry(ERPNextTestCase): mtn.cancel() def test_repack_multiple_fg(self): - "Test `is_finsihed_item` for one item repacked into two items." + "Test `is_finished_item` for one item repacked into two items." make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, basic_rate=100) repack = frappe.copy_doc(test_records[3]) @@ -237,7 +237,6 @@ class TestStockEntry(ERPNextTestCase): repack.items[0].qty = 100.0 repack.items[0].transfer_qty = 100.0 repack.items[1].qty = 50.0 - repack.items[1].basic_rate = 200 repack.append("items", { "conversion_factor": 1.0, @@ -259,6 +258,14 @@ class TestStockEntry(ERPNextTestCase): self.assertEqual(repack.items[1].is_finished_item, 1) self.assertEqual(repack.items[2].is_finished_item, 1) + repack.items[1].is_finished_item = 0 + repack.items[2].is_finished_item = 0 + + # must raise error if 0 fg in repack entry + self.assertRaises(FinishedGoodError, repack.validate_finished_goods) + + repack.delete() # teardown + def test_repack_no_change_in_valuation(self): make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100) make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",