[ 
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)

Reply via email to