Foo Developer created FINERACT-2867:
---------------------------------------
Summary: Submitting a savings account application with a FLAT
charge fails with HTTP 500 (NullPointerException on the account currency)
Key: FINERACT-2867
URL: https://issues.apache.org/jira/browse/FINERACT-2867
Project: Apache Fineract
Issue Type: Bug
Components: Savings
Reporter: Foo Developer
Assignee: Foo Developer
h3. Steps to reproduce
# Create a savings charge with calculation type FLAT, for example charge time
"Savings Activation":
{code:json}POST /fineract-provider/api/v1/charges
{
"name": "Flat activation fee", "chargeAppliesTo": 2, "currencyCode": "USD",
"chargeTimeType": 3, "chargeCalculationType": 1, "chargePaymentMode": 0,
"amount": 10, "active": true, "locale": "en"
}
{code}
# Submit a new savings account application that carries that charge:
{code:json}POST /fineract-provider/api/v1/savingsaccounts
{
"clientId": 1, "productId": 1, "submittedOnDate": "01 January 2024",
"locale": "en", "dateFormat": "dd MMMM yyyy",
"charges": [ { "chargeId": <charge id>, "amount": 10 } ]
}
{code}
The same failure is reachable from
{{SavingsAccountAssembler.assembleFrom(client, group, productId, ...)}}, which
copies a product's charges onto a new account through
{{SavingsAccountChargeAssembler.fromSavingsProduct}}, when the product has a
FLAT charge.
h3. Expected
The savings account application is created with the FLAT charge, its amount
rounded to the account currency.
h3. Actual
The request fails with HTTP 500. {{SavingsAccountCharge.populateDerivedFields}}
throws {{NullPointerException: Cannot invoke "SavingsAccount.getCurrency()"
because the return value of "SavingsAccountCharge.savingsAccount()" is null}}.
h3. Root cause
{{SavingsAccountChargeAssembler.fromParsedJson}} and {{fromSavingsProduct}}
build the charges of a new application with
{{SavingsAccountCharge.createNewWithoutSavingsAccount(...)}}, i.e. with
{{savingsAccount = null}}; the charge is attached to its account only
afterwards, through {{SavingsAccountCharge.update(SavingsAccount)}}. The
constructor always calls {{populateDerivedFields}}, and since FINERACT-2284 its
{{FLAT}} branch does {{Money.of(this.savingsAccount().getCurrency(),
chargeAmount)}} to apply the currency rounding. With no account yet, that
dereferences null. Charges added to an existing account ({{createNewFromJson}})
are not affected, because they are built with the account.
h3. Proposed fix
In {{populateDerivedFields}}, round the FLAT amount only when the account is
known and keep the raw amount otherwise. In {{update(SavingsAccount)}}, when a
FLAT charge is attached to its account for the first time, apply the currency
rounding to {{amount}} and {{amountOutstanding}} then, so a charge submitted
with a new application is rounded the same way as one added to an existing
account.
h3. Tests
A unit test in {{fineract-savings}} for {{SavingsAccountCharge}}: building a
FLAT charge with {{createNewWithoutSavingsAccount}} no longer throws, and
attaching it to an account rounds its amount and outstanding amount to the
account currency.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)