Aman-Mittal opened a new pull request, #193: URL: https://github.com/apache/fineract-backoffice-ui/pull/193
Closes #192. Completes the product-configuration phase begun in #189 and #191. Interest recalculation could not be configured at all. `isInterestRecalculationEnabled` was a hardcoded `false` in the create defaults and read back on edit — so creating a product here always disabled it, a product configured elsewhere kept its setting only by accident, and nothing let anyone see or change it. Its seven dependent fields did not exist in the form. ### Following a rule chain the API actually documents `POST /loanproducts` states the conditions explicitly, which is unusual for this client: > Additional Mandatory Fields if interest recalculation is enabled(true): > `interestRecalculationCompoundingMethod`, `rescheduleStrategyMethod`, > `recalculationRestFrequencyType` > > … if `recalculationRestFrequencyType` is not same as repayment period: > `recalculationRestFrequencyInterval` > > … if `interestRecalculationCompoundingMethod` is enabled: `recalculationCompoundingFrequencyType` > > … and if that is not same as repayment period: `recalculationCompoundingFrequencyInterval` The form follows that chain rather than showing everything at once, and switching recalculation off clears the whole group instead of leaving recalculation settings on a product that does not recalculate. The conditions match on each option's **code**, not its id, so Fineract's numbering doesn't become a magic number here. Also adds `chargeOffBehaviour`, `enableAccrualActivityPosting`, `fixedLength` and `repaymentStartDateType`. ### A correction to #191 That PR added the capitalised income and buy-down option lists as local constants, with a comment saying the product template does not return them. **It does** — `capitalizedIncomeTypeOptions`, `capitalizedIncomeCalculationTypeOptions`, `capitalizedIncomeStrategyOptions` and the three `buyDownFee*Options`, along with every list this PR needed. I got that wrong; the constants are gone and all six now come from the template, so labels are the server's and a value added upstream appears without a code change. ### The object-in-a-signal trap, again The conditional flags are held as their own signals rather than read off the payload. `product` is a signal holding an object, so assigning to one of its properties invalidates nothing and a `computed` reading `product().x` never re-runs. This is the third time this pattern has bitten (#189 for the down payment controls, #191's checkboxes) — here the unit tests caught it before it reached review, but it's a sharp edge in this component that would be worth removing properly at some point. ### Edit round trip Every new field is carried through `loadProductData`, which rebuilds the payload field by field. The response nests recalculation under `interestRecalculationData` and names the compounding frequency differently from the request (`interestRecalculationCompoundingFrequencyType` vs `recalculationCompoundingFrequencyType`); the round trip handles both. ### Comprehensibility The vocabulary here is the most specialist in the form, so the help does the most work: > **Recalculate interest on the actual balance** — Charge interest on what the borrower actually > owes on the day, rather than on the balance the original schedule assumed. A borrower who pays > early then pays less interest, and one who pays late pays more. Labels avoid jargon where plain words work: *What gets compounded*, *When the amount owed changes*, *How often interest is recalculated*, *Interest on early settlement*, *When the loan is charged off*. ### Verification | Check | Result | |---|---| | Unit tests | **729 passing** (720 → 729) | | Mocked Playwright | **208/208 passing** (204 → 208) | | `tsc` (app + spec) | 0 errors | | `npm run build` | passes | | lint (empty suppressions baseline), format, i18n, icons, license | all clean | Driven by hand against mocks before committing: with recalculation on, the mandatory three appear and neither interval does — correct, since the seeded frequency is "same as repayment period" and the seeded compounding method is "none". ### Not in this PR The demo step runs only in the `backend` project, which needs a live Fineract, so it is unverified here; its assertions mirror the mocked spec that does run. `isArrearsBasedOnOriginalSchedule`, the `*OnDayType` fields and the accounting mappings (`capitalizedIncomeClassificationToIncomeAccountMappings`) remain unexposed — accounting mappings are a separate area of the form, and the day-type fields only apply to frequency options this deployment does not currently surface. The pre-existing `NG0100` reports on this form (`ng-untouched`, and value changes on plain `[(ngModel)]` fields) are unchanged — the form-state class described earlier, advisory rather than enforced. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
