Merge pull request #51214 from aerele/fix/recalculate-batch-qty

fix(stock): ignore reserved stock while calculating batch qty
This commit is contained in:
rohitwaghchaure
2025-12-19 18:00:04 +05:30
committed by GitHub
3 changed files with 45 additions and 2 deletions

View File

@@ -159,8 +159,13 @@ class Batch(Document):
@frappe.whitelist() @frappe.whitelist()
def recalculate_batch_qty(self): def recalculate_batch_qty(self):
batches = get_batch_qty( batches = get_batch_qty(
batch_no=self.name, item_code=self.item, for_stock_levels=True, consider_negative_batches=True batch_no=self.name,
item_code=self.item,
for_stock_levels=True,
consider_negative_batches=True,
ignore_reserved_stock=True,
) )
batch_qty = 0.0 batch_qty = 0.0
if batches: if batches:
for row in batches: for row in batches:
@@ -241,6 +246,7 @@ def get_batch_qty(
for_stock_levels=False, for_stock_levels=False,
consider_negative_batches=False, consider_negative_batches=False,
do_not_check_future_batches=False, do_not_check_future_batches=False,
ignore_reserved_stock=False,
): ):
"""Returns batch actual qty if warehouse is passed, """Returns batch actual qty if warehouse is passed,
or returns dict of qty by warehouse if warehouse is None or returns dict of qty by warehouse if warehouse is None
@@ -269,6 +275,7 @@ def get_batch_qty(
"for_stock_levels": for_stock_levels, "for_stock_levels": for_stock_levels,
"consider_negative_batches": consider_negative_batches, "consider_negative_batches": consider_negative_batches,
"do_not_check_future_batches": do_not_check_future_batches, "do_not_check_future_batches": do_not_check_future_batches,
"ignore_reserved_stock": ignore_reserved_stock,
} }
) )

View File

@@ -324,6 +324,38 @@ class TestBatch(IntegrationTestCase):
self.assertEqual(get_batch_qty("batch a", "_Test Warehouse - _TC"), 90) self.assertEqual(get_batch_qty("batch a", "_Test Warehouse - _TC"), 90)
def test_ignore_reserved_qty(self):
from erpnext.selling.doctype.sales_order.sales_order import create_pick_list
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
batch_item_name = "Reserve Batch Item"
batch_id = "Reserve Batch 1"
# Create Batch Item
self.make_batch_item(batch_item_name)
# Create Batch and Material Receipt Entry with qty 90
self.make_new_batch_and_entry(batch_item_name, batch_id, "_Test Warehouse - _TC")
# Enable Stock Reservation
frappe.db.set_single_value("Stock Settings", "enable_stock_reservation", 1)
# Create Sales Order with qty 50
sales_order = make_sales_order(
item_code=batch_item_name, warehouse="_Test Warehouse - _TC", qty=50, rate=20
)
# Create Pick List for the Sales Order
pl = create_pick_list(sales_order.name)
pl.submit()
# Create Stock Reservation Entries
pl.create_stock_reservation_entries(notify=False)
batch = frappe.get_doc("Batch", batch_id)
# Recalculate Batch Qty
batch.recalculate_batch_qty()
batch.reload()
# Case: Ignore Reserved Qty
self.assertEqual(batch.batch_qty, 90)
def test_total_batch_qty(self): def test_total_batch_qty(self):
self.make_batch_item("ITEM-BATCH-3") self.make_batch_item("ITEM-BATCH-3")
existing_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty")) existing_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))

View File

@@ -2495,7 +2495,11 @@ def get_auto_batch_nos(kwargs):
available_batches = get_available_batches(kwargs) available_batches = get_available_batches(kwargs)
stock_ledgers_batches = get_stock_ledgers_batches(kwargs) stock_ledgers_batches = get_stock_ledgers_batches(kwargs)
pos_invoice_batches = get_reserved_batches_for_pos(kwargs) pos_invoice_batches = get_reserved_batches_for_pos(kwargs)
sre_reserved_batches = get_reserved_batches_for_sre(kwargs)
sre_reserved_batches = frappe._dict()
if not kwargs.ignore_reserved_stock:
sre_reserved_batches = get_reserved_batches_for_sre(kwargs)
if kwargs.against_sales_order and only_consider_batches: if kwargs.against_sales_order and only_consider_batches:
kwargs.batch_no = kwargs.warehouse = None kwargs.batch_no = kwargs.warehouse = None