Merge pull request #29274 from frappe/mergify/bp/version-13-hotfix/pr-29271

fix: Don't validate FG in repack entry (backport #29271)
This commit is contained in:
Marica
2022-01-13 16:50:02 +05:30
committed by GitHub
2 changed files with 71 additions and 32 deletions

View File

@@ -87,8 +87,11 @@ class StockEntry(StockController):
self.validate_warehouse() self.validate_warehouse()
self.validate_work_order() self.validate_work_order()
self.validate_bom() 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_with_material_request()
self.validate_batch() self.validate_batch()
self.validate_inspection() self.validate_inspection()
@@ -707,26 +710,25 @@ class StockEntry(StockController):
validate_bom_no(item_code, d.bom_no) validate_bom_no(item_code, d.bom_no)
def mark_finished_and_scrap_items(self): 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)]):
if any([d.item_code for d in self.items if (d.is_finished_item and d.t_warehouse)]): return
return
finished_item = self.get_finished_item() finished_item = self.get_finished_item()
if not finished_item and self.purpose == "Manufacture": if not finished_item and self.purpose == "Manufacture":
# In case of independent Manufacture entry, don't auto set # In case of independent Manufacture entry, don't auto set
# user must decide and set # user must decide and set
return return
for d in self.items: for d in self.items:
if d.t_warehouse and not d.s_warehouse: if d.t_warehouse and not d.s_warehouse:
if self.purpose=="Repack" or d.item_code == finished_item: if self.purpose=="Repack" or d.item_code == finished_item:
d.is_finished_item = 1 d.is_finished_item = 1
else:
d.is_scrap_item = 1
else: else:
d.is_finished_item = 0 d.is_scrap_item = 1
d.is_scrap_item = 0 else:
d.is_finished_item = 0
d.is_scrap_item = 0
def get_finished_item(self): def get_finished_item(self):
finished_item = None finished_item = None
@@ -739,9 +741,9 @@ class StockEntry(StockController):
def validate_finished_goods(self): def validate_finished_goods(self):
""" """
1. Check if FG exists 1. Check if FG exists (mfg, repack)
2. Check if Multiple FG Items are present 2. Check if Multiple FG Items are present (mfg)
3. Check FG Item and Qty against WO if present 3. Check FG Item and Qty against WO if present (mfg)
""" """
production_item, wo_qty, finished_items = None, 0, [] production_item, wo_qty, finished_items = None, 0, []
@@ -754,8 +756,9 @@ class StockEntry(StockController):
for d in self.get('items'): for d in self.get('items'):
if d.is_finished_item: if d.is_finished_item:
if not self.work_order: if not self.work_order:
# Independent MFG Entry/ Repack Entry, no WO to match against
finished_items.append(d.item_code) finished_items.append(d.item_code)
continue # Independent Manufacture Entry, no WO to match against continue
if d.item_code != production_item: if d.item_code != production_item:
frappe.throw(_("Finished Item {0} does not match with Work Order {1}") frappe.throw(_("Finished Item {0} does not match with Work Order {1}")
@@ -768,19 +771,17 @@ class StockEntry(StockController):
finished_items.append(d.item_code) finished_items.append(d.item_code)
if len(set(finished_items)) > 1: if not finished_items:
frappe.throw( frappe.throw(
msg=_("Multiple items cannot be marked as finished item"), msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name),
title=_("Note"), title=_("Missing Finished Good"), exc=FinishedGoodError
exc=FinishedGoodError
) )
if self.purpose == "Manufacture": if self.purpose == "Manufacture":
if not finished_items: if len(set(finished_items)) > 1:
frappe.throw( frappe.throw(
msg=_("There must be atleast 1 Finished Good in this Stock Entry").format(self.name), msg=_("Multiple items cannot be marked as finished item"),
title=_("Missing Finished Good"), title=_("Note"), exc=FinishedGoodError
exc=FinishedGoodError
) )
allowance_percentage = flt( allowance_percentage = flt(

View File

@@ -227,9 +227,47 @@ class TestStockEntry(ERPNextTestCase):
mtn.cancel() mtn.cancel()
def test_repack_no_change_in_valuation(self): def test_repack_multiple_fg(self):
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') "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])
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.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)
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", target="_Test Warehouse - _TC", qty=50, basic_rate=100)
make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
qty=50, basic_rate=100) qty=50, basic_rate=100)