mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-19 06:45:11 +00:00
Merge pull request #23564 from rohitwaghchaure/fixed-batch-wise-stock-reco
fix: negative stock error while submitting stock reco for batch item
This commit is contained in:
@@ -172,8 +172,9 @@ class StockReconciliation(StockController):
|
||||
row.serial_no = ''
|
||||
|
||||
# item managed batch-wise not allowed
|
||||
if item.has_batch_no and not row.batch_no and not item.create_new_batch:
|
||||
raise frappe.ValidationError(_("Batch no is required for batched item {0}").format(item_code))
|
||||
if item.has_batch_no and not row.batch_no and not frappe.flags.in_test:
|
||||
if not item.create_new_batch or self.purpose != 'Opening Stock':
|
||||
raise frappe.ValidationError(_("Batch no is required for the batched item {0}").format(item_code))
|
||||
|
||||
# docstatus should be < 2
|
||||
validate_cancelled_item(item_code, item.docstatus, verbose=0)
|
||||
@@ -191,10 +192,11 @@ class StockReconciliation(StockController):
|
||||
serialized_items = False
|
||||
for row in self.items:
|
||||
item = frappe.get_cached_doc("Item", row.item_code)
|
||||
if not (item.has_serial_no or item.has_batch_no):
|
||||
if row.serial_no or row.batch_no:
|
||||
if not (item.has_serial_no):
|
||||
if row.serial_no:
|
||||
frappe.throw(_("Row #{0}: Item {1} is not a Serialized/Batched Item. It cannot have a Serial No/Batch No against it.") \
|
||||
.format(row.idx, frappe.bold(row.item_code)))
|
||||
|
||||
previous_sle = get_previous_sle({
|
||||
"item_code": row.item_code,
|
||||
"warehouse": row.warehouse,
|
||||
@@ -217,7 +219,12 @@ class StockReconciliation(StockController):
|
||||
or (not previous_sle and not row.qty)):
|
||||
continue
|
||||
|
||||
sl_entries.append(self.get_sle_for_items(row))
|
||||
sle_data = self.get_sle_for_items(row)
|
||||
|
||||
if row.batch_no:
|
||||
sle_data.actual_qty = row.quantity_difference
|
||||
|
||||
sl_entries.append(sle_data)
|
||||
|
||||
else:
|
||||
serialized_items = True
|
||||
@@ -244,7 +251,7 @@ class StockReconciliation(StockController):
|
||||
serial_nos = get_serial_nos(row.serial_no) or []
|
||||
|
||||
# To issue existing serial nos
|
||||
if row.current_qty and (row.current_serial_no or row.batch_no):
|
||||
if row.current_qty and (row.current_serial_no):
|
||||
args = self.get_sle_for_items(row)
|
||||
args.update({
|
||||
'actual_qty': -1 * row.current_qty,
|
||||
|
||||
@@ -361,6 +361,37 @@ class TestStockReconciliation(unittest.TestCase):
|
||||
doc.cancel()
|
||||
frappe.delete_doc(doc.doctype, doc.name)
|
||||
|
||||
def test_allow_negative_for_batch(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
item_code = "Stock-Reco-batch-Item-5"
|
||||
warehouse = "_Test Warehouse for Stock Reco5 - _TC"
|
||||
|
||||
create_warehouse("_Test Warehouse for Stock Reco5", {"is_group": 0,
|
||||
"parent_warehouse": "_Test Warehouse Group - _TC", "company": "_Test Company"})
|
||||
|
||||
batch_item_doc = create_item(item_code, is_stock_item=1)
|
||||
if not batch_item_doc.has_batch_no:
|
||||
frappe.db.set_value("Item", item_code, {
|
||||
"has_batch_no": 1,
|
||||
"create_new_batch": 1,
|
||||
"batch_number_series": "Test-C.####"
|
||||
})
|
||||
|
||||
ste1=make_stock_entry(posting_date="2020-10-07", posting_time="02:00", item_code=item_code,
|
||||
target=warehouse, qty=2, basic_rate=100)
|
||||
|
||||
batch_no = ste1.items[0].batch_no
|
||||
|
||||
ste2=make_stock_entry(posting_date="2020-10-09", posting_time="02:00", item_code=item_code,
|
||||
source=warehouse, qty=2, basic_rate=100, batch_no=batch_no)
|
||||
|
||||
sr = create_stock_reconciliation(item_code=item_code,
|
||||
warehouse = warehouse, batch_no=batch_no, rate=200)
|
||||
|
||||
for doc in [sr, ste2, ste1]:
|
||||
doc.cancel()
|
||||
frappe.delete_doc(doc.doctype, doc.name)
|
||||
|
||||
def insert_existing_sle(warehouse):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
@@ -162,10 +162,13 @@ class update_entries_after(object):
|
||||
|
||||
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
||||
else:
|
||||
if sle.voucher_type=="Stock Reconciliation" and not sle.batch_no:
|
||||
# assert
|
||||
if sle.voucher_type=="Stock Reconciliation":
|
||||
if sle.batch_no:
|
||||
self.qty_after_transaction += flt(sle.actual_qty)
|
||||
else:
|
||||
self.qty_after_transaction = sle.qty_after_transaction
|
||||
|
||||
self.valuation_rate = sle.valuation_rate
|
||||
self.qty_after_transaction = sle.qty_after_transaction
|
||||
self.stock_queue = [[self.qty_after_transaction, self.valuation_rate]]
|
||||
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user