mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-17 08:28:44 +00:00
fix(accounts): stop coalescing a DATE with an int in Asset Depreciations report
The Asset Depreciations and Balances report tested disposal status with
IfNull(asset.disposal_date, 0) != 0 / == 0 — coalescing the DATE column
disposal_date with the integer 0. frappe.qb renders this as
COALESCE("disposal_date", 0); PostgreSQL requires COALESCE arguments to
share a type and raises:
psycopg2.errors.DatatypeMismatch: COALESCE types date and integer
cannot be matched
The predicate is in the WHERE/CASE of every query the report runs (both
group_by=Asset Category and group_by=Asset), so the whole report errored
on PostgreSQL. MariaDB's IFNULL(date, 0) is permissive and worked.
Replace each comparison with the null-test form already used elsewhere in
this same file: IfNull(disposal_date, 0) != 0 -> disposal_date.isnotnull(),
== 0 -> disposal_date.isnull(). Semantically identical (a stored date is
never 0), valid on both engines, MariaDB output unchanged.
This commit is contained in:
@@ -82,7 +82,7 @@ def get_asset_categories_for_grouped_by_category(filters):
|
||||
asset_capitalization = frappe.qb.DocType("Asset Capitalization")
|
||||
|
||||
disposal_in_period = (
|
||||
(IfNull(asset.disposal_date, 0) != 0)
|
||||
(asset.disposal_date.isnotnull())
|
||||
& (asset.disposal_date >= filters.from_date)
|
||||
& (asset.disposal_date <= filters.to_date)
|
||||
)
|
||||
@@ -92,7 +92,7 @@ def get_asset_categories_for_grouped_by_category(filters):
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(asset.purchase_date < filters.from_date)
|
||||
& ((IfNull(asset.disposal_date, 0) == 0) | (asset.disposal_date >= filters.from_date)),
|
||||
& ((asset.disposal_date.isnull()) | (asset.disposal_date >= filters.from_date)),
|
||||
asset.net_purchase_amount,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -209,9 +209,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(gl_entry.posting_date < filters.from_date)
|
||||
& (
|
||||
(IfNull(asset.disposal_date, 0) == 0) | (asset.disposal_date >= filters.from_date)
|
||||
),
|
||||
& ((asset.disposal_date.isnull()) | (asset.disposal_date >= filters.from_date)),
|
||||
gl_entry.debit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -222,7 +220,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(gl_entry.posting_date <= filters.to_date) & (IfNull(asset.disposal_date, 0) == 0),
|
||||
(gl_entry.posting_date <= filters.to_date) & (asset.disposal_date.isnull()),
|
||||
gl_entry.credit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -233,7 +231,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(IfNull(asset.disposal_date, 0) != 0)
|
||||
(asset.disposal_date.isnotnull())
|
||||
& (asset.disposal_date >= filters.from_date)
|
||||
& (asset.disposal_date <= filters.to_date)
|
||||
& (gl_entry.posting_date <= asset.disposal_date),
|
||||
@@ -249,10 +247,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
.when(
|
||||
(gl_entry.posting_date >= filters.from_date)
|
||||
& (gl_entry.posting_date <= filters.to_date)
|
||||
& (
|
||||
(IfNull(asset.disposal_date, 0) == 0)
|
||||
| (gl_entry.posting_date <= asset.disposal_date)
|
||||
),
|
||||
& ((asset.disposal_date.isnull()) | (gl_entry.posting_date <= asset.disposal_date)),
|
||||
gl_entry.debit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -282,7 +277,7 @@ def get_assets_for_grouped_by_category(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(IfNull(asset.disposal_date, 0) != 0) & (asset.disposal_date < filters.from_date),
|
||||
(asset.disposal_date.isnotnull()) & (asset.disposal_date < filters.from_date),
|
||||
0,
|
||||
)
|
||||
.else_(asset.opening_accumulated_depreciation)
|
||||
@@ -476,7 +471,7 @@ def get_asset_details_for_grouped_by_category(filters):
|
||||
asset_capitalization = frappe.qb.DocType("Asset Capitalization")
|
||||
|
||||
disposal_in_period = (
|
||||
(IfNull(asset.disposal_date, 0) != 0)
|
||||
(asset.disposal_date.isnotnull())
|
||||
& (asset.disposal_date >= filters.from_date)
|
||||
& (asset.disposal_date <= filters.to_date)
|
||||
)
|
||||
@@ -500,9 +495,7 @@ def get_asset_details_for_grouped_by_category(filters):
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(asset.purchase_date < filters.from_date)
|
||||
& (
|
||||
(IfNull(asset.disposal_date, 0) == 0) | (asset.disposal_date >= filters.from_date)
|
||||
),
|
||||
& ((asset.disposal_date.isnull()) | (asset.disposal_date >= filters.from_date)),
|
||||
asset.net_purchase_amount,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -599,9 +592,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(gl_entry.posting_date < filters.from_date)
|
||||
& (
|
||||
(IfNull(asset.disposal_date, 0) == 0) | (asset.disposal_date >= filters.from_date)
|
||||
),
|
||||
& ((asset.disposal_date.isnull()) | (asset.disposal_date >= filters.from_date)),
|
||||
gl_entry.debit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -612,7 +603,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(gl_entry.posting_date <= filters.to_date) & (IfNull(asset.disposal_date, 0) == 0),
|
||||
(gl_entry.posting_date <= filters.to_date) & (asset.disposal_date.isnull()),
|
||||
gl_entry.credit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -623,7 +614,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(IfNull(asset.disposal_date, 0) != 0)
|
||||
(asset.disposal_date.isnotnull())
|
||||
& (asset.disposal_date >= filters.from_date)
|
||||
& (asset.disposal_date <= filters.to_date)
|
||||
& (gl_entry.posting_date <= asset.disposal_date),
|
||||
@@ -639,10 +630,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
.when(
|
||||
(gl_entry.posting_date >= filters.from_date)
|
||||
& (gl_entry.posting_date <= filters.to_date)
|
||||
& (
|
||||
(IfNull(asset.disposal_date, 0) == 0)
|
||||
| (gl_entry.posting_date <= asset.disposal_date)
|
||||
),
|
||||
& ((asset.disposal_date.isnull()) | (gl_entry.posting_date <= asset.disposal_date)),
|
||||
gl_entry.debit,
|
||||
)
|
||||
.else_(0)
|
||||
@@ -672,7 +660,7 @@ def get_assets_for_grouped_by_asset(filters):
|
||||
Sum(
|
||||
frappe.qb.terms.Case()
|
||||
.when(
|
||||
(IfNull(asset.disposal_date, 0) != 0) & (asset.disposal_date < filters.from_date),
|
||||
(asset.disposal_date.isnotnull()) & (asset.disposal_date < filters.from_date),
|
||||
0,
|
||||
)
|
||||
.else_(asset.opening_accumulated_depreciation)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext.accounts.report.asset_depreciations_and_balances.asset_depreciations_and_balances import (
|
||||
execute,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestSuite
|
||||
|
||||
|
||||
class TestAssetDepreciationsAndBalancesReport(ERPNextTestSuite):
|
||||
def test_report_runs_on_both_engines(self):
|
||||
"""The report compared IfNull(asset.disposal_date, 0) against 0 -- coalescing a DATE
|
||||
column with integer 0. Postgres rejects that (COALESCE types date and integer cannot be
|
||||
matched) at plan time, so the whole report errored there regardless of data. It must run
|
||||
on both engines."""
|
||||
for group_by in ("Asset Category", "Asset"):
|
||||
filters = frappe._dict(
|
||||
company="_Test Company",
|
||||
from_date="2020-01-01",
|
||||
to_date="2030-12-31",
|
||||
group_by=group_by,
|
||||
)
|
||||
result = execute(filters)
|
||||
self.assertIsInstance(result[1], list)
|
||||
Reference in New Issue
Block a user