fix: stock ledger balance qty for the batch (#40274)
(cherry picked from commit e178ffc3c1)
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
This commit is contained in:
@@ -847,7 +847,7 @@ class SerialandBatchBundle(Document):
|
|||||||
|
|
||||||
available_batches = get_available_batches_qty(available_batches)
|
available_batches = get_available_batches_qty(available_batches)
|
||||||
for batch_no in batches:
|
for batch_no in batches:
|
||||||
if batch_no not in available_batches or available_batches[batch_no] < 0:
|
if batch_no in available_batches and available_batches[batch_no] < 0:
|
||||||
if flt(available_batches.get(batch_no)) < 0:
|
if flt(available_batches.get(batch_no)) < 0:
|
||||||
self.validate_negative_batch(batch_no, available_batches[batch_no])
|
self.validate_negative_batch(batch_no, available_batches[batch_no])
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,15 @@ frappe.query_reports["Stock Ledger"] = {
|
|||||||
"fieldname":"batch_no",
|
"fieldname":"batch_no",
|
||||||
"label": __("Batch No"),
|
"label": __("Batch No"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Batch"
|
"options": "Batch",
|
||||||
|
on_change() {
|
||||||
|
const batch_no = frappe.query_report.get_filter_value('batch_no');
|
||||||
|
if (batch_no) {
|
||||||
|
frappe.query_report.set_filter_value('segregate_serial_batch_bundle', 1);
|
||||||
|
} else {
|
||||||
|
frappe.query_report.set_filter_value('segregate_serial_batch_bundle', 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"brand",
|
"fieldname":"brand",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -31,7 +32,7 @@ def execute(filters=None):
|
|||||||
bundle_details = {}
|
bundle_details = {}
|
||||||
|
|
||||||
if filters.get("segregate_serial_batch_bundle"):
|
if filters.get("segregate_serial_batch_bundle"):
|
||||||
bundle_details = get_serial_batch_bundle_details(sl_entries)
|
bundle_details = get_serial_batch_bundle_details(sl_entries, filters)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
conversion_factors = []
|
conversion_factors = []
|
||||||
@@ -47,12 +48,13 @@ def execute(filters=None):
|
|||||||
available_serial_nos = {}
|
available_serial_nos = {}
|
||||||
inventory_dimension_filters_applied = check_inventory_dimension_filters_applied(filters)
|
inventory_dimension_filters_applied = check_inventory_dimension_filters_applied(filters)
|
||||||
|
|
||||||
|
batch_balance_dict = defaultdict(float)
|
||||||
for sle in sl_entries:
|
for sle in sl_entries:
|
||||||
item_detail = item_details[sle.item_code]
|
item_detail = item_details[sle.item_code]
|
||||||
|
|
||||||
sle.update(item_detail)
|
sle.update(item_detail)
|
||||||
if bundle_info := bundle_details.get(sle.serial_and_batch_bundle):
|
if bundle_info := bundle_details.get(sle.serial_and_batch_bundle):
|
||||||
data.extend(get_segregated_bundle_entries(sle, bundle_info))
|
data.extend(get_segregated_bundle_entries(sle, bundle_info, batch_balance_dict))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if filters.get("batch_no") or inventory_dimension_filters_applied:
|
if filters.get("batch_no") or inventory_dimension_filters_applied:
|
||||||
@@ -85,7 +87,7 @@ def execute(filters=None):
|
|||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
def get_segregated_bundle_entries(sle, bundle_details):
|
def get_segregated_bundle_entries(sle, bundle_details, batch_balance_dict):
|
||||||
segregated_entries = []
|
segregated_entries = []
|
||||||
qty_before_transaction = sle.qty_after_transaction - sle.actual_qty
|
qty_before_transaction = sle.qty_after_transaction - sle.actual_qty
|
||||||
stock_value_before_transaction = sle.stock_value - sle.stock_value_difference
|
stock_value_before_transaction = sle.stock_value - sle.stock_value_difference
|
||||||
@@ -93,7 +95,6 @@ def get_segregated_bundle_entries(sle, bundle_details):
|
|||||||
for row in bundle_details:
|
for row in bundle_details:
|
||||||
new_sle = copy.deepcopy(sle)
|
new_sle = copy.deepcopy(sle)
|
||||||
new_sle.update(row)
|
new_sle.update(row)
|
||||||
|
|
||||||
new_sle.update(
|
new_sle.update(
|
||||||
{
|
{
|
||||||
"in_out_rate": flt(new_sle.stock_value_difference / row.qty) if row.qty else 0,
|
"in_out_rate": flt(new_sle.stock_value_difference / row.qty) if row.qty else 0,
|
||||||
@@ -105,6 +106,10 @@ def get_segregated_bundle_entries(sle, bundle_details):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if row.batch_no:
|
||||||
|
batch_balance_dict[row.batch_no] += row.qty
|
||||||
|
new_sle.update({"qty_after_transaction": batch_balance_dict[row.batch_no]})
|
||||||
|
|
||||||
qty_before_transaction += row.qty
|
qty_before_transaction += row.qty
|
||||||
stock_value_before_transaction += new_sle.stock_value_difference
|
stock_value_before_transaction += new_sle.stock_value_difference
|
||||||
|
|
||||||
@@ -117,7 +122,7 @@ def get_segregated_bundle_entries(sle, bundle_details):
|
|||||||
return segregated_entries
|
return segregated_entries
|
||||||
|
|
||||||
|
|
||||||
def get_serial_batch_bundle_details(sl_entries):
|
def get_serial_batch_bundle_details(sl_entries, filters=None):
|
||||||
bundle_details = []
|
bundle_details = []
|
||||||
for sle in sl_entries:
|
for sle in sl_entries:
|
||||||
if sle.serial_and_batch_bundle:
|
if sle.serial_and_batch_bundle:
|
||||||
@@ -126,10 +131,14 @@ def get_serial_batch_bundle_details(sl_entries):
|
|||||||
if not bundle_details:
|
if not bundle_details:
|
||||||
return frappe._dict({})
|
return frappe._dict({})
|
||||||
|
|
||||||
|
query_filers = {"parent": ("in", bundle_details)}
|
||||||
|
if filters.get("batch_no"):
|
||||||
|
query_filers["batch_no"] = filters.batch_no
|
||||||
|
|
||||||
_bundle_details = frappe._dict({})
|
_bundle_details = frappe._dict({})
|
||||||
batch_entries = frappe.get_all(
|
batch_entries = frappe.get_all(
|
||||||
"Serial and Batch Entry",
|
"Serial and Batch Entry",
|
||||||
filters={"parent": ("in", bundle_details)},
|
filters=query_filers,
|
||||||
fields=["parent", "qty", "incoming_rate", "stock_value_difference", "batch_no", "serial_no"],
|
fields=["parent", "qty", "incoming_rate", "stock_value_difference", "batch_no", "serial_no"],
|
||||||
order_by="parent, idx",
|
order_by="parent, idx",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -325,9 +325,7 @@ class SerialBatchBundle:
|
|||||||
batches = frappe._dict({self.sle.batch_no: self.sle.actual_qty})
|
batches = frappe._dict({self.sle.batch_no: self.sle.actual_qty})
|
||||||
|
|
||||||
batches_qty = get_available_batches(
|
batches_qty = get_available_batches(
|
||||||
frappe._dict(
|
frappe._dict({"item_code": self.item_code, "batch_no": list(batches.keys())})
|
||||||
{"item_code": self.item_code, "warehouse": self.warehouse, "batch_no": list(batches.keys())}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for batch_no in batches:
|
for batch_no in batches:
|
||||||
|
|||||||
Reference in New Issue
Block a user