blob: 4e93ac93cb775da4bedada79dc2f6c7bb5466354 [file] [log] [blame]
Ankush Menat293eb8d2022-05-10 21:30:31 +05301import json
2
Ankush Menat47f27a52022-04-01 15:20:40 +05303import frappe
4from frappe.tests.utils import FrappeTestCase
5
Ankush Menat47f27a52022-04-01 15:20:40 +05306from erpnext.stock.utils import scan_barcode
7
8
Ankush Menat293eb8d2022-05-10 21:30:31 +05309class StockTestMixin:
10 """Mixin to simplfy stock ledger tests, useful for all stock transactions."""
11
12 def make_item(self, item_code=None, properties=None, *args, **kwargs):
13 from erpnext.stock.doctype.item.test_item import make_item
14
15 return make_item(item_code, properties, *args, **kwargs)
16
17 def assertSLEs(self, doc, expected_sles, sle_filters=None):
18 """Compare sorted SLEs, useful for vouchers that create multiple SLEs for same line"""
19
20 filters = {"voucher_no": doc.name, "voucher_type": doc.doctype, "is_cancelled": 0}
21 if sle_filters:
22 filters.update(sle_filters)
23 sles = frappe.get_all(
24 "Stock Ledger Entry",
25 fields=["*"],
26 filters=filters,
27 order_by="timestamp(posting_date, posting_time), creation",
28 )
Ankush Menat86919d22022-06-15 21:19:09 +053029 self.assertGreaterEqual(len(sles), len(expected_sles))
Ankush Menat293eb8d2022-05-10 21:30:31 +053030
31 for exp_sle, act_sle in zip(expected_sles, sles):
32 for k, v in exp_sle.items():
33 act_value = act_sle[k]
34 if k == "stock_queue":
35 act_value = json.loads(act_value)
36 if act_value and act_value[0][0] == 0:
37 # ignore empty fifo bins
38 continue
39
40 self.assertEqual(v, act_value, msg=f"{k} doesn't match \n{exp_sle}\n{act_sle}")
41
Ankush Menat77262712022-06-01 14:17:06 +053042 def assertGLEs(self, doc, expected_gles, gle_filters=None, order_by=None):
43 filters = {"voucher_no": doc.name, "voucher_type": doc.doctype, "is_cancelled": 0}
44
45 if gle_filters:
46 filters.update(gle_filters)
47 actual_gles = frappe.get_all(
48 "GL Entry",
49 fields=["*"],
50 filters=filters,
51 order_by=order_by or "posting_date, creation",
52 )
Ankush Menat86919d22022-06-15 21:19:09 +053053 self.assertGreaterEqual(len(actual_gles), len(expected_gles))
Ankush Menat77262712022-06-01 14:17:06 +053054 for exp_gle, act_gle in zip(expected_gles, actual_gles):
55 for k, exp_value in exp_gle.items():
56 act_value = act_gle[k]
57 self.assertEqual(exp_value, act_value, msg=f"{k} doesn't match \n{exp_gle}\n{act_gle}")
58
Ankush Menat293eb8d2022-05-10 21:30:31 +053059
60class TestStockUtilities(FrappeTestCase, StockTestMixin):
Ankush Menat47f27a52022-04-01 15:20:40 +053061 def test_barcode_scanning(self):
Ankush Menat293eb8d2022-05-10 21:30:31 +053062 simple_item = self.make_item(properties={"barcodes": [{"barcode": "12399"}]})
Ankush Menat47f27a52022-04-01 15:20:40 +053063 self.assertEqual(scan_barcode("12399")["item_code"], simple_item.name)
64
Ankush Menat293eb8d2022-05-10 21:30:31 +053065 batch_item = self.make_item(properties={"has_batch_no": 1, "create_new_batch": 1})
Ankush Menat47f27a52022-04-01 15:20:40 +053066 batch = frappe.get_doc(doctype="Batch", item=batch_item.name).insert()
67
68 batch_scan = scan_barcode(batch.name)
69 self.assertEqual(batch_scan["item_code"], batch_item.name)
70 self.assertEqual(batch_scan["batch_no"], batch.name)
71 self.assertEqual(batch_scan["has_batch_no"], 1)
72 self.assertEqual(batch_scan["has_serial_no"], 0)
73
Ankush Menat293eb8d2022-05-10 21:30:31 +053074 serial_item = self.make_item(properties={"has_serial_no": 1})
Ankush Menat47f27a52022-04-01 15:20:40 +053075 serial = frappe.get_doc(
76 doctype="Serial No", item_code=serial_item.name, serial_no=frappe.generate_hash()
77 ).insert()
78
79 serial_scan = scan_barcode(serial.name)
80 self.assertEqual(serial_scan["item_code"], serial_item.name)
81 self.assertEqual(serial_scan["serial_no"], serial.name)
82 self.assertEqual(serial_scan["has_batch_no"], 0)
83 self.assertEqual(serial_scan["has_serial_no"], 1)