You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ofbiz.apache.org by "Mridul Pathak (Jira)" <ji...@apache.org> on 2026/10/22 13:41:00 UTC
[jira] [Updated] (OFBIZ-13705) Multiple regressions in FixedAssetServices.groovy (maintenance and depreciation services)
[ https://issues.apache.org/jira/browse/OFBIZ-13705?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mridul Pathak updated OFBIZ-13705:
----------------------------------
Description:
Regressions from the mini-lang conversion in {{applications/accounting/src/main/groovy/org/apache/ofbiz/accounting/fixedasset/FixedAssetServices.groovy}}; all present on both branches.
h3. Maintenance
# {{createMaintsFromMeterReading}}: the due condition is inverted. Mini-lang created a maintenance when {{nextIntervalQty <= meterValue}} and (repeatCount <= 0 or listSize < repeatCount); the Groovy uses {{nextIntervalQty > meterValue || (repeatCount > 0 && listSize < repeatCount)}}. Any meter reading creates maintenances that are not due (e.g. ODOMETER 65 creates the 2500/5000/10000 COMPANY_VEHICLE maintenances) and misses those that are. Also {{maintList*.intervalQuantity.max()}} is null when all quantities are null (NPE on the next line) and a {{meterValue}} of 0 is skipped.
# {{createMaintsFromTimeInterval}}: {{Calendar.instance()}} is a property followed by {{call()}} and throws MissingMethodException for every time-based interval, so the FAM_AUTO_CREATE job fails. Once that is fixed, {{lastSvcDate = maintList ? ... : null}} never creates the first maintenance (mini-lang pre-set the epoch timestamp for an empty history).
# {{createFixedAssetMaint}}: {{maintTemplateWorkEffortId}} is only read inside {{if (parameters.productMaintSeqId)}}, so a template chosen on the Add Maintenance form without a ProductMaint is ignored. Also {{maintHistSeqId}} now comes from {{getNextSeqId('FixedAssetMaint')}} instead of {{setNextSubSeqId(..., 'maintHistSeqId', 5, 1)}}, breaking the per-asset sequence that {{createMaintsFromTimeInterval}} sorts on.
# {{createFixedAssetMaintOrder}}: {{queryList()?.orderItemSeqId}} spreads over the whole list and stores a value such as {{[00001]}} as orderItemSeqId when the user leaves it blank; mini-lang took {{orderItems[0]}}.
h3. Depreciation
# {{checkUpdateFixedAssetDepreciation}}: the condition is {{if (!acctgTrans && acctgTrans.acctgTransTypeId == 'DEPRECIATION' && ...)}} instead of {{if (acctgTrans && ...)}}, so the body never runs and {{FixedAsset.depreciation}} is never increased when a DEPRECIATION AcctgTrans is posted (the "Create an Accounting Transaction" link keeps proposing the same amount). Behind it: {{creditTransaction.currencyUomId}} in the warning is an undeclared variable (should be {{it}}), the {{origCurrencyUomId}}/{{origAmount}} fallback is gone, and a currency mismatch now returns {{failure()}} where mini-lang logged and returned success.
# {{doubleDecliningBalanceDepreciation}}: {{plannedPastDepreciationTotal}} is {{depreciationTotal - depreciation}} (mini-lang returned {{depreciationTotal}}), which changes the amount posted by the Create an Accounting Transaction link (e.g. 7500.00 becomes 4500 for cost 10000, salvage 1000, usage 2). The {{decimal-scale="2"}} rounding is gone, {{depreciationYear}} is never incremented so every row shows the acquisition year, and the "empty list, add default row" block is nested inside {{usageYears > 0}} and is dead.
# {{straightLineDepreciation}}: the grid {{year}} is {{i}} instead of {{assetAcquiredYear + i}}, and {{depreciation}} starts from {{fixedAsset.depreciation}} instead of 0.
# {{calculateFixedAssetDepreciation}}: the {{dateAcquired}} guard tests {{expectedEndOfLife}} again, so a null dateAcquired throws an NPE instead of returning the message (this can break the ListFixedAssets grid). The three early-return messages also go through {{success(label)}}/{{error(label)}} instead of {{successMessageList}}, which ShowFixedAssetDepreciation reads.
# {{createMaintsFromTimeInterval}}: {{Calendar.instance()}} is a property followed by {{call()}} and {{Calendar.add(int, int)}} receives a negated {{long}} ({{long intervalQuantity}}), so both throw MissingMethodException for every time-based interval and the FAM_AUTO_CREATE job fails. Once that is fixed, {{lastSvcDate = maintList ? ... : null}} never creates the first maintenance (mini-lang pre-set the epoch timestamp for an empty history).
was:
Regressions from the mini-lang conversion in {{applications/accounting/src/main/groovy/org/apache/ofbiz/accounting/fixedasset/FixedAssetServices.groovy}}; all present on both branches.
h3. Maintenance
# {{createMaintsFromMeterReading}}: the due condition is inverted. Mini-lang created a maintenance when {{nextIntervalQty <= meterValue}} and (repeatCount <= 0 or listSize < repeatCount); the Groovy uses {{nextIntervalQty > meterValue || (repeatCount > 0 && listSize < repeatCount)}}. Any meter reading creates maintenances that are not due (e.g. ODOMETER 65 creates the 2500/5000/10000 COMPANY_VEHICLE maintenances) and misses those that are. Also {{maintList*.intervalQuantity.max()}} is null when all quantities are null (NPE on the next line) and a {{meterValue}} of 0 is skipped.
# {{createMaintsFromTimeInterval}}: {{Calendar.instance()}} is a property followed by {{call()}} and throws MissingMethodException for every time-based interval, so the FAM_AUTO_CREATE job fails. Once that is fixed, {{lastSvcDate = maintList ? ... : null}} never creates the first maintenance (mini-lang pre-set the epoch timestamp for an empty history).
# {{createFixedAssetMaint}}: {{maintTemplateWorkEffortId}} is only read inside {{if (parameters.productMaintSeqId)}}, so a template chosen on the Add Maintenance form without a ProductMaint is ignored. Also {{maintHistSeqId}} now comes from {{getNextSeqId('FixedAssetMaint')}} instead of {{setNextSubSeqId(..., 'maintHistSeqId', 5, 1)}}, breaking the per-asset sequence that {{createMaintsFromTimeInterval}} sorts on.
# {{createFixedAssetMaintOrder}}: {{queryList()?.orderItemSeqId}} spreads over the whole list and stores a value such as {{[00001]}} as orderItemSeqId when the user leaves it blank; mini-lang took {{orderItems[0]}}.
h3. Depreciation
# {{checkUpdateFixedAssetDepreciation}}: the condition is {{if (!acctgTrans && acctgTrans.acctgTransTypeId == 'DEPRECIATION' && ...)}} instead of {{if (acctgTrans && ...)}}, so the body never runs and {{FixedAsset.depreciation}} is never increased when a DEPRECIATION AcctgTrans is posted (the "Create an Accounting Transaction" link keeps proposing the same amount). Behind it: {{creditTransaction.currencyUomId}} in the warning is an undeclared variable (should be {{it}}), the {{origCurrencyUomId}}/{{origAmount}} fallback is gone, and a currency mismatch now returns {{failure()}} where mini-lang logged and returned success.
# {{doubleDecliningBalanceDepreciation}}: {{plannedPastDepreciationTotal}} is {{depreciationTotal - depreciation}} (mini-lang returned {{depreciationTotal}}), which changes the amount posted by the Create an Accounting Transaction link (e.g. 7500.00 becomes 4500 for cost 10000, salvage 1000, usage 2). The {{decimal-scale="2"}} rounding is gone, {{depreciationYear}} is never incremented so every row shows the acquisition year, and the "empty list, add default row" block is nested inside {{usageYears > 0}} and is dead.
# {{straightLineDepreciation}}: the grid {{year}} is {{i}} instead of {{assetAcquiredYear + i}}, and {{depreciation}} starts from {{fixedAsset.depreciation}} instead of 0.
# {{calculateFixedAssetDepreciation}}: the {{dateAcquired}} guard tests {{expectedEndOfLife}} again, so a null dateAcquired throws an NPE instead of returning the message (this can break the ListFixedAssets grid). The three early-return messages also go through {{success(label)}}/{{error(label)}} instead of {{successMessageList}}, which ShowFixedAssetDepreciation reads.
> Multiple regressions in FixedAssetServices.groovy (maintenance and depreciation services)
> -----------------------------------------------------------------------------------------
>
> Key: OFBIZ-13705
> URL: https://issues.apache.org/jira/browse/OFBIZ-13705
> Project: OFBiz
> Issue Type: Bug
> Components: accounting
> Affects Versions: Upcoming Branch, 24.09.08
> Reporter: Mridul Pathak
> Assignee: Mridul Pathak
> Priority: Major
>
> Regressions from the mini-lang conversion in {{applications/accounting/src/main/groovy/org/apache/ofbiz/accounting/fixedasset/FixedAssetServices.groovy}}; all present on both branches.
> h3. Maintenance
> # {{createMaintsFromMeterReading}}: the due condition is inverted. Mini-lang created a maintenance when {{nextIntervalQty <= meterValue}} and (repeatCount <= 0 or listSize < repeatCount); the Groovy uses {{nextIntervalQty > meterValue || (repeatCount > 0 && listSize < repeatCount)}}. Any meter reading creates maintenances that are not due (e.g. ODOMETER 65 creates the 2500/5000/10000 COMPANY_VEHICLE maintenances) and misses those that are. Also {{maintList*.intervalQuantity.max()}} is null when all quantities are null (NPE on the next line) and a {{meterValue}} of 0 is skipped.
> # {{createMaintsFromTimeInterval}}: {{Calendar.instance()}} is a property followed by {{call()}} and throws MissingMethodException for every time-based interval, so the FAM_AUTO_CREATE job fails. Once that is fixed, {{lastSvcDate = maintList ? ... : null}} never creates the first maintenance (mini-lang pre-set the epoch timestamp for an empty history).
> # {{createFixedAssetMaint}}: {{maintTemplateWorkEffortId}} is only read inside {{if (parameters.productMaintSeqId)}}, so a template chosen on the Add Maintenance form without a ProductMaint is ignored. Also {{maintHistSeqId}} now comes from {{getNextSeqId('FixedAssetMaint')}} instead of {{setNextSubSeqId(..., 'maintHistSeqId', 5, 1)}}, breaking the per-asset sequence that {{createMaintsFromTimeInterval}} sorts on.
> # {{createFixedAssetMaintOrder}}: {{queryList()?.orderItemSeqId}} spreads over the whole list and stores a value such as {{[00001]}} as orderItemSeqId when the user leaves it blank; mini-lang took {{orderItems[0]}}.
> h3. Depreciation
> # {{checkUpdateFixedAssetDepreciation}}: the condition is {{if (!acctgTrans && acctgTrans.acctgTransTypeId == 'DEPRECIATION' && ...)}} instead of {{if (acctgTrans && ...)}}, so the body never runs and {{FixedAsset.depreciation}} is never increased when a DEPRECIATION AcctgTrans is posted (the "Create an Accounting Transaction" link keeps proposing the same amount). Behind it: {{creditTransaction.currencyUomId}} in the warning is an undeclared variable (should be {{it}}), the {{origCurrencyUomId}}/{{origAmount}} fallback is gone, and a currency mismatch now returns {{failure()}} where mini-lang logged and returned success.
> # {{doubleDecliningBalanceDepreciation}}: {{plannedPastDepreciationTotal}} is {{depreciationTotal - depreciation}} (mini-lang returned {{depreciationTotal}}), which changes the amount posted by the Create an Accounting Transaction link (e.g. 7500.00 becomes 4500 for cost 10000, salvage 1000, usage 2). The {{decimal-scale="2"}} rounding is gone, {{depreciationYear}} is never incremented so every row shows the acquisition year, and the "empty list, add default row" block is nested inside {{usageYears > 0}} and is dead.
> # {{straightLineDepreciation}}: the grid {{year}} is {{i}} instead of {{assetAcquiredYear + i}}, and {{depreciation}} starts from {{fixedAsset.depreciation}} instead of 0.
> # {{calculateFixedAssetDepreciation}}: the {{dateAcquired}} guard tests {{expectedEndOfLife}} again, so a null dateAcquired throws an NPE instead of returning the message (this can break the ListFixedAssets grid). The three early-return messages also go through {{success(label)}}/{{error(label)}} instead of {{successMessageList}}, which ShowFixedAssetDepreciation reads.
> # {{createMaintsFromTimeInterval}}: {{Calendar.instance()}} is a property followed by {{call()}} and {{Calendar.add(int, int)}} receives a negated {{long}} ({{long intervalQuantity}}), so both throw MissingMethodException for every time-based interval and the FAM_AUTO_CREATE job fails. Once that is fixed, {{lastSvcDate = maintList ? ... : null}} never creates the first maintenance (mini-lang pre-set the epoch timestamp for an empty history).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)