Jose Alberto Hernandez created FINERACT-2992:
------------------------------------------------

             Summary: Introduce a loan-only repayment frequency type instead of 
extending PeriodFrequencyType
                 Key: FINERACT-2992
                 URL: https://issues.apache.org/jira/browse/FINERACT-2992
             Project: Apache Fineract
          Issue Type: Improvement
          Components: Loan, Savings, Shares
    Affects Versions: 1.16.0
            Reporter: Jose Alberto Hernandez
             Fix For: 1.17.0


```
h2. Background
FINERACT-1322 (PR #6546) adds the semi-monthly repayment frequency to loans by 
appending \{{SEMI_MONTHLY(6)}} to 
\{{org.apache.fineract.portfolio.common.domain.PeriodFrequencyType}}. That enum 
is shared by loans, savings and deposit lock-in periods, recurring deposit 
frequencies, share lock-in periods and interest rate charts. Semi-monthly only 
has a meaning for loan repayments, so the shared enum now carries a value that 
most of its users must explicitly ignore.

h2. Problem / Motivation
* Every exhaustive \{{switch}} over \{{PeriodFrequencyType}} outside the loan 
domain needed a dummy \{{case SEMI_MONTHLY}} branch that only exists to keep 
the switch exhaustive: \{{SavingsAccount}} (lock-in), \{{DepositAccountUtils}} 
(recurring deposit date), \{{ShareAccountDataSerializer}} (lock-in) and 
\{{InterestRateChartEnumerations}}.
* \{{PeriodFrequencyType.integerValues()}} filters \{{SEMI_MONTHLY}} out so 
that interest rate chart validation does not accept it; the savings, deposit 
and share validators rely on \{{inMinMaxRange(0, 3)}} to keep the value out. 
The fence works, but it is spread over several modules and easy to break when 
the next loan-only frequency is added.
* This was raised in the review of PR #6546 by @galovics and agreed as a 
follow-up; see the dev@ thread: <link>.

h2. Proposed change
* Add a loan-specific frequency type (for example 
\{{LoanRepaymentFrequencyType}} in \{{fineract-loan}}) with \{{DAYS}}, 
\{{WEEKS}}, \{{MONTHS}}, \{{YEARS}} and \{{SEMI_MONTHLY}}, keeping the 
persisted integer values of \{{PeriodFrequencyType}} (0-3 and 6) so no data 
migration is needed for \{{m_product_loan.repayment_period_frequency_enum}} and 
\{{m_loan.repayment_period_frequency_enum}}.
* Change \{{repaymentPeriodFrequencyType}} to the new type in the loan domain: 
\{{LoanProductRelatedDetail}}, \{{ILoanConfigurationDetails}} / 
\{{LoanConfigurationDetails}}, \{{LoanApplicationTerms}}, 
\{{ScheduledDateGenerator}} / \{{DefaultScheduledDateGenerator}}, 
\{{PaymentPeriodsInOneYearCalculator}}, \{{AprCalculator}}, 
\{{LoanScheduleAssembler}}, the progressive EMI calculator and interest 
schedule model, and the loan read/write services and enumerations.
* Provide explicit conversion where the loan domain still talks to shared code 
that expects \{{PeriodFrequencyType}} (calendar utilities, re-aging, charge 
frequencies, API option lists), instead of relying on the shared enum carrying 
loan-only values.
* Remove \{{SEMI_MONTHLY}} from \{{PeriodFrequencyType}}, together with the 
dummy \{{case SEMI_MONTHLY}} branches in savings, deposits, shares and interest 
rate charts and the special case in \{{integerValues()}}.
* Keep the REST contract unchanged: \{{repaymentFrequencyType}} stays an 
integer with the same values on loan products, loans, templates and schedule 
calculation; the option lists returned by the templates must still include 
semi-monthly for loans only.

h2. Affected modules
* \{{fineract-core}} — \{{PeriodFrequencyType}} loses \{{SEMI_MONTHLY}} and the 
\{{integerValues()}} special case; \{{CommonEnumerations}} loses the loan-only 
option.
* \{{fineract-loan}} — new frequency type, \{{repaymentPeriodFrequencyType}} 
retyped across product, loan terms and schedule generation.
* \{{fineract-progressive-loan}} — EMI calculator and interest schedule model 
use the new type.
* \{{fineract-provider}} — loan assemblers, validators, read/write services, 
re-aging validator and interest rate chart enumerations; share account 
serializer loses the dummy branch.
* \{{fineract-savings}} — \{{SavingsAccount}} and \{{DepositAccountUtils}} lose 
the dummy branch.
* \{{fineract-e2e-tests-core}} / \{{integration-tests}} — test enums and 
builders follow the new type where they reference it by name.

h2. Acceptance criteria
* \{{PeriodFrequencyType}} has no \{{SEMI_MONTHLY}} constant and no module 
outside loans contains a \{{case SEMI_MONTHLY}} branch.
* Semi-monthly loan products and loans created before the change load, generate 
schedules and repay exactly as before; no Liquibase changeset is required.
* The loan product and loan APIs accept and return \{{repaymentFrequencyType}} 
with the same integer values as today, including \{{6}} for semi-monthly.
* Savings, deposit, share lock-in and interest rate chart APIs keep rejecting 
value \{{6}} with HTTP 400.
* Existing unit, integration and E2E tests for the semi-monthly frequency (for 
example \{{LoanSemiMonthlyRepaymentScheduleTest}}, 
\{{SemiMonthlyScheduleDatesTest}}, \{{LoanSemiMonthlyRepayment.feature}}) pass 
unchanged in behaviour.
```



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to