feat(tasks,savings,cashier): facility charge mapping screen, chained approve+activate, popup diff dialog, cash/transfer-only teller flow
Adds a Products > Facility Charge Mappings screen so each of the 16 facility toggles can be pointed at a real charge, backing the mapped-charge validation added on the backend. Bulk-approve on the pending accounts screen now chains straight into activation (matching the single-account approve flow) instead of leaving accounts sitting in Approved; the same screen's Confirm button no longer stays disabled on pre-filled but untouched dialogs. Add Charge is hidden on not-yet-active savings accounts, and Transfer Funds is disabled entirely pending a proper transfer flow. The pending savings-account edit "Proposed Changes" panel is now a MatDialog showing only the fields that actually changed, replacing the old always-open inline diff table. The teller transaction-entry Payment Type dropdown is filtered to Cash/Transfer only, mirroring the backend's retirement of the other system-defined payment types so share withdrawal and GL transfers now settle the same way real transfers do. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+60
-24
@@ -9,6 +9,7 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import {
|
||||
MatTableDataSource,
|
||||
MatTable,
|
||||
@@ -141,7 +142,8 @@ export class PendingAccountComponent {
|
||||
data: {
|
||||
title: 'Enter Approval Date',
|
||||
layout: { addButtonText: 'Confirm' },
|
||||
formfields
|
||||
formfields,
|
||||
pristine: false
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
@@ -166,7 +168,8 @@ export class PendingAccountComponent {
|
||||
data: {
|
||||
title: 'Enter Rejection Date',
|
||||
layout: { addButtonText: 'Confirm' },
|
||||
formfields
|
||||
formfields,
|
||||
pristine: false
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
@@ -183,7 +186,7 @@ export class PendingAccountComponent {
|
||||
const payload = { rejectedOnDate, dateFormat, locale };
|
||||
|
||||
const selected = this.selection.selected;
|
||||
let done = 0;
|
||||
let settled = 0;
|
||||
selected.forEach((account: any) => {
|
||||
const depositTypeId = account.depositType?.id;
|
||||
let reject$;
|
||||
@@ -196,39 +199,72 @@ export class PendingAccountComponent {
|
||||
} else {
|
||||
reject$ = this.tasksService.rejectSavingsAccount(account.id, payload);
|
||||
}
|
||||
reject$.subscribe(() => {
|
||||
done++;
|
||||
if (done === selected.length) {
|
||||
this.reload();
|
||||
reject$.subscribe({
|
||||
next: () => {
|
||||
settled++;
|
||||
if (settled === selected.length) {
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
error: () => {
|
||||
settled++;
|
||||
if (settled === selected.length) {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Approves an account, then immediately activates it on the same date -- Approve and Activate
|
||||
* are still two separate Fineract commands underneath (each shows up in the audit trail), but
|
||||
* the checker only sees and clicks through the one bulk action, matching what happens when
|
||||
* approving from inside an individual account (see e.g. ApproveSavingsAccountComponent).
|
||||
*/
|
||||
private approveAndActivate$(account: any, approvedOnDate: string, dateFormat: string, locale: string) {
|
||||
const approvePayload = { approvedOnDate, dateFormat, locale };
|
||||
const activatePayload = { activatedOnDate: approvedOnDate, dateFormat, locale };
|
||||
const depositTypeId = account.depositType?.id;
|
||||
|
||||
let approve$;
|
||||
let activate$;
|
||||
if (account.accountType === 'Current') {
|
||||
approve$ = this.tasksService.approveCurrentAccount(account.id, approvePayload);
|
||||
activate$ = () => this.tasksService.activateCurrentAccount(account.id, activatePayload);
|
||||
} else if (depositTypeId === 200) {
|
||||
approve$ = this.tasksService.approveFDAccount(account.id, approvePayload);
|
||||
activate$ = () => this.tasksService.activateFDAccount(account.id, activatePayload);
|
||||
} else if (depositTypeId === 300) {
|
||||
approve$ = this.tasksService.approveRDAccount(account.id, approvePayload);
|
||||
activate$ = () => this.tasksService.activateRDAccount(account.id, activatePayload);
|
||||
} else {
|
||||
approve$ = this.tasksService.approveSavingsAccount(account.id, approvePayload);
|
||||
activate$ = () => this.tasksService.activateSavingsAccount(account.id, activatePayload);
|
||||
}
|
||||
return approve$.pipe(switchMap(activate$));
|
||||
}
|
||||
|
||||
private bulkApprove(submittedData: any) {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const locale = this.settingsService.language.code;
|
||||
const approvedOnDate = this.dateUtils.formatDate(submittedData.value.approvedOnDate, dateFormat);
|
||||
const payload = { approvedOnDate, dateFormat, locale };
|
||||
|
||||
const selected = this.selection.selected;
|
||||
let done = 0;
|
||||
let settled = 0;
|
||||
selected.forEach((account: any) => {
|
||||
const depositTypeId = account.depositType?.id;
|
||||
let approve$;
|
||||
if (account.accountType === 'Current') {
|
||||
approve$ = this.tasksService.approveCurrentAccount(account.id, payload);
|
||||
} else if (depositTypeId === 200) {
|
||||
approve$ = this.tasksService.approveFDAccount(account.id, payload);
|
||||
} else if (depositTypeId === 300) {
|
||||
approve$ = this.tasksService.approveRDAccount(account.id, payload);
|
||||
} else {
|
||||
approve$ = this.tasksService.approveSavingsAccount(account.id, payload);
|
||||
}
|
||||
approve$.subscribe(() => {
|
||||
done++;
|
||||
if (done === selected.length) {
|
||||
this.reload();
|
||||
this.approveAndActivate$(account, approvedOnDate, dateFormat, locale).subscribe({
|
||||
next: () => {
|
||||
settled++;
|
||||
if (settled === selected.length) {
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
error: () => {
|
||||
settled++;
|
||||
if (settled === selected.length) {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user