mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-16 16:15:02 +00:00
fix: batch qty calculation performance issue
(cherry picked from commit 1a262483a4)
This commit is contained in:
committed by
Mergify
parent
08cfd00373
commit
921f317423
@@ -957,7 +957,9 @@ class StockController(AccountsController):
|
||||
from erpnext.stock.stock_ledger import make_sl_entries
|
||||
|
||||
make_sl_entries(sl_entries, allow_negative_stock, via_landed_cost_voucher)
|
||||
update_batch_qty(self.doctype, self.name, via_landed_cost_voucher=via_landed_cost_voucher)
|
||||
update_batch_qty(
|
||||
self.doctype, self.name, self.docstatus, via_landed_cost_voucher=via_landed_cost_voucher
|
||||
)
|
||||
|
||||
def make_gl_entries_on_cancel(self, from_repost=False):
|
||||
if not from_repost:
|
||||
|
||||
@@ -222,7 +222,12 @@ class TestSerialandBatchBundle(FrappeTestCase):
|
||||
).insert(ignore_permissions=True)
|
||||
|
||||
self.assertTrue(batch_doc.use_batchwise_valuation)
|
||||
batch_doc.db_set("use_batchwise_valuation", 0)
|
||||
batch_doc.db_set(
|
||||
{
|
||||
"use_batchwise_valuation": 0,
|
||||
"batch_qty": 30,
|
||||
}
|
||||
)
|
||||
|
||||
stock_queue = []
|
||||
qty_after_transaction = 0
|
||||
|
||||
@@ -1326,40 +1326,40 @@ def get_serial_nos_batch(serial_nos):
|
||||
)
|
||||
|
||||
|
||||
def update_batch_qty(voucher_type, voucher_no, via_landed_cost_voucher=False):
|
||||
from erpnext.stock.doctype.batch.batch import get_available_batches
|
||||
|
||||
batches = get_distinct_batches(voucher_type, voucher_no)
|
||||
def update_batch_qty(voucher_type, voucher_no, docstatus, via_landed_cost_voucher=False):
|
||||
batches = get_batchwise_qty(voucher_type, voucher_no)
|
||||
if not batches:
|
||||
return
|
||||
|
||||
precision = frappe.get_precision("Batch", "batch_qty")
|
||||
batch_data = get_available_batches(
|
||||
frappe._dict({"batch_no": batches, "consider_negative_batches": 1, "based_on_warehouse": True})
|
||||
)
|
||||
batchwise_qty = defaultdict(float)
|
||||
for batch, qty in batches.items():
|
||||
current_qty = get_batch_current_qty(batch)
|
||||
current_qty += flt(qty, precision) * (-1 if docstatus == 2 else 1)
|
||||
|
||||
for (batch_no, warehouse), qty in batch_data.items():
|
||||
if not via_landed_cost_voucher and flt(qty, precision) < 0:
|
||||
throw_negative_batch_validation(batch_no, warehouse, qty)
|
||||
if not via_landed_cost_voucher and current_qty < 0:
|
||||
throw_negative_batch_validation(batch, current_qty)
|
||||
|
||||
batchwise_qty[batch_no] += qty
|
||||
|
||||
for batch_no in batches:
|
||||
qty = flt(batchwise_qty.get(batch_no, 0), precision)
|
||||
frappe.db.set_value("Batch", batch_no, "batch_qty", qty)
|
||||
frappe.db.set_value("Batch", batch, "batch_qty", current_qty)
|
||||
|
||||
|
||||
def throw_negative_batch_validation(batch_no, warehouse, qty):
|
||||
def get_batch_current_qty(batch):
|
||||
doctype = frappe.qb.DocType("Batch")
|
||||
query = frappe.qb.from_(doctype).select(doctype.batch_qty).where(doctype.name == batch).for_update()
|
||||
batch_qty = query.run()
|
||||
|
||||
return flt(batch_qty[0][0]) if batch_qty else 0.0
|
||||
|
||||
|
||||
def throw_negative_batch_validation(batch_no, qty):
|
||||
frappe.throw(
|
||||
_("The Batch {0} has negative quantity {1} in warehouse {2}. Please correct the quantity.").format(
|
||||
bold(batch_no), bold(qty), bold(warehouse)
|
||||
_("The Batch {0} has negative quantity {1}. Please correct the quantity.").format(
|
||||
bold(batch_no), bold(qty)
|
||||
),
|
||||
title=_("Negative Batch Quantity"),
|
||||
)
|
||||
|
||||
|
||||
def get_distinct_batches(voucher_type, voucher_no):
|
||||
def get_batchwise_qty(voucher_type, voucher_no):
|
||||
bundles = frappe.get_all(
|
||||
"Serial and Batch Bundle",
|
||||
filters={"voucher_no": voucher_no, "voucher_type": voucher_type},
|
||||
@@ -1368,9 +1368,15 @@ def get_distinct_batches(voucher_type, voucher_no):
|
||||
if not bundles:
|
||||
return
|
||||
|
||||
return frappe.get_all(
|
||||
batches = frappe.get_all(
|
||||
"Serial and Batch Entry",
|
||||
filters={"parent": ("in", bundles), "batch_no": ("is", "set")},
|
||||
fields=["batch_no", "SUM(qty) as qty"],
|
||||
group_by="batch_no",
|
||||
pluck="batch_no",
|
||||
as_list=1,
|
||||
)
|
||||
|
||||
if not batches:
|
||||
return frappe._dict({})
|
||||
|
||||
return frappe._dict(batches)
|
||||
|
||||
Reference in New Issue
Block a user