diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py index dff218e77d1..03d5c9cc791 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py @@ -2499,6 +2499,86 @@ class TestPaymentReconciliation(ERPNextTestSuite): self.assertEqual(flt(pr.allocation[0].get("difference_amount")), -5000.0) pr.reconcile() + def test_foreign_currency_reverse_payment_entry_gain_for_supplier(self): + transaction_date = nowdate() + self.supplier = "_Test Supplier USD" + amount = 100 + department = frappe.db.get_value("Department", {"company": self.company, "is_group": 0}, "name") + + # Pay USD 100 at an exchange rate of 90. + pe = self.create_payment_entry(amount=amount, posting_date=transaction_date) + pe.payment_type = "Pay" + pe.party_type = "Supplier" + pe.party = self.supplier + pe.paid_from = self.cash + pe.paid_from_account_currency = "INR" + pe.target_exchange_rate = 90 + pe.paid_amount = 90 * amount + pe.received_amount = amount + pe.paid_to = self.creditors_usd + pe.paid_to_account_currency = "USD" + pe.department = department + pe = pe.save().submit() + + # Receive USD 100 from the supplier at an exchange rate of 100. + reverse_pe = self.create_payment_entry(amount=amount, posting_date=transaction_date) + reverse_pe.payment_type = "Receive" + reverse_pe.party_type = "Supplier" + reverse_pe.party = self.supplier + reverse_pe.paid_from = self.creditors_usd + reverse_pe.paid_from_account_currency = "USD" + reverse_pe.source_exchange_rate = 100 + reverse_pe.paid_amount = amount + reverse_pe.received_amount = 100 * amount + reverse_pe.paid_to = self.cash + reverse_pe.paid_to_account_currency = "INR" + reverse_pe.department = department + reverse_pe = reverse_pe.save().submit() + + pr = self.create_payment_reconciliation(party_is_customer=False) + pr.party = self.supplier + pr.receivable_payable_account = self.creditors_usd + pr.get_unreconciled_entries() + invoices = [invoice.as_dict() for invoice in pr.invoices] + payments = [payment.as_dict() for payment in pr.payments] + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + for row in pr.allocation: + row.department = department + + self.assertEqual(flt(pr.allocation[0].difference_amount), 1000) + pr.reconcile() + + gain_loss_journal = frappe.db.get_value( + "Journal Entry Account", + { + "reference_type": reverse_pe.doctype, + "reference_name": reverse_pe.name, + "party": self.supplier, + "docstatus": 1, + }, + "parent", + ) + party_row = frappe.db.get_value( + "Journal Entry Account", + {"parent": gain_loss_journal, "party": self.supplier}, + ["debit", "credit"], + as_dict=True, + ) + self.assertEqual(flt(party_row.debit), 1000) + self.assertEqual(flt(party_row.credit), 0) + + party_gl_entries = frappe.get_all( + "GL Entry", + filters={ + "voucher_no": ["in", [pe.name, reverse_pe.name, gain_loss_journal]], + "account": self.creditors_usd, + "party": self.supplier, + "is_cancelled": 0, + }, + fields=["debit", "credit"], + ) + self.assertEqual(flt(sum(row.debit - row.credit for row in party_gl_entries)), 0) + def test_foreign_currency_reverse_journal_entry_against_journal_entry_for_customer(self): transaction_date = nowdate() customer = self.customer_usd diff --git a/erpnext/accounts/services/exchange_gain_loss.py b/erpnext/accounts/services/exchange_gain_loss.py index 870266d2a99..a58a11105a1 100644 --- a/erpnext/accounts/services/exchange_gain_loss.py +++ b/erpnext/accounts/services/exchange_gain_loss.py @@ -195,7 +195,7 @@ def make_exchange_gain_loss_journal( def is_payable_account(reference_doctype: str, account: str) -> bool: if reference_doctype == "Purchase Invoice" or ( - reference_doctype == "Journal Entry" + reference_doctype in ("Journal Entry", "Payment Entry") and frappe.get_cached_value("Account", account, "account_type") == "Payable" ): return True