fix: match depreciation schedule rows at currency precision to avoid duplicate JEs

This commit is contained in:
khushi8112
2026-07-09 14:14:44 +05:30
parent 95e2ce6d85
commit 947ed5dfe1
2 changed files with 42 additions and 1 deletions

View File

@@ -94,11 +94,12 @@ class AssetService:
def update_journal_entry_link_on_depr_schedule(self, asset, je_row) -> None:
"""Stamp this entry onto the matching (date + amount) depreciation schedule row."""
depr_schedule = get_depr_schedule(asset.name, "Active", self.doc.finance_book)
precision = je_row.precision("debit")
for d in depr_schedule or []:
if (
d.schedule_date == self.doc.posting_date
and not d.journal_entry
and d.depreciation_amount == flt(je_row.debit)
and flt(d.depreciation_amount, precision) == flt(je_row.debit, precision)
):
frappe.db.set_value("Depreciation Schedule", d.name, "journal_entry", self.doc.name)

View File

@@ -1478,6 +1478,46 @@ class TestDepreciationBasics(AssetSetup):
self.assertFalse(depr_schedule[1].journal_entry)
self.assertFalse(depr_schedule[2].journal_entry)
def test_depr_schedule_link_matches_at_currency_precision(self):
"""A Depreciation Schedule row whose amount carries more decimals than the
company currency (e.g. 25701.202 vs a JE debit of 25701.20) must still be
matched and stamped with the Journal Entry. Comparing at exact float
equality left the link NULL, so the scheduler treated the row as unposted
and created a duplicate Journal Entry on every run. Regression test for
AssetService.update_journal_entry_link_on_depr_schedule()."""
from unittest.mock import MagicMock, patch
from erpnext.accounts.doctype.journal_entry.services import asset_service as asset_service_module
from erpnext.accounts.doctype.journal_entry.services.asset_service import AssetService
posting_date = getdate("2021-06-01")
je = frappe._dict(name="JE-DEPR-TEST", finance_book=None, posting_date=posting_date)
service = AssetService(je)
# JE debit is stored at company currency precision (2 dp)...
je_row = MagicMock()
je_row.debit = 25701.20
je_row.precision.return_value = 2
# ...while the schedule row amount carries a third decimal.
schedule_row = frappe._dict(
name="DS-ROW-1",
schedule_date=posting_date,
journal_entry=None,
depreciation_amount=25701.202,
)
asset = frappe._dict(name="ASSET-TEST")
with (
patch.object(asset_service_module, "get_depr_schedule", return_value=[schedule_row]),
patch.object(frappe.db, "set_value") as mock_set_value,
):
service.update_journal_entry_link_on_depr_schedule(asset, je_row)
mock_set_value.assert_called_once_with(
"Depreciation Schedule", "DS-ROW-1", "journal_entry", "JE-DEPR-TEST"
)
def test_depr_entry_posting_when_depr_expense_account_is_an_expense_account(self):
"""Tests if the Depreciation Expense Account gets debited and the Accumulated Depreciation Account gets credited when the former's an Expense Account."""