mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-28 06:08:25 +00:00
fix(stock): preserve LCV quantity across stock reconciliation (#58309)
Co-authored-by: RamachandranMD <ramachandran.md@finstein.ai>
This commit is contained in:
@@ -1333,6 +1333,70 @@ class TestLandedCostVoucher(ERPNextTestSuite):
|
|||||||
|
|
||||||
self.assertFalse(gl_entries)
|
self.assertFalse(gl_entries)
|
||||||
|
|
||||||
|
def test_landed_cost_voucher_does_not_change_qty_across_stock_reco(self):
|
||||||
|
"""LCV cost updates must not change quantity after a batch stock reconciliation."""
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
||||||
|
create_stock_reconciliation,
|
||||||
|
)
|
||||||
|
|
||||||
|
company = "_Test Company with perpetual inventory"
|
||||||
|
warehouse = "Stores - TCP1"
|
||||||
|
item = make_item(
|
||||||
|
properties={"has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "LCVRECO-.####"}
|
||||||
|
).name
|
||||||
|
first_batch = frappe.get_doc({"doctype": "Batch", "item": item}).insert().name
|
||||||
|
second_batch = frappe.get_doc({"doctype": "Batch", "item": item}).insert().name
|
||||||
|
|
||||||
|
# Inspect the immediate LCV result before a queued repost repairs it.
|
||||||
|
frappe.flags.dont_execute_stock_reposts = True
|
||||||
|
self.addCleanup(frappe.flags.pop, "dont_execute_stock_reposts", None)
|
||||||
|
|
||||||
|
receipt = make_purchase_receipt(
|
||||||
|
company=company,
|
||||||
|
warehouse=warehouse,
|
||||||
|
item_code=item,
|
||||||
|
qty=100,
|
||||||
|
rate=10,
|
||||||
|
use_serial_batch_fields=1,
|
||||||
|
batch_no=first_batch,
|
||||||
|
posting_date=add_days(today(), -30),
|
||||||
|
)
|
||||||
|
make_purchase_receipt(
|
||||||
|
company=company,
|
||||||
|
warehouse=warehouse,
|
||||||
|
item_code=item,
|
||||||
|
qty=60,
|
||||||
|
rate=10,
|
||||||
|
use_serial_batch_fields=1,
|
||||||
|
batch_no=second_batch,
|
||||||
|
posting_date=add_days(today(), -28),
|
||||||
|
)
|
||||||
|
create_stock_reconciliation(
|
||||||
|
company=company,
|
||||||
|
warehouse=warehouse,
|
||||||
|
item_code=item,
|
||||||
|
qty=55,
|
||||||
|
rate=10,
|
||||||
|
use_serial_batch_fields=1,
|
||||||
|
batch_no=second_batch,
|
||||||
|
posting_date=add_days(today(), -20),
|
||||||
|
)
|
||||||
|
|
||||||
|
def closing_balance():
|
||||||
|
return frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
filters={"item_code": item, "warehouse": warehouse, "is_cancelled": 0},
|
||||||
|
fields=["qty_after_transaction"],
|
||||||
|
order_by="posting_datetime desc, creation desc",
|
||||||
|
limit=1,
|
||||||
|
)[0].qty_after_transaction
|
||||||
|
|
||||||
|
balance_before = closing_balance()
|
||||||
|
create_landed_cost_voucher("Purchase Receipt", receipt.name, company)
|
||||||
|
|
||||||
|
self.assertEqual(closing_balance(), balance_before)
|
||||||
|
|
||||||
|
|
||||||
def make_landed_cost_voucher(**args):
|
def make_landed_cost_voucher(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
@@ -2401,9 +2401,6 @@ def get_next_stock_reco(kwargs):
|
|||||||
.limit(1)
|
.limit(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
if kwargs.get("batch_no"):
|
|
||||||
query = query.where(sle.batch_no == kwargs.get("batch_no"))
|
|
||||||
|
|
||||||
return query.run(as_dict=True)
|
return query.run(as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user