From 6f6644f4c45f739fcf4f0ba9ad83908cb01b945a Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 21 Nov 2024 18:30:37 +0530 Subject: [PATCH 1/3] fix: toggle debit credit amounts for transaction currency too; minor refactor (cherry picked from commit 8e759c32c431834f8e77c1665cf8c36ba881582b) # Conflicts: # erpnext/accounts/general_ledger.py --- erpnext/accounts/general_ledger.py | 74 +++++++++++++++--------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index f2bc8b3a2f8a..dc4a4d553b04 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -304,54 +304,54 @@ def check_if_in_list(gle, gl_map): def toggle_debit_credit_if_negative(gl_map): + debit_credit_field_map = { + "debit": "credit", + "debit_in_account_currency": "credit_in_account_currency", + "debit_in_transaction_currency": "credit_in_transaction_currency", + } + for entry in gl_map: # toggle debit, credit if negative entry +<<<<<<< HEAD if flt(entry.debit) < 0: entry.credit = flt(entry.credit) - flt(entry.debit) entry.debit = 0.0 +======= + for debit_field, credit_field in debit_credit_field_map.items(): + debit = flt(entry.get(debit_field)) + credit = flt(entry.get(credit_field)) + + if debit < 0 and credit < 0 and debit == credit: + debit *= -1 + credit *= -1 + + if debit < 0: + credit = credit - debit + debit = 0.0 +>>>>>>> 8e759c32c4 (fix: toggle debit credit amounts for transaction currency too; minor refactor) + + if credit < 0: + debit = debit - credit + credit = 0.0 + + # update net values + # In some scenarios net value needs to be shown in the ledger + # This method updates net values as debit or credit + if entry.post_net_value and debit and credit: + if debit > credit: + debit = debit - credit + credit = 0.0 - if flt(entry.debit_in_account_currency) < 0: - entry.credit_in_account_currency = flt(entry.credit_in_account_currency) - flt( - entry.debit_in_account_currency - ) - entry.debit_in_account_currency = 0.0 - - if flt(entry.credit) < 0: - entry.debit = flt(entry.debit) - flt(entry.credit) - entry.credit = 0.0 - - if flt(entry.credit_in_account_currency) < 0: - entry.debit_in_account_currency = flt(entry.debit_in_account_currency) - flt( - entry.credit_in_account_currency - ) - entry.credit_in_account_currency = 0.0 + else: + credit = credit - debit + debit = 0.0 - update_net_values(entry) + entry[debit_field] = debit + entry[credit_field] = credit return gl_map -def update_net_values(entry): - # In some scenarios net value needs to be shown in the ledger - # This method updates net values as debit or credit - if entry.post_net_value and entry.debit and entry.credit: - if entry.debit > entry.credit: - entry.debit = entry.debit - entry.credit - entry.debit_in_account_currency = ( - entry.debit_in_account_currency - entry.credit_in_account_currency - ) - entry.credit = 0 - entry.credit_in_account_currency = 0 - else: - entry.credit = entry.credit - entry.debit - entry.credit_in_account_currency = ( - entry.credit_in_account_currency - entry.debit_in_account_currency - ) - - entry.debit = 0 - entry.debit_in_account_currency = 0 - - def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False): if not from_repost: validate_cwip_accounts(gl_map) From 7f6c0e83d41c39d9b450f275c8aa7327a83927e2 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 21 Nov 2024 19:44:02 +0530 Subject: [PATCH 2/3] test: test case for toggling debit and credit if negative (cherry picked from commit a10e175bc926219a6d534eb5a1e006e66bf7b8fd) # Conflicts: # erpnext/accounts/doctype/journal_entry/test_journal_entry.py --- .../journal_entry/test_journal_entry.py | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index f219c228421a..cb1cf4835abc 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -421,6 +421,180 @@ def test_jv_account_and_party_balance_with_cost_centre(self): 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]) + + def test_negative_debit_and_credit_with_same_account_head(self): + from erpnext.accounts.general_ledger import process_gl_map + + # Create JV with defaut cost center - _Test Cost Center + frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) + + jv = make_journal_entry("_Test Bank - _TC", "_Test Bank - _TC", 100 * -1, save=True) + jv.append( + "accounts", + { + "account": "_Test Cash - _TC", + "debit": 100 * -1, + "credit": 100 * -1, + "debit_in_account_currency": 100 * -1, + "credit_in_account_currency": 100 * -1, + "exchange_rate": 1, + }, + ) + jv.flags.ignore_validate = True + jv.save() + + self.assertEqual(len(jv.accounts), 3) + + gl_map = jv.build_gl_map() + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.debit_in_account_currency, 100 * -1) + self.assertEqual(row.credit_in_account_currency, 100 * -1) + + gl_map = process_gl_map(gl_map, False) + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.debit_in_account_currency, 100) + self.assertEqual(row.credit_in_account_currency, 100) + + def test_toggle_debit_credit_if_negative(self): + from erpnext.accounts.general_ledger import process_gl_map + + # Create JV with defaut cost center - _Test Cost Center + frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) + + jv = frappe.new_doc("Journal Entry") + jv.posting_date = nowdate() + jv.company = "_Test Company" + jv.user_remark = "test" + jv.extend( + "accounts", + [ + { + "account": "_Test Cash - _TC", + "debit": 100 * -1, + "debit_in_account_currency": 100 * -1, + "exchange_rate": 1, + }, + { + "account": "_Test Bank - _TC", + "credit": 100 * -1, + "credit_in_account_currency": 100 * -1, + "exchange_rate": 1, + }, + ], + ) + + jv.flags.ignore_validate = True + jv.save() + + self.assertEqual(len(jv.accounts), 2) + + gl_map = jv.build_gl_map() + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.debit, 100 * -1) + self.assertEqual(row.debit_in_account_currency, 100 * -1) + self.assertEqual(row.debit_in_transaction_currency, 100 * -1) + + gl_map = process_gl_map(gl_map, False) + + for row in gl_map: + if row.account == "_Test Cash - _TC": + self.assertEqual(row.credit, 100) + self.assertEqual(row.credit_in_account_currency, 100) + self.assertEqual(row.credit_in_transaction_currency, 100) + + def test_transaction_exchange_rate_on_journals(self): + jv = make_journal_entry("_Test Bank - _TC", "_Test Receivable USD - _TC", 100, save=False) + jv.accounts[0].update({"debit_in_account_currency": 8500, "exchange_rate": 1}) + jv.accounts[1].update({"party_type": "Customer", "party": "_Test Customer USD", "exchange_rate": 85}) + jv.submit() + actual = frappe.db.get_all( + "GL Entry", + filters={"voucher_no": jv.name, "is_cancelled": 0}, + fields=["account", "transaction_exchange_rate"], + order_by="account", + ) + expected = [ + {"account": "_Test Bank - _TC", "transaction_exchange_rate": 1.0}, + {"account": "_Test Receivable USD - _TC", "transaction_exchange_rate": 85.0}, + ] + self.assertEqual(expected, actual) + +>>>>>>> a10e175bc9 (test: test case for toggling debit and credit if negative) def make_journal_entry( account1, From 3ae02bca3f2fd0301e0473d866e376bee3f9d23b Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Fri, 22 Nov 2024 18:44:33 +0530 Subject: [PATCH 3/3] chore: resolve conflicts --- .../journal_entry/test_journal_entry.py | 125 ------------------ erpnext/accounts/general_ledger.py | 6 - 2 files changed, 131 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py index cb1cf4835abc..82fcea024707 100644 --- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py @@ -421,113 +421,6 @@ def test_jv_account_and_party_balance_with_cost_centre(self): 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]) - - def test_negative_debit_and_credit_with_same_account_head(self): - from erpnext.accounts.general_ledger import process_gl_map - - # Create JV with defaut cost center - _Test Cost Center - frappe.db.set_single_value("Accounts Settings", "merge_similar_account_heads", 0) - - jv = make_journal_entry("_Test Bank - _TC", "_Test Bank - _TC", 100 * -1, save=True) - jv.append( - "accounts", - { - "account": "_Test Cash - _TC", - "debit": 100 * -1, - "credit": 100 * -1, - "debit_in_account_currency": 100 * -1, - "credit_in_account_currency": 100 * -1, - "exchange_rate": 1, - }, - ) - jv.flags.ignore_validate = True - jv.save() - - self.assertEqual(len(jv.accounts), 3) - - gl_map = jv.build_gl_map() - - for row in gl_map: - if row.account == "_Test Cash - _TC": - self.assertEqual(row.debit_in_account_currency, 100 * -1) - self.assertEqual(row.credit_in_account_currency, 100 * -1) - - gl_map = process_gl_map(gl_map, False) - - for row in gl_map: - if row.account == "_Test Cash - _TC": - self.assertEqual(row.debit_in_account_currency, 100) - self.assertEqual(row.credit_in_account_currency, 100) - def test_toggle_debit_credit_if_negative(self): from erpnext.accounts.general_ledger import process_gl_map @@ -577,24 +470,6 @@ def test_toggle_debit_credit_if_negative(self): self.assertEqual(row.credit_in_account_currency, 100) self.assertEqual(row.credit_in_transaction_currency, 100) - def test_transaction_exchange_rate_on_journals(self): - jv = make_journal_entry("_Test Bank - _TC", "_Test Receivable USD - _TC", 100, save=False) - jv.accounts[0].update({"debit_in_account_currency": 8500, "exchange_rate": 1}) - jv.accounts[1].update({"party_type": "Customer", "party": "_Test Customer USD", "exchange_rate": 85}) - jv.submit() - actual = frappe.db.get_all( - "GL Entry", - filters={"voucher_no": jv.name, "is_cancelled": 0}, - fields=["account", "transaction_exchange_rate"], - order_by="account", - ) - expected = [ - {"account": "_Test Bank - _TC", "transaction_exchange_rate": 1.0}, - {"account": "_Test Receivable USD - _TC", "transaction_exchange_rate": 85.0}, - ] - self.assertEqual(expected, actual) - ->>>>>>> a10e175bc9 (test: test case for toggling debit and credit if negative) def make_journal_entry( account1, diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index dc4a4d553b04..55379fe15ec2 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -312,11 +312,6 @@ def toggle_debit_credit_if_negative(gl_map): for entry in gl_map: # toggle debit, credit if negative entry -<<<<<<< HEAD - if flt(entry.debit) < 0: - entry.credit = flt(entry.credit) - flt(entry.debit) - entry.debit = 0.0 -======= for debit_field, credit_field in debit_credit_field_map.items(): debit = flt(entry.get(debit_field)) credit = flt(entry.get(credit_field)) @@ -328,7 +323,6 @@ def toggle_debit_credit_if_negative(gl_map): if debit < 0: credit = credit - debit debit = 0.0 ->>>>>>> 8e759c32c4 (fix: toggle debit credit amounts for transaction currency too; minor refactor) if credit < 0: debit = debit - credit