[
https://issues.apache.org/jira/browse/FINERACT-2863?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Aman Mittal updated FINERACT-2863:
----------------------------------
Fix Version/s: 1.16.0
> Retrieving a savings account with template=true fails with
> NullPointerException on productOptions accountingRule
> ----------------------------------------------------------------------------------------------------------------
>
> Key: FINERACT-2863
> URL: https://issues.apache.org/jira/browse/FINERACT-2863
> Project: Apache Fineract
> Issue Type: Bug
> Components: Savings
> Reporter: Foo Developer
> Assignee: Foo Developer
> Priority: Major
> Fix For: 1.16.0
>
>
> h3. Steps to reproduce
> # Create a savings product (any accounting rule), a client, and submit a
> savings account application for that client.
> # Load the account with its template, as a UI does for the "modify
> application" form:
> {code}GET
> /fineract-provider/api/v1/savingsaccounts/{accountId}?template=true&associations=charges
> {code}
> h3. Expected
> HTTP 200 with the account, including {{productOptions}} for the product
> dropdown.
> h3. Actual
> The request fails while the response is serialized: a
> {{NullPointerException}} inside a bean getter, returned as a raw error (HTTP
> 400 on current {{develop}}, with the exception text as the body), so the
> account cannot be edited:
> {code}Cannot invoke
> "org.apache.fineract.infrastructure.core.data.EnumOptionData.getValue()"
> because "this.accountingRule" is null
> (through reference chain:
> SavingsAccountData["productOptions"]->ArrayList[0]->SavingsProductData["accrualBasedAccountingEnabled"])
> {code}
> {{GET /savingsaccounts/{accountId}}} without {{template=true}} works, and so
> does {{GET /savingsaccounts/template?clientId=...}} (that endpoint serializes
> through {{ToApiJsonSerializer}}). A successful {{PUT
> /savingsaccounts/{accountId}}} cannot be read back with {{template=true}}
> either.
> h3. Root cause
> With {{template=true}}, {{SavingsAccountTemplateReadPlatformServiceImpl}}
> fills {{productOptions}} from
> {{SavingsProductReadPlatformService.retrieveAllForLookup()}}, whose row
> mapper returns {{SavingsProductData.lookup(id, name)}}. That factory
> deliberately leaves every field except id and name {{null}}, including
> {{accountingRule}}.
> {{SavingsAccountsApiResource.retrieveOne}} returns {{SavingsAccountData}}
> itself, so the JAX-RS Jackson provider serializes it and calls every public
> bean getter it finds. {{SavingsProductData.isCashBasedAccountingEnabled()}},
> {{isAccrualBasedAccountingEnabled()}}, {{isUpfrontAccrualAccounting()}} and
> {{isPeriodicAccrualAccounting()}} are picked up as properties, and they
> dereference {{accountingRule}} without a null check.
> {{hasAccountingEnabled()}} and {{accountingRuleTypeId()}} have the same
> unguarded dereference.
> h3. Proposed fix
> Null-guard the {{accountingRule}}-dependent methods in {{SavingsProductData}}
> (fineract-core), treating a missing accounting rule as "no accounting": the
> {{is...}}/{{has...}} methods return {{false}} and {{accountingRuleTypeId()}}
> returns {{AccountingRuleType.NONE}}. Behaviour for products that do carry an
> accounting rule is unchanged.
> h3. Test
> A unit test {{SavingsProductDataTest}} covering a lookup-only instance (all
> methods return "no accounting", and Jackson serialization no longer throws)
> and an instance with an accounting rule (still evaluated).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)