From e1c0c8ce7d6d88496a8966732fab3fc3310fbbd1 Mon Sep 17 00:00:00 2001 From: Animesh Kumar Date: Tue, 20 Oct 2026 09:01:57 +0530 Subject: [PATCH] fix(clients): link client charges, collateral and a new share account from the client page --- e2e/client-accounts.spec.ts | 22 ++++++++++ .../clients/client-view.component.test.ts | 22 ++++++++++ .../features/clients/client-view.component.ts | 41 +++++++++++++++++++ src/assets/i18n/en.json | 1 + src/assets/i18n/fr.json | 1 + src/assets/i18n/hi.json | 1 + src/assets/i18n/ko.json | 1 + 7 files changed, 89 insertions(+) diff --git a/e2e/client-accounts.spec.ts b/e2e/client-accounts.spec.ts index 485089c0a..cff9c8114 100644 --- a/e2e/client-accounts.spec.ts +++ b/e2e/client-accounts.spec.ts @@ -157,3 +157,25 @@ test('empty account tabs offer the matching creation action', async ({ page }, t await loanAction.click(); await expect(page).toHaveURL('/loans/create?clientId=2001'); }); + +test('the client page links to its charges, its collateral and a new share account', async ({ + page, +}) => { + await signIn(page); + await mockClient(page); + + await page.goto(CLIENT_URL); + await page.locator('#clientActionsMenu-trigger').click(); + await page.getByTestId('client-charges-action').click(); + await expect(page).toHaveURL(`/clients/${CLIENT_ID}/charges`); + + await page.goto(CLIENT_URL); + await page.locator('#clientActionsMenu-trigger').click(); + await page.getByTestId('client-collateral-action').click(); + await expect(page).toHaveURL(`/clients/${CLIENT_ID}/collaterals`); + + await page.goto(CLIENT_URL); + await page.locator('#createMenu-trigger').click(); + await page.getByTestId('client-create-share-account').click(); + await expect(page).toHaveURL(`/products/shares/create?clientId=${CLIENT_ID}`); +}); diff --git a/src/app/features/clients/client-view.component.test.ts b/src/app/features/clients/client-view.component.test.ts index 1b0ae6cdc..3dd600bd3 100644 --- a/src/app/features/clients/client-view.component.test.ts +++ b/src/app/features/clients/client-view.component.test.ts @@ -389,6 +389,28 @@ describe('ClientViewComponent', () => { }); }); + describe('client screens reachable from the page', () => { + it('opens the client charges', () => { + component.onViewCharges(); + + expect(routerSpy.navigate).toHaveBeenCalledWith(['/clients', 123, 'charges']); + }); + + it('opens the client collateral', () => { + component.onViewCollateral(); + + expect(routerSpy.navigate).toHaveBeenCalledWith(['/clients', 123, 'collaterals']); + }); + + it('opens a new share account pre-filled with the client', () => { + component.onCreateShare(); + + expect(routerSpy.navigate).toHaveBeenCalledWith(['/products/shares/create'], { + queryParams: { clientId: 123 }, + }); + }); + }); + describe('teardown', () => { it('dismisses popovers when destroyed', () => { const withPopovers = component as unknown as { diff --git a/src/app/features/clients/client-view.component.ts b/src/app/features/clients/client-view.component.ts index 55219a436..f30b25b5f 100644 --- a/src/app/features/clients/client-view.component.ts +++ b/src/app/features/clients/client-view.component.ts @@ -257,6 +257,7 @@ export type ClientTab = (typeof CLIENT_TAB)[keyof typeof CLIENT_TAB]; 'ASSIGNSTAFF_CLIENT', 'UNASSIGNSTAFF_CLIENT', 'UPDATESAVINGSACCOUNT_CLIENT', + 'READ_CLIENTCHARGE', ]" > @@ -442,6 +443,23 @@ export type ClientTab = (typeof CLIENT_TAB)[keyof typeof CLIENT_TAB]; {{ 'ACTIONS.UNDO_WITHDRAW_CLIENT' | appTranslate }} } + + + {{ 'CLIENT_CHARGES.TITLE' | appTranslate }} + + + + {{ 'CLIENT_COLLATERAL.TITLE' | appTranslate }} + @@ -482,6 +500,15 @@ export type ClientTab = (typeof CLIENT_TAB)[keyof typeof CLIENT_TAB]; {{ 'ACTIONS.RECURRING_DEPOSIT' | appTranslate }} + + + {{ 'ACTIONS.SHARE_ACCOUNT' | appTranslate }} + @@ -1615,6 +1642,20 @@ export class ClientViewComponent implements OnInit, OnDestroy { }); } + onCreateShare() { + this.router.navigate(['/products/shares/create'], { + queryParams: { clientId: this.clientId() }, + }); + } + + onViewCharges() { + this.router.navigate(['/clients', this.clientId(), 'charges']); + } + + onViewCollateral() { + this.router.navigate(['/clients', this.clientId(), 'collaterals']); + } + onSavingsTransaction(accountId: number, command: string) { this.router.navigate([`/products/savings-accounts/${accountId}/transactions/${command}`]); } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 9dc92bcfa..f8ddc7217 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -351,6 +351,7 @@ "PREMATURE_CLOSE": "Close before maturity", "REACTIVATE_CLIENT": "Reactivate Client", "RECURRING_DEPOSIT": "Recurring Deposit", + "SHARE_ACCOUNT": "Share Account", "REJECT": "Reject", "REJECTION_DATE": "Rejection Date", "REJECTION_REASON": "Rejection Reason", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 633bbaff6..5aeebd491 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -351,6 +351,7 @@ "PREMATURE_CLOSE": "Clôturer avant l'échéance", "REACTIVATE_CLIENT": "Réactiver le client", "RECURRING_DEPOSIT": "Dépôt périodique", + "SHARE_ACCOUNT": "Compte de parts sociales", "REJECT": "Rejeter", "REJECTION_DATE": "Date de rejet", "REJECTION_REASON": "Motif du rejet", diff --git a/src/assets/i18n/hi.json b/src/assets/i18n/hi.json index 05b1c2fef..cf762dbe3 100644 --- a/src/assets/i18n/hi.json +++ b/src/assets/i18n/hi.json @@ -334,6 +334,7 @@ "PREMATURE_CLOSE": "परिपक्वता से पहले बंद करें", "REACTIVATE_CLIENT": "ग्राहक को पुनः सक्रिय करें", "RECURRING_DEPOSIT": "आवर्ती जमा", + "SHARE_ACCOUNT": "शेयर खाता", "REJECT": "अस्वीकार करें", "REJECTION_DATE": "अस्वीकृति तिथि", "REJECTION_REASON": "अस्वीकृति का कारण", diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index b045dd647..d19d8d4cf 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -225,6 +225,7 @@ "SAVINGS_ACCOUNT": "예금 계좌", "FIXED_DEPOSIT": "정기 예금", "RECURRING_DEPOSIT": "적금", + "SHARE_ACCOUNT": "출자금 계좌", "APPROVE_ACCOUNT": "계좌 승인", "ACTIVATE_ACCOUNT": "계좌 활성화", "CLOSE_ACCOUNT": "계좌 종료",