Skip to content

Commit

Permalink
Merge pull request #26900 from deepeshgarg007/payment_entry_validatio…
Browse files Browse the repository at this point in the history
…ns_and_trigger_develop

fix: Multiple fixes in payment entry
  • Loading branch information
deepeshgarg007 authored Aug 23, 2021
2 parents 47b63a6 + df18504 commit 69973a6
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 13 deletions.
4 changes: 2 additions & 2 deletions erpnext/accounts/doctype/payment_entry/payment_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,8 @@ frappe.ui.form.on('Payment Entry', {
source_exchange_rate: function(frm) {
if (frm.doc.paid_amount) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
if(!frm.set_paid_amount_based_on_received_amount &&
(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
// target exchange rate should always be same as source if both account currencies is same
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
}
Expand Down
25 changes: 22 additions & 3 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ def validate(self):
self.validate_mandatory()
self.validate_reference_documents()
self.set_tax_withholding()
self.apply_taxes()
self.set_amounts()
self.validate_amounts()
self.apply_taxes()
self.set_amounts_after_tax()
self.clear_unallocated_reference_document_rows()
self.validate_payment_against_negative_invoice()
self.validate_transaction_reference()
self.set_title()
self.set_remarks()
self.validate_duplicate_entry()
self.validate_payment_type_with_outstanding()
self.validate_allocated_amount()
self.validate_paid_invoices()
self.ensure_supplier_is_not_blocked()
Expand Down Expand Up @@ -118,6 +121,11 @@ def set_bank_account_data(self):
if not self.get(field):
self.set(field, bank_data.account)

def validate_payment_type_with_outstanding(self):
total_outstanding = sum(d.allocated_amount for d in self.get('references'))
if total_outstanding < 0 and self.party_type == 'Customer' and self.payment_type == 'Receive':
frappe.throw(_("Cannot receive from customer against negative outstanding"), title=_("Incorrect Payment Type"))

def validate_allocated_amount(self):
for d in self.get("references"):
if (flt(d.allocated_amount))> 0:
Expand Down Expand Up @@ -236,7 +244,9 @@ def set_source_exchange_rate(self, ref_doc=None):
self.company_currency, self.posting_date)

def set_target_exchange_rate(self, ref_doc=None):
if self.paid_to and not self.target_exchange_rate:
if self.paid_from_account_currency == self.paid_to_account_currency:
self.target_exchange_rate = self.source_exchange_rate
elif self.paid_to and not self.target_exchange_rate:
if ref_doc:
if self.paid_to_account_currency == ref_doc.currency:
self.target_exchange_rate = ref_doc.get("exchange_rate")
Expand Down Expand Up @@ -468,13 +478,22 @@ def apply_taxes(self):
def set_amounts(self):
self.set_received_amount()
self.set_amounts_in_company_currency()
self.set_amounts_after_tax()
self.set_total_allocated_amount()
self.set_unallocated_amount()
self.set_difference_amount()

def validate_amounts(self):
self.validate_received_amount()

def validate_received_amount(self):
if self.paid_from_account_currency == self.paid_to_account_currency:
if self.paid_amount != self.received_amount:
frappe.throw(_("Received Amount cannot be greater than Paid Amount"))

def set_received_amount(self):
self.base_received_amount = self.base_paid_amount
if self.paid_from_account_currency == self.paid_to_account_currency:
self.received_amount = self.paid_amount

def set_amounts_after_tax(self):
applicable_tax = 0
Expand Down
6 changes: 3 additions & 3 deletions erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def test_payment_entry_against_si_usd_to_usd(self):
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.target_exchange_rate = 50
pe.source_exchange_rate = 50
pe.insert()
pe.submit()

Expand Down Expand Up @@ -154,7 +154,7 @@ def test_payment_against_sales_invoice_to_check_status(self):
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.target_exchange_rate = 50
pe.source_exchange_rate = 50
pe.insert()
pe.submit()

Expand Down Expand Up @@ -491,7 +491,7 @@ def test_payment_entry_exchange_gain_loss(self):
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
pe.target_exchange_rate = 55
pe.source_exchange_rate = 55

pe.append("deductions", {
"account": "_Test Exchange Gain/Loss - _TC",
Expand Down
39 changes: 38 additions & 1 deletion erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
from erpnext.stock.utils import get_incoming_rate
from erpnext.accounts.utils import PaymentEntryUnlinkError

class TestSalesInvoice(unittest.TestCase):
def make(self):
Expand Down Expand Up @@ -136,7 +137,7 @@ def test_payment_entry_unlink_against_invoice(self):
pe.paid_to_account_currency = si.currency
pe.source_exchange_rate = 1
pe.target_exchange_rate = 1
pe.paid_amount = si.grand_total
pe.paid_amount = si.outstanding_amount
pe.insert()
pe.submit()

Expand All @@ -145,6 +146,42 @@ def test_payment_entry_unlink_against_invoice(self):
self.assertRaises(frappe.LinkExistsError, si.cancel)
unlink_payment_on_cancel_of_invoice()

def test_payment_entry_unlink_against_standalone_credit_note(self):
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
si1 = create_sales_invoice(rate=1000)
si2 = create_sales_invoice(rate=300)
si3 = create_sales_invoice(qty=-1, rate=300, is_return=1)


pe = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Bank - _TC")
pe.append('references', {
'reference_doctype': 'Sales Invoice',
'reference_name': si2.name,
'total_amount': si2.grand_total,
'outstanding_amount': si2.outstanding_amount,
'allocated_amount': si2.outstanding_amount
})

pe.append('references', {
'reference_doctype': 'Sales Invoice',
'reference_name': si3.name,
'total_amount': si3.grand_total,
'outstanding_amount': si3.outstanding_amount,
'allocated_amount': si3.outstanding_amount
})

pe.reference_no = 'Test001'
pe.reference_date = nowdate()
pe.save()
pe.submit()

si2.load_from_db()
si2.cancel()

si1.load_from_db()
self.assertRaises(PaymentEntryUnlinkError, si1.cancel)


def test_sales_invoice_calculation_export_currency(self):
si = frappe.copy_doc(test_records[2])
si.currency = "USD"
Expand Down
15 changes: 11 additions & 4 deletions erpnext/accounts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError): pass
class FiscalYearError(frappe.ValidationError): pass
class PaymentEntryUnlinkError(frappe.ValidationError): pass

@frappe.whitelist()
def get_fiscal_year(date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False):
Expand Down Expand Up @@ -555,10 +556,16 @@ def remove_ref_doc_link_from_pe(ref_type, ref_no):
and docstatus < 2""", (now(), frappe.session.user, ref_type, ref_no))

for pe in linked_pe:
pe_doc = frappe.get_doc("Payment Entry", pe)
pe_doc.set_total_allocated_amount()
pe_doc.set_unallocated_amount()
pe_doc.clear_unallocated_reference_document_rows()
try:
pe_doc = frappe.get_doc("Payment Entry", pe)
pe_doc.set_amounts()
pe_doc.clear_unallocated_reference_document_rows()
pe_doc.validate_payment_type_with_outstanding()
except Exception as e:
msg = _("There were issues unlinking payment entry {0}.").format(pe_doc.name)
msg += '<br>'
msg += _("Please cancel payment entry manually first")
frappe.throw(msg, exc=PaymentEntryUnlinkError, title=_("Payment Unlink Error"))

frappe.db.sql("""update `tabPayment Entry` set total_allocated_amount=%s,
base_total_allocated_amount=%s, unallocated_amount=%s, modified=%s, modified_by=%s
Expand Down

0 comments on commit 69973a6

Please sign in to comment.