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) {
- This customer has no active savings account to transfer into. Open one first, or choose an action that
- pays out in cash instead.
+ This customer has no active savings account to transfer into. Premature closure has to be paid into a
+ savings account, so open one for this customer before closing this deposit.
}
@@ -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,