fix: not able to submit backdated stock reco

This commit is contained in:
Rohit Waghchaure
2026-01-03 14:56:12 +05:30
parent 3d4c8d6d35
commit cccd34b06a
3 changed files with 100 additions and 6 deletions

View File

@@ -76,6 +76,9 @@ class RepostItemValuation(Document):
def on_discard(self):
self.db_set("status", "Cancelled")
def repost_now(self):
repost(self)
def validate(self):
self.reset_repost_only_accounting_ledgers()
self.set_company()

View File

@@ -554,7 +554,7 @@ class SerialandBatchBundle(Document):
available_qty += flt(d.qty, precision)
if not allow_negative_stock:
self.validate_negative_batch(d.batch_no, available_qty)
self.validate_negative_batch(d.batch_no, available_qty, field)
d.stock_value_difference = flt(d.qty) * flt(d.incoming_rate)
@@ -567,8 +567,8 @@ class SerialandBatchBundle(Document):
}
)
def validate_negative_batch(self, batch_no, available_qty):
if available_qty < 0 and not self.is_stock_reco_for_valuation_adjustment(available_qty):
def validate_negative_batch(self, batch_no, available_qty, field=None):
if available_qty < 0 and not self.is_stock_reco_for_valuation_adjustment(available_qty, field=field):
msg = f"""Batch No {bold(batch_no)} of an Item {bold(self.item_code)}
has negative stock
of quantity {bold(available_qty)} in the
@@ -576,13 +576,16 @@ class SerialandBatchBundle(Document):
frappe.throw(_(msg), BatchNegativeStockError)
def is_stock_reco_for_valuation_adjustment(self, available_qty):
def is_stock_reco_for_valuation_adjustment(self, available_qty, field=None):
if (
self.voucher_type == "Stock Reconciliation"
and self.type_of_transaction == "Outward"
and self.voucher_detail_no
and abs(frappe.db.get_value("Stock Reconciliation Item", self.voucher_detail_no, "qty"))
== abs(available_qty)
and (
abs(frappe.db.get_value("Stock Reconciliation Item", self.voucher_detail_no, "qty"))
== abs(available_qty)
or field == "total_qty"
)
):
return True

View File

@@ -1569,6 +1569,94 @@ class TestStockReconciliation(IntegrationTestCase, StockTestMixin):
self.assertFalse(status == "Active")
def test_change_valuation_of_batch_using_backdated_stock_reco(self):
from erpnext.stock.doctype.batch.batch import get_batch_qty
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
item_code = self.make_item(
"Test Item Change Valuation of Batch",
{
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TEST-BATCH-CVB-.###",
},
).name
warehouse = "_Test Warehouse - _TC"
reco = create_stock_reconciliation(
item_code=item_code,
posting_date=add_days(nowdate(), -6),
warehouse=warehouse,
qty=10,
rate=80,
use_serial_batch_fields=1,
)
batch_no = get_batch_from_bundle(reco.items[0].serial_and_batch_bundle)
make_stock_entry(
item_code=item_code,
source=warehouse,
qty=2,
posting_date=add_days(nowdate(), -4),
use_serial_batch_fields=1,
batch_no=batch_no,
)
make_stock_entry(
item_code=item_code,
source=warehouse,
qty=2,
posting_date=add_days(nowdate(), -3),
use_serial_batch_fields=1,
batch_no=batch_no,
)
se4 = make_stock_entry(
item_code=item_code,
source=warehouse,
qty=2,
posting_date=add_days(nowdate(), -2),
use_serial_batch_fields=1,
batch_no=batch_no,
)
sle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_no": se4.name, "is_cancelled": 0},
["actual_qty", "stock_value_difference"],
as_dict=1,
)
valuation_rate = sle.stock_value_difference / sle.actual_qty
self.assertEqual(valuation_rate, 80)
create_stock_reconciliation(
item_code=item_code,
posting_date=add_days(nowdate(), -5),
warehouse=warehouse,
qty=10,
rate=100,
use_serial_batch_fields=1,
batch_no=batch_no,
)
sle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_no": se4.name, "is_cancelled": 0},
["actual_qty", "stock_value_difference"],
as_dict=1,
)
valuation_rate = sle.stock_value_difference / sle.actual_qty
self.assertEqual(valuation_rate, 100)
batch_qty = get_batch_qty(batch_no, warehouse, item_code)
self.assertEqual(batch_qty, 4)
def create_batch_item_with_batch(item_name, batch_id):
batch_item_doc = create_item(item_name, is_stock_item=1)