Skip to content

Commit

Permalink
Merge pull request #45670 from frappe/mergify/bp/version-14-hotfix/pr…
Browse files Browse the repository at this point in the history
…-44790

refactor: configurable posting date for Exc Gain / Loss journal (backport #44790)
  • Loading branch information
ruthra-kumar authored Feb 3, 2025
2 parents 235b38a + e9d934d commit 7bfe052
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
15 changes: 12 additions & 3 deletions erpnext/accounts/doctype/accounts_settings/accounts_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"section_break_jpd0",
"auto_reconcile_payments",
"stale_days",
"exchange_gain_loss_posting_date",
"invoicing_settings_tab",
"accounts_transactions_settings_section",
"over_billing_allowance",
Expand Down Expand Up @@ -383,7 +384,7 @@
{
"fieldname": "section_break_jpd0",
"fieldtype": "Section Break",
"label": "Payment Reconciliations"
"label": "Payment Reconciliation Settings"
},
{
"default": "0",
Expand Down Expand Up @@ -462,14 +463,22 @@
"fieldname": "remarks_section",
"fieldtype": "Section Break",
"label": "Remarks Column Length"
},
{
"default": "Payment",
"description": "Only applies for Normal Payments",
"fieldname": "exchange_gain_loss_posting_date",
"fieldtype": "Select",
"label": "Posting Date Inheritance for Exchange Gain / Loss",
"options": "Invoice\nPayment\nReconciliation Date"
}
],
"icon": "icon-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2024-01-22 12:10:10.151819",
"modified": "2025-01-23 13:15:44.077853",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
Expand Down Expand Up @@ -498,4 +507,4 @@
"sort_order": "ASC",
"states": [],
"track_changes": 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ def add_payment_entries(self, non_reconciled_payments):
for payment in non_reconciled_payments:
row = self.append("payments", {})
row.update(payment)
row.is_advance = payment.book_advance_payments_in_separate_party_account

def get_invoice_entries(self):
# Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
Expand Down Expand Up @@ -354,6 +355,9 @@ def calculate_difference_on_allocation_change(self, payment_entry, invoice, allo
def allocate_entries(self, args):
self.validate_entries()

exc_gain_loss_posting_date = frappe.db.get_single_value(
"Accounts Settings", "exchange_gain_loss_posting_date", cache=True
)
invoice_exchange_map = self.get_invoice_exchange_map(args.get("invoices"), args.get("payments"))
default_exchange_gain_loss_account = frappe.get_cached_value(
"Company", self.company, "exchange_gain_loss_account"
Expand All @@ -380,6 +384,11 @@ def allocate_entries(self, args):
res.difference_account = default_exchange_gain_loss_account
res.exchange_rate = inv.get("exchange_rate")
res.update({"gain_loss_posting_date": pay.get("posting_date")})
if not pay.get("is_advance"):
if exc_gain_loss_posting_date == "Invoice":
res.update({"gain_loss_posting_date": inv.get("invoice_date")})
elif exc_gain_loss_posting_date == "Reconciliation Date":
res.update({"gain_loss_posting_date": nowdate()})

if pay.get("amount") == 0:
entries.append(res)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"is_advance",
"section_break_5",
"difference_amount",
"gain_loss_posting_date",
"column_break_7",
"difference_account",
"exchange_rate",
Expand Down Expand Up @@ -153,11 +154,16 @@
"fieldtype": "Check",
"in_list_view": 1,
"label": "Reconciled"
},
{
"fieldname": "gain_loss_posting_date",
"fieldtype": "Date",
"label": "Difference Posting Date"
}
],
"istable": 1,
"links": [],
"modified": "2023-03-20 21:05:43.121945",
"modified": "2025-01-23 16:09:01.058574",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Payment Reconciliation Log Allocations",
Expand Down
64 changes: 63 additions & 1 deletion erpnext/controllers/tests/test_accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import frappe
from frappe import qb
from frappe.query_builder.functions import Sum
from frappe.tests.utils import FrappeTestCase
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, getdate, nowdate
from frappe.utils.data import getdate as convert_to_date

from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
Expand Down Expand Up @@ -707,6 +708,67 @@ def test_15_gain_loss_on_different_posting_date(self):
self.assertEqual(exc_je_for_si, [])
self.assertEqual(exc_je_for_pe, [])

@change_settings("Accounts Settings", {"exchange_gain_loss_posting_date": "Reconciliation Date"})
def test_17_gain_loss_posting_date_for_normal_payment(self):
# Sales Invoice in Foreign Currency
rate = 80
rate_in_account_currency = 1

adv_date = convert_to_date(add_days(nowdate(), -2))
inv_date = convert_to_date(add_days(nowdate(), -1))

si = self.create_sales_invoice(posting_date=inv_date, qty=1, rate=rate_in_account_currency)

# Test payments with different exchange rates
pe = self.create_payment_entry(posting_date=adv_date, amount=1, source_exc_rate=75.1).save().submit()

pr = self.create_payment_reconciliation()
pr.from_invoice_date = add_days(nowdate(), -1)
pr.to_invoice_date = nowdate()
pr.from_payment_date = add_days(nowdate(), -2)
pr.to_payment_date = nowdate()

pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
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)

# Outstanding in both currencies should be '0'
si.reload()
self.assertEqual(si.outstanding_amount, 0)
self.assert_ledger_outstanding(si.doctype, si.name, 0.0, 0.0)

# Exchange Gain/Loss Journal should've been created.
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
self.assertNotEqual(exc_je_for_si, [])
self.assertEqual(len(exc_je_for_si), 1)
self.assertEqual(len(exc_je_for_pe), 1)
self.assertEqual(exc_je_for_si[0], exc_je_for_pe[0])

self.assertEqual(
getdate(nowdate()), frappe.db.get_value("Journal Entry", exc_je_for_pe[0].parent, "posting_date")
)
# Cancel Payment
pe.reload()
pe.cancel()

# outstanding should be same as grand total
si.reload()
self.assertEqual(si.outstanding_amount, rate_in_account_currency)
self.assert_ledger_outstanding(si.doctype, si.name, rate, rate_in_account_currency)

# Exchange Gain/Loss Journal should've been cancelled
exc_je_for_si = self.get_journals_for(si.doctype, si.name)
exc_je_for_pe = self.get_journals_for(pe.doctype, pe.name)
self.assertEqual(exc_je_for_si, [])
self.assertEqual(exc_je_for_pe, [])

def test_20_journal_against_sales_invoice(self):
# Invoice in Foreign Currency
si = self.create_sales_invoice(qty=1, conversion_rate=80, rate=1)
Expand Down
2 changes: 1 addition & 1 deletion erpnext/patches.txt
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,4 @@ erpnext.patches.v14_0.enable_set_priority_for_pricing_rules #1
erpnext.patches.v14_0.update_currency_exchange_settings_for_frankfurter
erpnext.patches.v14_0.update_stock_uom_in_work_order_item
erpnext.patches.v14_0.disable_add_row_in_gross_profit

execute:frappe.db.set_single_value("Accounts Settings", "exchange_gain_loss_posting_date", "Payment")

0 comments on commit 7bfe052

Please sign in to comment.