Aman-Mittal opened a new pull request, #375:
URL: https://github.com/apache/fineract-backoffice-ui/pull/375
## Summary
Closes the functional gaps between this application and the platform it
drives: screens for
things Fineract supports that had no screen here at all, and two defects the
work uncovered.
Every contract in this PR was verified against a running
`apache/fineract:latest`
(`1.15.0-303-gf4f927e`, built 2026-08-15) before it was written. Where the
platform refused, that
is reported below rather than worked around.
## What was added
**Accounting** — the ledger could not be operated without these.
| Screen | Endpoint |
|---|---|
| Journal entry detail, with reversal | `GET /journalentries/{id}`, `POST
/journalentries/{transactionId}?command=reverse` |
| Define opening balances | `GET /journalentries/openingbalance`, `POST
/journalentries?command=defineOpeningBalance` |
| Frequent postings | `GET /accountingrules`, `POST /journalentries` |
A posting made here could not be reversed here. The detail screen loads the
clicked line together
with its siblings — one line never balances on its own — and offers reversal
only where the
platform accepts it: manual entries that are not already reversed.
**Administration**
- **Report definitions** (`/system/report-definitions`) — reports could be
run but never created,
edited or retired. Core reports are a platform-enforced special case: the
database refuses to
delete one and refuses every field but "in use" on update, so a core
report opens read-only with
that single toggle rather than as a form whose fields silently fail to
save.
- **Office detail view** — offices had a list and a form but no record
screen, so a data table
registered against `m_office` had nowhere to be read or written.
- **Approval queues** (`/tasks/work-queues`) — pending loans, loans awaiting
disbursal, pending
clients and pending reschedule requests, actioned together through `POST
/batches`.
**Portfolio screens**
- Savings accounts gain notes, documents, standing instructions and custom
fields; groups gain
their accounts, documents and custom fields; clients gain share accounts
and standing
instructions.
- Notes and documents are one templated endpoint each, so the loan-only
copies are now shared
components taking the entity as an input. A per-entity copy is exactly how
the savings account
ended up without either.
## Defects fixed
**A fixed deposit opened the savings account screen.** Fineract returns
savings, fixed deposits and
recurring deposits in one `savingsAccounts` array, told apart only by
`depositType.id`. The client
screen listed all three as savings and linked every one to
`/products/savings-accounts/view`, so
opening a term deposit showed the wrong screen and offered savings actions
against it. The type ids
(100, 200, 300) were confirmed by opening one of each against a running
platform.
**NG0100 on every visit to a loan.** The loan edit form logged
`ExpressionChangedAfterItHasBeenChecked` each time an existing loan was
opened — the record arrives
after the view is created and `[(ngModel)]` writes back in a microtask. The
form now waits for its
record, which also stops an edit form flashing empty defaults over a real
loan. The e2e harness then
caught the new report form repeating the same pattern, fixed the same way.
## Platform behaviour worth knowing
These are the platform's own spellings, and getting either wrong is an error
rather than an empty
list:
- `GET /loans?status=` wants the **numeric** status id and answers 500 with a
`NumberFormatException` if given the display name.
- `GET /clients?status=` wants the **lowercase name** and rejects the
numeric id with a 400.
- `accountingRuleId` is declared in the specification but the running
platform answers
*"The parameter accountingRuleId is not supported"*, so frequent postings
expands the rule into
the debit and credit lines the endpoint does accept.
- `GET /groups/{id}/accounts` **omits** empty collections rather than
returning them empty.
- The share account list returns only approved and active accounts; a
pending application is
readable by id but absent from the list.
- Notes on a savings account live under `savings`, not `savingsaccounts`.
## Not implemented, and why
Three items in scope turned out to be blocked by the platform on PostgreSQL,
verified against the
latest image. No screen was shipped for them, because a screen for any of
them could only fail.
| Item | What the platform does |
|---|---|
| GLIM (group loan individual monitoring) | Creation fails: `null value in
column "principal_amount" of relation "glim_accounts" violates not-null
constraint`. `clientMembers` is rejected as unsupported, so there is no other
payload to try. |
| GSIM (group savings individual monitoring) | Accepts the request and
answers `gsimId: 0`; no parent record is formed and `GET
/groups/{id}/gsimaccounts` stays empty. |
| Centre collection sheet | `POST
/centers/{id}?command=generateCollectionSheet` answers 500: `operator does not
exist: boolean = integer` — the query compares `completed_derived` to `0`. |
The individual collection sheet, which this application already has, is
unaffected and its
`generate` / `save` commands are the ones this backend accepts.
## Testing
| Layer | Result |
|---|---|
| Unit | 1091 SUCCESS (1057 before) |
| E2E — new screens, real Fineract | 9 passed |
| E2E — full suite | running as this opens; the number goes here when it
lands |
| Build | passes |
| lint:prune, format, i18n, route permissions, typecheck:e2e, licence | pass
|
| `api:surface` | manifest updated: 9 operations added, none removed |
| `ga:check` | 8/9, **0 blocking**; adapter backlog falls 420 → 416 |
The backend spec is the one that matters here: each case seeds a real
record, drives the UI, then
asks the platform whether it happened. The reversal is confirmed by reading
the transaction back
rather than by trusting the badge on screen.
## Also in here
**Tabs are named rather than numbered.** Twelve screens addressed their tabs
as `'0'` through
`'16'`. A bare number says nothing at the point of use, and inserting a tab
in the middle silently
changes what every later number means — which is exactly what this PR does
to the client and
savings screens. Each screen now declares a named constant and a union type,
and the loan screen's
map of conditionally-available tabs is keyed the same way, where `'7'` and
`'12'` were doing real
work with no clue which tabs they were.
**Share accounts load with their tab.** Firing that request on load added
one to every client
screen, and a tenant without the shares module got an error toast for it
each time — which the
mocked e2e run surfaced. It now loads once, when the tab is first opened,
with the toast
suppressed.
## Breaking changes
None. Two routes changed meaning for the better: a client's fixed and
recurring deposits now open
the deposit screens instead of the savings screen.
--
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]