Adam Saghy created FINERACT-2936:
------------------------------------
Summary: Fix daysInYearCustomStrategy plumbing defects in the loan
and loan product APIs
Key: FINERACT-2936
URL: https://issues.apache.org/jira/browse/FINERACT-2936
Project: Apache Fineract
Issue Type: Bug
Components: Loan
Affects Versions: 1.15.0
Reporter: Adam Saghy
Assignee: Adam Saghy
*Requires a regenerated Fineract client (swagger / OpenAPI changes)*
* LoansApiResourceSwagger.PostLoansRequest (line 1408): allowableValues is one
string, "FULL_LEAP_YEAR, FEB_29_PERIOD_ONLY". The generated client enum
therefore has a single merged constant, FULL_LEAP_YEAR_FEB_29_PERIOD_ONLY, and
can't send a real value. Change it to an array: {"FULL_LEAP_YEAR",
"FEB_29_PERIOD_ONLY"}.
** *Decision: Add it*
* LoansApiResourceSwagger.GetLoansLoanIdResponse (line 105) has no
daysInYearCustomStrategy, and
LoanProductsApiResourceSwagger.GetLoanProductsTemplateResponse (line 755) has
no daysInYearCustomStrategyOptions. The server already returns both; only the
generated models lack them. This is additive.
** *Decision: Add it*
*Server-only (behaviour changes)*
* LoanApplicationValidator.validateForCreate (line 777): passes the string
literal "daysInYearCustomStrategyParameterName" to enumValueOfParameterNamed
instead of the constant LoanApiConstants.daysInYearCustomStrategyParameterName.
The lookup always returns null, so the progressive-only and ACTUAL-only checks
(lines 775–791) never run.
** *Decision: Fix it*
* LoanScheduleAssembler.assembleLoanApplicationTermsFrom (line 576): always
passes the product's value to LoanApplicationTerms.assembleFrom. The loan
request's value is never read, even though LoanApplicationValidator accepts the
parameter (supported parameters, line 178). It is silently ignored.
** *Decision:* Fix by implementing a per-loan override (like
interestRecognitionOnDisbursementDate)
* LoanApplicationTerms(Builder builder) (private constructor, line 308): never
copies builder.daysInYearCustomStrategy into the new object.
assembleFrom(LoanRepaymentScheduleModelData, MathContext) does set it on the
Builder (line 615), but the value is dropped when build() runs. As a result the
embeddable progressive schedule generator ignores the strategy.
** *Decision: Fix it, but i wonder why it was not an issue during testing*
* LoanProductRelatedDetailUpdateUtil.updateLoanRepaymentSchedule (lines
277–280): uses
DaysInYearCustomStrategyType.valueOf(command.stringValueOfParameterNamed(...)).
** An explicit "daysInYearCustomStrategy": null becomes valueOf(""), which
throws an IllegalArgumentException, most likely a 500. So the value can't be
cleared via PUT.
** Clearing is needed: LoanProduct.validateLoanProductPreSave (lines 464–474)
requires it to be null for cumulative products and for non-ACTUAL days in year.
A product that has it set can't be switched to either.
** There's no changed-value check either, so every PUT that sends it reports
it as changed.
** *Decision: Fix it, we should be able to clear it if it’s cumulative or
“non-Actual” days in year, otherwise it needs to have a value*
* LoanProductDataValidator.validateForCreate / validateForUpdate (lines 233 /
1345): daysInYearCustomStrategyis the only string-enum product parameter
without an isOneOfEnumValues check; it's only listed as supported (line 203).
An invalid value on create is rejected late, by LoanProductAssembler's generic
enum parsing (line 212). On update it reaches
DaysInYearCustomStrategyType.valueOf(...) in
LoanProductRelatedDetailUpdateUtil(line 279), which most likely fails with a
500.
** *Decision: Fix it*
*
AdvancedPaymentScheduleTransactionProcessor.handleReAgeWithInterestRecalculationEnabled
(lines 4283–4291): builds the re-age LoanApplicationTerms with
daysInMonthType, daysInYearType, interestRecognitionOnDisbursementDate,
daysInYearCustomStrategy and allowPartialPeriodInterestCalculationread from the
*product* (loan.getLoanProduct()…), not from the loan's own copy. The rest of
the builder already reads from the loan.
** Changing any of these on the product leaks into existing loans when they're
re-aged.
** interestRecognitionOnDisbursementDate can be overridden per loan at
submission, so re-age ignores that override even when the product is never
changed.
** (Possibly related: installmentAmountInMultiplesOf is read from the product
at line 1788, in the capitalized-income handling.)
*
** *Decision: Fix it*
--
This message was sent by Atlassian Jira
(v8.20.10#820010)