Repository navigation
Deposit and Withdraw on a term deposit account navigate to routes that do not exist #279
Description
Business value
The account view shared by fixed and recurring deposits offers two actions, and neither reaches a screen.
src/app/features/products/deposit-account-view.component.ts:367-375:
onDeposit(): void {
this.router.navigate([`/products/recurring-deposits/${this.accountId}/transactions/deposit`]);
}
onWithdraw(): void {
const type = this.isRD ? 'recurring-deposits' : 'fixed-deposits';
this.router.navigate([`/products/${type}/${this.accountId}/transactions/withdrawal`]);
}The only transaction routes declared in src/app/features/products/products.routes.ts are:
fixed-deposits/:accountId/transactions (:345)
recurring-deposits/:accountId/transactions/create (:352)
So there are two separate defects:
- Neither target exists.
.../transactions/depositand.../transactions/withdrawalare not declared for either product, so both buttons fall through to the catch-all and the user is bounced to the dashboard, losing the account they were on. onDepositignoresisRD. On a fixed deposit account it still builds arecurring-depositsURL. Even once a route exists, this sends the user to the wrong product family.
The practical effect is that a term deposit account, once opened, can never be transacted against from the UI. For an institution offering fixed or recurring deposits, that is the whole product.
Reproducing it
Open any fixed or recurring deposit account and press Deposit or Withdraw. You land on the dashboard.
grep -n "transactions" src/app/features/products/products.routes.ts
grep -n "onDeposit\|onWithdraw" src/app/features/products/deposit-account-view.component.ts
Describing the change
Route the two actions at a screen that exists, and respect the account type.
The recurring-deposit transaction form is already built (recurring-deposit-transactions/recurring-deposit-transaction-form.component.ts) and routed at recurring-deposits/:accountId/transactions/create. The fixed-deposit side has a transactions list but no form.
A reasonable shape, and the one the savings screens already use — see savings-account-view.component.ts:735:
onTransaction(command: string) {
this.router.navigate([`/products/savings-accounts/${this.accountId}/transactions/${command}`]);
}so a :command segment carrying deposit or withdrawal, with the form reading it from the route.
Two things to be careful about.
- Derive the product family from
isRDin both handlers, not justonWithdraw. The bug inonDepositis a one-character-class fix but it is the kind that comes back; a single private helper returning the prefix is better than repeating the ternary. - The recurring-deposit form currently cannot save — it omits the
commandquery parameter the platform requires, so every submission 400s. That is issue A recurring deposit transaction can never be saved — the form omits the command the platform requires #278. Please do not fix it here; the two changes will conflict. If you want the whole flow working end to end, say so on both issues and take them together.
If wiring a fixed-deposit transaction form is more than you want to take on, fixing only the routing and the isRD bug is a complete and useful contribution — say so in the PR and leave the FD form to a follow-up.
Testing
The platform's own acceptance tests give the required order. From fineract-e2e-tests-runner/src/test/resources/features/SavingsAccount.feature in apache/fineract (develop), scenario C2438:
And Client creates a new EUR savings account with "1 June 2022" submitted on date
And Approve EUR savings account on "1 June 2022" date
And Activate EUR savings account on "1 June 2022" date
And Client successfully deposits 1000 EUR to the savings account on "1 June 2022" dateNote that approve and activate come first — a deposit to a pending account is refused, so any test must walk the account through its lifecycle rather than jumping to the transaction.
What to write:
- A unit spec on
deposit-account-view.component.tsasserting the URL each handler navigates to, for bothisRD === trueandisRD === false. Four assertions. TheisRDbug is invisible unless you test both branches. - A mocked e2e that opens a deposit account, clicks Deposit, and asserts the resulting URL matches the transaction route —
await expect(page).toHaveURL(/\/transactions\//). Today this fails with/dashboard.
One trap worth knowing about, from an earlier e2e in this repo: list rows are inert. The routerLink lives on the name cell, so row.click() does nothing and the test sits on the list until it times out. Click the link inside the row:
await row.getByRole('link').first().click();Scope
In scope: the two handlers, the missing route declarations, and the isRD bug.
Out of scope: the missing command parameter (#278), and any change to the transaction form's fields.
Getting started
- Routes:
src/app/features/products/products.routes.ts - View:
src/app/features/products/deposit-account-view.component.ts npm test,npm run lint:pruneandnpm run buildmust pass.npm run e2e:stackbrings up a platform if you want to click through it.
Activity
LE0-Lin commentedon Sep 4, 2026
Hi, I'd like to work on the scoped routing fix. I'll correct the deposit and withdrawal routes for both fixed and recurring deposit accounts, preserve the product-family branching, and add focused regression tests for all four navigation paths. I'll keep the unrelated transaction-form submission issue out of scope.
LE0-Lin commentedon Sep 4, 2026
Update after checking the current main branch: the original routing defects have already been resolved across merged PRs #341 and #335. #341 adds the fixed-deposit transaction form and route, routes deposits by product type, and deliberately hides withdrawal for fixed deposits because Fineract rejects that command; #335 makes the recurring-deposit command route-driven. I am therefore withdrawing my claim rather than submitting a duplicate or re-exposing an unsupported fixed-deposit withdrawal. This issue appears ready to close.