Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/frappe/erpnext into #34282
Browse files Browse the repository at this point in the history
…-Record-advance-payment-as-a-liability
  • Loading branch information
deepeshgarg007 committed Jun 30, 2023
2 parents 80e6c90 + fa3ab67 commit fda2d2b
Show file tree
Hide file tree
Showing 261 changed files with 835 additions and 22,776 deletions.
1 change: 0 additions & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

erpnext/accounts/ @deepeshgarg007 @ruthra-kumar
erpnext/assets/ @anandbaburajan @deepeshgarg007
erpnext/loan_management/ @deepeshgarg007
erpnext/regional @deepeshgarg007 @ruthra-kumar
erpnext/selling @deepeshgarg007 @ruthra-kumar
erpnext/support/ @deepeshgarg007
Expand Down
276 changes: 120 additions & 156 deletions erpnext/accounts/doctype/bank_clearance/bank_clearance.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import frappe
from frappe import _, msgprint
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, fmt_money, getdate

import erpnext
Expand All @@ -22,12 +21,89 @@ def get_payment_entries(self):
if not self.account:
frappe.throw(_("Account is mandatory to get payment entries"))

condition = ""
if not self.include_reconciled_entries:
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
entries = []

# get entries from all the apps
for method_name in frappe.get_hooks("get_payment_entries_for_bank_clearance"):
entries += (
frappe.get_attr(method_name)(
self.from_date,
self.to_date,
self.account,
self.bank_account,
self.include_reconciled_entries,
self.include_pos_transactions,
)
or []
)

journal_entries = frappe.db.sql(
"""
entries = sorted(
entries,
key=lambda k: getdate(k["posting_date"]),
)

self.set("payment_entries", [])
default_currency = erpnext.get_default_currency()

for d in entries:
row = self.append("payment_entries", {})

amount = flt(d.get("debit", 0)) - flt(d.get("credit", 0))

if not d.get("account_currency"):
d.account_currency = default_currency

formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
d.posting_date = getdate(d.posting_date)

d.pop("credit")
d.pop("debit")
d.pop("account_currency")
row.update(d)

@frappe.whitelist()
def update_clearance_date(self):
clearance_date_updated = False
for d in self.get("payment_entries"):
if d.clearance_date:
if not d.payment_document:
frappe.throw(_("Row #{0}: Payment document is required to complete the transaction"))

if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
frappe.throw(
_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}").format(
d.idx, d.clearance_date, d.cheque_date
)
)

if d.clearance_date or self.include_reconciled_entries:
if not d.clearance_date:
d.clearance_date = None

payment_entry = frappe.get_doc(d.payment_document, d.payment_entry)
payment_entry.db_set("clearance_date", d.clearance_date)

clearance_date_updated = True

if clearance_date_updated:
self.get_payment_entries()
msgprint(_("Clearance Date updated"))
else:
msgprint(_("Clearance Date not mentioned"))


def get_payment_entries_for_bank_clearance(
from_date, to_date, account, bank_account, include_reconciled_entries, include_pos_transactions
):
entries = []

condition = ""
if not include_reconciled_entries:
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"

journal_entries = frappe.db.sql(
"""
select
"Journal Entry" as payment_document, t1.name as payment_entry,
t1.cheque_no as cheque_number, t1.cheque_date,
Expand All @@ -42,17 +118,17 @@ def get_payment_entries(self):
group by t2.account, t1.name
order by t1.posting_date ASC, t1.name DESC
""".format(
condition=condition
),
{"account": self.account, "from": self.from_date, "to": self.to_date},
as_dict=1,
)
condition=condition
),
{"account": account, "from": from_date, "to": to_date},
as_dict=1,
)

if self.bank_account:
condition += "and bank_account = %(bank_account)s"
if bank_account:
condition += "and bank_account = %(bank_account)s"

payment_entries = frappe.db.sql(
"""
payment_entries = frappe.db.sql(
"""
select
"Payment Entry" as payment_document, name as payment_entry,
reference_no as cheque_number, reference_date as cheque_date,
Expand All @@ -68,82 +144,21 @@ def get_payment_entries(self):
order by
posting_date ASC, name DESC
""".format(
condition=condition
),
{
"account": self.account,
"from": self.from_date,
"to": self.to_date,
"bank_account": self.bank_account,
},
as_dict=1,
)

loan_disbursement = frappe.qb.DocType("Loan Disbursement")

query = (
frappe.qb.from_(loan_disbursement)
.select(
ConstantColumn("Loan Disbursement").as_("payment_document"),
loan_disbursement.name.as_("payment_entry"),
loan_disbursement.disbursed_amount.as_("credit"),
ConstantColumn(0).as_("debit"),
loan_disbursement.reference_number.as_("cheque_number"),
loan_disbursement.reference_date.as_("cheque_date"),
loan_disbursement.clearance_date.as_("clearance_date"),
loan_disbursement.disbursement_date.as_("posting_date"),
loan_disbursement.applicant.as_("against_account"),
)
.where(loan_disbursement.docstatus == 1)
.where(loan_disbursement.disbursement_date >= self.from_date)
.where(loan_disbursement.disbursement_date <= self.to_date)
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
.orderby(loan_disbursement.disbursement_date)
.orderby(loan_disbursement.name, order=frappe.qb.desc)
)

if not self.include_reconciled_entries:
query = query.where(loan_disbursement.clearance_date.isnull())

loan_disbursements = query.run(as_dict=1)

loan_repayment = frappe.qb.DocType("Loan Repayment")

query = (
frappe.qb.from_(loan_repayment)
.select(
ConstantColumn("Loan Repayment").as_("payment_document"),
loan_repayment.name.as_("payment_entry"),
loan_repayment.amount_paid.as_("debit"),
ConstantColumn(0).as_("credit"),
loan_repayment.reference_number.as_("cheque_number"),
loan_repayment.reference_date.as_("cheque_date"),
loan_repayment.clearance_date.as_("clearance_date"),
loan_repayment.applicant.as_("against_account"),
loan_repayment.posting_date,
)
.where(loan_repayment.docstatus == 1)
.where(loan_repayment.posting_date >= self.from_date)
.where(loan_repayment.posting_date <= self.to_date)
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
)

if not self.include_reconciled_entries:
query = query.where(loan_repayment.clearance_date.isnull())

if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
query = query.where((loan_repayment.repay_from_salary == 0))

query = query.orderby(loan_repayment.posting_date).orderby(
loan_repayment.name, order=frappe.qb.desc
)

loan_repayments = query.run(as_dict=True)

pos_sales_invoices, pos_purchase_invoices = [], []
if self.include_pos_transactions:
pos_sales_invoices = frappe.db.sql(
"""
condition=condition
),
{
"account": account,
"from": from_date,
"to": to_date,
"bank_account": bank_account,
},
as_dict=1,
)

pos_sales_invoices, pos_purchase_invoices = [], []
if include_pos_transactions:
pos_sales_invoices = frappe.db.sql(
"""
select
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
si.posting_date, si.customer as against_account, sip.clearance_date,
Expand All @@ -155,12 +170,12 @@ def get_payment_entries(self):
order by
si.posting_date ASC, si.name DESC
""",
{"account": self.account, "from": self.from_date, "to": self.to_date},
as_dict=1,
)
{"account": account, "from": from_date, "to": to_date},
as_dict=1,
)

pos_purchase_invoices = frappe.db.sql(
"""
pos_purchase_invoices = frappe.db.sql(
"""
select
"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,
Expand All @@ -172,66 +187,15 @@ def get_payment_entries(self):
order by
pi.posting_date ASC, pi.name DESC
""",
{"account": self.account, "from": self.from_date, "to": self.to_date},
as_dict=1,
)

entries = sorted(
list(payment_entries)
+ list(journal_entries)
+ list(pos_sales_invoices)
+ list(pos_purchase_invoices)
+ list(loan_disbursements)
+ list(loan_repayments),
key=lambda k: getdate(k["posting_date"]),
{"account": account, "from": from_date, "to": to_date},
as_dict=1,
)

self.set("payment_entries", [])
default_currency = erpnext.get_default_currency()

for d in entries:
row = self.append("payment_entries", {})

amount = flt(d.get("debit", 0)) - flt(d.get("credit", 0))
entries = (
list(payment_entries)
+ list(journal_entries)
+ list(pos_sales_invoices)
+ list(pos_purchase_invoices)
)

if not d.get("account_currency"):
d.account_currency = default_currency

formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
d.posting_date = getdate(d.posting_date)

d.pop("credit")
d.pop("debit")
d.pop("account_currency")
row.update(d)

@frappe.whitelist()
def update_clearance_date(self):
clearance_date_updated = False
for d in self.get("payment_entries"):
if d.clearance_date:
if not d.payment_document:
frappe.throw(_("Row #{0}: Payment document is required to complete the transaction"))

if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
frappe.throw(
_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}").format(
d.idx, d.clearance_date, d.cheque_date
)
)

if d.clearance_date or self.include_reconciled_entries:
if not d.clearance_date:
d.clearance_date = None

payment_entry = frappe.get_doc(d.payment_document, d.payment_entry)
payment_entry.db_set("clearance_date", d.clearance_date)

clearance_date_updated = True

if clearance_date_updated:
self.get_payment_entries()
msgprint(_("Clearance Date updated"))
else:
msgprint(_("Clearance Date not mentioned"))
return entries
Loading

0 comments on commit fda2d2b

Please sign in to comment.