mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-03 20:29:09 +00:00
fix: Outstanding amount on making payment against discounted invoice
This commit is contained in:
@@ -175,13 +175,20 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
|
|||||||
else:
|
else:
|
||||||
party_condition = ""
|
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
|
# get final outstanding amt
|
||||||
bal = flt(frappe.db.sql("""
|
bal = flt(frappe.db.sql("""
|
||||||
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
|
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
|
||||||
from `tabGL Entry`
|
from `tabGL Entry`
|
||||||
where against_voucher_type=%s and against_voucher=%s
|
where against_voucher_type=%s and against_voucher=%s
|
||||||
and account = %s {0}""".format(party_condition),
|
and voucher_type != 'Invoice Discounting'
|
||||||
(against_voucher_type, against_voucher, account))[0][0] or 0.0)
|
{0} {1}""".format(party_condition, account_condition),
|
||||||
|
(against_voucher_type, against_voucher))[0][0] or 0.0)
|
||||||
|
|
||||||
if against_voucher_type == 'Purchase Invoice':
|
if against_voucher_type == 'Purchase Invoice':
|
||||||
bal = -bal
|
bal = -bal
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ frappe.ui.form.on('Invoice Discounting', {
|
|||||||
"docstatus": 1,
|
"docstatus": 1,
|
||||||
"company": doc.company,
|
"company": doc.company,
|
||||||
"outstanding_amount": [">", 0]
|
"outstanding_amount": [">", 0]
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ class InvoiceDiscounting(AccountsController):
|
|||||||
self.set_end_date()
|
self.set_end_date()
|
||||||
|
|
||||||
def set_end_date(self):
|
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):
|
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"))
|
frappe.throw(_("Loan Start Date and Loan Period are mandatory to save the Invoice Discounting"))
|
||||||
|
|
||||||
def calculate_total_amount(self):
|
def calculate_total_amount(self):
|
||||||
|
|||||||
@@ -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
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_payment_entry_against_invoice
|
||||||
class TestInvoiceDiscounting(unittest.TestCase):
|
class TestInvoiceDiscounting(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.ar_credit = create_account(account_name="_Test Accounts Receivable Credit", parent_account = "Accounts Receivable - _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")
|
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")
|
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")
|
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" )
|
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")
|
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)
|
frappe.db.set_value("Company", "_Test Company", "default_bank_account", self.bank_account)
|
||||||
|
|
||||||
def test_total_amount(self):
|
def test_total_amount(self):
|
||||||
@@ -104,9 +104,11 @@ class TestInvoiceDiscounting(unittest.TestCase):
|
|||||||
je.submit()
|
je.submit()
|
||||||
|
|
||||||
inv_disc.reload()
|
inv_disc.reload()
|
||||||
|
|
||||||
self.assertEqual(inv_disc.status, "Disbursed")
|
self.assertEqual(inv_disc.status, "Disbursed")
|
||||||
|
|
||||||
|
inv.reload()
|
||||||
|
self.assertEqual(inv.outstanding_amount, 500)
|
||||||
|
|
||||||
def test_on_close_after_loan_period(self):
|
def test_on_close_after_loan_period(self):
|
||||||
inv = create_sales_invoice(rate=600)
|
inv = create_sales_invoice(rate=600)
|
||||||
inv_disc = create_invoice_discounting([inv.name],
|
inv_disc = create_invoice_discounting([inv.name],
|
||||||
@@ -186,13 +188,21 @@ class TestInvoiceDiscounting(unittest.TestCase):
|
|||||||
je.posting_date = nowdate()
|
je.posting_date = nowdate()
|
||||||
je.submit()
|
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].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[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].account, self.bank_account)
|
||||||
self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount))
|
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):
|
def test_make_payment_before_after_period(self):
|
||||||
#it has problem
|
#it has problem
|
||||||
inv = create_sales_invoice(rate=700)
|
inv = create_sales_invoice(rate=700)
|
||||||
@@ -216,13 +226,20 @@ class TestInvoiceDiscounting(unittest.TestCase):
|
|||||||
je.posting_date = nowdate()
|
je.posting_date = nowdate()
|
||||||
je.submit()
|
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].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[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].account, self.bank_account)
|
||||||
self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount))
|
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):
|
def create_invoice_discounting(invoices, **args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
@@ -259,7 +259,11 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
# check if party and account match
|
# check if party and account match
|
||||||
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
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}")
|
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],
|
.format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
|
||||||
d.reference_type, d.reference_name))
|
d.reference_type, d.reference_name))
|
||||||
|
|||||||
Reference in New Issue
Block a user