From f01e1a8e20d6fa32e48ff22d850e737be5e32e2b Mon Sep 17 00:00:00 2001 From: Vishv-silveroak <108357657+Vishv-024@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:03:40 +0530 Subject: [PATCH 1/6] fix: exception on register reports when filtered on cost center 1 --- erpnext/accounts/report/utils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py index d6c1b95cf7c..2a72b10e4eb 100644 --- a/erpnext/accounts/report/utils.py +++ b/erpnext/accounts/report/utils.py @@ -255,7 +255,9 @@ def get_journal_entries(filters, args): ) .orderby(je.posting_date, je.name, order=Order.desc) ) - query = apply_common_conditions(filters, query, doctype="Journal Entry", payments=True) + query = apply_common_conditions( + filters, query, doctype="Journal Entry", child_doctype="Journal Entry Account", payments=True + ) journal_entries = query.run(as_dict=True) return journal_entries @@ -306,7 +308,9 @@ def apply_common_conditions(filters, query, doctype, child_doctype=None, payment query = query.where(parent_doc.posting_date <= filters.to_date) if payments: - if filters.get("cost_center"): + if doctype == "Journal Entry" and filters.get("cost_center"): + query = query.where(child_doc.cost_center == filters.cost_center) + elif filters.get("cost_center"): query = query.where(parent_doc.cost_center == filters.cost_center) else: if filters.get("cost_center"): From 657201b32485cc3471fc91fdb6b20c7d73abdf60 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 8 Nov 2024 12:08:05 +0530 Subject: [PATCH 2/6] test: basic report output --- .../sales_register/test_sales_register.py | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 erpnext/accounts/report/sales_register/test_sales_register.py diff --git a/erpnext/accounts/report/sales_register/test_sales_register.py b/erpnext/accounts/report/sales_register/test_sales_register.py new file mode 100644 index 00000000000..6ed754fa837 --- /dev/null +++ b/erpnext/accounts/report/sales_register/test_sales_register.py @@ -0,0 +1,64 @@ +import frappe +from frappe.tests import IntegrationTestCase +from frappe.utils import getdate, today + +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice +from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import execute +from erpnext.accounts.test.accounts_mixin import AccountsTestMixin + + +class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): + def setUp(self): + self.create_company() + self.create_customer() + self.create_item() + + def tearDown(self): + frappe.db.rollback() + + def create_sales_invoice(self, rate=100, do_not_submit=False): + si = create_sales_invoice( + item=self.item, + company=self.company, + customer=self.customer, + debit_to=self.debit_to, + posting_date=today(), + parent_cost_center=self.cost_center, + cost_center=self.cost_center, + rate=rate, + price_list_rate=rate, + do_not_save=1, + ) + si = si.save() + if not do_not_submit: + si = si.submit() + return si + + def test_basic_report_output(self): + si = self.create_sales_invoice(rate=98) + + filters = frappe._dict({"from_date": today(), "to_date": today(), "company": self.company}) + report = execute(filters) + + self.assertEqual(len(report[1]), 1) + + expected_result = { + "item_code": si.items[0].item_code, + "invoice": si.name, + "posting_date": getdate(), + "customer": si.customer, + "debit_to": si.debit_to, + "company": self.company, + "income_account": si.items[0].income_account, + "stock_qty": 1.0, + "stock_uom": si.items[0].stock_uom, + "rate": 98.0, + "amount": 98.0, + "total_tax": 0, + "total_other_charges": 0, + "total": 98.0, + "currency": "INR", + } + + report_output = {k: v for k, v in report[1][0].items() if k in expected_result} + self.assertDictEqual(report_output, expected_result) From c255f34eead1cba9210df609b22eb21e643f3d40 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Nov 2024 12:18:25 +0530 Subject: [PATCH 3/6] test: journals with cost center --- .../sales_register/test_sales_register.py | 121 +++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/sales_register/test_sales_register.py b/erpnext/accounts/report/sales_register/test_sales_register.py index 6ed754fa837..0bd67f39907 100644 --- a/erpnext/accounts/report/sales_register/test_sales_register.py +++ b/erpnext/accounts/report/sales_register/test_sales_register.py @@ -3,7 +3,7 @@ from frappe.tests import IntegrationTestCase from frappe.utils import getdate, today from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice -from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import execute +from erpnext.accounts.report.sales_register.sales_register import execute from erpnext.accounts.test.accounts_mixin import AccountsTestMixin @@ -12,10 +12,27 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): self.create_company() self.create_customer() self.create_item() + self.create_child_cost_center() def tearDown(self): frappe.db.rollback() + def create_child_cost_center(self): + cc_name = "South Wing" + if frappe.db.exists("Cost Center", cc_name): + cc = frappe.get_doc("Cost Center", cc_name) + else: + cc = frappe.get_doc( + { + "doctype": "Cost Center", + "parent_cost_center": self.cost_center, + "company": self.company, + "is_group": False, + } + ) + cc = cc.save() + self.south_cc = cc.name + def create_sales_invoice(self, rate=100, do_not_submit=False): si = create_sales_invoice( item=self.item, @@ -62,3 +79,105 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): report_output = {k: v for k, v in report[1][0].items() if k in expected_result} self.assertDictEqual(report_output, expected_result) + + def test_journal_with_cost_center_filter(self): + je1 = frappe.get_doc( + { + "doctype": "Journal Entry", + "voucher_type": "Journal Entry", + "company": self.company, + "posting_date": getdate(), + "accounts": [ + { + "account": self.debit_to, + "party_type": "Customer", + "party": self.customer, + "credit_in_account_currency": 77, + "credit": 77, + "is_advance": "Yes", + "cost_center": self.south_cc, + }, + { + "account": self.cash, + "debit_in_account_currency": 77, + "debit": 77, + }, + ], + } + ) + je1.submit() + + je2 = frappe.get_doc( + { + "doctype": "Journal Entry", + "voucher_type": "Journal Entry", + "company": self.company, + "posting_date": getdate(), + "accounts": [ + { + "account": self.debit_to, + "party_type": "Customer", + "party": self.customer, + "credit_in_account_currency": 98, + "credit": 98, + "is_advance": "Yes", + "cost_center": self.cost_center, + }, + { + "account": self.cash, + "debit_in_account_currency": 98, + "debit": 98, + }, + ], + } + ) + je2.submit() + + filters = frappe._dict( + { + "from_date": today(), + "to_date": today(), + "company": self.company, + "include_payments": True, + "customer": self.customer, + "cost_center": self.cost_center, + } + ) + result = [x for x in execute(filters)[1] if x.voucher_no == je1.name] + expected_result = { + "voucher_type": je1.doctype, + "voucher_no": je1.name, + "posting_date": je1.posting_date, + "customer": self.customer, + "receivable_account": self.debit_to, + "net_total": 77, + "cost_center": self.south_cc, + "credit": 77, + } + result_output = {k: v for k, v in result.items() if k in expected_result} + self.assertDictEqual(result_output, expected_result) + + # Without cost center filter + filters = frappe._dict( + { + "from_date": today(), + "to_date": today(), + "company": self.company, + "include_payments": True, + "customer": self.customer, + "cost_center": self.south_cc, + } + ) + result = [x for x in execute(filters)[1] if x.voucher_no == je2.name] + expected_result = { + "voucher_type": je2.doctype, + "voucher_no": je2.name, + "posting_date": je2.posting_date, + "customer": self.customer, + "receivable_account": self.debit_to, + "net_total": 98, + "cost_center": self.south_cc, + "credit": 98, + } + result_output = {k: v for k, v in result.items() if k in expected_result} + self.assertDictEqual(result_output, expected_result) From d6030e71121f5c9d7d25c4d11310f4e56cc46833 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Nov 2024 12:34:54 +0530 Subject: [PATCH 4/6] refactor(test): fix incorrect assertion --- .../sales_register/test_sales_register.py | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/report/sales_register/test_sales_register.py b/erpnext/accounts/report/sales_register/test_sales_register.py index 0bd67f39907..dbb4cd89851 100644 --- a/erpnext/accounts/report/sales_register/test_sales_register.py +++ b/erpnext/accounts/report/sales_register/test_sales_register.py @@ -60,21 +60,14 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): self.assertEqual(len(report[1]), 1) expected_result = { - "item_code": si.items[0].item_code, - "invoice": si.name, - "posting_date": getdate(), - "customer": si.customer, - "debit_to": si.debit_to, - "company": self.company, - "income_account": si.items[0].income_account, - "stock_qty": 1.0, - "stock_uom": si.items[0].stock_uom, - "rate": 98.0, - "amount": 98.0, - "total_tax": 0, - "total_other_charges": 0, - "total": 98.0, - "currency": "INR", + "voucher_type": si.doctype, + "voucher_no": si.name, + "posting_date": si.posting_date, + "customer": self.customer, + "receivable_account": self.debit_to, + "net_total": 98, + "grand_total": 98, + "credit": 98, } report_output = {k: v for k, v in report[1][0].items() if k in expected_result} @@ -151,13 +144,12 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "customer": self.customer, "receivable_account": self.debit_to, "net_total": 77, - "cost_center": self.south_cc, + "cost_center": self.cost_center, "credit": 77, } result_output = {k: v for k, v in result.items() if k in expected_result} self.assertDictEqual(result_output, expected_result) - # Without cost center filter filters = frappe._dict( { "from_date": today(), From c53e9637dd1ee39ebfeb713f39e0eaafb414e5c7 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Nov 2024 13:06:09 +0530 Subject: [PATCH 5/6] refactor(test): pass all mandatory fields --- erpnext/accounts/report/sales_register/test_sales_register.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/report/sales_register/test_sales_register.py b/erpnext/accounts/report/sales_register/test_sales_register.py index dbb4cd89851..cb8f37a4f0f 100644 --- a/erpnext/accounts/report/sales_register/test_sales_register.py +++ b/erpnext/accounts/report/sales_register/test_sales_register.py @@ -28,6 +28,7 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "parent_cost_center": self.cost_center, "company": self.company, "is_group": False, + "cost_center_name": cc_name, } ) cc = cc.save() From 1d11131afeef9040ad98647c834daf2faafcb782 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 11 Nov 2024 14:16:49 +0530 Subject: [PATCH 6/6] refactor(test): assertion refactoring and exact decimals --- .../sales_register/test_sales_register.py | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/report/sales_register/test_sales_register.py b/erpnext/accounts/report/sales_register/test_sales_register.py index cb8f37a4f0f..50f12e52e33 100644 --- a/erpnext/accounts/report/sales_register/test_sales_register.py +++ b/erpnext/accounts/report/sales_register/test_sales_register.py @@ -22,12 +22,13 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): if frappe.db.exists("Cost Center", cc_name): cc = frappe.get_doc("Cost Center", cc_name) else: + parent = frappe.db.get_value("Cost Center", self.cost_center, "parent_cost_center") cc = frappe.get_doc( { "doctype": "Cost Center", - "parent_cost_center": self.cost_center, "company": self.company, "is_group": False, + "parent_cost_center": parent, "cost_center_name": cc_name, } ) @@ -63,12 +64,12 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): expected_result = { "voucher_type": si.doctype, "voucher_no": si.name, - "posting_date": si.posting_date, + "posting_date": getdate(), "customer": self.customer, "receivable_account": self.debit_to, - "net_total": 98, - "grand_total": 98, - "credit": 98, + "net_total": 98.0, + "grand_total": 98.0, + "debit": 98.0, } report_output = {k: v for k, v in report[1][0].items() if k in expected_result} @@ -89,7 +90,7 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "credit_in_account_currency": 77, "credit": 77, "is_advance": "Yes", - "cost_center": self.south_cc, + "cost_center": self.cost_center, }, { "account": self.cash, @@ -115,7 +116,7 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "credit_in_account_currency": 98, "credit": 98, "is_advance": "Yes", - "cost_center": self.cost_center, + "cost_center": self.south_cc, }, { "account": self.cash, @@ -137,19 +138,20 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "cost_center": self.cost_center, } ) - result = [x for x in execute(filters)[1] if x.voucher_no == je1.name] + report_output = execute(filters)[1] + filtered_output = [x for x in report_output if x.get("voucher_no") == je1.name] + self.assertEqual(len(filtered_output), 1) expected_result = { "voucher_type": je1.doctype, "voucher_no": je1.name, "posting_date": je1.posting_date, "customer": self.customer, "receivable_account": self.debit_to, - "net_total": 77, - "cost_center": self.cost_center, - "credit": 77, + "net_total": 77.0, + "credit": 77.0, } - result_output = {k: v for k, v in result.items() if k in expected_result} - self.assertDictEqual(result_output, expected_result) + result_fields = {k: v for k, v in filtered_output[0].items() if k in expected_result} + self.assertDictEqual(result_fields, expected_result) filters = frappe._dict( { @@ -161,16 +163,17 @@ class TestItemWiseSalesRegister(AccountsTestMixin, IntegrationTestCase): "cost_center": self.south_cc, } ) - result = [x for x in execute(filters)[1] if x.voucher_no == je2.name] + report_output = execute(filters)[1] + filtered_output = [x for x in report_output if x.get("voucher_no") == je2.name] + self.assertEqual(len(filtered_output), 1) expected_result = { "voucher_type": je2.doctype, "voucher_no": je2.name, "posting_date": je2.posting_date, "customer": self.customer, "receivable_account": self.debit_to, - "net_total": 98, - "cost_center": self.south_cc, - "credit": 98, + "net_total": 98.0, + "credit": 98.0, } - result_output = {k: v for k, v in result.items() if k in expected_result} + result_output = {k: v for k, v in filtered_output[0].items() if k in expected_result} self.assertDictEqual(result_output, expected_result)