diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 836ebc326922638d45e9dc06d0897ad393de96d0..9f69ac97297b59943930d1b2a5e24fa587d96648 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -671,7 +671,7 @@ class ReceivablePayableReport(object): else: future_amount_field = "future_amount_in_base_currency" - if row.remaining_balance > 0 and future.get(future_amount_field): + if row.remaining_balance != 0 and future.get(future_amount_field): if future.get(future_amount_field) > row.outstanding: row.future_amount = row.outstanding future[future_amount_field] = future.get(future_amount_field) - row.outstanding diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py index 58187cc003ca6315263664c1c9cd200face4bf5c..7a0a035b32f6fd388108cba9c8bac2726a7a3c4b 100644 --- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py @@ -169,6 +169,82 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): ], ) + def test_cr_note_flag_to_update_self(self): + filters = { + "company": self.company, + "report_date": today(), + "range1": 30, + "range2": 60, + "range3": 90, + "range4": 120, + "show_remarks": True, + } + + # check invoice grand total and invoiced column's value for 3 payment terms + si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True) + si.set_posting_time = True + si.posting_date = add_days(today(), -1) + si.save().submit() + + report = execute(filters) + + expected_data = [100, 100, f"Sales Invoice: {si.name} / Customer: {si.customer}"] # @dokos + + self.assertEqual(len(report[1]), 1) + row = report[1][0] + self.assertEqual(expected_data, [row.invoice_grand_total, row.invoiced, row.remarks]) + + # check invoice grand total, invoiced, paid and outstanding column's value after payment + self.create_payment_entry(si.name) + report = execute(filters) + + expected_data_after_payment = [100, 100, 40, 60] + self.assertEqual(len(report[1]), 1) + row = report[1][0] + self.assertEqual( + expected_data_after_payment, + [row.invoice_grand_total, row.invoiced, row.paid, row.outstanding], + ) + + # check invoice grand total, invoiced, paid and outstanding column's value after credit note + cr_note = self.create_credit_note(si.name, do_not_submit=True) + cr_note.update_outstanding_for_self = True + cr_note.save().submit() + report = execute(filters) + + expected_data_after_credit_note = [ + [100.0, 100.0, 40.0, 0.0, 60.0, si.name], + [0, 0, 100.0, 0.0, -100.0, cr_note.name], + ] + self.assertEqual(len(report[1]), 2) + si_row = [ + [ + row.invoice_grand_total, + row.invoiced, + row.paid, + row.credit_note, + row.outstanding, + row.voucher_no, + ] + for row in report[1] + if row.voucher_no == si.name + ][0] + + cr_note_row = [ + [ + row.invoice_grand_total, + row.invoiced, + row.paid, + row.credit_note, + row.outstanding, + row.voucher_no, + ] + for row in report[1] + if row.voucher_no == cr_note.name + ][0] + self.assertEqual(expected_data_after_credit_note[0], si_row) + self.assertEqual(expected_data_after_credit_note[1], cr_note_row) + def test_payment_againt_po_in_receivable_report(self): """ Payments made against Purchase Order will show up as outstanding amount @@ -392,11 +468,30 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): ) def test_future_payments(self): + sr = self.create_sales_invoice(do_not_submit=True) + sr.is_return = 1 + sr.items[0].qty = -1 + sr.items[0].rate = 10 + sr.calculate_taxes_and_totals() + sr.submit() + si = self.create_sales_invoice() pe = get_payment_entry(si.doctype, si.name) + pe.append( + "references", + { + "reference_doctype": sr.doctype, + "reference_name": sr.name, + "due_date": sr.due_date, + "total_amount": sr.grand_total, + "outstanding_amount": sr.outstanding_amount, + "allocated_amount": sr.outstanding_amount, + }, + ) + pe.posting_date = add_days(today(), 1) - pe.paid_amount = 90.0 - pe.references[0].allocated_amount = 90.0 + pe.paid_amount = 80 + pe.references[0].allocated_amount = 90.0 # pe.paid_amount + sr.grand_total pe.save().submit() filters = { "company": self.company, @@ -408,16 +503,21 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase): "show_future_payments": True, } report = execute(filters)[1] - self.assertEqual(len(report), 1) + self.assertEqual(len(report), 2) - expected_data = [100.0, 100.0, 10.0, 90.0] + expected_data = {sr.name: [10.0, -10.0, 0.0, -10], si.name: [100.0, 100.0, 10.0, 90.0]} - row = report[0] - self.assertEqual( - expected_data, [row.invoiced, row.outstanding, row.remaining_balance, row.future_amount] - ) + rows = report[:2] + for row in rows: + self.assertEqual( + expected_data[row.voucher_no], + [row.invoiced or row.paid, row.outstanding, row.remaining_balance, row.future_amount], + ) pe.cancel() + sr.load_from_db() # Outstanding amount is updated so a updated timestamp is needed. + sr.cancel() + # full payment in future date pe = get_payment_entry(si.doctype, si.name) pe.posting_date = add_days(today(), 1)