From ac48c3d4e7903dab168563ee60ff2d83d3549255 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 11 Jul 2024 17:21:41 +0530 Subject: [PATCH 01/11] fix: missing discount on POS Credit Notes (cherry picked from commit 1049550951011c09fd705c4b01b925e02b6a84ee) # Conflicts: # erpnext/accounts/doctype/sales_invoice/sales_invoice.js --- erpnext/accounts/doctype/sales_invoice/sales_invoice.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index ad857840147..36f5a792ff1 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -431,9 +431,18 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e return this.frm.call({ doc: me.frm.doc, method: "set_missing_values", +<<<<<<< HEAD callback: function(r) { if(!r.exc) { if(r.message && r.message.print_format) { +======= + args: { + for_validate: true, + }, + callback: function (r) { + if (!r.exc) { + if (r.message && r.message.print_format) { +>>>>>>> 1049550951 (fix: missing discount on POS Credit Notes) me.frm.pos_print_format = r.message.print_format; } me.frm.trigger("update_stock"); From edfb408464bc0957abfc6633e7b4c4466cece4ae Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 11 Jul 2024 17:31:20 +0530 Subject: [PATCH 02/11] chore: resolve conflict --- erpnext/accounts/doctype/sales_invoice/sales_invoice.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 36f5a792ff1..76b4f595a00 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -431,18 +431,12 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e return this.frm.call({ doc: me.frm.doc, method: "set_missing_values", -<<<<<<< HEAD - callback: function(r) { - if(!r.exc) { - if(r.message && r.message.print_format) { -======= args: { for_validate: true, }, callback: function (r) { if (!r.exc) { if (r.message && r.message.print_format) { ->>>>>>> 1049550951 (fix: missing discount on POS Credit Notes) me.frm.pos_print_format = r.message.print_format; } me.frm.trigger("update_stock"); From 1646517dc44b398d7ad4ffea9723e648e53ee91a Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 5 Jul 2024 09:40:33 +0530 Subject: [PATCH 03/11] chore: rename test suite for payable report (cherry picked from commit 9474f727760da7592fec05331643b145e9f132f9) --- .../accounts/report/accounts_payable/test_accounts_payable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py index f5c9d16073e..43856bf569f 100644 --- a/erpnext/accounts/report/accounts_payable/test_accounts_payable.py +++ b/erpnext/accounts/report/accounts_payable/test_accounts_payable.py @@ -7,7 +7,7 @@ from erpnext.accounts.report.accounts_payable.accounts_payable import execute from erpnext.accounts.test.accounts_mixin import AccountsTestMixin -class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): +class TestAccountsPayable(AccountsTestMixin, FrappeTestCase): def setUp(self): self.create_company() self.create_customer() From 9a50a0a1295bfa3527bf4bd5391963dbd9bd52e9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 5 Jul 2024 09:42:27 +0530 Subject: [PATCH 04/11] refactor: test suite for item-wise sales register (cherry picked from commit 3aaa22e672ae5363ca6347d0ce280aa7fba062f0) --- .../test_item_wise_sales_register.py | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py diff --git a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py new file mode 100644 index 00000000000..c26530ca564 --- /dev/null +++ b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py @@ -0,0 +1,64 @@ +import frappe +from frappe.tests.utils import FrappeTestCase +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, FrappeTestCase): + def setUp(self): + self.create_company() + self.create_customer() + self.create_item() + + def tearDown(self): + frappe.db.rollback() + + def create_sales_invoice(self, 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=100, + price_list_rate=100, + 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() + + 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": "Nos", + "rate": 100.0, + "amount": 100.0, + "total_tax": 0, + "total_other_charges": 0, + "total": 100.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 7903e8d66975ec8958f86cfa954b127bb04702f3 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 5 Jul 2024 10:30:16 +0530 Subject: [PATCH 05/11] refactor(test): use each instance UOM for assertion (cherry picked from commit cf4fbfb60150e5af44641a2dd0811fb64d003774) --- .../item_wise_sales_register/test_item_wise_sales_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py index c26530ca564..6fd5d601e84 100644 --- a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py @@ -51,7 +51,7 @@ class TestItemWiseSalesRegister(AccountsTestMixin, FrappeTestCase): "company": self.company, "income_account": si.items[0].income_account, "stock_qty": 1.0, - "stock_uom": "Nos", + "stock_uom": si.items[0].stock_uom, "rate": 100.0, "amount": 100.0, "total_tax": 0, From f98716cc2acc3270e7c892f2a05fe7457bfbae34 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 11 Jul 2024 21:03:29 +0530 Subject: [PATCH 06/11] refactor(test): clear old records --- .../item_wise_sales_register/test_item_wise_sales_register.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py index 6fd5d601e84..4dfdf3058e4 100644 --- a/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py @@ -12,6 +12,7 @@ class TestItemWiseSalesRegister(AccountsTestMixin, FrappeTestCase): self.create_company() self.create_customer() self.create_item() + self.clear_old_entries() def tearDown(self): frappe.db.rollback() From 4668a2d7d825450818e04a1b785deb61d861ed29 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 12 Jul 2024 10:04:54 +0530 Subject: [PATCH 07/11] refactor: make reposting implicit (cherry picked from commit 722ef9232484df34b8a3cbcc817cdc47bc9e442d) # Conflicts: # erpnext/accounts/doctype/journal_entry/journal_entry.py --- .../doctype/journal_entry/journal_entry.py | 14 ++++++++++++++ .../doctype/purchase_invoice/purchase_invoice.py | 1 + .../doctype/sales_invoice/sales_invoice.py | 1 + 3 files changed, 16 insertions(+) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index b4fb13e42c3..a90a3c1d6b8 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -99,6 +99,20 @@ class JournalEntry(AccountsController): self.update_asset_value() self.update_inter_company_jv() self.update_invoice_discounting() +<<<<<<< HEAD +======= + self.update_booked_depreciation() + + def on_update_after_submit(self): + if hasattr(self, "repost_required"): + self.needs_repost = self.check_if_fields_updated( + fields_to_check=[], child_tables={"accounts": []} + ) + if self.needs_repost: + self.validate_for_repost() + self.db_set("repost_required", self.needs_repost) + self.repost_accounting_entries() +>>>>>>> 722ef92324 (refactor: make reposting implicit) def on_cancel(self): # References for this Journal are removed on the `on_cancel` event in accounts_controller diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 2015dd1b634..fd018309282 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -601,6 +601,7 @@ class PurchaseInvoice(BuyingController): if self.needs_repost: self.validate_for_repost() self.db_set("repost_required", self.needs_repost) + self.repost_accounting_entries() def make_gl_entries(self, gl_entries=None, from_repost=False): update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes" diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 009c48a385c..d01e494e60d 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -549,6 +549,7 @@ class SalesInvoice(SellingController): if self.needs_repost: self.validate_for_repost() self.db_set("repost_required", self.needs_repost) + self.repost_accounting_entries() def set_paid_amount(self): paid_amount = 0.0 From 980ca1d8c5038ee770022afc1d82ef72354da24d Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 15 Jul 2024 14:21:47 +0530 Subject: [PATCH 08/11] refactor(test): no need to assert repost_required flag Reposting happens implicitly upon 'Update After Submit' (cherry picked from commit 8f135e9859bad9fc0bc295b2583b166ed3ca87d9) # Conflicts: # erpnext/accounts/doctype/journal_entry/test_journal_entry.py --- .../journal_entry/test_journal_entry.py | 70 +++++++++++++++++++ .../purchase_invoice/test_purchase_invoice.py | 2 - 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 979f964b62a..2aea25b431e 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -421,6 +421,76 @@ class TestJournalEntry(unittest.TestCase): account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center) self.assertEqual(expected_account_balance, account_balance) +<<<<<<< HEAD +======= + def test_repost_accounting_entries(self): + from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center + + # Configure Repost Accounting Ledger for JVs + settings = frappe.get_doc("Repost Accounting Ledger Settings") + if not [x for x in settings.allowed_types if x.document_type == "Journal Entry"]: + settings.append("allowed_types", {"document_type": "Journal Entry", "allowed": True}) + settings.save() + + # Create JV with defaut cost center - _Test Cost Center + jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False) + jv.multi_currency = 0 + jv.submit() + + # Check GL entries before reposting + self.voucher_no = jv.name + + self.fields = [ + "account", + "debit_in_account_currency", + "credit_in_account_currency", + "cost_center", + ] + + self.expected_gle = [ + { + "account": "_Test Bank - _TC", + "debit_in_account_currency": 0, + "credit_in_account_currency": 100, + "cost_center": "_Test Cost Center - _TC", + }, + { + "account": "_Test Cash - _TC", + "debit_in_account_currency": 100, + "credit_in_account_currency": 0, + "cost_center": "_Test Cost Center - _TC", + }, + ] + + self.check_gl_entries() + + # Change cost center for bank account - _Test Cost Center for BS Account + create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company") + jv.accounts[1].cost_center = "_Test Cost Center for BS Account - _TC" + jv.save() + + # Check GL entries after reposting + jv.load_from_db() + self.expected_gle[0]["cost_center"] = "_Test Cost Center for BS Account - _TC" + self.check_gl_entries() + + def check_gl_entries(self): + gl = frappe.qb.DocType("GL Entry") + query = frappe.qb.from_(gl) + for field in self.fields: + query = query.select(gl[field]) + + query = query.where( + (gl.voucher_type == "Journal Entry") & (gl.voucher_no == self.voucher_no) & (gl.is_cancelled == 0) + ).orderby(gl.account) + + gl_entries = query.run(as_dict=True) + + for i in range(len(self.expected_gle)): + for field in self.fields: + self.assertEqual(self.expected_gle[i][field], gl_entries[i][field]) + +>>>>>>> 8f135e9859 (refactor(test): no need to assert repost_required flag) def make_journal_entry( account1, diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 22e28e6ce36..a2d97e70416 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1910,8 +1910,6 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): pi.items[0].expense_account = "Service - _TC" pi.save() pi.load_from_db() - self.assertTrue(pi.repost_required) - pi.repost_accounting_entries() expected_gle = [ ["Creditors - _TC", 0.0, 1000, nowdate()], From d20f3ab492eb88dee331ed067c78b465827ec525 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 15 Jul 2024 14:27:16 +0530 Subject: [PATCH 09/11] refactor(test): reposting happens implicitly (cherry picked from commit c283cda1694847c9561f3eecc39d3977ee995d32) --- .../accounts/doctype/sales_invoice/test_sales_invoice.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index f22218fcd33..159ed405686 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2884,13 +2884,9 @@ class TestSalesInvoice(FrappeTestCase): si.items[0].income_account = "Service - _TC" si.additional_discount_account = "_Test Account Sales - _TC" si.taxes[0].account_head = "TDS Payable - _TC" + # Ledger reposted implicitly upon 'Update After Submit' si.save() - si.load_from_db() - self.assertTrue(si.repost_required) - - si.repost_accounting_entries() - expected_gle = [ ["_Test Account Sales - _TC", 22.0, 0.0, nowdate()], ["Debtors - _TC", 88, 0.0, nowdate()], From 8f03769bf26ef592f7d9ed4bcdcacec081b3df01 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 15 Jul 2024 14:29:07 +0530 Subject: [PATCH 10/11] chore: contextual comments (cherry picked from commit 794a62aecb1248d3ed0a9581c1d30c852cc3f67b) --- erpnext/accounts/doctype/journal_entry/test_journal_entry.py | 1 + .../accounts/doctype/purchase_invoice/test_purchase_invoice.py | 1 + 2 files changed, 2 insertions(+) diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 2aea25b431e..6838c4a0975 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -467,6 +467,7 @@ class TestJournalEntry(unittest.TestCase): # Change cost center for bank account - _Test Cost Center for BS Account create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company") jv.accounts[1].cost_center = "_Test Cost Center for BS Account - _TC" + # Ledger reposted implicitly upon 'Update After Submit' jv.save() # Check GL entries after reposting diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index a2d97e70416..b3a3a9634fb 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1908,6 +1908,7 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin): check_gl_entries(self, pi.name, expected_gle, nowdate()) pi.items[0].expense_account = "Service - _TC" + # Ledger reposted implicitly upon 'Update After Submit' pi.save() pi.load_from_db() From b96b3b51b6ee21d2a07e8d315bfe7b7b76faad1f Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 15 Jul 2024 15:22:06 +0530 Subject: [PATCH 11/11] chore: resolve conflicts --- .../doctype/journal_entry/journal_entry.py | 14 ---- .../journal_entry/test_journal_entry.py | 71 ------------------- 2 files changed, 85 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index a90a3c1d6b8..b4fb13e42c3 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -99,20 +99,6 @@ class JournalEntry(AccountsController): self.update_asset_value() self.update_inter_company_jv() self.update_invoice_discounting() -<<<<<<< HEAD -======= - self.update_booked_depreciation() - - def on_update_after_submit(self): - if hasattr(self, "repost_required"): - self.needs_repost = self.check_if_fields_updated( - fields_to_check=[], child_tables={"accounts": []} - ) - if self.needs_repost: - self.validate_for_repost() - self.db_set("repost_required", self.needs_repost) - self.repost_accounting_entries() ->>>>>>> 722ef92324 (refactor: make reposting implicit) def on_cancel(self): # References for this Journal are removed on the `on_cancel` event in accounts_controller diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index 6838c4a0975..979f964b62a 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -421,77 +421,6 @@ class TestJournalEntry(unittest.TestCase): account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center) self.assertEqual(expected_account_balance, account_balance) -<<<<<<< HEAD -======= - def test_repost_accounting_entries(self): - from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center - - # Configure Repost Accounting Ledger for JVs - settings = frappe.get_doc("Repost Accounting Ledger Settings") - if not [x for x in settings.allowed_types if x.document_type == "Journal Entry"]: - settings.append("allowed_types", {"document_type": "Journal Entry", "allowed": True}) - settings.save() - - # Create JV with defaut cost center - _Test Cost Center - jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, save=False) - jv.multi_currency = 0 - jv.submit() - - # Check GL entries before reposting - self.voucher_no = jv.name - - self.fields = [ - "account", - "debit_in_account_currency", - "credit_in_account_currency", - "cost_center", - ] - - self.expected_gle = [ - { - "account": "_Test Bank - _TC", - "debit_in_account_currency": 0, - "credit_in_account_currency": 100, - "cost_center": "_Test Cost Center - _TC", - }, - { - "account": "_Test Cash - _TC", - "debit_in_account_currency": 100, - "credit_in_account_currency": 0, - "cost_center": "_Test Cost Center - _TC", - }, - ] - - self.check_gl_entries() - - # Change cost center for bank account - _Test Cost Center for BS Account - create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company") - jv.accounts[1].cost_center = "_Test Cost Center for BS Account - _TC" - # Ledger reposted implicitly upon 'Update After Submit' - jv.save() - - # Check GL entries after reposting - jv.load_from_db() - self.expected_gle[0]["cost_center"] = "_Test Cost Center for BS Account - _TC" - self.check_gl_entries() - - def check_gl_entries(self): - gl = frappe.qb.DocType("GL Entry") - query = frappe.qb.from_(gl) - for field in self.fields: - query = query.select(gl[field]) - - query = query.where( - (gl.voucher_type == "Journal Entry") & (gl.voucher_no == self.voucher_no) & (gl.is_cancelled == 0) - ).orderby(gl.account) - - gl_entries = query.run(as_dict=True) - - for i in range(len(self.expected_gle)): - for field in self.fields: - self.assertEqual(self.expected_gle[i][field], gl_entries[i][field]) - ->>>>>>> 8f135e9859 (refactor(test): no need to assert repost_required flag) def make_journal_entry( account1,