mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-31 02:40:43 +02:00
fix: consider journal entry and return invoice in paid_amount calculation (backport #46129) (#46319)
fix: consider journal entry and return invoice in paid_amount calculation (#46129)
* fix: consider journal entry and return invoice in paid_amount calculation
* test: add new unit test to consider journal entry and return invoice in paid_amount calculation
(cherry picked from commit 425fb12e91)
Co-authored-by: Sugesh G <73237300+Sugesh393@users.noreply.github.com>
This commit is contained in:
@@ -768,29 +768,39 @@ def get_existing_payment_request_amount(ref_dt, ref_dn, statuses: list | None =
|
|||||||
|
|
||||||
|
|
||||||
def get_existing_paid_amount(doctype, name):
|
def get_existing_paid_amount(doctype, name):
|
||||||
PL = frappe.qb.DocType("Payment Ledger Entry")
|
PLE = frappe.qb.DocType("Payment Ledger Entry")
|
||||||
PER = frappe.qb.DocType("Payment Entry Reference")
|
PER = frappe.qb.DocType("Payment Entry Reference")
|
||||||
|
|
||||||
query = (
|
query = (
|
||||||
frappe.qb.from_(PL)
|
frappe.qb.from_(PLE)
|
||||||
.left_join(PER)
|
.left_join(PER)
|
||||||
.on(
|
.on(
|
||||||
(PL.against_voucher_type == PER.reference_doctype)
|
(PLE.against_voucher_type == PER.reference_doctype)
|
||||||
& (PL.against_voucher_no == PER.reference_name)
|
& (PLE.against_voucher_no == PER.reference_name)
|
||||||
& (PL.voucher_type == PER.parenttype)
|
& (PLE.voucher_type == PER.parenttype)
|
||||||
& (PL.voucher_no == PER.parent)
|
& (PLE.voucher_no == PER.parent)
|
||||||
|
)
|
||||||
|
.select(
|
||||||
|
Abs(Sum(PLE.amount)).as_("total_amount"),
|
||||||
|
Abs(Sum(frappe.qb.terms.Case().when(PER.payment_request.isnotnull(), PLE.amount).else_(0))).as_(
|
||||||
|
"request_paid_amount"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
(PLE.voucher_type.isin([doctype, "Journal Entry", "Payment Entry"]))
|
||||||
|
& (PLE.against_voucher_type == doctype)
|
||||||
|
& (PLE.against_voucher_no == name)
|
||||||
|
& (PLE.delinked == 0)
|
||||||
|
& (PLE.docstatus == 1)
|
||||||
|
& (PLE.amount < 0)
|
||||||
)
|
)
|
||||||
.select(Abs(Sum(PL.amount)).as_("total_paid_amount"))
|
|
||||||
.where(PL.against_voucher_type.eq(doctype))
|
|
||||||
.where(PL.against_voucher_no.eq(name))
|
|
||||||
.where(PL.amount < 0)
|
|
||||||
.where(PL.delinked == 0)
|
|
||||||
.where(PER.docstatus == 1)
|
|
||||||
.where(PER.payment_request.isnull())
|
|
||||||
)
|
)
|
||||||
response = query.run()
|
|
||||||
|
|
||||||
return response[0][0] if response[0] else 0
|
result = query.run()
|
||||||
|
ledger_amount = flt(result[0][0]) if result else 0
|
||||||
|
request_paid_amount = flt(result[0][1]) if result else 0
|
||||||
|
|
||||||
|
return ledger_amount - request_paid_amount
|
||||||
|
|
||||||
|
|
||||||
def get_gateway_details(args): # nosemgrep
|
def get_gateway_details(args): # nosemgrep
|
||||||
|
|||||||
@@ -581,6 +581,34 @@ class TestPaymentRequest(FrappeTestCase):
|
|||||||
pi.load_from_db()
|
pi.load_from_db()
|
||||||
self.assertEqual(pr_2.grand_total, pi.outstanding_amount)
|
self.assertEqual(pr_2.grand_total, pi.outstanding_amount)
|
||||||
|
|
||||||
|
def test_consider_journal_entry_and_return_invoice(self):
|
||||||
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||||
|
|
||||||
|
si = create_sales_invoice(currency="INR", qty=5, rate=500)
|
||||||
|
|
||||||
|
je = make_journal_entry("_Test Cash - _TC", "Debtors - _TC", 500, save=False)
|
||||||
|
je.accounts[1].party_type = "Customer"
|
||||||
|
je.accounts[1].party = si.customer
|
||||||
|
je.accounts[1].reference_type = "Sales Invoice"
|
||||||
|
je.accounts[1].reference_name = si.name
|
||||||
|
je.accounts[1].credit_in_account_currency = 500
|
||||||
|
je.submit()
|
||||||
|
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name)
|
||||||
|
pe.paid_amount = 500
|
||||||
|
pe.references[0].allocated_amount = 500
|
||||||
|
pe.save()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
cr_note = create_sales_invoice(qty=-1, rate=500, is_return=1, return_against=si.name, do_not_save=1)
|
||||||
|
cr_note.update_outstanding_for_self = 0
|
||||||
|
cr_note.save()
|
||||||
|
cr_note.submit()
|
||||||
|
|
||||||
|
si.load_from_db()
|
||||||
|
pr = make_payment_request(dt="Sales Invoice", dn=si.name, mute_email=1)
|
||||||
|
self.assertEqual(pr.grand_total, si.outstanding_amount)
|
||||||
|
|
||||||
|
|
||||||
def test_partial_paid_invoice_with_submitted_payment_entry(self):
|
def test_partial_paid_invoice_with_submitted_payment_entry(self):
|
||||||
pi = make_purchase_invoice(currency="INR", qty=1, rate=5000)
|
pi = make_purchase_invoice(currency="INR", qty=1, rate=5000)
|
||||||
|
|||||||
Reference in New Issue
Block a user