fix: do not reset picked items
This commit is contained in:
@@ -74,9 +74,8 @@ class PickList(Document):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_for_qty()
|
self.validate_for_qty()
|
||||||
if self.pick_manually and self.get("locations"):
|
self.validate_stock_qty()
|
||||||
self.validate_stock_qty()
|
self.check_serial_no_status()
|
||||||
self.check_serial_no_status()
|
|
||||||
|
|
||||||
def before_save(self):
|
def before_save(self):
|
||||||
self.update_status()
|
self.update_status()
|
||||||
@@ -90,14 +89,24 @@ class PickList(Document):
|
|||||||
from erpnext.stock.doctype.batch.batch import get_batch_qty
|
from erpnext.stock.doctype.batch.batch import get_batch_qty
|
||||||
|
|
||||||
for row in self.get("locations"):
|
for row in self.get("locations"):
|
||||||
if row.batch_no and not row.qty:
|
if not row.picked_qty:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if row.batch_no and row.picked_qty:
|
||||||
batch_qty = get_batch_qty(row.batch_no, row.warehouse, row.item_code)
|
batch_qty = get_batch_qty(row.batch_no, row.warehouse, row.item_code)
|
||||||
|
|
||||||
if row.qty > batch_qty:
|
if row.picked_qty > batch_qty:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_(
|
_(
|
||||||
"At Row #{0}: The picked quantity {1} for the item {2} is greater than available stock {3} for the batch {4} in the warehouse {5}."
|
"At Row #{0}: The picked quantity {1} for the item {2} is greater than available stock {3} for the batch {4} in the warehouse {5}. Please restock the item."
|
||||||
).format(row.idx, row.item_code, batch_qty, row.batch_no, bold(row.warehouse)),
|
).format(
|
||||||
|
row.idx,
|
||||||
|
row.picked_qty,
|
||||||
|
row.item_code,
|
||||||
|
batch_qty,
|
||||||
|
row.batch_no,
|
||||||
|
bold(row.warehouse),
|
||||||
|
),
|
||||||
title=_("Insufficient Stock"),
|
title=_("Insufficient Stock"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,11 +118,11 @@ class PickList(Document):
|
|||||||
"actual_qty",
|
"actual_qty",
|
||||||
)
|
)
|
||||||
|
|
||||||
if row.qty > flt(bin_qty):
|
if row.picked_qty > flt(bin_qty):
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_(
|
_(
|
||||||
"At Row #{0}: The picked quantity {1} for the item {2} is greater than available stock {3} in the warehouse {4}."
|
"At Row #{0}: The picked quantity {1} for the item {2} is greater than available stock {3} in the warehouse {4}."
|
||||||
).format(row.idx, row.qty, bold(row.item_code), bin_qty, bold(row.warehouse)),
|
).format(row.idx, row.picked_qty, bold(row.item_code), bin_qty, bold(row.warehouse)),
|
||||||
title=_("Insufficient Stock"),
|
title=_("Insufficient Stock"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -429,7 +438,14 @@ class PickList(Document):
|
|||||||
locations_replica = self.get("locations")
|
locations_replica = self.get("locations")
|
||||||
|
|
||||||
# reset
|
# reset
|
||||||
self.delete_key("locations")
|
reset_rows = []
|
||||||
|
for row in self.get("locations"):
|
||||||
|
if not row.picked_qty:
|
||||||
|
reset_rows.append(row)
|
||||||
|
|
||||||
|
for row in reset_rows:
|
||||||
|
self.remove(row)
|
||||||
|
|
||||||
updated_locations = frappe._dict()
|
updated_locations = frappe._dict()
|
||||||
for item_doc in items:
|
for item_doc in items:
|
||||||
item_code = item_doc.item_code
|
item_code = item_doc.item_code
|
||||||
@@ -499,6 +515,9 @@ class PickList(Document):
|
|||||||
# aggregate qty for same item
|
# aggregate qty for same item
|
||||||
item_map = OrderedDict()
|
item_map = OrderedDict()
|
||||||
for item in locations:
|
for item in locations:
|
||||||
|
if item.picked_qty:
|
||||||
|
continue
|
||||||
|
|
||||||
if not item.item_code:
|
if not item.item_code:
|
||||||
frappe.throw(f"Row #{item.idx}: Item Code is Mandatory")
|
frappe.throw(f"Row #{item.idx}: Item Code is Mandatory")
|
||||||
if not cint(
|
if not cint(
|
||||||
|
|||||||
@@ -879,7 +879,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
|
|
||||||
so = make_sales_order(item_code=item, qty=4, rate=100)
|
so = make_sales_order(item_code=item, qty=4, rate=100)
|
||||||
pl = create_pick_list(so.name)
|
pl = create_pick_list(so.name)
|
||||||
self.assertFalse(hasattr(pl, "locations"))
|
self.assertFalse(pl.locations)
|
||||||
|
|
||||||
def test_pick_list_validation_for_serial_no(self):
|
def test_pick_list_validation_for_serial_no(self):
|
||||||
warehouse = "_Test Warehouse - _TC"
|
warehouse = "_Test Warehouse - _TC"
|
||||||
@@ -910,7 +910,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
|
|
||||||
so = make_sales_order(item_code=item, qty=4, rate=100)
|
so = make_sales_order(item_code=item, qty=4, rate=100)
|
||||||
pl = create_pick_list(so.name)
|
pl = create_pick_list(so.name)
|
||||||
self.assertFalse(hasattr(pl, "locations"))
|
self.assertFalse(pl.locations)
|
||||||
|
|
||||||
def test_pick_list_validation_for_batch_no(self):
|
def test_pick_list_validation_for_batch_no(self):
|
||||||
warehouse = "_Test Warehouse - _TC"
|
warehouse = "_Test Warehouse - _TC"
|
||||||
@@ -946,7 +946,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
|
|
||||||
so = make_sales_order(item_code=item, qty=4, rate=100)
|
so = make_sales_order(item_code=item, qty=4, rate=100)
|
||||||
pl = create_pick_list(so.name)
|
pl = create_pick_list(so.name)
|
||||||
self.assertFalse(hasattr(pl, "locations"))
|
self.assertFalse(pl.locations)
|
||||||
|
|
||||||
def test_pick_list_validation_for_batch_no_and_serial_item(self):
|
def test_pick_list_validation_for_batch_no_and_serial_item(self):
|
||||||
warehouse = "_Test Warehouse - _TC"
|
warehouse = "_Test Warehouse - _TC"
|
||||||
@@ -986,7 +986,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
|
|
||||||
so = make_sales_order(item_code=item, qty=4, rate=100)
|
so = make_sales_order(item_code=item, qty=4, rate=100)
|
||||||
pl = create_pick_list(so.name)
|
pl = create_pick_list(so.name)
|
||||||
self.assertFalse(hasattr(pl, "locations"))
|
self.assertFalse(pl.locations)
|
||||||
|
|
||||||
def test_pick_list_validation_for_multiple_batches_and_sales_order(self):
|
def test_pick_list_validation_for_multiple_batches_and_sales_order(self):
|
||||||
warehouse = "_Test Warehouse - _TC"
|
warehouse = "_Test Warehouse - _TC"
|
||||||
@@ -1181,6 +1181,7 @@ class TestPickList(IntegrationTestCase):
|
|||||||
|
|
||||||
for row in pl.locations:
|
for row in pl.locations:
|
||||||
row.qty = row.qty + 10
|
row.qty = row.qty + 10
|
||||||
|
row.picked_qty = row.qty
|
||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, pl.save)
|
self.assertRaises(frappe.ValidationError, pl.save)
|
||||||
|
|
||||||
@@ -1275,3 +1276,42 @@ class TestPickList(IntegrationTestCase):
|
|||||||
delivery_note = create_delivery_note(pl.name)
|
delivery_note = create_delivery_note(pl.name)
|
||||||
|
|
||||||
self.assertEqual(len(delivery_note.items), 1)
|
self.assertEqual(len(delivery_note.items), 1)
|
||||||
|
|
||||||
|
def test_pick_list_not_reset_batch(self):
|
||||||
|
warehouse = "_Test Warehouse - _TC"
|
||||||
|
item = make_item(
|
||||||
|
"Test Do Not Reset Picked Item",
|
||||||
|
properties={
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"has_batch_no": 1,
|
||||||
|
"create_new_batch": 1,
|
||||||
|
"batch_number_series": "BTH-PICKLT-.######",
|
||||||
|
},
|
||||||
|
).name
|
||||||
|
|
||||||
|
se = make_stock_entry(item=item, to_warehouse=warehouse, qty=10)
|
||||||
|
batch1 = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
|
||||||
|
se = make_stock_entry(item=item, to_warehouse=warehouse, qty=10)
|
||||||
|
batch2 = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
|
||||||
|
|
||||||
|
so = make_sales_order(item_code=item, qty=10, rate=100)
|
||||||
|
|
||||||
|
pl = create_pick_list(so.name)
|
||||||
|
pl.save()
|
||||||
|
|
||||||
|
for loc in pl.locations:
|
||||||
|
self.assertEqual(loc.batch_no, batch1)
|
||||||
|
loc.batch_no = batch2
|
||||||
|
loc.picked_qty = 0.0
|
||||||
|
|
||||||
|
pl.save()
|
||||||
|
|
||||||
|
for loc in pl.locations:
|
||||||
|
self.assertEqual(loc.batch_no, batch1)
|
||||||
|
loc.batch_no = batch2
|
||||||
|
loc.picked_qty = 10.0
|
||||||
|
|
||||||
|
pl.save()
|
||||||
|
|
||||||
|
for loc in pl.locations:
|
||||||
|
self.assertEqual(loc.batch_no, batch2)
|
||||||
|
|||||||
Reference in New Issue
Block a user