fix: stock reco negative qty validation
(cherry picked from commit 289495c308)
# Conflicts:
# erpnext/stock/stock_ledger.py
This commit is contained in:
committed by
Mergify
parent
62702b8bd6
commit
aee03fe2ef
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user