From b65e58c1ae215215a73ad92e24791e9c6090cfa5 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Thu, 8 Jun 2023 18:15:37 +0530 Subject: [PATCH] test: add tests for advance liability entries Add Sales and Purchase Invoice Tests to check if GL entries and Outstanding Amount are generated correctly when advance entries are recorded as liability. Few changes to return value of added column in Payment Entry References. --- .../doctype/payment_entry/payment_entry.py | 8 ++- .../payment_entry_reference.json | 2 +- .../purchase_invoice/test_purchase_invoice.py | 60 +++++++++++++++--- .../sales_invoice/test_sales_invoice.py | 63 +++++++++++++++---- erpnext/accounts/utils.py | 1 + 5 files changed, 113 insertions(+), 21 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 291f8e4411..236a78a370 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1741,6 +1741,9 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre if reference_doctype in ("Sales Invoice", "Purchase Invoice"): outstanding_amount = ref_doc.get("outstanding_amount") + account = ( + ref_doc.get("debit_to") if reference_doctype == "Sales Invoice" else ref_doc.get("credit_to") + ) else: outstanding_amount = flt(total_amount) - flt(ref_doc.get("advance_paid")) @@ -1748,7 +1751,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre # Get the exchange rate based on the posting date of the ref doc. exchange_rate = get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date) - return frappe._dict( + res = frappe._dict( { "due_date": ref_doc.get("due_date"), "total_amount": flt(total_amount), @@ -1757,6 +1760,9 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre "bill_no": ref_doc.get("bill_no"), } ) + if account: + res.update({"account": account}) + return res @frappe.whitelist() diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json index c318ea53bd..12aa0b520e 100644 --- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json +++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json @@ -113,7 +113,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2023-06-07 14:35:06.166907", + "modified": "2023-06-08 07:40:38.487874", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Entry Reference", diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index a6d7df6971..ebb4970b3d 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -1662,22 +1662,66 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin): self.assertTrue(return_pi.docstatus == 1) + 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_account": "Debtors - _TC"}, + ) + pe = create_payment_entry( + company="_Test Company", + payment_type="Pay", + party_type="Supplier", + party="_Test Supplier", + paid_from="Cash - _TC", + paid_to=get_party_account("Supplier", "_Test Supplier", "_Test Company", is_advance=True), + paid_amount=1000, + ) + pe.submit() + + pi = make_purchase_invoice( + company="_Test Company", customer="_Test Supplier", do_not_save=True, do_not_submit=True + ) + pi.base_grand_total = 100 + pi.grand_total = 100 + pi.set_advances() + self.assertEqual(pi.advances[0].allocated_amount, 100) + pi.advances[0].allocated_amount = 50 + pi.advances = [pi.advances[0]] + pi.save() + pi.submit() + expected_gle = [ + ["Creditors - _TC", 50, 100], + ["Debtors - _TC", 0.0, 50], + ["Stock Received But Not Billed - _TC", 100, 0.0], + ] + + check_gl_entries(self, pi.name, expected_gle, nowdate()) + self.assertEqual(pi.outstanding_amount, 200) + def check_gl_entries(doc, voucher_no, expected_gle, posting_date): - gl_entries = frappe.db.sql( - """select account, debit, credit, posting_date - from `tabGL Entry` - where voucher_type='Purchase Invoice' and voucher_no=%s and posting_date >= %s - order by posting_date asc, account asc""", - (voucher_no, posting_date), - as_dict=1, + gl = frappe.qb.DocType("GL Entry") + q = ( + frappe.qb.from_(gl) + .select(gl.account, gl.debit, gl.credit, gl.posting_date) + .where( + (gl.voucher_type == "Sales Invoice") + & (gl.voucher_no == voucher_no) + & (gl.posting_date >= posting_date) + & (gl.is_cancelled == 0) + ) + .orderby(gl.posting_date, gl.account) ) + gl_entries = q.run(as_dict=True) for i, gle in enumerate(gl_entries): doc.assertEqual(expected_gle[i][0], gle.account) doc.assertEqual(expected_gle[i][1], gle.debit) doc.assertEqual(expected_gle[i][2], gle.credit) - doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date) def create_tax_witholding_category(category_name, company, account): diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index dbc277044a..d10fa05a19 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -3313,6 +3313,46 @@ class TestSalesInvoice(unittest.TestCase): ) self.assertRaises(frappe.ValidationError, si.submit) + 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_account": "Creditors - _TC"}, + ) + pe = create_payment_entry( + company="_Test Company", + payment_type="Receive", + party_type="Customer", + party="_Test Customer", + paid_from=get_party_account("Customer", "_Test Customer", "_Test Company", is_advance=True), + paid_to="Cash - _TC", + paid_amount=1000, + ) + pe.submit() + + si = create_sales_invoice( + company="_Test Company", customer="_Test Customer", do_not_save=True, do_not_submit=True + ) + si.base_grand_total = 100 + si.grand_total = 100 + si.set_advances() + self.assertEqual(si.advances[0].allocated_amount, 100) + si.advances[0].allocated_amount = 50 + si.advances = [si.advances[0]] + si.save() + si.submit() + expected_gle = [ + ["Creditors - _TC", 50, 0.0], + ["Debtors - _TC", 100, 50], + ["Sales - _TC", 0.0, 100], + ] + + check_gl_entries(self, si.name, expected_gle, nowdate()) + self.assertEqual(si.outstanding_amount, 50) + def get_sales_invoice_for_e_invoice(): si = make_sales_invoice_for_ewaybill() @@ -3350,23 +3390,24 @@ def get_sales_invoice_for_e_invoice(): def check_gl_entries(doc, voucher_no, expected_gle, posting_date): - gl_entries = frappe.db.sql( - """select account, debit, credit, posting_date - from `tabGL Entry` - where voucher_type='Sales Invoice' and voucher_no=%s and posting_date >= %s - and is_cancelled = 0 - order by posting_date asc, account asc""", - (voucher_no, posting_date), - as_dict=1, - debug=True, + gl = frappe.qb.DocType("GL Entry") + q = ( + frappe.qb.from_(gl) + .select(gl.account, gl.debit, gl.credit, gl.posting_date) + .where( + (gl.voucher_type == "Sales Invoice") + & (gl.voucher_no == voucher_no) + & (gl.posting_date >= posting_date) + & (gl.is_cancelled == 0) + ) + .orderby(gl.posting_date, gl.account) ) + gl_entries = q.run(as_dict=True) for i, gle in enumerate(gl_entries): - print(i, gle) doc.assertEqual(expected_gle[i][0], gle.account) doc.assertEqual(expected_gle[i][1], gle.debit) doc.assertEqual(expected_gle[i][2], gle.credit) - doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date) def create_sales_invoice(**args): diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 506279c1e5..c1d365304f 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -625,6 +625,7 @@ def update_reference_in_payment_entry( if not d.exchange_gain_loss else payment_entry.get_exchange_rate(), "exchange_gain_loss": d.exchange_gain_loss, # only populated from invoice in case of advance allocation + "account": d.account, } if d.voucher_detail_no: