From 17341adf1cb385e3326552d95dc1bcd00e4b938a Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Tue, 13 Jun 2023 15:00:46 +0530 Subject: [PATCH] fix: calculate outstanding amount on reconcile correctly --- .../doctype/payment_entry/payment_entry.py | 21 ++++--- .../purchase_invoice/test_purchase_invoice.py | 58 ++++++++++------- .../sales_invoice/test_sales_invoice.py | 62 ++++++++++--------- erpnext/accounts/utils.py | 2 +- erpnext/buying/doctype/supplier/supplier.js | 2 +- erpnext/controllers/accounts_controller.py | 6 +- erpnext/selling/doctype/customer/customer.js | 2 +- erpnext/setup/doctype/company/company.js | 4 +- 8 files changed, 85 insertions(+), 72 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 7a31dc5885..dd3490936f 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -872,12 +872,12 @@ class PaymentEntry(AccountsController): self.set("remarks", "\n".join(remarks)) - def build_gl_map(self): + def build_gl_map(self, is_reconcile=False): if self.payment_type in ("Receive", "Pay") and not self.get("party_account_field"): self.setup_party_account_field() gl_entries = [] - self.add_party_gl_entries(gl_entries) + self.add_party_gl_entries(gl_entries, is_reconcile) self.add_bank_gl_entries(gl_entries) self.add_deductions_gl_entries(gl_entries) self.add_tax_gl_entries(gl_entries) @@ -888,7 +888,7 @@ class PaymentEntry(AccountsController): gl_entries = process_gl_map(gl_entries) make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj) - def add_party_gl_entries(self, gl_entries): + def add_party_gl_entries(self, gl_entries, is_reconcile): if self.party_account: if self.payment_type == "Receive": against_account = self.paid_to @@ -917,13 +917,14 @@ class PaymentEntry(AccountsController): d.reference_doctype in ["Sales Invoice", "Purchase Invoice"] and book_advance_payments_as_liability ): - self.make_invoice_liability_entry(gl_entries, d) - gle.update( - { - "against_voucher_type": "Payment Entry", - "against_voucher": self.name, - } - ) + if not is_reconcile: + self.make_invoice_liability_entry(gl_entries, d) + gle.update( + { + "against_voucher_type": "Payment Entry", + "against_voucher": self.name, + } + ) allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d) gle.update( diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 1ac231bc19..6ebb6afe6e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1664,13 +1664,9 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin): def test_advance_entries_as_liability(self): from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry - from erpnext.accounts.party import get_party_account - frappe.db.set_value( - "Company", - "_Test Company", - {"book_advance_payments_as_liability": 1, "default_advance_paid_account": "Debtors - _TC"}, - ) + set_advance_flag(company="_Test Company", flag=1, default_account="Debtors - _TC") + pe = create_payment_entry( company="_Test Company", payment_type="Pay", @@ -1678,34 +1674,48 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin): party="_Test Supplier", paid_from="Cash - _TC", paid_to="Creditors - _TC", - paid_amount=1000, + paid_amount=500, ) pe.submit() pi = make_purchase_invoice( - company="_Test Company", customer="_Test Supplier", do_not_save=True, do_not_submit=True + company="_Test Company", + customer="_Test Supplier", + do_not_save=True, + do_not_submit=True, + rate=1000, + price_list_rate=1000, + qty=1, ) - pi.base_grand_total = 100 - pi.grand_total = 100 + pi.base_grand_total = 1000 + pi.grand_total = 1000 pi.set_advances() - self.assertEqual(pi.advances[0].allocated_amount, 100) - pi.advances[0].allocated_amount = 50 - pi.advances = [pi.advances[0]] + for advance in pi.advances: + advance.allocated_amount = 500 if advance.reference_name == pe.name else 0 pi.save() pi.submit() - expected_gle = [ - ["Creditors - _TC", 50, 100, nowdate()], - ["Debtors - _TC", 0.0, 50, nowdate()], - ["Stock Received But Not Billed - _TC", 100, 0.0, nowdate()], - ] + self.assertEqual(pi.advances[0].allocated_amount, 500) + expected_gle = [ + ["Creditors - _TC", 500, 1000, nowdate()], + ["Debtors - _TC", 0.0, 500, nowdate()], + ["Stock Received But Not Billed - _TC", 1000, 0.0, nowdate()], + ] check_gl_entries(self, pi.name, expected_gle, nowdate()) - self.assertEqual(pi.outstanding_amount, 200) - frappe.db.set_value( - "Company", - "_Test Company", - {"book_advance_payments_as_liability": 0, "default_advance_paid_account": ""}, - ) + self.assertEqual(pi.outstanding_amount, 500) + + set_advance_flag(company="_Test Company", flag=0, default_account="") + + +def set_advance_flag(company, flag, default_account): + frappe.db.set_value( + "Company", + company, + { + "book_advance_payments_as_liability": flag, + "default_advance_paid_account": default_account, + }, + ) def check_gl_entries(doc, voucher_no, expected_gle, posting_date): diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 8ab7fd7cd0..067808d9a1 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -3315,16 +3315,10 @@ class TestSalesInvoice(unittest.TestCase): def test_advance_entries_as_liability(self): from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry - from erpnext.accounts.party import get_party_account + from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute + + set_advance_flag(company="_Test Company", flag=1, default_account="Creditors - _TC") - frappe.db.set_value( - "Company", - "_Test Company", - { - "book_advance_payments_as_liability": 1, - "default_advance_received_account": "Creditors - _TC", - }, - ) pe = create_payment_entry( company="_Test Company", payment_type="Receive", @@ -3337,32 +3331,42 @@ class TestSalesInvoice(unittest.TestCase): pe.submit() si = create_sales_invoice( - company="_Test Company", customer="_Test Customer", do_not_save=True, do_not_submit=True + company="_Test Company", + customer="_Test Customer", + do_not_save=True, + do_not_submit=True, + rate=500, + price_list_rate=500, ) - si.base_grand_total = 100 - si.grand_total = 100 + si.base_grand_total = 500 + si.grand_total = 500 si.set_advances() - self.assertEqual(si.advances[0].allocated_amount, 100) - si.advances[0].allocated_amount = 50 - si.advances = [si.advances[0]] + for advance in si.advances: + advance.allocated_amount = 500 if advance.reference_name == pe.name else 0 si.save() si.submit() - expected_gle = [ - ["Creditors - _TC", 50, 0.0, nowdate()], - ["Debtors - _TC", 100, 50, nowdate()], - ["Sales - _TC", 0.0, 100, nowdate()], - ] + self.assertEqual(si.advances[0].allocated_amount, 500) + expected_gle = [ + ["Creditors - _TC", 500, 0.0, nowdate()], + ["Debtors - _TC", 500, 500, nowdate()], + ["Sales - _TC", 0.0, 500, nowdate()], + ] check_gl_entries(self, si.name, expected_gle, nowdate()) - self.assertEqual(si.outstanding_amount, 50) - frappe.db.set_value( - "Company", - "_Test Company", - { - "book_advance_payments_as_liability": 0, - "default_advance_received_account": "", - }, - ) + self.assertEqual(si.outstanding_amount, 0) + + set_advance_flag(company="_Test Company", flag=0, default_account="") + + +def set_advance_flag(company, flag, default_account): + frappe.db.set_value( + "Company", + company, + { + "book_advance_payments_as_liability": flag, + "default_advance_received_account": default_account, + }, + ) def get_sales_invoice_for_e_invoice(): diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index c1d365304f..728a6d7a96 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -472,7 +472,7 @@ def reconcile_against_document(args, skip_ref_details_update_for_pe=False): # n doc.save(ignore_permissions=True) # re-submit advance entry doc = frappe.get_doc(entry.voucher_type, entry.voucher_no) - gl_map = doc.build_gl_map() + gl_map = doc.build_gl_map(is_reconcile=True) create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1) # Only update outstanding for newly linked vouchers diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 50f9bb6cb9..a5bf4b246b 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -22,7 +22,7 @@ frappe.ui.form.on("Supplier", { let d = locals[cdt][cdn]; return { filters: { - "root_type": 'Asset', + "account_type": "Receivable", "company": d.company, "is_group": 0 } diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 3fac56cfa2..7b2039d193 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2940,10 +2940,8 @@ def make_advance_liability_entry( dr_or_cr + "_in_account_currency": allocated_amount, rev: 0, rev + "_in_account_currency": 0, - "against_voucher": invoice.return_against - if cint(invoice.is_return) and invoice.return_against - else invoice.name, - "against_voucher_type": invoice.doctype, + "against_voucher": pe.name, + "against_voucher_type": "Payment Entry", "cost_center": invoice.cost_center, "project": invoice.project, "voucher_type": voucher_type, diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 8f828807a5..408e89b0ef 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -39,7 +39,7 @@ frappe.ui.form.on("Customer", { let d = locals[cdt][cdn]; return { filters: { - "root_type": 'Liability', + "account_type": 'Payable', "company": d.company, "is_group": 0 } diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js index 436fe0595a..089e20d442 100644 --- a/erpnext/setup/doctype/company/company.js +++ b/erpnext/setup/doctype/company/company.js @@ -227,8 +227,8 @@ erpnext.company.setup_queries = function(frm) { ["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}], ["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}], ["default_provisional_account", {"root_type": ["in", ["Liability", "Asset"]]}], - ["default_advance_received_account", {"root_type": "Liability"}], - ["default_advance_paid_account", {"root_type": "Asset"}], + ["default_advance_received_account", {"account_type": "Payable"}], + ["default_advance_paid_account", {"account_type": "Receivable"}], ], function(i, v) { erpnext.company.set_custom_query(frm, v); });