Ankush Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 1 | import json |
| 2 | |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 3 | import frappe |
| 4 | from frappe.tests.utils import FrappeTestCase |
| 5 | |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 6 | from erpnext.stock.utils import scan_barcode |
| 7 | |
| 8 | |
Ankush Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 9 | class 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 Menat | 86919d2 | 2022-06-15 21:19:09 +0530 | [diff] [blame] | 29 | self.assertGreaterEqual(len(sles), len(expected_sles)) |
Ankush Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 30 | |
| 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 Menat | 7726271 | 2022-06-01 14:17:06 +0530 | [diff] [blame] | 42 | 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 Menat | 86919d2 | 2022-06-15 21:19:09 +0530 | [diff] [blame] | 53 | self.assertGreaterEqual(len(actual_gles), len(expected_gles)) |
Ankush Menat | 7726271 | 2022-06-01 14:17:06 +0530 | [diff] [blame] | 54 | 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 Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 59 | |
| 60 | class TestStockUtilities(FrappeTestCase, StockTestMixin): |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 61 | def test_barcode_scanning(self): |
Ankush Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 62 | simple_item = self.make_item(properties={"barcodes": [{"barcode": "12399"}]}) |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 63 | self.assertEqual(scan_barcode("12399")["item_code"], simple_item.name) |
| 64 | |
Ankush Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 65 | batch_item = self.make_item(properties={"has_batch_no": 1, "create_new_batch": 1}) |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 66 | 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 Menat | 293eb8d | 2022-05-10 21:30:31 +0530 | [diff] [blame] | 74 | serial_item = self.make_item(properties={"has_serial_no": 1}) |
Ankush Menat | 47f27a5 | 2022-04-01 15:20:40 +0530 | [diff] [blame] | 75 | 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) |