Merge pull request #31737 from ruthra-kumar/fix_invoice_outstanding_in_reconciliation_tool

fix: incorrect invoice outstanding in reconciliation tool
This commit is contained in:
ruthra kumar 2022-08-04 14:07:15 +05:30 committed by GitHub
commit c95b986414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 6 deletions

View File

@ -1184,6 +1184,7 @@ def get_outstanding_reference_documents(args):
ple = qb.DocType("Payment Ledger Entry")
common_filter = []
posting_and_due_date = []
# confirm that Supplier is not blocked
if args.get("party_type") == "Supplier":
@ -1224,7 +1225,7 @@ def get_outstanding_reference_documents(args):
condition += " and {0} between '{1}' and '{2}'".format(
fieldname, args.get(date_fields[0]), args.get(date_fields[1])
)
common_filter.append(ple[fieldname][args.get(date_fields[0]) : args.get(date_fields[1])])
posting_and_due_date.append(ple[fieldname][args.get(date_fields[0]) : args.get(date_fields[1])])
if args.get("company"):
condition += " and company = {0}".format(frappe.db.escape(args.get("company")))
@ -1235,6 +1236,7 @@ def get_outstanding_reference_documents(args):
args.get("party"),
args.get("party_account"),
common_filter=common_filter,
posting_date=posting_and_due_date,
min_outstanding=args.get("outstanding_amt_greater_than"),
max_outstanding=args.get("outstanding_amt_less_than"),
)

View File

@ -22,6 +22,7 @@ class PaymentReconciliation(Document):
def __init__(self, *args, **kwargs):
super(PaymentReconciliation, self).__init__(*args, **kwargs)
self.common_filter_conditions = []
self.ple_posting_date_filter = []
@frappe.whitelist()
def get_unreconciled_entries(self):
@ -150,6 +151,7 @@ class PaymentReconciliation(Document):
return_outstanding = ple_query.get_voucher_outstandings(
vouchers=return_invoices,
common_filter=self.common_filter_conditions,
posting_date=self.ple_posting_date_filter,
min_outstanding=-(self.minimum_payment_amount) if self.minimum_payment_amount else None,
max_outstanding=-(self.maximum_payment_amount) if self.maximum_payment_amount else None,
get_payments=True,
@ -187,6 +189,7 @@ class PaymentReconciliation(Document):
self.party,
self.receivable_payable_account,
common_filter=self.common_filter_conditions,
posting_date=self.ple_posting_date_filter,
min_outstanding=self.minimum_invoice_amount if self.minimum_invoice_amount else None,
max_outstanding=self.maximum_invoice_amount if self.maximum_invoice_amount else None,
)
@ -350,6 +353,7 @@ class PaymentReconciliation(Document):
def build_qb_filter_conditions(self, get_invoices=False, get_return_invoices=False):
self.common_filter_conditions.clear()
self.ple_posting_date_filter.clear()
ple = qb.DocType("Payment Ledger Entry")
self.common_filter_conditions.append(ple.company == self.company)
@ -359,15 +363,15 @@ class PaymentReconciliation(Document):
if get_invoices:
if self.from_invoice_date:
self.common_filter_conditions.append(ple.posting_date.gte(self.from_invoice_date))
self.ple_posting_date_filter.append(ple.posting_date.gte(self.from_invoice_date))
if self.to_invoice_date:
self.common_filter_conditions.append(ple.posting_date.lte(self.to_invoice_date))
self.ple_posting_date_filter.append(ple.posting_date.lte(self.to_invoice_date))
elif get_return_invoices:
if self.from_payment_date:
self.common_filter_conditions.append(ple.posting_date.gte(self.from_payment_date))
self.ple_posting_date_filter.append(ple.posting_date.gte(self.from_payment_date))
if self.to_payment_date:
self.common_filter_conditions.append(ple.posting_date.lte(self.to_payment_date))
self.ple_posting_date_filter.append(ple.posting_date.lte(self.to_payment_date))
def get_conditions(self, get_payments=False):
condition = " and company = '{0}' ".format(self.company)

View File

@ -283,6 +283,41 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(len(pr.get("invoices")), 2)
self.assertEqual(len(pr.get("payments")), 2)
def test_filter_posting_date_case2(self):
"""
Posting date should not affect outstanding amount calculation
"""
from_date = add_days(nowdate(), -30)
to_date = nowdate()
self.create_payment_entry(amount=25, posting_date=from_date).submit()
self.create_sales_invoice(rate=25, qty=1, posting_date=to_date)
pr = self.create_payment_reconciliation()
pr.from_invoice_date = pr.from_payment_date = from_date
pr.to_invoice_date = pr.to_payment_date = to_date
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
invoices = [x.as_dict() for x in pr.invoices]
payments = [x.as_dict() for x in pr.payments]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
pr.reconcile()
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 0)
self.assertEqual(len(pr.payments), 0)
pr.from_invoice_date = pr.from_payment_date = to_date
pr.to_invoice_date = pr.to_payment_date = to_date
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 0)
def test_filter_invoice_limit(self):
# check filter condition - invoice limit
transaction_date = nowdate()

View File

@ -823,7 +823,13 @@ def get_held_invoices(party_type, party):
def get_outstanding_invoices(
party_type, party, account, common_filter=None, min_outstanding=None, max_outstanding=None
party_type,
party,
account,
common_filter=None,
posting_date=None,
min_outstanding=None,
max_outstanding=None,
):
ple = qb.DocType("Payment Ledger Entry")
@ -850,6 +856,7 @@ def get_outstanding_invoices(
ple_query = QueryPaymentLedger()
invoice_list = ple_query.get_voucher_outstandings(
common_filter=common_filter,
posting_date=posting_date,
min_outstanding=min_outstanding,
max_outstanding=max_outstanding,
get_invoices=True,
@ -1501,6 +1508,7 @@ class QueryPaymentLedger(object):
# query filters
self.vouchers = []
self.common_filter = []
self.voucher_posting_date = []
self.min_outstanding = None
self.max_outstanding = None
@ -1571,6 +1579,7 @@ class QueryPaymentLedger(object):
.where(ple.delinked == 0)
.where(Criterion.all(filter_on_voucher_no))
.where(Criterion.all(self.common_filter))
.where(Criterion.all(self.voucher_posting_date))
.groupby(ple.voucher_type, ple.voucher_no, ple.party_type, ple.party)
)
@ -1652,6 +1661,7 @@ class QueryPaymentLedger(object):
self,
vouchers=None,
common_filter=None,
posting_date=None,
min_outstanding=None,
max_outstanding=None,
get_payments=False,
@ -1671,6 +1681,7 @@ class QueryPaymentLedger(object):
self.reset()
self.vouchers = vouchers
self.common_filter = common_filter or []
self.voucher_posting_date = posting_date or []
self.min_outstanding = min_outstanding
self.max_outstanding = max_outstanding
self.get_payments = get_payments