Aman-Mittal opened a new pull request, #306:
URL: https://github.com/apache/fineract-backoffice-ui/pull/306

   Closes #289. Closes #290. Part of #288.
   
   Both sub-tasks in one PR rather than the two the issues describe: #290 is 
the only consumer of #289, and splitting them would have meant merging a shared 
component with nothing using it.
   
   ## The problem
   
   `accountingRule: 1` (NONE) is hardcoded in all five product forms, and there 
is not one GL-account field anywhere in the application. An institution can 
create its entire product catalogue through this UI and produce no trial 
balance from it.
   
   ## What this adds
   
   A rule selector and a rule-driven GL-account mapping section, wired into the 
loan product form.
   
   **The section is data, not a form.** `product-accounting.model.ts` describes 
a slot as `{request key, response key, account class, label, the rules that 
require it}`, and `ProductAccountingSectionComponent` renders whatever list it 
is handed. Savings, deposit and share products differ only in their list — 
which is what the four remaining sub-tasks of #288 need from this one.
   
   Both components live in `src/app/features/products/accounting/` rather than 
`shared/`, per the note on #289. They are shaped entirely by the product 
template response — option lists, rule labels, slot names — and nothing outside 
products has a use for them.
   
   **Filtering each picker by account class is not cosmetic.** Pointing a slot 
at the wrong class is refused outright:
   
   ```
   403 validation.msg.domain.rule.violation
   Passed in GLAccount fundSourceAccountId with Id 5 maps to the account
   Probe INC of type INCOME, the expected account type was ASSET
   ```
   
   So the class a slot expects is what lets the picker offer only accounts that 
will work.
   
   ## Where the slot list came from
   
   Not from documentation. Posting a product with a rule and no mappings 
answers 400 naming every missing parameter, which enumerates the mandatory set 
exactly:
   
   ```
   POST /loanproducts {"accountingRule": 2, …no mapping ids…}
   → fundSourceAccountId, loanPortfolioAccountId, transfersInSuspenseAccountId,
     interestOnLoanAccountId, incomeFromFeeAccountId, 
incomeFromPenaltyAccountId,
     incomeFromRecoveryAccountId, writeOffAccountId, 
overpaymentLiabilityAccountId
   ```
   
   Cash requires those nine; both accrual rules require them plus 
`receivableInterestAccountId`, `receivableFeeAccountId`, 
`receivablePenaltyAccountId`. That is where `incomeFromRecoveryAccountId` came 
from — reading the ordinary repayment story would have missed it, and the issue 
text I wrote listed eight.
   
   Selections are held beside the request object and merged in at submit, so 
slots a rule does not have are never sent: `NONE` sends no mapping keys at all, 
and switching accrual → cash does not leak the receivables.
   
   The template omits an option list entirely when the tenant has no accounts 
of that class — a fresh install has none — so the section says so instead of 
rendering empty dropdowns.
   
   ## Three pre-existing defects found on the way
   
   All in the same submit path. The edit round-trip #290 asks for cannot pass 
without the first two, which is how they surfaced.
   
   | | |
   |---|---|
   | `enableAutoRepaymentForDownPayment: false` sent alongside 
`enableDownPayment: false` | Create tolerates the pair; **update refuses it**. 
Every loan product without down payment was unsaveable from the edit screen. |
   | `chargeOffBehaviour` bound to the option's `code` 
(`chargeOffBehaviour.regular`) where the platform accepts its `id` (`REGULAR`) 
| Choosing one answered `validation.msg.enum.value.not.found` — on **create** 
as well as edit. |
   | The edit path dropped accounting entirely | A configured product opened 
and saved would have gone back with nothing mapped once the rule changed. |
   
   ## Verifying it
   
   `e2e/loan-product-accounting.spec.ts` is the test that decides whether this 
works. Against a real platform it creates the four GL accounts **through the 
chart of accounts screen**, configures a cash-accounting product, reopens it, 
and proves the mappings survive an unrelated edit. No API seeding — the chart 
of accounts is where a tenant that cannot configure accounting actually gets 
stuck, so skipping it would skip the step that matters.
   
   | | |
   |---|---|
   | `loan-product-accounting.spec.ts` (real backend) | passed |
   | Full unit suite | 865 passed |
   | `product-accounting-section.component.spec.ts` | 13 new |
   | `loan-product-form.component.spec.ts` | 33 (10 new) |
   | `npm run lint`, `npm run i18n:check`, `npm run build`, `tsc` | clean |
   
   ## Not in this PR
   
   Savings (#291), deposit (#292), share (#293) and the advanced mappings 
(#294). The savings slot set is already probed — seven, and 
`interestOnSavingsAccount` is an expense rather than income — but each family 
needs its own verification pass against the platform, and this PR is already 
the size of one review.
   


-- 
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]

Reply via email to