fix: incorrect batch fetched for the serialized items (#20119)
* fix: incorrect batch fetched for the serialized items * Update stock_controller.py Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
fe0adc8b25
commit
9af557f9d7
@ -20,6 +20,7 @@ class StockController(AccountsController):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
super(StockController, self).validate()
|
super(StockController, self).validate()
|
||||||
self.validate_inspection()
|
self.validate_inspection()
|
||||||
|
self.validate_serialized_batch()
|
||||||
|
|
||||||
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
|
||||||
if self.docstatus == 2:
|
if self.docstatus == 2:
|
||||||
@ -42,6 +43,17 @@ class StockController(AccountsController):
|
|||||||
gl_entries = self.get_asset_gl_entry(gl_entries)
|
gl_entries = self.get_asset_gl_entry(gl_entries)
|
||||||
make_gl_entries(gl_entries, from_repost=from_repost)
|
make_gl_entries(gl_entries, from_repost=from_repost)
|
||||||
|
|
||||||
|
def validate_serialized_batch(self):
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
for d in self.get("items"):
|
||||||
|
if hasattr(d, 'serial_no') and hasattr(d, 'batch_no') and d.serial_no and d.batch_no:
|
||||||
|
serial_nos = get_serial_nos(d.serial_no)
|
||||||
|
for serial_no_data in frappe.get_all("Serial No",
|
||||||
|
filters={"name": ("in", serial_nos)}, fields=["batch_no", "name"]):
|
||||||
|
if serial_no_data.batch_no != d.batch_no:
|
||||||
|
frappe.throw(_("Row #{0}: Serial No {1} does not belong to Batch {2}")
|
||||||
|
.format(d.idx, serial_no_data.name, d.batch_no))
|
||||||
|
|
||||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
||||||
default_cost_center=None):
|
default_cost_center=None):
|
||||||
|
|
||||||
|
|||||||
@ -226,16 +226,14 @@ def set_batch_nos(doc, warehouse_field, throw=False):
|
|||||||
warehouse = d.get(warehouse_field, None)
|
warehouse = d.get(warehouse_field, None)
|
||||||
if has_batch_no and warehouse and qty > 0:
|
if has_batch_no and warehouse and qty > 0:
|
||||||
if not d.batch_no:
|
if not d.batch_no:
|
||||||
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw)
|
d.batch_no = get_batch_no(d.item_code, warehouse, qty, throw, d.serial_no)
|
||||||
else:
|
else:
|
||||||
batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
|
batch_qty = get_batch_qty(batch_no=d.batch_no, warehouse=warehouse)
|
||||||
if flt(batch_qty, d.precision("qty")) < flt(qty, d.precision("qty")):
|
if flt(batch_qty, d.precision("qty")) < flt(qty, d.precision("qty")):
|
||||||
frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, qty))
|
frappe.throw(_("Row #{0}: The batch {1} has only {2} qty. Please select another batch which has {3} qty available or split the row into multiple rows, to deliver/issue from multiple batches").format(d.idx, d.batch_no, batch_qty, qty))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
def get_batch_no(item_code, warehouse, qty=1, throw=False, serial_no=None):
|
||||||
"""
|
"""
|
||||||
Get batch number using First Expiring First Out method.
|
Get batch number using First Expiring First Out method.
|
||||||
:param item_code: `item_code` of Item Document
|
:param item_code: `item_code` of Item Document
|
||||||
@ -245,7 +243,7 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
batch_no = None
|
batch_no = None
|
||||||
batches = get_batches(item_code, warehouse, qty, throw)
|
batches = get_batches(item_code, warehouse, qty, throw, serial_no)
|
||||||
|
|
||||||
for batch in batches:
|
for batch in batches:
|
||||||
if cint(qty) <= cint(batch.qty):
|
if cint(qty) <= cint(batch.qty):
|
||||||
@ -260,7 +258,23 @@ def get_batch_no(item_code, warehouse, qty=1, throw=False):
|
|||||||
return batch_no
|
return batch_no
|
||||||
|
|
||||||
|
|
||||||
def get_batches(item_code, warehouse, qty=1, throw=False):
|
def get_batches(item_code, warehouse, qty=1, throw=False, serial_no=None):
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
cond = ''
|
||||||
|
if serial_no:
|
||||||
|
batch = frappe.get_all("Serial No",
|
||||||
|
fields = ["distinct batch_no"],
|
||||||
|
filters= {
|
||||||
|
"item_code": item_code,
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"name": ("in", get_serial_nos(serial_no))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if batch and len(batch) > 1:
|
||||||
|
return []
|
||||||
|
|
||||||
|
cond = " and `tabBatch`.name = %s" %(frappe.db.escape(batch[0].batch_no))
|
||||||
|
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select batch_id, sum(`tabStock Ledger Entry`.actual_qty) as qty
|
select batch_id, sum(`tabStock Ledger Entry`.actual_qty) as qty
|
||||||
@ -268,7 +282,7 @@ def get_batches(item_code, warehouse, qty=1, throw=False):
|
|||||||
join `tabStock Ledger Entry` ignore index (item_code, warehouse)
|
join `tabStock Ledger Entry` ignore index (item_code, warehouse)
|
||||||
on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )
|
on (`tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )
|
||||||
where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s
|
where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s
|
||||||
and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)
|
and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL) {0}
|
||||||
group by batch_id
|
group by batch_id
|
||||||
order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC
|
order by `tabBatch`.expiry_date ASC, `tabBatch`.creation ASC
|
||||||
""", (item_code, warehouse), as_dict=True)
|
""".format(cond), (item_code, warehouse), as_dict=True)
|
||||||
@ -75,6 +75,7 @@ class StockEntry(StockController):
|
|||||||
set_batch_nos(self, 's_warehouse')
|
set_batch_nos(self, 's_warehouse')
|
||||||
|
|
||||||
self.set_incoming_rate()
|
self.set_incoming_rate()
|
||||||
|
self.validate_serialized_batch()
|
||||||
self.set_actual_qty()
|
self.set_actual_qty()
|
||||||
self.calculate_rate_and_amount(update_finished_item_rate=False)
|
self.calculate_rate_and_amount(update_finished_item_rate=False)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user