From ee12ec36cc479679865cd6bda5b65a6c7a19912a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 14:10:08 +0530 Subject: [PATCH] fix: pick list with multiple batch issue (backport #41335) (backport #41338) (#41340) fix: pick list with multiple batch issue (backport #41335) (#41338) fix: pick list with multiple batch issue (#41335) fix: pick list with batchb issue (cherry picked from commit ebfbe94aaf6c91263daed7074a335f0f0f904064) Co-authored-by: rohitwaghchaure (cherry picked from commit 1b1dfa8893c23691fbfea1754af78cb39266e9a8) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- erpnext/stock/doctype/pick_list/pick_list.py | 31 +++++++++++----- .../stock/doctype/pick_list/test_pick_list.py | 36 +++++++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index e3dbdb5726b..d7e84d2fb93 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -790,7 +790,7 @@ def get_available_item_locations( locations = get_locations_based_on_required_qty(locations, required_qty) if not ignore_validation: - validate_picked_materials(item_code, required_qty, locations) + validate_picked_materials(item_code, required_qty, locations, picked_item_details) return locations @@ -810,7 +810,7 @@ def get_locations_based_on_required_qty(locations, required_qty): return filtered_locations -def validate_picked_materials(item_code, required_qty, locations): +def validate_picked_materials(item_code, required_qty, locations, picked_item_details=None): for location in list(locations): if location["qty"] < 0: locations.remove(location) @@ -819,15 +819,25 @@ def validate_picked_materials(item_code, required_qty, locations): remaining_qty = required_qty - total_qty_available if remaining_qty > 0: - frappe.msgprint( - _("{0} units of Item {1} is picked in another Pick List.").format( - remaining_qty, get_link_to_form("Item", item_code) - ), - title=_("Already Picked"), - ) + if picked_item_details: + frappe.msgprint( + _("{0} units of Item {1} is picked in another Pick List.").format( + remaining_qty, get_link_to_form("Item", item_code) + ), + title=_("Already Picked"), + ) + + else: + frappe.msgprint( + _("{0} units of Item {1} is not available in any of the warehouses.").format( + remaining_qty, get_link_to_form("Item", item_code) + ), + title=_("Insufficient Stock"), + ) def filter_locations_by_picked_materials(locations, picked_item_details) -> list[dict]: + filterd_locations = [] for row in locations: key = row.warehouse if row.batch_no: @@ -845,7 +855,10 @@ def filter_locations_by_picked_materials(locations, picked_item_details) -> list if row.serial_nos: row.serial_nos = list(set(row.serial_nos) - set(picked_item_details[key].get("serial_no"))) - return locations + if row.qty > 0: + filterd_locations.append(row) + + return filterd_locations def get_available_item_locations_for_serial_and_batched_item( diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py index 87a71503be5..499eaa84282 100644 --- a/erpnext/stock/doctype/pick_list/test_pick_list.py +++ b/erpnext/stock/doctype/pick_list/test_pick_list.py @@ -977,3 +977,39 @@ class TestPickList(FrappeTestCase): so = make_sales_order(item_code=item, qty=4, rate=100) pl = create_pick_list(so.name) self.assertFalse(hasattr(pl, "locations")) + + def test_pick_list_validation_for_multiple_batches_and_sales_order(self): + warehouse = "_Test Warehouse - _TC" + item = make_item( + "Test Batch Pick List Item For Multiple Batches", + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "batch_number_series": "SN-BT-BATCH-SPLIMBATCH-.####", + "create_new_batch": 1, + }, + ).name + + make_stock_entry(item=item, to_warehouse=warehouse, qty=5) + make_stock_entry(item=item, to_warehouse=warehouse, qty=5) + + so = make_sales_order(item_code=item, qty=6, rate=100) + + pl1 = create_pick_list(so.name) + pl1.save() + self.assertEqual(pl1.locations[0].qty, 5.0) + self.assertEqual(pl1.locations[1].qty, 1.0) + + so = make_sales_order(item_code=item, qty=4, rate=100) + + pl = create_pick_list(so.name) + pl.save() + self.assertEqual(pl.locations[0].qty, 4.0) + self.assertTrue(hasattr(pl, "locations")) + + pl1.submit() + + pl.reload() + pl.submit() + self.assertEqual(pl.locations[0].qty, 4.0) + self.assertTrue(hasattr(pl, "locations"))