mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 08:24:47 +00:00
chore: Tests for Stock Reconciliation
This commit is contained in:
@@ -16,6 +16,7 @@ from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
|||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry import move_sample_to_retention_warehouse, make_stock_in_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry import move_sample_to_retention_warehouse, make_stock_in_entry
|
||||||
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import OpeningEntryAccountError
|
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import OpeningEntryAccountError
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
def get_sle(**args):
|
def get_sle(**args):
|
||||||
@@ -526,7 +527,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
@@ -559,7 +560,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
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()
|
||||||
|
|
||||||
@@ -573,7 +574,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
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")
|
||||||
|
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
warehouse = "_Test Warehouse for Stock Reco2 - _TC"
|
warehouse = "_Test Warehouse for Stock Reco2 - _TC"
|
||||||
|
|
||||||
sr = create_stock_reconciliation(item_code=item_code,
|
sr = create_stock_reconciliation(item_code=item_code,
|
||||||
warehouse = warehouse, qty=5, rate=200, do_not_submit=1)
|
warehouse = warehouse, qty=5, rate=200, do_not_save=1, do_not_submit=1)
|
||||||
sr.save(ignore_permissions=True)
|
sr.save(ignore_permissions=True)
|
||||||
sr.submit()
|
sr.submit()
|
||||||
|
|
||||||
@@ -204,6 +204,109 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
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):
|
||||||
|
set_perpetual_inventory()
|
||||||
|
|
||||||
|
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.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
|
from erpnext.stock.doctype.batch.batch import get_batch_qty
|
||||||
|
|
||||||
|
set_perpetual_inventory()
|
||||||
|
|
||||||
|
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 insert_existing_sle(warehouse):
|
def insert_existing_sle(warehouse):
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
@@ -260,11 +363,13 @@ def create_stock_reconciliation(**args):
|
|||||||
"batch_no": args.batch_no
|
"batch_no": args.batch_no
|
||||||
})
|
})
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
def set_valuation_method(item_code, valuation_method):
|
def set_valuation_method(item_code, valuation_method):
|
||||||
|
|||||||
Reference in New Issue
Block a user