Aman-Mittal opened a new pull request, #800: URL: https://github.com/apache/fineract-backoffice-ui/pull/800
Closes #770, closes #771, closes #772, closes #777. ## What and why Four of the eight open Working Capital issues. #773, #774, #775 and #776 are untouched and stay open. ### RBAC (#777) Every action route was gated on `UPDATE_WORKINGCAPITALLOAN` and every action button on the loan screen was rendered with no check at all. Fineract authorises each Working Capital command with its own code, and `UPDATE_WORKINGCAPITALLOAN` authorises none of them — the same defect term loans had in #691, so it failed in both directions: an approver holding `APPROVE_WORKINGCAPITALLOAN` was sent to `/forbidden`, while a user with only read access was still offered Approve, Disburse, Delete, Waive charge and the rest, each of which could only ever answer 403. `WC_LOAN_COMMAND_PERMISSIONS` now resolves the code from the `:command` segment, exactly as `LOAN_COMMAND_PERMISSIONS` does for term loans, and the charge, breach, near-breach and delinquency routes carry their own codes instead of the portfolio one. Every write control on the loan screen is gated — disabled with the missing code named, which is the shape this codebase uses for an action on the record already on screen. The two icon-only row actions (waive a charge, detach an originator) are **removed** rather than disabled. `appRequiresPermission` owns `attr.aria-label` to carry its explanation, so on a control whose only accessible name *is* an aria-label it erases that name the moment it grants. That is a latent limitation of the shared directive rather than something specific to this screen; worth fixing there separately, and noted here so the asymmetry is not read as an oversight. No code was guessed. The module documents the pairing endpoint by endpoint, and all 39 Working Capital codes are present in `scripts/permission-codes.json` — the catalogue snapshot `check-permission-codes.mjs` enforces. ### Modifying a submitted application (#770) **Edit** navigated to `loans/edit/:id`, which the route table did not declare, so it fell through to the wildcard. The route is added and serves `wc-loan-form` in edit mode: Fineract's `PUT` body is the `POST` body, so a separate screen for the same fields would be two places to change whenever the application shape does. It sends only the fields the user changed — `PUT` is a modification command and audits whatever it is handed, so posting the whole form back would log every field as modified on every save — and it withholds the form until the prefill arrives, rather than filling bindings that have already been checked (an `NG0100` in development, an inconsistent first paint in production, and an empty form that fills itself a moment later for the user). ### The missing transactions (#771, #772) Repayment was the only transaction the UI could post. Added, each offered only in a status the platform accepts it in: **prepay**, **goodwill credit**, **payout refund**, **credit balance refund**, **charge-off** and its undo, **write-off** and its undo, and **recovery payment**. - Defaults come from `GET …/transactions/template?command=…`. The payoff figure and the still-recoverable amount are the platform's own numbers — the template caps a recovery at `totalWrittenOff - totalRecovered`, so the figure it offers is one the API will accept where the gross written-off amount would be rejected. - Each request carries only the fields its command takes, because Fineract rejects a request with a parameter the command does not support: a stray amount left over from another branch of the form would turn a valid undo into a 400. - Write-off reasons come from the **product** template, which is where Fineract assembles `writeOffReasonOptions`; the transaction template carries only the charge-off ones. Without `READ_WORKINGCAPITALLOANPRODUCT` the reason list is simply absent, and the write-off still posts, because the reason is optional. - `prepay` posts `command=repayment`: Fineract has no prepay command, and a prepayment is a repayment — which is also why it maps to `REPAYMENT_WORKINGCAPITALLOAN` rather than a code of its own. - Status gates follow the module's documentation: a charge-off is a non-monetary tag that leaves the loan `ACTIVE`, while a written-off loan is locked to everything but a recovery payment, and undoing the write-off is refused while any recovery stands. ## Verification - `npm test` — 2151 unit tests pass across 299 files; working-capital is 102 tests, up from 70. New coverage: the command-to-code map including each undo being separable from the action it reverses, the edit-mode prefill and changed-fields-only `PUT`, each transaction command's posted command and body, and the permission gating (an approver without `UPDATE` can approve; a read-only user has no enabled write control). - `npx playwright test --project=mocked e2e/working-capital-loan-actions.spec.ts` — 17/17 pass, covering each new command's `command` query parameter, the state-dependent menu, the edit route end to end and a read-only role's disabled controls. Two pre-existing tests in that file failed on this branch until the gating was corrected, and pass now. - `check-route-permissions`, `check-permission-codes`, `check-api-surface`, `check-icons`, `check-a11y-names`, `check-ui-primitives`, `check-template-text`, `check-responsive`, `check-nav-ids`, `check-translations`, `prettier --check`, `eslint` (no new suppressions) and `typecheck:e2e` all pass. Hindi stays at 100% coverage, reusing the wording already established for the term-loan equivalents. Not verified against a live backend: these endpoints are recent-Fineract-only, which is why this spec is mocked, as the file's header already notes. ## Screenshots Not applicable — no new screens; the loan screen gains menu entries and the existing application form gains an edit mode. ## Checklist - [x] I did not hand-edit generated files under `frontend/src/openapi-client/` (nor `src/app/api/`; `api-surface.json` was regenerated with `check-api-surface.mjs --write`). - [x] Backend code follows the feature and CQRS layout in AGENTS.md — not applicable, this is frontend-only; the new map sits beside the existing ones in `core/guards/`. - [x] I did not add entries to a lint or architecture baseline. - [x] User-facing strings use translation keys (14 new keys, `en` and `hi`). - [x] I added or updated tests appropriate to this change. - [x] UI workflow changes include suitable e2e coverage, including real-backend testing where relevant — mocked here, for the reason above. - [x] Commits are signed. - [x] I followed the AI-assisted contributions guidance. - [x] These are bug fixes and the UI side of endpoints the platform already exposes, raised as issues #770–#777 before this change. -- 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]
