fix(banking): include paid purchase invoices in reports and bank clearance (#52675)

* fix(banking): include paid purchase invoices in reports and bank clearance

* fix: condition for amounts not reflected in system

* fix: set Sales Invoice to be the payment document in bank rec

* fix: add additional filter for `is_paid`

* fix: added is_paid

* fix: added invoice number in bank clearance tool

* chore: make requested changes

* fix: exclude opening JEs

* fix: bring back banking icon in desktop

(cherry picked from commit ef32622166)

# Conflicts:
#	erpnext/accounts/doctype/bank_clearance/bank_clearance.py
#	erpnext/desktop_icon/banking.json
This commit is contained in:
Nikhil Kothari
2026-03-17 10:17:32 +05:30
committed by Mergify
parent eec8cf8a71
commit ab9d960aa8
4 changed files with 447 additions and 188 deletions

View File

@@ -5,8 +5,14 @@
import frappe import frappe
from frappe import _, msgprint from frappe import _, msgprint
from frappe.model.document import Document from frappe.model.document import Document
from frappe.query_builder import Case
from frappe.query_builder.custom import ConstantColumn from frappe.query_builder.custom import ConstantColumn
<<<<<<< HEAD
from frappe.utils import flt, fmt_money, get_link_to_form, getdate from frappe.utils import flt, fmt_money, get_link_to_form, getdate
=======
from frappe.query_builder.functions import Coalesce, Sum
from frappe.utils import cint, flt, fmt_money, getdate
>>>>>>> ef32622166 (fix(banking): include paid purchase invoices in reports and bank clearance (#52675))
from pypika import Order from pypika import Order
import erpnext import erpnext
@@ -136,65 +142,162 @@ def get_payment_entries_for_bank_clearance(
): ):
entries = [] entries = []
condition = "" journal_entry = frappe.qb.DocType("Journal Entry")
pe_condition = "" journal_entry_account = frappe.qb.DocType("Journal Entry Account")
journal_entry_query = (
frappe.qb.from_(journal_entry_account)
.inner_join(journal_entry)
.on(journal_entry_account.parent == journal_entry.name)
.select(
ConstantColumn("Journal Entry").as_("payment_document"),
journal_entry.name.as_("payment_entry"),
journal_entry.cheque_no.as_("cheque_number"),
journal_entry.cheque_date,
Sum(journal_entry_account.debit_in_account_currency).as_("debit"),
Sum(journal_entry_account.credit_in_account_currency).as_("credit"),
journal_entry.posting_date,
journal_entry_account.against_account,
journal_entry.clearance_date,
journal_entry_account.account_currency,
)
.where(
(journal_entry_account.account == account)
& (journal_entry.docstatus == 1)
& (journal_entry.posting_date >= from_date)
& (journal_entry.posting_date <= to_date)
& (journal_entry.is_opening == "No")
)
)
if not include_reconciled_entries: if not include_reconciled_entries:
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')" journal_entry_query = journal_entry_query.where(
pe_condition = "and (pe.clearance_date IS NULL or pe.clearance_date='0000-00-00')" (journal_entry.clearance_date.isnull()) | (journal_entry.clearance_date == "0000-00-00")
)
journal_entries = frappe.db.sql( journal_entries = (
f""" journal_entry_query.groupby(journal_entry_account.account, journal_entry.name)
select .orderby(journal_entry.posting_date)
"Journal Entry" as payment_document, t1.name as payment_entry, .orderby(journal_entry.name, order=Order.desc)
t1.cheque_no as cheque_number, t1.cheque_date, ).run(as_dict=True)
sum(t2.debit_in_account_currency) as debit, sum(t2.credit_in_account_currency) as credit,
t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency pe = frappe.qb.DocType("Payment Entry")
from company = frappe.qb.DocType("Company")
`tabJournal Entry` t1, `tabJournal Entry Account` t2 payment_entry_query = (
where frappe.qb.from_(pe)
t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1 .join(company)
and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s .on(pe.company == company.name)
and ifnull(t1.is_opening, 'No') = 'No' {condition} .select(
group by t2.account, t1.name ConstantColumn("Payment Entry").as_("payment_document"),
order by t1.posting_date ASC, t1.name DESC pe.name.as_("payment_entry"),
""", pe.reference_no.as_("cheque_number"),
{"account": account, "from": from_date, "to": to_date}, pe.reference_date.as_("cheque_date"),
as_dict=1, (
Case()
.when(
pe.paid_from == account,
(
pe.paid_amount
+ (
Case()
.when(
(pe.payment_type == "Pay")
& (company.default_currency == pe.paid_from_account_currency),
pe.base_total_taxes_and_charges,
)
.else_(pe.total_taxes_and_charges)
)
),
)
.else_(0)
).as_("credit"),
(
Case()
.when(pe.paid_from == account, 0)
.else_(
pe.received_amount
+ (
Case()
.when(
company.default_currency == pe.paid_to_account_currency,
pe.base_total_taxes_and_charges,
)
.else_(pe.total_taxes_and_charges)
)
)
).as_("debit"),
pe.posting_date,
Coalesce(pe.party, Case().when(pe.paid_from == account, pe.paid_to).else_(pe.paid_from)).as_(
"against_account"
),
pe.clearance_date,
(
Case()
.when(pe.paid_to == account, pe.paid_to_account_currency)
.else_(pe.paid_from_account_currency)
).as_("account_currency"),
)
.where(
((pe.paid_from == account) | (pe.paid_to == account))
& (pe.docstatus == 1)
& (pe.posting_date >= from_date)
& (pe.posting_date <= to_date)
)
) )
payment_entries = frappe.db.sql( if not include_reconciled_entries:
f""" payment_entry_query = payment_entry_query.where(
select (pe.clearance_date.isnull()) | (pe.clearance_date == "0000-00-00")
"Payment Entry" as payment_document, pe.name as payment_entry, )
pe.reference_no as cheque_number, pe.reference_date as cheque_date,
if(pe.paid_from=%(account)s, pe.paid_amount + if(pe.payment_type = 'Pay' and c.default_currency = pe.paid_from_account_currency, pe.base_total_taxes_and_charges, pe.total_taxes_and_charges) , 0) as credit, payment_entries = (payment_entry_query.orderby(pe.posting_date).orderby(pe.name, order=Order.desc)).run(
if(pe.paid_from=%(account)s, 0, pe.received_amount + pe.total_taxes_and_charges) as debit, as_dict=True
pe.posting_date, ifnull(pe.party,if(pe.paid_from=%(account)s,pe.paid_to,pe.paid_from)) as against_account, pe.clearance_date,
if(pe.paid_to=%(account)s, pe.paid_to_account_currency, pe.paid_from_account_currency) as account_currency
from `tabPayment Entry` as pe
join `tabCompany` c on c.name = pe.company
where
(pe.paid_from=%(account)s or pe.paid_to=%(account)s) and pe.docstatus=1
and pe.posting_date >= %(from)s and pe.posting_date <= %(to)s
{pe_condition}
order by
pe.posting_date ASC, pe.name DESC
""",
{
"account": account,
"from": from_date,
"to": to_date,
},
as_dict=1,
) )
pos_sales_invoices, pos_purchase_invoices = [], [] acc = frappe.qb.DocType("Account")
pi = frappe.qb.DocType("Purchase Invoice")
paid_purchase_invoices_query = (
frappe.qb.from_(pi)
.inner_join(acc)
.on(pi.cash_bank_account == acc.name)
.select(
ConstantColumn("Purchase Invoice").as_("payment_document"),
pi.name.as_("payment_entry"),
pi.paid_amount.as_("credit"),
pi.posting_date,
pi.supplier.as_("against_account"),
pi.bill_no.as_("cheque_number"),
pi.clearance_date,
acc.account_currency,
ConstantColumn(0).as_("debit"),
)
.where(
(pi.docstatus == 1)
& (pi.is_paid == 1)
& (pi.cash_bank_account == account)
& (pi.posting_date >= from_date)
& (pi.posting_date <= to_date)
)
)
if not include_reconciled_entries:
paid_purchase_invoices_query = paid_purchase_invoices_query.where(
(pi.clearance_date.isnull()) | (pi.clearance_date == "0000-00-00")
)
paid_purchase_invoices = (
paid_purchase_invoices_query.orderby(pi.posting_date).orderby(pi.name, order=Order.desc)
).run(as_dict=True)
pos_sales_invoices = []
if include_pos_transactions: if include_pos_transactions:
si_payment = frappe.qb.DocType("Sales Invoice Payment") si_payment = frappe.qb.DocType("Sales Invoice Payment")
si = frappe.qb.DocType("Sales Invoice") si = frappe.qb.DocType("Sales Invoice")
acc = frappe.qb.DocType("Account")
pos_sales_invoices = ( pos_sales_invoices_query = (
frappe.qb.from_(si_payment) frappe.qb.from_(si_payment)
.inner_join(si) .inner_join(si)
.on(si_payment.parent == si.name) .on(si_payment.parent == si.name)
@@ -217,38 +320,22 @@ def get_payment_entries_for_bank_clearance(
& (si.posting_date >= from_date) & (si.posting_date >= from_date)
& (si.posting_date <= to_date) & (si.posting_date <= to_date)
) )
.orderby(si.posting_date) )
.orderby(si.name, order=Order.desc)
).run(as_dict=True)
pi = frappe.qb.DocType("Purchase Invoice") if not include_reconciled_entries:
pos_sales_invoices_query = pos_sales_invoices_query.where(
(si_payment.clearance_date.isnull()) | (si_payment.clearance_date == "0000-00-00")
)
pos_purchase_invoices = ( pos_sales_invoices = (
frappe.qb.from_(pi) pos_sales_invoices_query.orderby(si.posting_date).orderby(si.name, order=Order.desc)
.inner_join(acc)
.on(pi.cash_bank_account == acc.name)
.select(
ConstantColumn("Purchase Invoice").as_("payment_document"),
pi.name.as_("payment_entry"),
pi.paid_amount.as_("credit"),
pi.posting_date,
pi.supplier.as_("against_account"),
pi.clearance_date,
acc.account_currency,
ConstantColumn(0).as_("debit"),
)
.where(
(pi.docstatus == 1)
& (pi.cash_bank_account == account)
& (pi.posting_date >= from_date)
& (pi.posting_date <= to_date)
)
.orderby(pi.posting_date)
.orderby(pi.name, order=Order.desc)
).run(as_dict=True) ).run(as_dict=True)
entries = ( entries = (
list(payment_entries) + list(journal_entries) + list(pos_sales_invoices) + list(pos_purchase_invoices) list(payment_entries)
+ list(journal_entries)
+ list(pos_sales_invoices)
+ list(paid_purchase_invoices)
) )
return entries return entries

View File

@@ -4,7 +4,10 @@
import frappe import frappe
from frappe import _ from frappe import _
from frappe.utils import getdate, nowdate from frappe.query_builder import Case
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import getdate
from pypika import Order
def execute(filters=None): def execute(filters=None):
@@ -48,17 +51,6 @@ def get_columns():
return columns return columns
def get_conditions(filters):
conditions = ""
if filters.get("from_date"):
conditions += " and posting_date>=%(from_date)s"
if filters.get("to_date"):
conditions += " and posting_date<=%(to_date)s"
return conditions
def get_entries(filters): def get_entries(filters):
entries = [] entries = []
@@ -73,41 +65,90 @@ def get_entries(filters):
return sorted( return sorted(
entries, entries,
key=lambda k: k[2].strftime("%H%M%S") or getdate(nowdate()), key=lambda k: getdate(k[2]),
) )
def get_entries_for_bank_clearance_summary(filters): def get_entries_for_bank_clearance_summary(filters):
entries = [] entries = []
conditions = get_conditions(filters) je = frappe.qb.DocType("Journal Entry")
jea = frappe.qb.DocType("Journal Entry Account")
journal_entries = frappe.db.sql( journal_entries = (
f"""SELECT frappe.qb.from_(jea)
"Journal Entry", jv.name, jv.posting_date, jv.cheque_no, .inner_join(je)
jv.clearance_date, jvd.against_account, jvd.debit - jvd.credit .on(jea.parent == je.name)
FROM .select(
`tabJournal Entry Account` jvd, `tabJournal Entry` jv ConstantColumn("Journal Entry").as_("payment_document"),
WHERE je.name.as_("payment_entry"),
jvd.parent = jv.name and jv.docstatus=1 and jvd.account = %(account)s {conditions} je.posting_date,
order by posting_date DESC, jv.name DESC""", je.cheque_no,
filters, je.clearance_date,
as_list=1, jea.against_account,
) jea.debit_in_account_currency - jea.credit_in_account_currency,
)
.where(
(jea.account == filters.account)
& (je.docstatus == 1)
& (je.posting_date >= filters.from_date)
& (je.posting_date <= filters.to_date)
& ((je.is_opening == "No") | (je.is_opening.isnull()))
)
.orderby(je.posting_date, order=Order.desc)
.orderby(je.name, order=Order.desc)
).run(as_list=True)
payment_entries = frappe.db.sql( pe = frappe.qb.DocType("Payment Entry")
f"""SELECT payment_entries = (
"Payment Entry", name, posting_date, reference_no, clearance_date, party, frappe.qb.from_(pe)
if(paid_from=%(account)s, ((paid_amount * -1) - total_taxes_and_charges) , received_amount) .select(
FROM ConstantColumn("Payment Entry").as_("payment_document"),
`tabPayment Entry` pe.name.as_("payment_entry"),
WHERE pe.posting_date,
docstatus=1 and (paid_from = %(account)s or paid_to = %(account)s) {conditions} pe.reference_no.as_("cheque_no"),
order by posting_date DESC, name DESC""", pe.clearance_date,
filters, pe.party.as_("against_account"),
as_list=1, Case()
) .when(
(pe.paid_from == filters.account),
((pe.paid_amount * -1) - pe.total_taxes_and_charges),
)
.else_(pe.received_amount),
)
.where((pe.paid_from == filters.account) | (pe.paid_to == filters.account))
.where(
(pe.docstatus == 1)
& (pe.posting_date >= filters.from_date)
& (pe.posting_date <= filters.to_date)
)
.orderby(pe.posting_date, order=Order.desc)
.orderby(pe.name, order=Order.desc)
).run(as_list=True)
entries = journal_entries + payment_entries pi = frappe.qb.DocType("Purchase Invoice")
purchase_invoices = (
frappe.qb.from_(pi)
.select(
ConstantColumn("Purchase Invoice").as_("payment_document"),
pi.name.as_("payment_entry"),
pi.posting_date,
pi.bill_no.as_("cheque_no"),
pi.clearance_date,
pi.supplier.as_("against_account"),
(pi.paid_amount * -1).as_("amount"),
)
.where(
(pi.docstatus == 1)
& (pi.is_paid == 1)
& (pi.cash_bank_account == filters.account)
& (pi.posting_date >= filters.from_date)
& (pi.posting_date <= filters.to_date)
)
.orderby(pi.posting_date, order=Order.desc)
.orderby(pi.name, order=Order.desc)
).run(as_list=True)
entries = journal_entries + payment_entries + purchase_invoices
return entries return entries

View File

@@ -4,7 +4,11 @@
import frappe import frappe
from frappe import _ from frappe import _
from frappe.query_builder import Case
from frappe.query_builder.custom import ConstantColumn
from frappe.query_builder.functions import Coalesce, Sum
from frappe.utils import flt, getdate from frappe.utils import flt, getdate
from pypika import Order
from erpnext.accounts.utils import get_balance_on from erpnext.accounts.utils import get_balance_on
@@ -123,73 +127,143 @@ def get_entries_for_bank_reconciliation_statement(filters):
payment_entries = get_payment_entries(filters) payment_entries = get_payment_entries(filters)
purchase_invoices = get_purchase_invoices(filters)
pos_entries = [] pos_entries = []
if filters.include_pos_transactions: if filters.include_pos_transactions:
pos_entries = get_pos_entries(filters) pos_entries = get_pos_entries(filters)
return list(journal_entries) + list(payment_entries) + list(pos_entries) return list(journal_entries) + list(payment_entries) + list(pos_entries) + list(purchase_invoices)
def get_journal_entries(filters): def get_journal_entries(filters):
return frappe.db.sql( je = frappe.qb.DocType("Journal Entry")
""" jea = frappe.qb.DocType("Journal Entry Account")
select "Journal Entry" as payment_document, jv.posting_date, return (
jv.name as payment_entry, jvd.debit_in_account_currency as debit, frappe.qb.from_(jea)
jvd.credit_in_account_currency as credit, jvd.against_account, .join(je)
jv.cheque_no as reference_no, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency .on(jea.parent == je.name)
from .select(
`tabJournal Entry Account` jvd, `tabJournal Entry` jv ConstantColumn("Journal Entry").as_("payment_document"),
where jvd.parent = jv.name and jv.docstatus=1 je.name.as_("payment_entry"),
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s je.posting_date,
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s jea.debit_in_account_currency.as_("debit"),
and ifnull(jv.is_opening, 'No') = 'No' jea.credit_in_account_currency.as_("credit"),
and jv.company = %(company)s """, jea.against_account,
filters, je.cheque_no.as_("reference_no"),
as_dict=1, je.cheque_date.as_("ref_date"),
) je.clearance_date,
jea.account_currency,
)
.where(
(je.docstatus == 1)
& (jea.account == filters.account)
& (je.posting_date <= filters.report_date)
& (je.clearance_date.isnull() | (je.clearance_date > filters.report_date))
& (je.company == filters.company)
& ((je.is_opening.isnull()) | (je.is_opening == "No"))
)
.orderby(je.posting_date)
.orderby(je.name, order=Order.desc)
).run(as_dict=True)
def get_payment_entries(filters): def get_payment_entries(filters):
return frappe.db.sql( pe = frappe.qb.DocType("Payment Entry")
""" return (
select frappe.qb.from_(pe)
"Payment Entry" as payment_document, name as payment_entry, .select(
reference_no, reference_date as ref_date, ConstantColumn("Payment Entry").as_("payment_document"),
if(paid_to=%(account)s, received_amount_after_tax, 0) as debit, pe.name.as_("payment_entry"),
if(paid_from=%(account)s, paid_amount_after_tax, 0) as credit, pe.reference_no.as_("reference_no"),
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date, pe.reference_date.as_("ref_date"),
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency Case().when(pe.paid_to == filters.account, pe.received_amount_after_tax).else_(0).as_("debit"),
from `tabPayment Entry` Case().when(pe.paid_from == filters.account, pe.paid_amount_after_tax).else_(0).as_("credit"),
where pe.posting_date,
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1 Coalesce(
and posting_date <= %(report_date)s pe.party, Case().when(pe.paid_from == filters.account, pe.paid_to).else_(pe.paid_from)
and ifnull(clearance_date, '4000-01-01') > %(report_date)s ).as_("against_account"),
and company = %(company)s pe.clearance_date,
""", (
filters, Case()
as_dict=1, .when(pe.paid_to == filters.account, pe.paid_to_account_currency)
) .else_(pe.paid_from_account_currency)
).as_("account_currency"),
)
.where(
(pe.docstatus == 1)
& ((pe.paid_from == filters.account) | (pe.paid_to == filters.account))
& (pe.posting_date <= filters.report_date)
& (pe.clearance_date.isnull() | (pe.clearance_date > filters.report_date))
& (pe.company == filters.company)
)
.orderby(pe.posting_date)
.orderby(pe.name, order=Order.desc)
).run(as_dict=True)
def get_purchase_invoices(filters):
pi = frappe.qb.DocType("Purchase Invoice")
acc = frappe.qb.DocType("Account")
return (
frappe.qb.from_(pi)
.inner_join(acc)
.on(pi.cash_bank_account == acc.name)
.select(
ConstantColumn("Purchase Invoice").as_("payment_document"),
pi.name.as_("payment_entry"),
pi.bill_no.as_("reference_no"),
pi.posting_date.as_("ref_date"),
Case().when(pi.paid_amount < 0, pi.paid_amount * -1).else_(0).as_("debit"),
Case().when(pi.paid_amount > 0, pi.paid_amount).else_(0).as_("credit"),
pi.posting_date,
pi.supplier.as_("against_account"),
pi.clearance_date,
acc.account_currency,
)
.where(
(pi.docstatus == 1)
& (pi.is_paid == 1)
& (pi.cash_bank_account == filters.account)
& (pi.posting_date <= filters.report_date)
& (pi.clearance_date.isnull() | (pi.clearance_date > filters.report_date))
& (pi.company == filters.company)
)
.orderby(pi.posting_date)
.orderby(pi.name, order=Order.desc)
).run(as_dict=True)
def get_pos_entries(filters): def get_pos_entries(filters):
return frappe.db.sql( si = frappe.qb.DocType("Sales Invoice")
""" si_payment = frappe.qb.DocType("Sales Invoice Payment")
select acc = frappe.qb.DocType("Account")
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit, return (
si.posting_date, si.debit_to as against_account, sip.clearance_date, frappe.qb.from_(si_payment)
account.account_currency, 0 as credit .join(si)
from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account .on(si_payment.parent == si.name)
where .join(acc)
sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name .on(si_payment.account == acc.name)
and account.name = sip.account and si.posting_date <= %(report_date)s and .select(
ifnull(sip.clearance_date, '4000-01-01') > %(report_date)s ConstantColumn("Sales Invoice").as_("payment_document"),
and si.company = %(company)s si.name.as_("payment_entry"),
order by si_payment.amount.as_("debit"),
si.posting_date ASC, si.name DESC si.posting_date,
""", si.debit_to.as_("against_account"),
filters, si_payment.clearance_date,
as_dict=1, acc.account_currency,
) ConstantColumn(0).as_("credit"),
)
.where(
(si_payment.account == filters.account)
& (si.docstatus == 1)
& (si.posting_date <= filters.report_date)
& (si_payment.clearance_date.isnull() | (si_payment.clearance_date > filters.report_date))
& (si.company == filters.company)
)
.orderby(si.posting_date)
.orderby(si_payment.name, order=Order.desc)
).run(as_dict=True)
def get_amounts_not_reflected_in_system(filters): def get_amounts_not_reflected_in_system(filters):
@@ -205,30 +279,66 @@ def get_amounts_not_reflected_in_system(filters):
def get_amounts_not_reflected_in_system_for_bank_reconciliation_statement(filters): def get_amounts_not_reflected_in_system_for_bank_reconciliation_statement(filters):
je_amount = frappe.db.sql( je = frappe.qb.DocType("Journal Entry")
""" jea = frappe.qb.DocType("Journal Entry Account")
select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv je_amount = (
where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%(account)s frappe.qb.from_(jea)
and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s .inner_join(je)
and ifnull(jv.is_opening, 'No') = 'No' """, .on(jea.parent == je.name)
filters, .select(
Sum(jea.debit_in_account_currency - jea.credit_in_account_currency).as_("amount"),
)
.where(
(je.docstatus == 1)
& (jea.account == filters.account)
& (je.posting_date > filters.report_date)
& (je.clearance_date <= filters.report_date)
& (je.company == filters.company)
& ((je.is_opening.isnull()) | (je.is_opening == "No"))
)
.run(as_dict=True)
) )
je_amount = flt(je_amount[0].amount) if je_amount else 0.0
je_amount = flt(je_amount[0][0]) if je_amount else 0.0 pe = frappe.qb.DocType("Payment Entry")
pe_amount = (
pe_amount = frappe.db.sql( frappe.qb.from_(pe)
""" .select(
select sum(if(paid_from=%(account)s, paid_amount, received_amount)) Sum(Case().when(pe.paid_from == filters.account, pe.paid_amount).else_(pe.received_amount)).as_(
from `tabPayment Entry` "amount"
where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1 ),
and posting_date > %(report_date)s and clearance_date <= %(report_date)s""", )
filters, .where(
((pe.paid_from == filters.account) | (pe.paid_to == filters.account))
& (pe.docstatus == 1)
& (pe.posting_date > filters.report_date)
& (pe.clearance_date <= filters.report_date)
& (pe.company == filters.company)
)
.run(as_dict=True)
) )
pe_amount = flt(pe_amount[0].amount) if pe_amount else 0.0
pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0 pi = frappe.qb.DocType("Purchase Invoice")
pi_amount = (
frappe.qb.from_(pi)
.select(
Sum(pi.paid_amount).as_("amount"),
)
.where(
(pi.docstatus == 1)
& (pi.is_paid == 1)
& (pi.cash_bank_account == filters.account)
& (pi.posting_date > filters.report_date)
& (pi.clearance_date <= filters.report_date)
& (pi.company == filters.company)
)
).run(as_dict=True)
return je_amount + pe_amount pi_amount = flt(pi_amount[0].amount) if pi_amount else 0.0
return je_amount + pe_amount + pi_amount
def get_balance_row(label, amount, account_currency): def get_balance_row(label, amount, account_currency):

View File

@@ -0,0 +1,21 @@
{
"app": "erpnext",
"creation": "2025-11-12 14:51:14.307331",
"docstatus": 0,
"doctype": "Desktop Icon",
"hidden": 0,
"icon": "dollar-sign",
"icon_type": "Link",
"idx": 5,
"label": "Banking",
"link_to": "Banking",
"link_type": "Workspace Sidebar",
"modified": "2026-02-12 12:29:48.687545",
"modified_by": "Administrator",
"name": "Banking",
"owner": "Administrator",
"parent_icon": "Accounting",
"restrict_removal": 0,
"roles": [],
"standard": 1
}