fix(savings): show a clear message when an action is parked for checker approval
Approve, close, reject, undo-approval, withdraw-by-client, and post-interest on a savings account all silently behaved as if nothing happened when the backend parks the command in the Checker Inbox instead of executing it (HTTP 200 with rollbackTransaction: true) -- misleading the maker into thinking the action either failed or quietly succeeded. Each now shows an explicit alert naming what was sent for approval and that the account/ application is unchanged until a checker approves it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+15
-1
@@ -11,6 +11,7 @@ import { Component, OnInit, inject } from '@angular/core';
|
|||||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||||
import { Dates } from 'app/core/utils/dates';
|
import { Dates } from 'app/core/utils/dates';
|
||||||
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { SavingsService } from 'app/savings/savings.service';
|
import { SavingsService } from 'app/savings/savings.service';
|
||||||
@@ -37,6 +38,7 @@ export class ApproveSavingsAccountComponent implements OnInit {
|
|||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private settingsService = inject(SettingsService);
|
private settingsService = inject(SettingsService);
|
||||||
|
private alertService = inject(AlertService);
|
||||||
|
|
||||||
/** Minimum date allowed. */
|
/** Minimum date allowed. */
|
||||||
minDate = new Date(2000, 0, 1);
|
minDate = new Date(2000, 0, 1);
|
||||||
@@ -98,7 +100,19 @@ export class ApproveSavingsAccountComponent implements OnInit {
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
locale
|
locale
|
||||||
};
|
};
|
||||||
this.savingsService.executeSavingsAccountCommand(this.accountId, 'approve', data).subscribe(() => {
|
this.savingsService.executeSavingsAccountCommand(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(['../../transactions'], { relativeTo: this.route });
|
||||||
|
return;
|
||||||
|
}
|
||||||
const activationData = {
|
const activationData = {
|
||||||
activatedOnDate: approveSavingsAccountFormData.approvedOnDate,
|
activatedOnDate: approveSavingsAccountFormData.approvedOnDate,
|
||||||
dateFormat,
|
dateFormat,
|
||||||
|
|||||||
+11
-1
@@ -20,6 +20,7 @@ import { Dates } from 'app/core/utils/dates';
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { SavingsService } from 'app/savings/savings.service';
|
import { SavingsService } from 'app/savings/savings.service';
|
||||||
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
import { MatCheckbox } from '@angular/material/checkbox';
|
import { MatCheckbox } from '@angular/material/checkbox';
|
||||||
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
||||||
@@ -47,6 +48,7 @@ export class CloseSavingsAccountComponent implements OnInit {
|
|||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private settingsService = inject(SettingsService);
|
private settingsService = inject(SettingsService);
|
||||||
|
private alertService = inject(AlertService);
|
||||||
|
|
||||||
/** Minimum date allowed. */
|
/** Minimum date allowed. */
|
||||||
minDate = new Date(2000, 0, 1);
|
minDate = new Date(2000, 0, 1);
|
||||||
@@ -158,7 +160,15 @@ export class CloseSavingsAccountComponent implements OnInit {
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
locale
|
locale
|
||||||
};
|
};
|
||||||
this.savingsService.executeSavingsAccountCommand(this.accountId, 'close', data).subscribe(() => {
|
this.savingsService.executeSavingsAccountCommand(this.accountId, 'close', data).subscribe((response: any) => {
|
||||||
|
// Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true),
|
||||||
|
// so the account is still open -- 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 account is unchanged until a checker approves it.'
|
||||||
|
});
|
||||||
|
}
|
||||||
this.router.navigate(['../../transactions'], { relativeTo: this.route });
|
this.router.navigate(['../../transactions'], { relativeTo: this.route });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -14,6 +14,7 @@ import { Dates } from 'app/core/utils/dates';
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { SavingsService } from 'app/savings/savings.service';
|
import { SavingsService } from 'app/savings/savings.service';
|
||||||
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
||||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||||
@@ -37,6 +38,7 @@ export class RejectSavingsAccountComponent implements OnInit {
|
|||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private settingsService = inject(SettingsService);
|
private settingsService = inject(SettingsService);
|
||||||
|
private alertService = inject(AlertService);
|
||||||
|
|
||||||
/** Minimum date allowed. */
|
/** Minimum date allowed. */
|
||||||
minDate = new Date(2000, 0, 1);
|
minDate = new Date(2000, 0, 1);
|
||||||
@@ -97,7 +99,16 @@ export class RejectSavingsAccountComponent implements OnInit {
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
locale
|
locale
|
||||||
};
|
};
|
||||||
this.savingsService.executeSavingsAccountCommand(this.accountId, 'reject', data).subscribe(() => {
|
this.savingsService.executeSavingsAccountCommand(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 });
|
this.router.navigate(['../../'], { relativeTo: this.route });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -13,6 +13,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { SavingsService } from 'app/savings/savings.service';
|
import { SavingsService } from 'app/savings/savings.service';
|
||||||
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
||||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ export class UndoApprovalSavingsAccountComponent implements OnInit {
|
|||||||
private savingsService = inject(SavingsService);
|
private savingsService = inject(SavingsService);
|
||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
|
private alertService = inject(AlertService);
|
||||||
|
|
||||||
/** Undo Approval Savings Account form. */
|
/** Undo Approval Savings Account form. */
|
||||||
undoApprovalSavingsAccountForm: UntypedFormGroup;
|
undoApprovalSavingsAccountForm: UntypedFormGroup;
|
||||||
@@ -73,8 +75,19 @@ export class UndoApprovalSavingsAccountComponent implements OnInit {
|
|||||||
const data = {
|
const data = {
|
||||||
...this.undoApprovalSavingsAccountForm.value
|
...this.undoApprovalSavingsAccountForm.value
|
||||||
};
|
};
|
||||||
this.savingsService.executeSavingsAccountCommand(this.accountId, 'undoapproval', data).subscribe(() => {
|
this.savingsService
|
||||||
this.router.navigate(['../../transactions'], { relativeTo: this.route });
|
.executeSavingsAccountCommand(this.accountId, 'undoapproval', data)
|
||||||
});
|
.subscribe((response: any) => {
|
||||||
|
// Parked in the Checker Inbox rather than executed (HTTP 200 with rollbackTransaction: true),
|
||||||
|
// so the account reloads unchanged -- say so instead of letting that read as "it worked".
|
||||||
|
if (response?.rollbackTransaction) {
|
||||||
|
this.alertService.alert({
|
||||||
|
type: 'Success',
|
||||||
|
message:
|
||||||
|
'Undo approval has been sent for checker approval. The account is unchanged until a checker approves it.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.router.navigate(['../../transactions'], { relativeTo: this.route });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -14,6 +14,7 @@ import { Dates } from 'app/core/utils/dates';
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { SavingsService } from 'app/savings/savings.service';
|
import { SavingsService } from 'app/savings/savings.service';
|
||||||
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
||||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||||
@@ -37,6 +38,7 @@ export class WithdrawByClientSavingsAccountComponent implements OnInit {
|
|||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private settingsService = inject(SettingsService);
|
private settingsService = inject(SettingsService);
|
||||||
|
private alertService = inject(AlertService);
|
||||||
|
|
||||||
/** Minimum date allowed. */
|
/** Minimum date allowed. */
|
||||||
minDate = new Date(2000, 0, 1);
|
minDate = new Date(2000, 0, 1);
|
||||||
@@ -97,8 +99,19 @@ export class WithdrawByClientSavingsAccountComponent implements OnInit {
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
locale
|
locale
|
||||||
};
|
};
|
||||||
this.savingsService.executeSavingsAccountCommand(this.accountId, 'withdrawnByApplicant', data).subscribe(() => {
|
this.savingsService
|
||||||
this.router.navigate(['../../'], { relativeTo: this.route });
|
.executeSavingsAccountCommand(this.accountId, 'withdrawnByApplicant', 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:
|
||||||
|
'Withdrawal has been sent for checker approval. The application is unchanged until a checker approves it.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.router.navigate(['../../'], { relativeTo: this.route });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -446,7 +446,16 @@ export class SavingsAccountViewComponent implements OnInit {
|
|||||||
if (response.confirm) {
|
if (response.confirm) {
|
||||||
this.savingsService
|
this.savingsService
|
||||||
.executeSavingsAccountCommand(this.savingsAccountData.id, 'postInterest', {})
|
.executeSavingsAccountCommand(this.savingsAccountData.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();
|
this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user