mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-14 09:23:09 +00:00
refactor(journal_entry): give get_outstanding an explicit parameter list
Replace the single opaque `args` parameter of the whitelisted get_outstanding with explicit named parameters (the supported interface), splitting the body into _get_journal_entry_outstanding / _get_invoice_outstanding. The legacy `args` payload is still accepted via kwargs for backward compatibility with custom apps. Resolves the overusing-args semgrep finding.
This commit is contained in:
@@ -409,18 +409,16 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_outstanding(doctype, docname, company, child) {
|
get_outstanding(doctype, docname, company, child) {
|
||||||
var args = {
|
|
||||||
doctype: doctype,
|
|
||||||
docname: docname,
|
|
||||||
party: child.party,
|
|
||||||
account: child.account,
|
|
||||||
account_currency: child.account_currency,
|
|
||||||
company: company,
|
|
||||||
};
|
|
||||||
|
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_outstanding",
|
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_outstanding",
|
||||||
args: { args: args },
|
args: {
|
||||||
|
doctype: doctype,
|
||||||
|
docname: docname,
|
||||||
|
company: company,
|
||||||
|
account: child.account,
|
||||||
|
party: child.party,
|
||||||
|
account_currency: child.account_currency,
|
||||||
|
},
|
||||||
callback: function (r) {
|
callback: function (r) {
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
$.each(r.message, function (field, value) {
|
$.each(r.message, function (field, value) {
|
||||||
|
|||||||
@@ -1101,68 +1101,92 @@ def get_against_jv(
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_outstanding(args: str | dict) -> dict:
|
def get_outstanding(
|
||||||
"""Return the outstanding amount and side to set when referencing a JV / Invoice."""
|
doctype: str | None = None,
|
||||||
|
docname: str | None = None,
|
||||||
|
company: str | None = None,
|
||||||
|
account: str | None = None,
|
||||||
|
party: str | None = None,
|
||||||
|
account_currency: str | None = None,
|
||||||
|
**kwargs,
|
||||||
|
) -> dict | None:
|
||||||
|
"""Return the outstanding amount and side to set when referencing a JV / Invoice.
|
||||||
|
|
||||||
|
The named parameters are the supported interface. The legacy `args` payload dict
|
||||||
|
(captured via kwargs) is still accepted for backward compatibility with callers,
|
||||||
|
including custom apps, and is unpacked into the named parameters below.
|
||||||
|
"""
|
||||||
if not frappe.has_permission("Account"):
|
if not frappe.has_permission("Account"):
|
||||||
frappe.msgprint(_("No Permission"), raise_exception=1)
|
frappe.msgprint(_("No Permission"), raise_exception=1)
|
||||||
|
|
||||||
if isinstance(args, str):
|
if legacy_payload := kwargs.get("args"):
|
||||||
args = json.loads(args)
|
if isinstance(legacy_payload, str):
|
||||||
|
legacy_payload = json.loads(legacy_payload)
|
||||||
|
doctype = legacy_payload.get("doctype")
|
||||||
|
docname = legacy_payload.get("docname")
|
||||||
|
company = legacy_payload.get("company")
|
||||||
|
account = legacy_payload.get("account")
|
||||||
|
party = legacy_payload.get("party")
|
||||||
|
account_currency = legacy_payload.get("account_currency")
|
||||||
|
|
||||||
company_currency = erpnext.get_company_currency(args.get("company"))
|
if doctype == "Journal Entry":
|
||||||
due_date = None
|
return _get_journal_entry_outstanding(docname, account, party)
|
||||||
|
|
||||||
if args.get("doctype") == "Journal Entry":
|
if doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
jea = frappe.qb.DocType("Journal Entry Account")
|
return _get_invoice_outstanding(doctype, docname, company, account_currency)
|
||||||
query = (
|
|
||||||
frappe.qb.from_(jea)
|
|
||||||
.select(Sum(jea.debit_in_account_currency) - Sum(jea.credit_in_account_currency))
|
def _get_journal_entry_outstanding(docname: str, account: str | None, party: str | None) -> dict:
|
||||||
.where(
|
"""Unreferenced debit-minus-credit balance for an account on a Journal Entry."""
|
||||||
(jea.parent == args.get("docname"))
|
jea = frappe.qb.DocType("Journal Entry Account")
|
||||||
& (jea.account == args.get("account"))
|
query = (
|
||||||
& (jea.reference_type.isnull() | (jea.reference_type == ""))
|
frappe.qb.from_(jea)
|
||||||
)
|
.select(Sum(jea.debit_in_account_currency) - Sum(jea.credit_in_account_currency))
|
||||||
|
.where(
|
||||||
|
(jea.parent == docname)
|
||||||
|
& (jea.account == account)
|
||||||
|
& (jea.reference_type.isnull() | (jea.reference_type == ""))
|
||||||
)
|
)
|
||||||
if args.get("party"):
|
)
|
||||||
query = query.where(jea.party == args.get("party"))
|
if party:
|
||||||
|
query = query.where(jea.party == party)
|
||||||
|
|
||||||
against_jv_amount = query.run()
|
result = query.run()
|
||||||
against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
|
balance = flt(result[0][0]) if result else 0
|
||||||
amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency"
|
amount_field = "credit_in_account_currency" if balance > 0 else "debit_in_account_currency"
|
||||||
return {amount_field: abs(against_jv_amount)}
|
return {amount_field: abs(balance)}
|
||||||
elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"):
|
|
||||||
party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier"
|
|
||||||
invoice = frappe.db.get_value(
|
def _get_invoice_outstanding(doctype: str, docname: str, company: str, account_currency: str | None) -> dict:
|
||||||
args["doctype"],
|
"""Outstanding amount, side, party and exchange rate for a Sales/Purchase Invoice."""
|
||||||
args["docname"],
|
party_type = "Customer" if doctype == "Sales Invoice" else "Supplier"
|
||||||
["outstanding_amount", "conversion_rate", scrub(party_type), "due_date"],
|
invoice = frappe.db.get_value(
|
||||||
as_dict=1,
|
doctype,
|
||||||
|
docname,
|
||||||
|
["outstanding_amount", "conversion_rate", scrub(party_type), "due_date"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
company_currency = erpnext.get_company_currency(company)
|
||||||
|
exchange_rate = invoice.conversion_rate if account_currency != company_currency else 1
|
||||||
|
|
||||||
|
outstanding_is_positive = flt(invoice.outstanding_amount) > 0
|
||||||
|
if doctype == "Sales Invoice":
|
||||||
|
amount_field = (
|
||||||
|
"credit_in_account_currency" if outstanding_is_positive else "debit_in_account_currency"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
amount_field = (
|
||||||
|
"debit_in_account_currency" if outstanding_is_positive else "credit_in_account_currency"
|
||||||
)
|
)
|
||||||
|
|
||||||
due_date = invoice.get("due_date")
|
return {
|
||||||
|
amount_field: abs(flt(invoice.outstanding_amount)),
|
||||||
exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1
|
"exchange_rate": exchange_rate,
|
||||||
|
"party_type": party_type,
|
||||||
if args["doctype"] == "Sales Invoice":
|
"party": invoice.get(scrub(party_type)),
|
||||||
amount_field = (
|
"reference_due_date": invoice.get("due_date"),
|
||||||
"credit_in_account_currency"
|
}
|
||||||
if flt(invoice.outstanding_amount) > 0
|
|
||||||
else "debit_in_account_currency"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
amount_field = (
|
|
||||||
"debit_in_account_currency"
|
|
||||||
if flt(invoice.outstanding_amount) > 0
|
|
||||||
else "credit_in_account_currency"
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
amount_field: abs(flt(invoice.outstanding_amount)),
|
|
||||||
"exchange_rate": exchange_rate,
|
|
||||||
"party_type": party_type,
|
|
||||||
"party": invoice.get(scrub(party_type)),
|
|
||||||
"reference_due_date": due_date,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
Reference in New Issue
Block a user