chore: Tests for Stock Reconciliation

(cherry picked from commit 5bc5af1066e0bb4bead98598ed4bf9911d340734)
This commit is contained in:
marination 2020-09-02 19:21:16 +05:30 committed by Mergify
parent 3bc3cf34eb
commit 14ea40d270
2 changed files with 137 additions and 25 deletions

View File

@ -654,14 +654,14 @@ class TestStockEntry(FrappeTestCase):
def test_serial_batch_item_stock_entry(self): def test_serial_batch_item_stock_entry(self):
""" """
Behaviour: 1) Submit Stock Entry (Receipt) with Serial & Batched Item Behaviour: 1) Submit Stock Entry (Receipt) with Serial & Batched Item
2) Cancel same Stock Entry 2) Cancel same Stock Entry
Expected Result: 1) Batch is created with Reference in Serial No Expected Result: 1) Batch is created with Reference in Serial No
2) Batch is deleted and Serial No is Inactive 2) Batch is deleted and Serial No is Inactive
""" """
from erpnext.stock.doctype.batch.batch import get_batch_qty from erpnext.stock.doctype.batch.batch import get_batch_qty
item = frappe.db.exists("Item", {'item_name': 'Batched and Serialised Item'}) item = frappe.db.exists("Item", {"item_name": "Batched and Serialised Item"})
if not item: if not item:
item = create_item("Batched and Serialised Item") item = create_item("Batched and Serialised Item")
item.has_batch_no = 1 item.has_batch_no = 1
@ -671,9 +671,11 @@ class TestStockEntry(FrappeTestCase):
item.serial_no_series = "S-.####" item.serial_no_series = "S-.####"
item.save() item.save()
else: else:
item = frappe.get_doc("Item", {'item_name': 'Batched and Serialised Item'}) item = frappe.get_doc("Item", {"item_name": "Batched and Serialised Item"})
se = make_stock_entry(item_code=item.item_code, target="_Test Warehouse - _TC", qty=1, basic_rate=100) se = make_stock_entry(
item_code=item.item_code, target="_Test Warehouse - _TC", qty=1, basic_rate=100
)
batch_no = se.items[0].batch_no batch_no = se.items[0].batch_no
serial_no = get_serial_nos(se.items[0].serial_no)[0] serial_no = get_serial_nos(se.items[0].serial_no)[0]
batch_qty = get_batch_qty(batch_no, "_Test Warehouse - _TC", item.item_code) batch_qty = get_batch_qty(batch_no, "_Test Warehouse - _TC", item.item_code)
@ -693,15 +695,15 @@ class TestStockEntry(FrappeTestCase):
def test_serial_batch_item_qty_deduction(self): def test_serial_batch_item_qty_deduction(self):
""" """
Behaviour: Create 2 Stock Entries, both adding Serial Nos to same batch Behaviour: Create 2 Stock Entries, both adding Serial Nos to same batch
Expected Result: 1) Cancelling first Stock Entry (origin transaction of created batch) Expected Result: 1) Cancelling first Stock Entry (origin transaction of created batch)
should throw a Link Exists Error should throw a LinkExistsError
2) Cancelling second Stock Entry should make Serial Nos that are, linked to mentioned batch 2) Cancelling second Stock Entry should make Serial Nos that are, linked to mentioned batch
and in that transaction only, Inactive. and in that transaction only, Inactive.
""" """
from erpnext.stock.doctype.batch.batch import get_batch_qty from erpnext.stock.doctype.batch.batch import get_batch_qty
item = frappe.db.exists("Item", {'item_name': 'Batched and Serialised Item'}) item = frappe.db.exists("Item", {"item_name": "Batched and Serialised Item"})
if not item: if not item:
item = create_item("Batched and Serialised Item") item = create_item("Batched and Serialised Item")
item.has_batch_no = 1 item.has_batch_no = 1
@ -711,24 +713,31 @@ class TestStockEntry(FrappeTestCase):
item.serial_no_series = "S-.####" item.serial_no_series = "S-.####"
item.save() item.save()
else: else:
item = frappe.get_doc("Item", {'item_name': 'Batched and Serialised Item'}) item = frappe.get_doc("Item", {"item_name": "Batched and Serialised Item"})
se1 = make_stock_entry(item_code=item.item_code, target="_Test Warehouse - _TC", qty=1, basic_rate=100) se1 = make_stock_entry(
item_code=item.item_code, target="_Test Warehouse - _TC", qty=1, basic_rate=100
)
batch_no = se1.items[0].batch_no batch_no = se1.items[0].batch_no
serial_no1 = get_serial_nos(se1.items[0].serial_no)[0] serial_no1 = get_serial_nos(se1.items[0].serial_no)[0]
# Check Source (Origin) Document of Batch # Check Source (Origin) Document of Batch
self.assertEqual(frappe.db.get_value("Batch", batch_no, "reference_name"), se1.name) self.assertEqual(frappe.db.get_value("Batch", batch_no, "reference_name"), se1.name)
se2 = make_stock_entry(item_code=item.item_code, target="_Test Warehouse - _TC", qty=1, basic_rate=100, se2 = make_stock_entry(
batch_no=batch_no) item_code=item.item_code,
target="_Test Warehouse - _TC",
qty=1,
basic_rate=100,
batch_no=batch_no,
)
serial_no2 = get_serial_nos(se2.items[0].serial_no)[0] serial_no2 = get_serial_nos(se2.items[0].serial_no)[0]
batch_qty = get_batch_qty(batch_no, "_Test Warehouse - _TC", item.item_code) batch_qty = get_batch_qty(batch_no, "_Test Warehouse - _TC", item.item_code)
self.assertEqual(batch_qty, 2) self.assertEqual(batch_qty, 2)
frappe.db.commit() frappe.db.commit()
# Cancelling Origin Document # Cancelling Origin Document of Batch
self.assertRaises(frappe.LinkExistsError, se1.cancel) self.assertRaises(frappe.LinkExistsError, se1.cancel)
frappe.db.rollback() frappe.db.rollback()
@ -742,7 +751,7 @@ class TestStockEntry(FrappeTestCase):
self.assertEqual(frappe.db.get_value("Serial No", serial_no1, "batch_no"), batch_no) self.assertEqual(frappe.db.get_value("Serial No", serial_no1, "batch_no"), batch_no)
self.assertEqual(frappe.db.get_value("Serial No", serial_no1, "status"), "Active") self.assertEqual(frappe.db.get_value("Serial No", serial_no1, "status"), "Active")
# Check id Serial No from Stock Entry 2 is Unlinked and Inactive # Check if Serial No from Stock Entry 2 is Unlinked and Inactive
self.assertEqual(frappe.db.get_value("Serial No", serial_no2, "batch_no"), None) self.assertEqual(frappe.db.get_value("Serial No", serial_no2, "batch_no"), None)
self.assertEqual(frappe.db.get_value("Serial No", serial_no2, "status"), "Inactive") self.assertEqual(frappe.db.get_value("Serial No", serial_no2, "status"), "Inactive")

View File

@ -250,7 +250,7 @@ class TestStockReconciliation(FrappeTestCase):
warehouse = "_Test Warehouse for Stock Reco2 - _TC" warehouse = "_Test Warehouse for Stock Reco2 - _TC"
sr = create_stock_reconciliation( sr = create_stock_reconciliation(
item_code=item_code, warehouse=warehouse, qty=5, rate=200, do_not_submit=1 item_code=item_code, warehouse=warehouse, qty=5, rate=200, do_not_save=1
) )
sr.save() sr.save()
sr.submit() sr.submit()
@ -288,6 +288,107 @@ class TestStockReconciliation(FrappeTestCase):
stock_doc = frappe.get_doc("Stock Reconciliation", d) stock_doc = frappe.get_doc("Stock Reconciliation", d)
stock_doc.cancel() stock_doc.cancel()
def test_stock_reco_for_serial_and_batch_item(self):
item = frappe.db.exists("Item", {"item_name": "Batched and Serialised Item"})
if not item:
item = create_item("Batched and Serialised Item")
item.has_batch_no = 1
item.create_new_batch = 1
item.has_serial_no = 1
item.batch_number_series = "B-BATCH-.##"
item.serial_no_series = "S-.####"
item.save()
else:
item = frappe.get_doc("Item", {"item_name": "Batched and Serialised Item"})
warehouse = "_Test Warehouse for Stock Reco2 - _TC"
sr = create_stock_reconciliation(item_code=item.item_code, warehouse=warehouse, qty=1, rate=100)
batch_no = sr.items[0].batch_no
serial_nos = get_serial_nos(sr.items[0].serial_no)
self.assertEqual(len(serial_nos), 1)
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0], "batch_no"), batch_no)
sr.cancel()
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0], "status"), "Inactive")
self.assertEqual(frappe.db.exists("Batch", batch_no), None)
if frappe.db.exists("Serial No", serial_nos[0]):
frappe.delete_doc("Serial No", serial_nos[0])
def test_stock_reco_for_serial_and_batch_item_with_future_dependent_entry(self):
"""
Behaviour: 1) Create Stock Reconciliation, which will be the origin document
of a new batch having a serial no
2) Create a Stock Entry that adds a serial no to the same batch following this
Stock Reconciliation
3) Cancel Stock Reconciliation
4) Cancel Stock Entry
Expected Result: 3) Cancelling the Stock Reco throws a LinkExistsError since
Stock Entry is dependent on the batch involved
4) Serial No only in the Stock Entry is Inactive and Batch qty decreases
"""
from erpnext.stock.doctype.batch.batch import get_batch_qty
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
item = frappe.db.exists("Item", {"item_name": "Batched and Serialised Item"})
if not item:
item = create_item("Batched and Serialised Item")
item.has_batch_no = 1
item.create_new_batch = 1
item.has_serial_no = 1
item.batch_number_series = "B-BATCH-.##"
item.serial_no_series = "S-.####"
item.save()
else:
item = frappe.get_doc("Item", {"item_name": "Batched and Serialised Item"})
warehouse = "_Test Warehouse for Stock Reco2 - _TC"
stock_reco = create_stock_reconciliation(
item_code=item.item_code, warehouse=warehouse, qty=1, rate=100
)
batch_no = stock_reco.items[0].batch_no
serial_no = get_serial_nos(stock_reco.items[0].serial_no)[0]
stock_entry = make_stock_entry(
item_code=item.item_code, target=warehouse, qty=1, basic_rate=100, batch_no=batch_no
)
serial_no_2 = get_serial_nos(stock_entry.items[0].serial_no)[0]
# Check Batch qty after 2 transactions
batch_qty = get_batch_qty(batch_no, warehouse, item.item_code)
self.assertEqual(batch_qty, 2)
frappe.db.commit()
# Cancelling Origin Document of Batch
self.assertRaises(frappe.LinkExistsError, stock_reco.cancel)
frappe.db.rollback()
stock_entry.cancel()
# Check Batch qty after cancellation
batch_qty = get_batch_qty(batch_no, warehouse, item.item_code)
self.assertEqual(batch_qty, 1)
# Check if Serial No from Stock Reconcilation is intact
self.assertEqual(frappe.db.get_value("Serial No", serial_no, "batch_no"), batch_no)
self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Active")
# Check if Serial No from Stock Entry is Unlinked and Inactive
self.assertEqual(frappe.db.get_value("Serial No", serial_no_2, "batch_no"), None)
self.assertEqual(frappe.db.get_value("Serial No", serial_no_2, "status"), "Inactive")
stock_reco.load_from_db()
stock_reco.cancel()
for sn in (serial_no, serial_no_2):
if frappe.db.exists("Serial No", sn):
frappe.delete_doc("Serial No", sn)
def test_customer_provided_items(self): def test_customer_provided_items(self):
item_code = "Stock-Reco-customer-Item-100" item_code = "Stock-Reco-customer-Item-100"
create_item( create_item(
@ -684,11 +785,13 @@ def create_stock_reconciliation(**args):
}, },
) )
try: if not args.do_not_save:
if not args.do_not_submit: sr.insert()
sr.submit() try:
except EmptyStockReconciliationItemsError: if not args.do_not_submit:
pass sr.submit()
except EmptyStockReconciliationItemsError:
pass
return sr return sr