Skip to content

Commit

Permalink
Merge pull request #40856 from ruthra-kumar/better_approach_for_exc_r…
Browse files Browse the repository at this point in the history
…ate_updating

fix: unwanted Exc Gain/Loss journals on Payment against Journal entry
  • Loading branch information
ruthra-kumar authored Apr 5, 2024
2 parents 1816f1d + fe84558 commit 8b9079d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
10 changes: 7 additions & 3 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ def set_missing_ref_details(
self,
force: bool = False,
update_ref_details_only_for: list | None = None,
ref_exchange_rate: float | None = None,
reference_exchange_details: dict | None = None,
) -> None:
for d in self.get("references"):
if d.allocated_amount:
Expand All @@ -500,8 +500,12 @@ def set_missing_ref_details(
)

# Only update exchange rate when the reference is Journal Entry
if ref_exchange_rate and d.reference_doctype == "Journal Entry":
ref_details.update({"exchange_rate": ref_exchange_rate})
if (
reference_exchange_details
and d.reference_doctype == reference_exchange_details.reference_doctype
and d.reference_name == reference_exchange_details.reference_name
):
ref_details.update({"exchange_rate": reference_exchange_details.exchange_rate})

for field, value in ref_details.items():
if d.exchange_gain_loss:
Expand Down
14 changes: 13 additions & 1 deletion erpnext/accounts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,19 @@ def update_reference_in_payment_entry(
payment_entry.setup_party_account_field()
payment_entry.set_missing_values()
if not skip_ref_details_update_for_pe:
payment_entry.set_missing_ref_details(ref_exchange_rate=d.exchange_rate or None)
reference_exchange_details = frappe._dict()
if d.against_voucher_type == "Journal Entry" and d.exchange_rate:
reference_exchange_details.update(
{
"reference_doctype": d.against_voucher_type,
"reference_name": d.against_voucher,
"exchange_rate": d.exchange_rate,
}
)
payment_entry.set_missing_ref_details(
update_ref_details_only_for=[(d.against_voucher_type, d.against_voucher)],
reference_exchange_details=reference_exchange_details,
)
payment_entry.set_amounts()

payment_entry.make_exchange_gain_loss_journal(
Expand Down
70 changes: 69 additions & 1 deletion erpnext/controllers/tests/test_accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class TestAccountsController(FrappeTestCase):
20 series - Sales Invoice against Journals
30 series - Sales Invoice against Credit Notes
40 series - Company default Cost center is unset
50 series = Journals against Journals
50 series - Journals against Journals
60 series - Journals against Payment Entries
90 series - Dimension inheritence
"""

Expand Down Expand Up @@ -1538,3 +1539,70 @@ def test_50_journal_against_journal(self):
exc_je_for_je = self.get_journals_for(journal_as_payment.doctype, journal_as_payment.name)
self.assertEqual(exc_je_for_si, [])
self.assertEqual(exc_je_for_je, [])

def test_60_payment_entry_against_journal(self):
# Invoices
exc_rate1 = 75
exc_rate2 = 77
amount = 1
je1 = self.create_journal_entry(
acc1=self.debit_usd,
acc1_exc_rate=exc_rate1,
acc2=self.cash,
acc1_amount=amount,
acc2_amount=(amount * 75),
acc2_exc_rate=1,
)
je1.accounts[0].party_type = "Customer"
je1.accounts[0].party = self.customer
je1 = je1.save().submit()

je2 = self.create_journal_entry(
acc1=self.debit_usd,
acc1_exc_rate=exc_rate2,
acc2=self.cash,
acc1_amount=amount,
acc2_amount=(amount * exc_rate2),
acc2_exc_rate=1,
)
je2.accounts[0].party_type = "Customer"
je2.accounts[0].party = self.customer
je2 = je2.save().submit()

# Payment
pe = self.create_payment_entry(amount=2, source_exc_rate=exc_rate1).save().submit()

pr = self.create_payment_reconciliation()
pr.receivable_payable_account = self.debit_usd
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 2)
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()
self.assertEqual(len(pr.invoices), 0)
self.assertEqual(len(pr.payments), 0)

# There should be no outstanding in both currencies
self.assert_ledger_outstanding(je1.doctype, je1.name, 0.0, 0.0)
self.assert_ledger_outstanding(je2.doctype, je2.name, 0.0, 0.0)

# Exchange Gain/Loss Journal should've been created only for JE2
exc_je_for_je1 = self.get_journals_for(je1.doctype, je1.name)
exc_je_for_je2 = self.get_journals_for(je2.doctype, je2.name)
self.assertEqual(exc_je_for_je1, [])
self.assertEqual(len(exc_je_for_je2), 1)

# Cancel Payment
pe.reload()
pe.cancel()

self.assert_ledger_outstanding(je1.doctype, je1.name, (amount * exc_rate1), amount)
self.assert_ledger_outstanding(je2.doctype, je2.name, (amount * exc_rate2), amount)

# Exchange Gain/Loss Journal should've been cancelled
exc_je_for_je1 = self.get_journals_for(je1.doctype, je1.name)
exc_je_for_je2 = self.get_journals_for(je2.doctype, je2.name)
self.assertEqual(exc_je_for_je1, [])
self.assertEqual(exc_je_for_je2, [])

0 comments on commit 8b9079d

Please sign in to comment.