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:
rohitwaghchaure
2020-10-12 15:11:41 +05:30
committed by GitHub
3 changed files with 50 additions and 9 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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: