Skip to content

Commit

Permalink
fix: not able to reconciliation expired batches
Browse files Browse the repository at this point in the history
  • Loading branch information
rohitwaghchaure committed Nov 7, 2024
1 parent 44832c3 commit 2ac2eeb
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 7 deletions.
10 changes: 8 additions & 2 deletions erpnext/controllers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,6 @@ def get_batches_from_stock_ledger_entries(searchfields, txt, filters, start=0, p
stock_ledger_entry.batch_no,
Sum(stock_ledger_entry.actual_qty).as_("qty"),
)
.where((batch_table.expiry_date >= expiry_date) | (batch_table.expiry_date.isnull()))
.where(stock_ledger_entry.is_cancelled == 0)
.where(
(stock_ledger_entry.item_code == filters.get("item_code"))
Expand All @@ -433,6 +432,9 @@ def get_batches_from_stock_ledger_entries(searchfields, txt, filters, start=0, p
.limit(page_len)
)

if not filters.get("include_expired_batches"):
query = query.where((batch_table.expiry_date >= expiry_date) | (batch_table.expiry_date.isnull()))

query = query.select(
Concat("MFG-", batch_table.manufacturing_date).as_("manufacturing_date"),
Concat("EXP-", batch_table.expiry_date).as_("expiry_date"),
Expand Down Expand Up @@ -471,7 +473,6 @@ def get_batches_from_serial_and_batch_bundle(searchfields, txt, filters, start=0
bundle.batch_no,
Sum(bundle.qty).as_("qty"),
)
.where((batch_table.expiry_date >= expiry_date) | (batch_table.expiry_date.isnull()))
.where(stock_ledger_entry.is_cancelled == 0)
.where(
(stock_ledger_entry.item_code == filters.get("item_code"))
Expand All @@ -484,6 +485,11 @@ def get_batches_from_serial_and_batch_bundle(searchfields, txt, filters, start=0
.limit(page_len)
)

if not filters.get("include_expired_batches"):
bundle_query = bundle_query.where(
(batch_table.expiry_date >= expiry_date) | (batch_table.expiry_date.isnull())
)

bundle_query = bundle_query.select(
Concat("MFG-", batch_table.manufacturing_date),
Concat("EXP-", batch_table.expiry_date),
Expand Down
11 changes: 11 additions & 0 deletions erpnext/public/js/utils/serial_no_batch_selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,13 +457,16 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
is_inward = true;
}

let include_expired_batches = me.include_expired_batches();

return {
query: "erpnext.controllers.queries.get_batch_no",
filters: {
item_code: this.item.item_code,
warehouse:
this.item.s_warehouse || this.item.t_warehouse || this.item.warehouse,
is_inward: is_inward,
include_expired_batches: include_expired_batches,
},
};
},
Expand Down Expand Up @@ -492,6 +495,14 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
return fields;
}

include_expired_batches() {
return (
this.frm.doc.doctype === "Stock Reconciliation" ||
(this.frm.doc.doctype === "Stock Entry" &&
["Material Receipt", "Material Transfer", "Material Issue"].includes(this.frm.doc.purpose))
);
}

get_auto_data() {
let { qty, based_on } = this.dialog.get_values();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,18 @@ def validate_serial_nos_duplicate(self):
kwargs = frappe._dict(
{
"item_code": self.item_code,
"posting_date": self.posting_date,
"posting_time": self.posting_time,
"serial_nos": serial_nos,
}
)

if self.voucher_type == "Stock Reconciliation":
kwargs.update(
{
"posting_date": self.posting_date,
"posting_time": self.posting_time,
}
)

if self.returned_against and self.docstatus == 1:
kwargs["ignore_voucher_detail_no"] = self.voucher_detail_no

Expand Down Expand Up @@ -689,6 +695,9 @@ def validate_serial_and_batch_no(self):
serial_batches = {}
for row in self.entries:
if not row.qty and row.batch_no and not row.serial_no:
if self.voucher_type == "Stock Reconciliation" and self.type_of_transaction == "Inward":
continue

frappe.throw(
_("At row {0}: Qty is mandatory for the batch {1}").format(
bold(row.idx), bold(row.batch_no)
Expand Down
4 changes: 4 additions & 0 deletions erpnext/stock/doctype/stock_entry/stock_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ frappe.ui.form.on("Stock Entry", {
filters["is_inward"] = 1;
}

if (["Material Receipt", "Material Transfer", "Material Issue"].includes(doc.purpose)) {
filters["include_expired_batches"] = 1;
}

return {
query: "erpnext.controllers.queries.get_batch_no",
filters: filters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ def get_bundle_for_specific_serial_batch(self, row) -> str:
row.item_code,
posting_date=self.posting_date,
posting_time=self.posting_time,
for_stock_levels=True,
)

total_current_qty += current_qty
Expand Down Expand Up @@ -1322,7 +1323,16 @@ def get_stock_balance_for(
qty, rate = data

if item_dict.get("has_batch_no"):
qty = get_batch_qty(batch_no, warehouse, posting_date=posting_date, posting_time=posting_time) or 0
qty = (
get_batch_qty(
batch_no,
warehouse,
posting_date=posting_date,
posting_time=posting_time,
for_stock_levels=True,
)
or 0
)

return {
"qty": qty,
Expand Down
4 changes: 2 additions & 2 deletions erpnext/stock/serial_batch_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def validate_actual_qty(self, sn_doc):
"Outward": self.sle.actual_qty < 0,
}.get(sn_doc.type_of_transaction)

if not condition:
if not condition and self.sle.actual_qty:
correct_type = "Inward"
if sn_doc.type_of_transaction == "Inward":
correct_type = "Outward"
Expand All @@ -133,7 +133,7 @@ def validate_actual_qty(self, sn_doc):
frappe.throw(_(msg), title=_("Incorrect Type of Transaction"))

precision = sn_doc.precision("total_qty")
if flt(sn_doc.total_qty, precision) != flt(self.sle.actual_qty, precision):
if self.sle.actual_qty and flt(sn_doc.total_qty, precision) != flt(self.sle.actual_qty, precision):
msg = f"Total qty {flt(sn_doc.total_qty, precision)} of Serial and Batch Bundle {link} is not equal to Actual Qty {flt(self.sle.actual_qty, precision)} in the {self.sle.voucher_type} {self.sle.voucher_no}"
frappe.throw(_(msg))

Expand Down
1 change: 1 addition & 0 deletions erpnext/stock/stock_ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ def recalculate_amounts_in_stock_entry(self, voucher_no, voucher_detail_no):
stock_entry.calculate_rate_and_amount(reset_outgoing_rate=False, raise_error_if_no_rate=False)
stock_entry.db_update()
for d in stock_entry.items:
# Update only the row that matches the voucher_detail_no or the row containing an FG/Scrap Item.
if d.name == voucher_detail_no or (not d.s_warehouse and d.t_warehouse):
d.db_update()

Expand Down

0 comments on commit 2ac2eeb

Please sign in to comment.