fix: stock reco negative qty validation

(cherry picked from commit 289495c308)

# Conflicts:
#	erpnext/stock/stock_ledger.py
This commit is contained in:
Rohit Waghchaure
2024-04-19 15:11:28 +05:30
committed by Mergify
parent 62702b8bd6
commit aee03fe2ef
2 changed files with 119 additions and 0 deletions

View File

@@ -986,6 +986,108 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin):
active_serial_no = frappe.get_all("Serial No", filters={"status": "Active", "item_code": item_code})
self.assertEqual(len(active_serial_no), 5)
def test_balance_qty_for_batch_with_backdated_stock_reco_and_future_entries(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
item = self.make_item(
"Test Batch Item Original Test",
{
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TEST-BATCH-SRWFEE-.###",
},
)
warehouse = "_Test Warehouse - _TC"
se1 = make_stock_entry(
item_code=item.name,
target=warehouse,
qty=50,
basic_rate=100,
posting_date=add_days(nowdate(), -2),
)
batch1 = get_batch_from_bundle(se1.items[0].serial_and_batch_bundle)
se2 = make_stock_entry(
item_code=item.name,
target=warehouse,
qty=50,
basic_rate=100,
posting_date=add_days(nowdate(), -2),
)
batch2 = get_batch_from_bundle(se2.items[0].serial_and_batch_bundle)
se3 = make_stock_entry(
item_code=item.name,
target=warehouse,
qty=100,
basic_rate=100,
posting_date=add_days(nowdate(), -2),
)
batch3 = get_batch_from_bundle(se3.items[0].serial_and_batch_bundle)
se3 = make_stock_entry(
item_code=item.name,
target=warehouse,
qty=100,
basic_rate=100,
posting_date=nowdate(),
)
sle = frappe.get_all(
"Stock Ledger Entry",
filters={
"item_code": item.name,
"warehouse": warehouse,
"is_cancelled": 0,
"voucher_no": se3.name,
},
fields=["qty_after_transaction"],
order_by="posting_time desc, creation desc",
)
self.assertEqual(flt(sle[0].qty_after_transaction), flt(300.0))
sr = create_stock_reconciliation(
item_code=item.name,
warehouse=warehouse,
qty=0,
batch_no=batch1,
posting_date=add_days(nowdate(), -1),
use_serial_batch_fields=1,
do_not_save=1,
)
for batch in [batch2, batch3]:
sr.append(
"items",
{
"item_code": item.name,
"warehouse": warehouse,
"qty": 0,
"batch_no": batch,
"use_serial_batch_fields": 1,
},
)
sr.save()
sr.submit()
sle = frappe.get_all(
"Stock Ledger Entry",
filters={
"item_code": item.name,
"warehouse": warehouse,
"is_cancelled": 0,
"voucher_no": se3.name,
},
fields=["qty_after_transaction"],
order_by="posting_time desc, creation desc",
)
self.assertEqual(flt(sle[0].qty_after_transaction), flt(100.0))
def create_batch_item_with_batch(item_name, batch_id):
batch_item_doc = create_item(item_name, is_stock_item=1)

View File

@@ -1728,6 +1728,10 @@ def get_stock_reco_qty_shift(args):
stock_reco_qty_shift = flt(args.qty_after_transaction) - flt(last_balance)
else:
stock_reco_qty_shift = flt(args.actual_qty)
elif args.get("serial_and_batch_bundle"):
stock_reco_qty_shift = flt(args.actual_qty)
else:
# reco is being submitted
last_balance = get_previous_sle_of_current_voucher(args, "<=", exclude_current_voucher=True).get(
@@ -1799,7 +1803,20 @@ def get_datetime_limit_condition(detail):
def validate_negative_qty_in_future_sle(args, allow_negative_stock=False):
if allow_negative_stock or is_negative_stock_allowed(item_code=args.item_code):
return
<<<<<<< HEAD
if not (args.actual_qty < 0 or args.voucher_type == "Stock Reconciliation"):
=======
if (
args.voucher_type == "Stock Reconciliation"
and args.actual_qty < 0
and args.get("serial_and_batch_bundle")
and frappe.db.get_value("Stock Reconciliation Item", args.voucher_detail_no, "qty") > 0
):
return
if args.actual_qty >= 0 and args.voucher_type != "Stock Reconciliation":
>>>>>>> 289495c308 (fix: stock reco negative qty validation)
return
neg_sle = get_future_sle_with_negative_qty(args)