diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 21adb2759b44..29b52729cd34 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -277,12 +277,13 @@ def validate_allocated_amount_with_latest_data(self): fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.") - if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount): - frappe.throw(fail_message.format(d.idx)) - - if d.payment_term and ( - (flt(d.allocated_amount)) > 0 - and flt(d.allocated_amount) > flt(latest.payment_term_outstanding) + if ( + d.payment_term + and ( + (flt(d.allocated_amount)) > 0 + and flt(d.allocated_amount) > flt(latest.payment_term_outstanding) + ) + and self.term_based_allocation_enabled_for_reference(d.reference_doctype, d.reference_name) ): frappe.throw( _( @@ -292,6 +293,9 @@ def validate_allocated_amount_with_latest_data(self): ) ) + if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount): + frappe.throw(fail_message.format(d.idx)) + # Check for negative outstanding invoices as well if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount): frappe.throw(fail_message.format(d.idx)) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index c6e93f3f7a29..dc44fc359cca 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -1156,6 +1156,52 @@ def test_overallocation_validation_on_payment_terms(self): si3.cancel() si3.delete() + @change_settings( + "Accounts Settings", + { + "unlink_payment_on_cancellation_of_invoice": 1, + "delete_linked_ledger_entries": 1, + "allow_multi_currency_invoices_against_single_party_account": 1, + }, + ) + def test_overallocation_validation_shouldnt_misfire(self): + """ + Overallocation validation shouldn't fire for Template without "Allocate Payment based on Payment Terms" enabled + + """ + customer = create_customer() + create_payment_terms_template() + + template = frappe.get_doc("Payment Terms Template", "Test Receivable Template") + template.allocate_payment_based_on_payment_terms = 0 + template.save() + + # Validate allocation on base/company currency + si = create_sales_invoice(do_not_save=1, qty=1, rate=200) + si.payment_terms_template = "Test Receivable Template" + si.save().submit() + + si.reload() + pe = get_payment_entry(si.doctype, si.name).save() + # There will no term based allocation + self.assertEqual(len(pe.references), 1) + self.assertEqual(pe.references[0].payment_term, None) + self.assertEqual(flt(pe.references[0].allocated_amount), flt(si.grand_total)) + pe.save() + + # specify a term + pe.references[0].payment_term = template.terms[0].payment_term + # no validation error should be thrown + pe.save() + + pe.paid_amount = si.grand_total + 1 + pe.references[0].allocated_amount = si.grand_total + 1 + self.assertRaises(frappe.ValidationError, pe.save) + + template = frappe.get_doc("Payment Terms Template", "Test Receivable Template") + template.allocate_payment_based_on_payment_terms = 1 + template.save() + def create_payment_entry(**args): payment_entry = frappe.new_doc("Payment Entry")