Aman-Mittal opened a new pull request, #276:
URL: https://github.com/apache/fineract-backoffice-ui/pull/276
Closes #272, closes #273, closes #274.
## What this does
The platform advertises twelve client commands — sending an unrecognised one
makes it list them:
```
POST /clients/2?command=totallyNotACommand
→ 400 args:
["activate","unassignStaff","assignStaff","close","proposeTransfer",
"withdrawTransfer","acceptTransfer","rejectTransfer",
"updateSavingsAccount","reject","withdraw","reactivate"]
```
The client detail view implemented five of them. This adds the seven that
were missing, plus the one-step `proposeAndAcceptTransfer`, and fixes two menu
items that could never have worked.
**Transfers (#272)** are the substantial part. `proposeTransfer` moves a
client to *Transfer in progress* while leaving them at the source office; the
destination branch then accepts or rejects. That handshake is the control that
stops one branch pushing delinquent accounts onto another. Without any of it, a
member who moves branch has to be closed and re-created — which severs their
loan and savings history and makes them look new to credit assessment.
**Staff assignment and the default savings account (#274)** were reachable
only at onboarding. A staff departure or a book reassignment could not be
recorded, so the collection sheet kept routing clients to an officer who may
have left.
**Undo Rejection / Undo Withdrawal (#273)** posted `command=undoReject` and
`command=undoWithdraw`. The platform answers `400 "unsupported value"` and
never reaches the payload, so both menu items were dead — a mistakenly rejected
application could never be reopened, and the workaround was a duplicate client
record.
## The bodies were probed, not inferred
Every command was run against a running instance before any of this was
written, including a full propose → accept round trip and each refusal path.
They disagree with each other in ways that only surface at runtime:
| Command | Body | Refuses |
|---|---|---|
| `proposeTransfer` | `{locale, dateFormat, destinationOfficeId,
transferDate, note?}` | — |
| `acceptTransfer` | `{note?}` | `locale`, `dateFormat`, **`transferDate`** |
| `rejectTransfer` | `{note?}` | — |
| `withdrawTransfer` | `{note?}` | — |
| `proposeAndAcceptTransfer` | `{destinationOfficeId, note?}` |
**`transferDate`** |
| `assignStaff` | `{staffId}` | `locale`, `dateFormat` |
| `unassignStaff` | `{staffId}` | — (**the id is mandatory even to remove
it**) |
| `updateSavingsAccount` | `{savingsAccountId}` | `locale`, `dateFormat` |
Two consequences worth calling out in review:
- The transfer answers get **their own dialog** rather than reusing
`ClientActionDialogComponent`, which always collects a date. Routing them
through it would send `transferDate`, `locale` and `dateFormat` and earn a 400
on all three.
- `withdrawTransfer` is offered from **both** pending states. A rejected
transfer leaves the client *Transfer on hold* at the source office, and this
command is the only way back to Active — verified from both states.
## Notes for review
`GetClientsClientIdResponse` describes neither `staffId`/`staffName` nor
`savingsAccountId`, and `PostClientsClientIdRequest` covers only the
activate/reject/withdraw/close family. The spec is regenerated from upstream on
a schedule (ADR-0002) and is not edited by hand, so the shapes the platform
actually sends are declared in `client-servicing.model.ts` with the reasoning
attached — the same approach taken for the loan fields in #269.
New components go through the adapter boundary (ADR-0003): `OVERLAY` and
`TranslatePipe`, with `DialogService.confirm()` for the unassign confirmation.
## Testing
- **17 unit tests** (`client-view.servicing.spec.ts`) asserting the **exact
body** posted for each command, not merely that something was posted —
including that `proposeAndAcceptTransfer` carries no `transferDate`, that
`acceptTransfer` sends `{}` when the note is blank, and that `unassignStaff`
echoes the current holder back.
- **15 mocked e2e tests** (`client-servicing-gaps.spec.ts`) driving the same
assertions through the UI, plus the negatives: transfer answers are not offered
when none is pending, accept/reject disappear once a transfer is on hold, and
the client's own office is not offered as a destination.
- A backend e2e round trip is following in a second commit on this branch.
Local gates: `lint`, HTML lint, `format:check`, `i18n:check`, `check:icons`
and the production build all pass. `check:icons` caught `git-compare-outline`
as unregistered, which is now added to `APP_ICONS`.
--
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]