From 076cc38c294c0b00196d93378961aecc382d9d76 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 15 Apr 2019 18:42:10 +0530 Subject: [PATCH] fix: Outstanding amount on making payment against discounted invoice --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 11 ++++-- .../invoice_discounting.js | 2 +- .../invoice_discounting.py | 5 +-- .../test_invoice_discounting.py | 35 ++++++++++++++----- .../doctype/journal_entry/journal_entry.py | 6 +++- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index e264467a5a..3ced9a39eb 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -175,13 +175,20 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga else: party_condition = "" + if against_voucher_type == "Sales Invoice": + party_account = frappe.db.get_value(against_voucher_type, against_voucher, "debit_to") + account_condition = "and account in ({0}, {1})".format(frappe.db.escape(account), frappe.db.escape(party_account)) + else: + account_condition = " and account = {0}".format(frappe.db.escape(account)) + # get final outstanding amt bal = flt(frappe.db.sql(""" select sum(debit_in_account_currency) - sum(credit_in_account_currency) from `tabGL Entry` where against_voucher_type=%s and against_voucher=%s - and account = %s {0}""".format(party_condition), - (against_voucher_type, against_voucher, account))[0][0] or 0.0) + and voucher_type != 'Invoice Discounting' + {0} {1}""".format(party_condition, account_condition), + (against_voucher_type, against_voucher))[0][0] or 0.0) if against_voucher_type == 'Purchase Invoice': bal = -bal diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js index 88cb939678..5563f031bb 100644 --- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js +++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js @@ -9,7 +9,7 @@ frappe.ui.form.on('Invoice Discounting', { "docstatus": 1, "company": doc.company, "outstanding_amount": [">", 0] - } + }, }; }); diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py index f5fc92cd68..64aa4e4af6 100644 --- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py +++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py @@ -17,10 +17,11 @@ class InvoiceDiscounting(AccountsController): self.set_end_date() def set_end_date(self): - self.loan_end_date = add_days(self.loan_start_date, self.loan_period) + if self.loan_start_date and self.loan_period: + self.loan_end_date = add_days(self.loan_start_date, self.loan_period) def validate_mandatory(self): - if not (self.loan_start_date and self.loan_period): + if self.docstatus == 1 and not (self.loan_start_date and self.loan_period): frappe.throw(_("Loan Start Date and Loan Period are mandatory to save the Invoice Discounting")) def calculate_total_amount(self): diff --git a/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py index 92b0385364..4f93e11def 100644 --- a/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py +++ b/erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py @@ -12,12 +12,12 @@ from erpnext.accounts.doctype.account.test_account import create_account from erpnext.accounts.doctype.journal_entry.journal_entry import get_payment_entry_against_invoice class TestInvoiceDiscounting(unittest.TestCase): def setUp(self): - self.ar_credit = create_account(account_name="_Test Accounts Receivable Credit", parent_account = "Accounts Receivable - _TC") - self.ar_discounted = create_account(account_name="_Test Accounts Receivable Discounted", parent_account = "Accounts Receivable - _TC") - self.ar_unpaid = create_account(account_name="_Test Accounts Receivable Unpaid", parent_account = "Accounts Receivable - _TC") - self.short_term_loan = create_account(account_name="_Test Short Term Loan", parent_account = "Source of Funds (Liabilities) - _TC") - self.bank_account = create_account(account_name="_Test Bank 2", parent_account = "Bank Accounts - _TC" ) - self.bank_charges_account = create_account(account_name="_Test Bank Charges Account", parent_account = "Expenses - _TC") + self.ar_credit = create_account(account_name="_Test Accounts Receivable Credit", parent_account = "Accounts Receivable - _TC", company="_Test Company") + self.ar_discounted = create_account(account_name="_Test Accounts Receivable Discounted", parent_account = "Accounts Receivable - _TC", company="_Test Company") + self.ar_unpaid = create_account(account_name="_Test Accounts Receivable Unpaid", parent_account = "Accounts Receivable - _TC", company="_Test Company") + self.short_term_loan = create_account(account_name="_Test Short Term Loan", parent_account = "Source of Funds (Liabilities) - _TC", company="_Test Company") + self.bank_account = create_account(account_name="_Test Bank 2", parent_account = "Bank Accounts - _TC", company="_Test Company") + self.bank_charges_account = create_account(account_name="_Test Bank Charges Account", parent_account = "Expenses - _TC", company="_Test Company") frappe.db.set_value("Company", "_Test Company", "default_bank_account", self.bank_account) def test_total_amount(self): @@ -104,9 +104,11 @@ class TestInvoiceDiscounting(unittest.TestCase): je.submit() inv_disc.reload() - self.assertEqual(inv_disc.status, "Disbursed") + inv.reload() + self.assertEqual(inv.outstanding_amount, 500) + def test_on_close_after_loan_period(self): inv = create_sales_invoice(rate=600) inv_disc = create_invoice_discounting([inv.name], @@ -186,13 +188,21 @@ class TestInvoiceDiscounting(unittest.TestCase): je.posting_date = nowdate() je.submit() - je_on_payment = get_payment_entry_against_invoice("Sales Invoice", inv.name) + je_on_payment = frappe.get_doc(get_payment_entry_against_invoice("Sales Invoice", inv.name)) + je_on_payment.posting_date = nowdate() + je_on_payment.cheque_no = "126981" + je_on_payment.cheque_date = nowdate() + je_on_payment.save() + je_on_payment.submit() self.assertEqual(je_on_payment.accounts[0].account, self.ar_discounted) self.assertEqual(je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount)) self.assertEqual(je_on_payment.accounts[1].account, self.bank_account) self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount)) + inv.reload() + self.assertEqual(inv.outstanding_amount, 0) + def test_make_payment_before_after_period(self): #it has problem inv = create_sales_invoice(rate=700) @@ -216,13 +226,20 @@ class TestInvoiceDiscounting(unittest.TestCase): je.posting_date = nowdate() je.submit() - je_on_payment = get_payment_entry_against_invoice("Sales Invoice", inv.name) + je_on_payment = frappe.get_doc(get_payment_entry_against_invoice("Sales Invoice", inv.name)) + je_on_payment.posting_date = nowdate() + je_on_payment.cheque_no = "126981" + je_on_payment.cheque_date = nowdate() + je_on_payment.submit() self.assertEqual(je_on_payment.accounts[0].account, self.ar_unpaid) self.assertEqual(je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount)) self.assertEqual(je_on_payment.accounts[1].account, self.bank_account) self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount)) + inv.reload() + self.assertEqual(inv.outstanding_amount, 0) + def create_invoice_discounting(invoices, **args): args = frappe._dict(args) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index d3f75f65f1..28869d86d9 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -259,7 +259,11 @@ class JournalEntry(AccountsController): # check if party and account match if d.reference_type in ("Sales Invoice", "Purchase Invoice"): - if (against_voucher[0] != d.party or against_voucher[1] != d.account): + if d.reference_type == "Sales Invoice": + party_account = get_party_account_based_on_invoice_discounting(d.reference_name) or against_voucher[1] + else: + party_account = against_voucher[1] + if (against_voucher[0] != d.party or party_account != d.account): frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}") .format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1], d.reference_type, d.reference_name))