From 9f7d9d28fd07923910696785054efc2815e751c5 Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Sun, 4 Oct 2026 09:12:06 +0530 Subject: [PATCH] feat: Fixed Deposit - premature close, payment dialog, account actions, translations and env updates --- .../payment-dialog.component.ts | 13 ++- .../premature-close-dialog.component.html | 18 ++++- .../premature-close-dialog.component.ts | 80 ++++++++++++++++--- .../fixed-deposit-account-view.component.ts | 13 ++- ...pprove-fixed-deposits-account.component.ts | 38 ++++++--- .../close-fixed-deposits-account.component.ts | 18 ++++- ...reject-fixed-deposits-account.component.ts | 19 ++++- ...proval-fixed-deposits-account.component.ts | 26 +++++- ...client-fixed-deposits-account.component.ts | 13 ++- src/assets/env.js | 2 +- src/assets/translations/en-US.json | 1 + src/environments/.env.ts | 2 +- src/environments/environment.prod.ts | 2 +- src/environments/environment.ts | 2 +- 14 files changed, 205 insertions(+), 42 deletions(-) diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/payment-dialog/payment-dialog.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/payment-dialog/payment-dialog.component.ts index d481a87bf..521656fa8 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/payment-dialog/payment-dialog.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/payment-dialog/payment-dialog.component.ts @@ -24,6 +24,7 @@ import { UntypedFormBuilder, UntypedFormGroup, UntypedFormControl, ValidatorFn, /** Custom Services */ import { FixedDepositsService } from '../../../fixed-deposits.service'; import { SettingsService } from 'app/settings/settings.service'; +import { AlertService } from 'app/core/alert/alert.service'; import { Dates } from 'app/core/utils/dates'; import { FormatNumberPipe } from '../../../../../pipes/format-number.pipe'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -97,6 +98,7 @@ export class PaymentDialogComponent implements OnInit { private fixedDepositsService = inject(FixedDepositsService); private settingsService = inject(SettingsService); private dateUtils = inject(Dates); + private alertService = inject(AlertService); paymentForm: UntypedFormGroup; /** Loaded once, on open, from the same closure template the existing Close action already uses. */ @@ -375,7 +377,16 @@ export class PaymentDialogComponent implements OnInit { this.fixedDepositsService .executeFixedDepositsAccountCommand(this.data.accountId as string, 'payment', data) .subscribe({ - next: () => { + next: (response: any) => { + // Parked in the Checker Inbox rather than executed -- see the same handling in + // PrematureCloseDialogComponent for why an HTTP 200 here can still mean "not applied yet". + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'This payment has been submitted for approval. The deposit is unchanged until a checker approves it.' + }); + } this.dialogRef.close({ confirm: true }); }, // Keep the dialog open with the entered values and say what went wrong, rather than leaving a diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.html b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.html index 00f425f6e..cc6736b60 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.html +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.html @@ -140,7 +140,9 @@ Interest Earned (to {{ 'labels.inputs.Premature Close Date' | translate }}) - + {{ interestEarned | formatNumber }} + {{ interestEarned >= 0 ? '+' : '' }} {{ interestEarned | formatNumber }} }
@@ -205,8 +207,8 @@ @if (noDestinationAccounts) { } @@ -229,6 +231,16 @@ } + @if (prematureCloseForm.contains('toGlAccountId')) { + + + } + @if (prematureCloseForm.contains('transferDescription')) { {{ 'labels.inputs.Transfer Description' | translate }} diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.ts index fbb1dab00..f24a480c5 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/custom-dialogs/premature-close-dialog/premature-close-dialog.component.ts @@ -23,13 +23,19 @@ import { UntypedFormBuilder, UntypedFormGroup, UntypedFormControl, Validators } /** Custom Services */ import { FixedDepositsService } from '../../../fixed-deposits.service'; import { SettingsService } from 'app/settings/settings.service'; +import { AccountingService } from 'app/accounting/accounting.service'; +import { AlertService } from 'app/core/alert/alert.service'; import { Dates } from 'app/core/utils/dates'; import { FormatNumberPipe } from '../../../../../pipes/format-number.pipe'; +import { GlAccountSelectorComponent } from 'app/shared/accounting/gl-account-selector/gl-account-selector.component'; +import { GLAccount } from 'app/shared/models/general.model'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; /** * "Premature Close" dialog -- Active-only, no reinvest option (the deposit hasn't matured, so there's - * nothing to renew): pay out in cash, or transfer the pre-maturity balance to a savings account. Same + * nothing to renew): transfer the pre-maturity balance to a savings account, or post it to a GL account. + * There is deliberately no cash payout -- the backend does not offer or accept one for a premature + * closure, so the proceeds always stay traceable to an account. Same * `.pcd__*` visual language as the Payment dialog ({@link PaymentDialogComponent}), in this Danger Zone * action's own red accent rather than Payment's blue, since it's an irreversible, usually * penalty-bearing action rather than a routine one. @@ -49,22 +55,26 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; MatDialogClose, CdkTextareaAutosize, FaIconComponent, - FormatNumberPipe + FormatNumberPipe, + GlAccountSelectorComponent ] }) export class PrematureCloseDialogComponent implements OnInit { /** The `onAccountClosureId` codes Premature Close can offer -- same codes Payment/Close use. */ private static readonly WITHDRAW_DEPOSIT_ID = 100; private static readonly TRANSFER_TO_SAVINGS_ID = 200; + private static readonly TRANSFER_TO_GL_ID = 600; private static readonly ACTION_ICONS: Record = { [PrematureCloseDialogComponent.WITHDRAW_DEPOSIT_ID]: 'money-bill-wave', - [PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID]: 'wallet' + [PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID]: 'wallet', + [PrematureCloseDialogComponent.TRANSFER_TO_GL_ID]: 'book' }; private static readonly ACTION_DESCRIPTIONS: Record = { [PrematureCloseDialogComponent.WITHDRAW_DEPOSIT_ID]: 'Pay out the full balance in cash', - [PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID]: 'Move the full balance to another savings account' + [PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID]: 'Move the full balance to another savings account', + [PrematureCloseDialogComponent.TRANSFER_TO_GL_ID]: 'Post the full balance to a GL account' }; /** @@ -108,11 +118,15 @@ export class PrematureCloseDialogComponent implements OnInit { private formBuilder = inject(UntypedFormBuilder); private fixedDepositsService = inject(FixedDepositsService); private settingsService = inject(SettingsService); + private accountingService = inject(AccountingService); + private alertService = inject(AlertService); private dateUtils = inject(Dates); prematureCloseForm: UntypedFormGroup; onAccountClosureOptions: any[] = []; savingsAccountsData: any[] = []; + /** Postable GL accounts, loaded once -- only read when the GL action is chosen. */ + glAccountsData: GLAccount[] = []; maturityAmount: number = null; /** The rate actually resolved for THIS preview by the backend (actual-period vs contracted, * penalty-deducted or not) -- distinct from data.nominalAnnualInterestRate, which is always the @@ -228,19 +242,50 @@ export class PrematureCloseDialogComponent implements OnInit { }); } - /** Adds/removes the destination-account control to match what the chosen type needs. */ + /** Adds/removes the destination control to match what the chosen type needs. */ private onClosureTypeChange(id: number): void { - if (id === PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID) { - if (!this.prematureCloseForm.contains('toSavingsAccountId')) { - this.prematureCloseForm.addControl('toSavingsAccountId', new UntypedFormControl('', Validators.required)); - this.prematureCloseForm.addControl('transferDescription', new UntypedFormControl('')); - } - } else { + const toSavings = id === PrematureCloseDialogComponent.TRANSFER_TO_SAVINGS_ID; + const toGl = id === PrematureCloseDialogComponent.TRANSFER_TO_GL_ID; + + if (toSavings && !this.prematureCloseForm.contains('toSavingsAccountId')) { + this.prematureCloseForm.addControl('toSavingsAccountId', new UntypedFormControl('', Validators.required)); + } else if (!toSavings) { this.prematureCloseForm.removeControl('toSavingsAccountId'); + } + + if (toGl) { + if (!this.prematureCloseForm.contains('toGlAccountId')) { + this.prematureCloseForm.addControl('toGlAccountId', new UntypedFormControl('', Validators.required)); + } + this.loadGlAccounts(); + } else { + this.prematureCloseForm.removeControl('toGlAccountId'); + } + + // Both destinations carry the description through -- to the account transfer, or to the narration on + // the journal entry that credits the GL account. + if ((toSavings || toGl) && !this.prematureCloseForm.contains('transferDescription')) { + this.prematureCloseForm.addControl('transferDescription', new UntypedFormControl('')); + } else if (!toSavings && !toGl) { this.prematureCloseForm.removeControl('transferDescription'); } } + /** Fetched on first use rather than with the dialog, since most closures never pick the GL action. */ + private loadGlAccounts(): void { + if (this.glAccountsData.length) { + return; + } + this.accountingService.getGlAccounts().subscribe((accounts: GLAccount[]) => { + this.glAccountsData = accounts ?? []; + }); + } + + /** The GL selector takes a control instance, not a control name. */ + get toGlAccountControl(): UntypedFormControl { + return this.prematureCloseForm.get('toGlAccountId') as UntypedFormControl; + } + /** The gap between the deposit and the computed maturity amount -- the actual interest this premature * closure earns, at whatever rate (contracted, or the lower pre-closure-penalty one below) applied. */ get interestEarned(): number | null { @@ -373,7 +418,18 @@ export class PrematureCloseDialogComponent implements OnInit { this.fixedDepositsService .executeFixedDepositsAccountCommand(this.data.accountId as string, 'prematureClose', data) .subscribe({ - next: () => { + next: (response: any) => { + // A command on a maker-checker permission is parked in the Checker Inbox, not executed: + // the platform rolls its transaction back and still answers HTTP 200 with + // rollbackTransaction: true. Without saying so, the dialog closes and the account reloads + // unchanged -- which reads as "nothing happened" rather than "waiting for approval". + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'Premature closure has been submitted for approval. The deposit is unchanged until a checker approves it.' + }); + } this.dialogRef.close({ confirm: true }); }, // Keep the dialog open with the entered values and say what went wrong, rather than leaving a diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts index 9ebae159f..088e31ec2 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts @@ -30,6 +30,7 @@ import { AccountsService } from 'app/accounts/accounts.service'; import { Currency } from 'app/shared/models/general.model'; import { SettingsService } from 'app/settings/settings.service'; import { Dates } from 'app/core/utils/dates'; +import { AlertService } from 'app/core/alert/alert.service'; import { AuthenticationService } from '../../../core/authentication/authentication.service'; import { MatTooltip } from '@angular/material/tooltip'; import { NgClass, CurrencyPipe } from '@angular/common'; @@ -74,6 +75,7 @@ import { DormancyAlertPanelComponent } from 'app/shared/dormancy-alert-panel/dor export class FixedDepositAccountViewComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); + private alertService = inject(AlertService); private fixedDepositsService = inject(FixedDepositsService); private savingsService = inject(SavingsService); private accountsService = inject(AccountsService); @@ -419,7 +421,16 @@ export class FixedDepositAccountViewComponent implements OnInit { if (response.confirm) { this.fixedDepositsService .executeFixedDepositsAccountCommand(this.fixedDepositsAccountData.id, 'postInterest', {}) - .subscribe(() => { + .subscribe((commandResponse: any) => { + // Parked in the Checker Inbox rather than executed (HTTP 200 with + // rollbackTransaction: true), so the reload below shows no new interest posting. + if (commandResponse?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'Interest posting has been sent for checker approval. No interest is posted until a checker approves it.' + }); + } this.reload(); }); } diff --git a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/approve-fixed-deposits-account/approve-fixed-deposits-account.component.ts b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/approve-fixed-deposits-account/approve-fixed-deposits-account.component.ts index a517f98b5..9ae78708e 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/approve-fixed-deposits-account/approve-fixed-deposits-account.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/approve-fixed-deposits-account/approve-fixed-deposits-account.component.ts @@ -11,6 +11,7 @@ import { Component, OnInit, inject } from '@angular/core'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { Dates } from 'app/core/utils/dates'; +import { AlertService } from 'app/core/alert/alert.service'; /** Custom Services */ import { FixedDepositsService } from 'app/deposits/fixed-deposits/fixed-deposits.service'; @@ -37,6 +38,7 @@ export class ApproveFixedDepositsAccountComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); private settingsService = inject(SettingsService); + private alertService = inject(AlertService); /** Minimum date allowed. */ minDate = new Date(2000, 0, 1); @@ -98,17 +100,31 @@ export class ApproveFixedDepositsAccountComponent implements OnInit { dateFormat, locale }; - this.fixedDepositsService.executeFixedDepositsAccountCommand(this.accountId, 'approve', data).subscribe(() => { - const activationData = { - activatedOnDate: approveFixedDepositsAccountFormData.approvedOnDate, - dateFormat, - locale - }; - this.fixedDepositsService - .executeFixedDepositsAccountCommand(this.accountId, 'activate', activationData) - .subscribe(() => { + this.fixedDepositsService + .executeFixedDepositsAccountCommand(this.accountId, 'approve', data) + .subscribe((response: any) => { + // Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true). + // The account is therefore still pending, so chaining activation onto it would be applied to an + // unapproved account -- stop here and say what is actually waiting. + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'This approval has been sent for checker approval. The account stays pending until a checker approves it.' + }); this.router.navigate(['../../'], { relativeTo: this.route }); - }); - }); + return; + } + const activationData = { + activatedOnDate: approveFixedDepositsAccountFormData.approvedOnDate, + dateFormat, + locale + }; + this.fixedDepositsService + .executeFixedDepositsAccountCommand(this.accountId, 'activate', activationData) + .subscribe(() => { + this.router.navigate(['../../'], { relativeTo: this.route }); + }); + }); } } diff --git a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/close-fixed-deposits-account/close-fixed-deposits-account.component.ts b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/close-fixed-deposits-account/close-fixed-deposits-account.component.ts index 002d3a90f..0564d7e2f 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/close-fixed-deposits-account/close-fixed-deposits-account.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/close-fixed-deposits-account/close-fixed-deposits-account.component.ts @@ -21,6 +21,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { FixedDepositsService } from '../../fixed-deposits.service'; import { SettingsService } from 'app/settings/settings.service'; import { Dates } from 'app/core/utils/dates'; +import { AlertService } from 'app/core/alert/alert.service'; import { CdkTextareaAutosize } from '@angular/cdk/text-field'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -43,6 +44,7 @@ export class CloseFixedDepositsAccountComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); private settingsService = inject(SettingsService); + private alertService = inject(AlertService); /** Minimum date allowed. */ minDate = new Date(2000, 0, 1); @@ -139,8 +141,18 @@ export class CloseFixedDepositsAccountComponent implements OnInit { dateFormat, locale }; - this.fixedDepositsService.executeFixedDepositsAccountCommand(this.accountId, 'close', data).subscribe(() => { - this.router.navigate(['../../'], { relativeTo: this.route }); - }); + this.fixedDepositsService + .executeFixedDepositsAccountCommand(this.accountId, 'close', data) + .subscribe((response: any) => { + // Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true), + // so the deposit reloads unchanged -- say so instead of letting that read as "nothing happened". + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: 'Closure has been sent for checker approval. The deposit is unchanged until a checker approves it.' + }); + } + this.router.navigate(['../../'], { relativeTo: this.route }); + }); } } diff --git a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/reject-fixed-deposits-account/reject-fixed-deposits-account.component.ts b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/reject-fixed-deposits-account/reject-fixed-deposits-account.component.ts index 82371da17..475037f30 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/reject-fixed-deposits-account/reject-fixed-deposits-account.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/reject-fixed-deposits-account/reject-fixed-deposits-account.component.ts @@ -11,6 +11,7 @@ import { Component, OnInit, inject } from '@angular/core'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { Dates } from 'app/core/utils/dates'; +import { AlertService } from 'app/core/alert/alert.service'; /** Custom Services */ import { FixedDepositsService } from 'app/deposits/fixed-deposits/fixed-deposits.service'; @@ -37,6 +38,7 @@ export class RejectFixedDepositsAccountComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); private settingsService = inject(SettingsService); + private alertService = inject(AlertService); /** Minimum date allowed. */ minDate = new Date(2000, 0, 1); @@ -97,8 +99,19 @@ export class RejectFixedDepositsAccountComponent implements OnInit { dateFormat, locale }; - this.fixedDepositsService.executeFixedDepositsAccountCommand(this.accountId, 'reject', data).subscribe(() => { - this.router.navigate(['../../'], { relativeTo: this.route }); - }); + this.fixedDepositsService + .executeFixedDepositsAccountCommand(this.accountId, 'reject', data) + .subscribe((response: any) => { + // Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true), + // so the application is still open -- say so instead of letting that read as "nothing happened". + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'Rejection has been sent for checker approval. The application is unchanged until a checker approves it.' + }); + } + this.router.navigate(['../../'], { relativeTo: this.route }); + }); } } diff --git a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/undo-approval-fixed-deposits-account/undo-approval-fixed-deposits-account.component.ts b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/undo-approval-fixed-deposits-account/undo-approval-fixed-deposits-account.component.ts index 227618b1d..2bb7b5f0a 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/undo-approval-fixed-deposits-account/undo-approval-fixed-deposits-account.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/undo-approval-fixed-deposits-account/undo-approval-fixed-deposits-account.component.ts @@ -12,6 +12,7 @@ import { UntypedFormGroup, UntypedFormBuilder, ReactiveFormsModule } from '@angu import { ActivatedRoute, Router, RouterLink } from '@angular/router'; /** Custom Services */ +import { AlertService } from 'app/core/alert/alert.service'; import { SavingsService } from 'app/savings/savings.service'; import { FixedDepositsService } from '../../fixed-deposits.service'; import { CdkTextareaAutosize } from '@angular/cdk/text-field'; @@ -35,6 +36,7 @@ export class UndoApprovalFixedDepositsAccountComponent implements OnInit { private fixedDepositsService = inject(FixedDepositsService); private route = inject(ActivatedRoute); private router = inject(Router); + private alertService = inject(AlertService); /** Undo Approval Fixed Deposits Account form. */ undoApprovalFixedDepositsAccountForm: UntypedFormGroup; @@ -87,12 +89,30 @@ export class UndoApprovalFixedDepositsAccountComponent implements OnInit { if (this.undoAction === 'Undo Activation') { this.fixedDepositsService .executeFixedDepositsAccountCommand(this.accountId, this.undoCommand, data) - .subscribe(() => { + .subscribe((response: any) => { + this.notifyIfSentForApproval(response); this.router.navigate(['../../'], { relativeTo: this.route }); }); } else { - this.savingsService.executeSavingsAccountCommand(this.accountId, this.undoCommand, data).subscribe(() => { - this.router.navigate(['../../'], { relativeTo: this.route }); + this.savingsService + .executeSavingsAccountCommand(this.accountId, this.undoCommand, data) + .subscribe((response: any) => { + this.notifyIfSentForApproval(response); + this.router.navigate(['../../'], { relativeTo: this.route }); + }); + } + } + + /** + * Both undo commands sit on maker-checker permissions, so either can come back parked in the + * Checker Inbox rather than executed -- HTTP 200 with rollbackTransaction: true, and the account + * reloaded unchanged. Without this the navigation away reads as "it worked". + */ + private notifyIfSentForApproval(response: any): void { + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: `${this.undoAction} has been sent for checker approval. The account is unchanged until a checker approves it.` }); } } diff --git a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/withdraw-by-client-fixed-deposits-account/withdraw-by-client-fixed-deposits-account.component.ts b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/withdraw-by-client-fixed-deposits-account/withdraw-by-client-fixed-deposits-account.component.ts index f871a71a1..de0afd163 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/withdraw-by-client-fixed-deposits-account/withdraw-by-client-fixed-deposits-account.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposits-account-actions/withdraw-by-client-fixed-deposits-account/withdraw-by-client-fixed-deposits-account.component.ts @@ -11,6 +11,7 @@ import { Component, OnInit, inject } from '@angular/core'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { Dates } from 'app/core/utils/dates'; +import { AlertService } from 'app/core/alert/alert.service'; /** Custom Services */ import { FixedDepositsService } from 'app/deposits/fixed-deposits/fixed-deposits.service'; @@ -37,6 +38,7 @@ export class WithdrawByClientFixedDepositsAccountComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); private settingsService = inject(SettingsService); + private alertService = inject(AlertService); /** Minimum date allowed. */ minDate = new Date(2000, 0, 1); @@ -99,7 +101,16 @@ export class WithdrawByClientFixedDepositsAccountComponent implements OnInit { }; this.fixedDepositsService .executeFixedDepositsAccountCommand(this.accountId, 'withdrawnByApplicant', data) - .subscribe(() => { + .subscribe((response: any) => { + // Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true), + // so the application is still open -- say so instead of letting that read as "nothing happened". + if (response?.rollbackTransaction) { + this.alertService.alert({ + type: 'Success', + message: + 'Withdrawal has been sent for checker approval. The application is unchanged until a checker approves it.' + }); + } this.router.navigate(['../../'], { relativeTo: this.route }); }); } diff --git a/src/assets/env.js b/src/assets/env.js index 410cacdc0..e278f8d6f 100644 --- a/src/assets/env.js +++ b/src/assets/env.js @@ -21,7 +21,7 @@ // in the tenants table of the tenant-store database, or the platform rejects the request as an // unknown tenant. window["env"]["fineractPlatformTenantId"] = 'utkarshbank'; - window["env"]["fineractPlatformTenantIds"] = 'utkarshbank'; + window["env"]["fineractPlatformTenantIds"] = 'utkarshbank,lincpay'; window['env']['tenantLogoUrl'] = ''; window['env']['tenantLogoUrlDark'] = ''; diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index 2ce8822a5..f5fd8d159 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -2971,6 +2971,7 @@ "Transfer Interest to Savings Account": "Transfer Interest to Savings Account", "Transfer Type": "Transfer Type", "Transfer in suspense": "Transfer in suspense", + "Transfer to GL Account": "Transfer to GL Account", "Transfer to Savings": "Transfer to Savings", "Transfer to savings account": "Transfer to savings account", "Trigger Type": "Trigger Type", diff --git a/src/environments/.env.ts b/src/environments/.env.ts index 0bcf1486e..469fe4b54 100644 --- a/src/environments/.env.ts +++ b/src/environments/.env.ts @@ -10,7 +10,7 @@ export default { 'mifos_x': { 'version': '261001', - 'hash': 'b6994c0b' + 'hash': '1ffac4b1' }, 'allow_switching_backend_instance': true }; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3b02a7373..7e1be2f0b 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -20,7 +20,7 @@ export const environment = { hash: env.mifos_x.hash, // For connecting to server running elsewhere update the tenant identifier fineractPlatformTenantId: loadedEnv['fineractPlatformTenantId'] || 'utkarshbank', - fineractPlatformTenantIds: loadedEnv['fineractPlatformTenantIds'] || 'utkarshbank', + fineractPlatformTenantIds: loadedEnv['fineractPlatformTenantIds'] || 'utkarshbank,lincpay', // For connecting to others servers running elsewhere update the base API URL baseApiUrls: loadedEnv['fineractApiUrls'] || 'https://demo.mifos.community,https://localhost:8443,' + window.location.origin, diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 2679b3c20..dabb366fb 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -23,7 +23,7 @@ export const environment = { hash: env.mifos_x.hash, // For connecting to server running elsewhere update the tenant identifier fineractPlatformTenantId: loadedEnv.fineractPlatformTenantId || 'utkarshbank', - fineractPlatformTenantIds: loadedEnv.fineractPlatformTenantIds || 'utkarshbank', + fineractPlatformTenantIds: loadedEnv.fineractPlatformTenantIds || 'utkarshbank,lincpay', // For connecting to others servers running elsewhere update the base API URL baseApiUrls: loadedEnv.fineractApiUrls || 'https://demo.mifos.community,https://localhost:8443,' + window.location.origin,