From 9bf16df41ed15f8ed57558262db5277c0d9f3ae4 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Fri, 15 Nov 2024 17:03:22 +0530 Subject: [PATCH] feat: inventory dimension for rejected materials (#44156) --- erpnext/controllers/stock_controller.py | 9 ++++++ .../inventory_dimension.py | 23 +++++++++++-- .../test_inventory_dimension.py | 32 +++++++++++++++++-- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 4dcf4744da1..737e8496d33 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -839,6 +839,15 @@ class StockController(AccountsController): if not dimension: continue + if ( + self.doctype in ["Purchase Invoice", "Purchase Receipt"] + and row.get("rejected_warehouse") + and sl_dict.get("warehouse") == row.get("rejected_warehouse") + ): + fieldname = f"rejected_{dimension.source_fieldname}" + sl_dict[dimension.target_fieldname] = row.get(fieldname) + continue + if self.doctype in [ "Purchase Invoice", "Purchase Receipt", diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py index 3bafa12983f..4f8a166932d 100644 --- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py +++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py @@ -107,6 +107,7 @@ class InventoryDimension(Document): self.source_fieldname, f"to_{self.source_fieldname}", f"from_{self.source_fieldname}", + f"rejected_{self.source_fieldname}", ], ) } @@ -171,12 +172,12 @@ class InventoryDimension(Document): if label_start_with: label = f"{label_start_with} {self.dimension_name}" - return [ + dimension_fields = [ dict( fieldname="inventory_dimension", fieldtype="Section Break", insert_after=self.get_insert_after_fieldname(doctype), - label="Inventory Dimension", + label=_("Inventory Dimension"), collapsible=1, ), dict( @@ -184,13 +185,29 @@ class InventoryDimension(Document): fieldtype="Link", insert_after="inventory_dimension", options=self.reference_document, - label=label, + label=_(label), search_index=1, reqd=self.reqd, mandatory_depends_on=self.mandatory_depends_on, ), ] + if doctype in ["Purchase Invoice Item", "Purchase Receipt Item"]: + dimension_fields.append( + dict( + fieldname="rejected_" + self.source_fieldname, + fieldtype="Link", + insert_after=self.source_fieldname, + options=self.reference_document, + label=_("Rejected " + self.dimension_name), + search_index=1, + reqd=self.reqd, + mandatory_depends_on=self.mandatory_depends_on, + ) + ) + + return dimension_fields + def add_custom_fields(self): custom_fields = {} diff --git a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py index 0da189bf915..cf477492eae 100644 --- a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py +++ b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py @@ -278,21 +278,47 @@ class TestInventoryDimension(IntegrationTestCase): item_code = "Test Inventory Dimension Item" create_item(item_code) warehouse = create_warehouse("Store Warehouse") + rj_warehouse = create_warehouse("RJ Warehouse") + + if not frappe.db.exists("Store", "Rejected Store"): + frappe.get_doc({"doctype": "Store", "store_name": "Rejected Store"}).insert( + ignore_permissions=True + ) # Purchase Receipt -> Inward in Store 1 pr_doc = make_purchase_receipt( - item_code=item_code, warehouse=warehouse, qty=10, rate=100, do_not_submit=True + item_code=item_code, + warehouse=warehouse, + qty=10, + rejected_qty=5, + rate=100, + rejected_warehouse=rj_warehouse, + do_not_submit=True, ) pr_doc.items[0].store = "Store 1" + pr_doc.items[0].rejected_store = "Rejected Store" pr_doc.save() pr_doc.submit() - entries = get_voucher_sl_entries(pr_doc.name, ["warehouse", "store", "incoming_rate"]) + entries = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_no": pr_doc.name, "warehouse": warehouse}, + fields=["store"], + order_by="creation", + ) - self.assertEqual(entries[0].warehouse, warehouse) self.assertEqual(entries[0].store, "Store 1") + entries = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_no": pr_doc.name, "warehouse": rj_warehouse}, + fields=["store"], + order_by="creation", + ) + + self.assertEqual(entries[0].store, "Rejected Store") + # Stock Entry -> Transfer from Store 1 to Store 2 se_doc = make_stock_entry( item_code=item_code, qty=10, from_warehouse=warehouse, to_warehouse=warehouse, do_not_save=True