existing account saving and current add or remove nominee and digital & account features and also FE & RD nominee add or remove
This commit is contained in:
+10
-6
@@ -104,18 +104,22 @@ export class CheckerInboxComponent implements OnInit {
|
||||
];
|
||||
|
||||
/**
|
||||
* Entities whose pending edits are gated by our own m_savings_product_temp lock rather than the
|
||||
* native command-source pipeline. They're excluded from Checker Inbox entirely - approving/rejecting
|
||||
* them here would call the native /makercheckers/{id}?command=approve endpoint, which replays the
|
||||
* original command handler directly and never touches our temp table, leaving its lock stuck forever.
|
||||
* Action them from Approvals -> Pending Product Edits instead, where that's handled correctly.
|
||||
* Entities whose pending edits are gated by our own custom staging tables (m_savings_product_temp
|
||||
* for products, the savings account edit-request table for Nominee/Digital-Feature edits) rather
|
||||
* than the native command-source pipeline. They're excluded from Checker Inbox entirely -
|
||||
* approving/rejecting them here would call the native /makercheckers/{id}?command=approve endpoint,
|
||||
* which replays the original command handler directly and never touches our staging table, leaving
|
||||
* its lock/hold stuck forever. Action them from Approvals -> Pending Product Edits / Pending Account
|
||||
* Edits instead, where that's handled correctly.
|
||||
*/
|
||||
private readonly productEditEntities = [
|
||||
'SAVINGSPRODUCT',
|
||||
'CURRENTPRODUCT',
|
||||
'SHAREPRODUCT',
|
||||
'FIXEDDEPOSITPRODUCT',
|
||||
'RECURRINGDEPOSITPRODUCT'
|
||||
'RECURRINGDEPOSITPRODUCT',
|
||||
'SAVINGSACCOUNT',
|
||||
'CURRENTACCOUNT'
|
||||
];
|
||||
|
||||
private excludeProductEdits(items: any[]): any[] {
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
<!--
|
||||
Copyright since 2025 Mifos Initiative
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
-->
|
||||
|
||||
<div class="psae-tab-content">
|
||||
@if (showData) {
|
||||
<div class="psae-action-bar">
|
||||
<mat-form-field appearance="outline" class="psae-search-field">
|
||||
<mat-icon matPrefix>search</mat-icon>
|
||||
<input #filterInput matInput placeholder="Search by account number" (keyup)="applyFilter(filterInput.value)" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="modern-table">
|
||||
<ng-container matColumnDef="accountNo">
|
||||
<th mat-header-cell *matHeaderCellDef>Account No.</th>
|
||||
<td mat-cell *matCellDef="let edit">{{ edit.accountNo }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="accountType">
|
||||
<th mat-header-cell *matHeaderCellDef>Account Type</th>
|
||||
<td mat-cell *matCellDef="let edit">
|
||||
<span
|
||||
class="status-badge"
|
||||
[class.status-badge--savings]="edit.accountType === 'Savings'"
|
||||
[class.status-badge--current]="edit.accountType === 'Current'"
|
||||
[class.status-badge--fd]="edit.accountType === 'Fixed Deposit'"
|
||||
[class.status-badge--rd]="edit.accountType === 'Recurring Deposit'"
|
||||
>
|
||||
{{ edit.accountType }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="makerUsername">
|
||||
<th mat-header-cell *matHeaderCellDef>Submitted By</th>
|
||||
<td mat-cell *matCellDef="let edit">{{ edit.makerUsername }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="createdOn">
|
||||
<th mat-header-cell *matHeaderCellDef>Submitted On</th>
|
||||
<td mat-cell *matCellDef="let edit">{{ formatDate(edit.createdOn) }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="holdAmount">
|
||||
<th mat-header-cell *matHeaderCellDef>Hold Amount</th>
|
||||
<td mat-cell *matCellDef="let edit">
|
||||
@if (edit.holdAmount) {
|
||||
<span class="status-badge status-badge--hold">{{ edit.holdAmount }}</span>
|
||||
} @else {
|
||||
—
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>Status</th>
|
||||
<td mat-cell *matCellDef="let edit">
|
||||
<span class="status-badge status-badge--pending">{{ edit.status }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>Actions</th>
|
||||
<td mat-cell *matCellDef="let edit">
|
||||
<button mat-stroked-button class="psae-btn psae-btn-view" (click)="viewCompare(edit)">
|
||||
<fa-icon icon="eye" class="m-r-10"></fa-icon>Compare
|
||||
</button>
|
||||
<button mat-stroked-button class="psae-btn psae-btn-approve" (click)="approve(edit)">
|
||||
<fa-icon icon="check" class="m-r-10"></fa-icon>Approve
|
||||
</button>
|
||||
<button mat-stroked-button class="psae-btn psae-btn-reject" (click)="reject(edit)">
|
||||
<fa-icon icon="ban" class="m-r-10"></fa-icon>Reject
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if (selectedEdit) {
|
||||
<div class="psae-diff-panel">
|
||||
<div class="psae-diff-header">
|
||||
<h3>Proposed Changes — Account "{{ selectedEdit.accountNo }}"</h3>
|
||||
<button mat-icon-button (click)="closeCompare()"><fa-icon icon="times"></fa-icon></button>
|
||||
</div>
|
||||
|
||||
@if (selectedEdit.facilityConfigSubmitted) {
|
||||
<div class="psae-diff-block">
|
||||
<h4>Digital & Account Features</h4>
|
||||
<table class="psae-diff-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Feature</th>
|
||||
<th>Proposed Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (row of entries(selectedEdit.proposedFacilityConfig); track row.key) {
|
||||
<tr>
|
||||
<td class="psae-diff-label">{{ row.key }}</td>
|
||||
<td class="psae-diff-proposed">{{ row.value }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (selectedEdit.nomineeSubmitted) {
|
||||
<div class="psae-diff-block">
|
||||
<h4>Nominee Change</h4>
|
||||
<table class="psae-diff-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Proposed Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (row of entries(selectedEdit.proposedNominee); track row.key) {
|
||||
<tr>
|
||||
<td class="psae-diff-label">{{ row.key }}</td>
|
||||
<td class="psae-diff-proposed">{{ row.value }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!selectedEdit.facilityConfigSubmitted && !selectedEdit.nomineeSubmitted) {
|
||||
<p class="psae-diff-loading">No proposed changes recorded on this edit.</p>
|
||||
}
|
||||
|
||||
@if (selectedEdit.rejectReason) {
|
||||
<p class="psae-reject-reason"><strong>Reject Reason:</strong> {{ selectedEdit.rejectReason }}</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@if (!showData) {
|
||||
<div class="empty-state">
|
||||
<fa-icon icon="hourglass-half" class="empty-icon"></fa-icon>
|
||||
<p class="empty-title">No pending account edits</p>
|
||||
<p class="empty-text">There are no Nominee / Digital-Feature edits awaiting approval at this time.</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
$border: #e2e8f0;
|
||||
$text-muted: #64748b;
|
||||
|
||||
.psae-tab-content {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.psae-action-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.psae-search-field {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
.psae-btn {
|
||||
font-size: 11.5px;
|
||||
font-weight: 600;
|
||||
border-radius: 8px !important;
|
||||
height: 32px;
|
||||
padding: 0 10px;
|
||||
margin-right: 6px;
|
||||
|
||||
fa-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-btn-view {
|
||||
border-color: #2563eb;
|
||||
color: #2563eb;
|
||||
|
||||
&:hover {
|
||||
background: #eff6ff;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-btn-approve {
|
||||
border-color: #16a34a;
|
||||
color: #16a34a;
|
||||
|
||||
&:hover {
|
||||
background: #f0fdf4;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-btn-reject {
|
||||
border-color: #dc2626;
|
||||
color: #dc2626;
|
||||
|
||||
&:hover {
|
||||
background: #fef2f2;
|
||||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
|
||||
&--pending {
|
||||
background: #fef9c3;
|
||||
color: #854d0e;
|
||||
}
|
||||
|
||||
&--hold {
|
||||
background: #ffedd5;
|
||||
color: #9a3412;
|
||||
}
|
||||
|
||||
&--savings {
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
&--current {
|
||||
background: #f3e8ff;
|
||||
color: #6b21a8;
|
||||
}
|
||||
|
||||
&--fd {
|
||||
background: #fef2f2;
|
||||
color: #991b1b;
|
||||
}
|
||||
|
||||
&--rd {
|
||||
background: #ecfdf5;
|
||||
color: #065f46;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-diff-panel {
|
||||
margin-top: 20px;
|
||||
border: 1px solid $border;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.psae-diff-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-diff-block {
|
||||
margin-top: 16px;
|
||||
|
||||
h4 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 12.5px;
|
||||
font-weight: 700;
|
||||
color: #0d1b2a;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-diff-loading {
|
||||
color: $text-muted;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.psae-diff-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 4px;
|
||||
font-size: 12.5px;
|
||||
|
||||
th,
|
||||
td {
|
||||
text-align: left;
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid $border;
|
||||
}
|
||||
|
||||
th {
|
||||
color: $text-muted;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.psae-diff-label {
|
||||
font-weight: 600;
|
||||
color: #0d1b2a;
|
||||
}
|
||||
|
||||
.psae-diff-proposed {
|
||||
color: #15803d;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.psae-reject-reason {
|
||||
margin-top: 14px;
|
||||
font-size: 12.5px;
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 24px;
|
||||
background: #fff;
|
||||
border: 1px dashed $border;
|
||||
border-radius: 14px;
|
||||
text-align: center;
|
||||
margin: 16px 0;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 42px;
|
||||
color: #cbd5e1;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.empty-title {
|
||||
margin: 0 0 4px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #0d1b2a;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin: 0;
|
||||
font-size: 12.5px;
|
||||
color: $text-muted;
|
||||
max-width: 380px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import {
|
||||
MatTableDataSource,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderCell,
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow
|
||||
} from '@angular/material/table';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
|
||||
import { SavingsService } from 'app/savings/savings.service';
|
||||
import { CurrentAccountsService } from 'app/current-accounts/current-accounts.service';
|
||||
import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component';
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
* Checker-facing list of savings account Nominee / Digital-Feature edits awaiting approval.
|
||||
* Mirrors PendingSavingsProductsComponent's list + compare + approve/reject pattern.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-pending-savings-account-edits',
|
||||
templateUrl: './pending-savings-account-edits.component.html',
|
||||
styleUrls: ['./pending-savings-account-edits.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
FaIconComponent,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderCell,
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow,
|
||||
MatIcon,
|
||||
MatIconButton
|
||||
]
|
||||
})
|
||||
export class PendingSavingsAccountEditsComponent {
|
||||
private route = inject(ActivatedRoute);
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private savingsService = inject(SavingsService);
|
||||
private currentAccountsService = inject(CurrentAccountsService);
|
||||
|
||||
dataSource: MatTableDataSource<any>;
|
||||
showData = false;
|
||||
|
||||
displayedColumns: string[] = [
|
||||
'accountNo',
|
||||
'accountType',
|
||||
'makerUsername',
|
||||
'createdOn',
|
||||
'holdAmount',
|
||||
'status',
|
||||
'actions'
|
||||
];
|
||||
|
||||
selectedEdit: any = null;
|
||||
|
||||
constructor() {
|
||||
this.route.data.subscribe((data: { pendingSavingsAccountEditsData: any; pendingCurrentAccountEditsData: any }) => {
|
||||
const savingsItems = (data.pendingSavingsAccountEditsData || []).map((item: any) => {
|
||||
let type = 'Savings';
|
||||
if (item.depositAccountType === 'FIXED_DEPOSIT') {
|
||||
type = 'Fixed Deposit';
|
||||
} else if (item.depositAccountType === 'RECURRING_DEPOSIT') {
|
||||
type = 'Recurring Deposit';
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
accountType: type
|
||||
};
|
||||
});
|
||||
const currentItems = (data.pendingCurrentAccountEditsData || []).map((item: any) => ({
|
||||
...item,
|
||||
accountType: 'Current'
|
||||
}));
|
||||
const items = [
|
||||
...savingsItems,
|
||||
...currentItems
|
||||
];
|
||||
this.showData = items.length > 0;
|
||||
this.dataSource = new MatTableDataSource(items);
|
||||
});
|
||||
}
|
||||
|
||||
applyFilter(filterValue: string = '') {
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
|
||||
formatDate(date: any): string {
|
||||
if (!date) return '';
|
||||
const d = Array.isArray(date)
|
||||
? new Date(date[0], date[1] - 1, date[2], date[3] || 0, date[4] || 0)
|
||||
: new Date(date);
|
||||
return isNaN(d.getTime()) ? String(date) : d.toLocaleString('en-IN');
|
||||
}
|
||||
|
||||
/** Readable list of "key: value" pairs for the proposed facility/nominee changes. */
|
||||
entries(obj: any): { key: string; value: any }[] {
|
||||
if (!obj) return [];
|
||||
return Object.keys(obj).map((key) => ({ key, value: obj[key] }));
|
||||
}
|
||||
|
||||
viewCompare(edit: any): void {
|
||||
this.selectedEdit = this.selectedEdit === edit ? null : edit;
|
||||
}
|
||||
|
||||
closeCompare(): void {
|
||||
this.selectedEdit = null;
|
||||
}
|
||||
|
||||
approve(edit: any): void {
|
||||
const isCurrent = edit.accountType === 'Current';
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: {
|
||||
heading: isCurrent ? 'Approve Current Account Edit' : 'Approve Savings Account Edit',
|
||||
dialogContext: `Apply the pending Nominee/Digital-Feature edit for account "${edit.accountNo}"? This cannot be undone.`,
|
||||
type: 'basic'
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response?.confirm) {
|
||||
if (isCurrent) {
|
||||
this.currentAccountsService.approveCurrentAccountEdit(edit.currentAccountId).subscribe(() => this.reload());
|
||||
} else {
|
||||
this.savingsService.approveSavingsAccountEdit(edit.savingsAccountId).subscribe(() => this.reload());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reject(edit: any): void {
|
||||
const isCurrent = edit.accountType === 'Current';
|
||||
const formfields: FormfieldBase[] = [
|
||||
new InputBase({
|
||||
controlName: 'rejectReason',
|
||||
label: 'Reason for rejection',
|
||||
value: '',
|
||||
type: 'text',
|
||||
required: false
|
||||
})
|
||||
];
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, {
|
||||
data: {
|
||||
title: `Reject edit for account "${edit.accountNo}"`,
|
||||
layout: { addButtonText: 'Reject' },
|
||||
formfields
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response?.data) {
|
||||
const rejectReason = response.data.value.rejectReason || '';
|
||||
if (isCurrent) {
|
||||
this.currentAccountsService
|
||||
.rejectCurrentAccountEdit(edit.currentAccountId, rejectReason)
|
||||
.subscribe(() => this.reload());
|
||||
} else {
|
||||
this.savingsService
|
||||
.rejectSavingsAccountEdit(edit.savingsAccountId, rejectReason)
|
||||
.subscribe(() => this.reload());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reload(): void {
|
||||
this.closeCompare();
|
||||
const url = this.router.url;
|
||||
this.router
|
||||
.navigateByUrl('/checker-inbox-and-tasks', { skipLocationChange: true })
|
||||
.then(() => this.router.navigate([url]));
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,18 @@
|
||||
<fa-icon icon="piggy-bank" class="ac-tab__ic"></fa-icon>
|
||||
<span>Pending Product Edits</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="ac-tab"
|
||||
[routerLink]="['./pending-savings-account-edits']"
|
||||
routerLinkActive
|
||||
#pendingSavingsAccountEdits="routerLinkActive"
|
||||
[active]="pendingSavingsAccountEdits.isActive"
|
||||
*mifosxHasPermission="'ALL_FUNCTIONS_READ'"
|
||||
>
|
||||
<fa-icon icon="edit" class="ac-tab__ic"></fa-icon>
|
||||
<span>Pending Account Edits</span>
|
||||
</a>
|
||||
<a
|
||||
mat-tab-link
|
||||
class="ac-tab"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CurrentAccountsService } from 'app/current-accounts/current-accounts.service';
|
||||
|
||||
/**
|
||||
* Resolves all current account Nominee/Digital-Feature edits currently awaiting checker approval,
|
||||
* for the Pending Current Account Edits screen.
|
||||
*/
|
||||
@Injectable()
|
||||
export class GetPendingCurrentAccountEdits implements Resolve<any> {
|
||||
private currentAccountsService = inject(CurrentAccountsService);
|
||||
|
||||
resolve(): Observable<any> {
|
||||
return this.currentAccountsService.getAllPendingCurrentAccountEdits();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright since 2025 Mifos Initiative
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { SavingsService } from 'app/savings/savings.service';
|
||||
|
||||
/**
|
||||
* Resolves all savings account Nominee/Digital-Feature edits currently awaiting checker approval,
|
||||
* for the Pending Savings Account Edits screen.
|
||||
*/
|
||||
@Injectable()
|
||||
export class GetPendingSavingsAccountEdits implements Resolve<any> {
|
||||
private savingsService = inject(SavingsService);
|
||||
|
||||
resolve(): Observable<any> {
|
||||
return this.savingsService.getAllPendingSavingsAccountEdits();
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import { PendingAccountComponent } from './checker-inbox-and-tasks-tabs/pending-
|
||||
import { RejectedAccountComponent } from './checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component';
|
||||
import { TerminatedAccountComponent } from './checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component';
|
||||
import { PendingSavingsProductsComponent } from './checker-inbox-and-tasks-tabs/pending-savings-products/pending-savings-products.component';
|
||||
import { PendingSavingsAccountEditsComponent } from './checker-inbox-and-tasks-tabs/pending-savings-account-edits/pending-savings-account-edits.component';
|
||||
import { ViewCheckerInboxComponent } from './view-checker-inbox/view-checker-inbox.component';
|
||||
|
||||
/** Custom Resolvers */
|
||||
@@ -42,6 +43,8 @@ import { GetPendingAccounts } from './common-resolvers/getPendingAccounts.resolv
|
||||
import { GetRejectedAccounts } from './common-resolvers/getRejectedAccounts.resolver';
|
||||
import { GetTerminatedAccounts } from './common-resolvers/getTerminatedAccounts.resolver';
|
||||
import { GetPendingSavingsProducts } from './common-resolvers/getPendingSavingsProducts.resolver';
|
||||
import { GetPendingSavingsAccountEdits } from './common-resolvers/getPendingSavingsAccountEdits.resolver';
|
||||
import { GetPendingCurrentAccountEdits } from './common-resolvers/getPendingCurrentAccountEdits.resolver';
|
||||
|
||||
/** Tasks Routes */
|
||||
const routes: Routes = [
|
||||
@@ -125,6 +128,19 @@ const routes: Routes = [
|
||||
pendingSavingsProductsData: GetPendingSavingsProducts
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'pending-savings-account-edits',
|
||||
component: PendingSavingsAccountEditsComponent,
|
||||
data: { title: 'Pending Account Edits' },
|
||||
resolve: {
|
||||
pendingSavingsAccountEditsData: GetPendingSavingsAccountEdits,
|
||||
pendingCurrentAccountEditsData: GetPendingCurrentAccountEdits
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'pending-current-account-edits',
|
||||
redirectTo: 'pending-savings-account-edits'
|
||||
},
|
||||
{
|
||||
path: 'withdrawal-requests',
|
||||
component: WithdrawalRequestsComponent,
|
||||
@@ -197,7 +213,9 @@ const routes: Routes = [
|
||||
GetPendingAccounts,
|
||||
GetRejectedAccounts,
|
||||
GetTerminatedAccounts,
|
||||
GetPendingSavingsProducts
|
||||
GetPendingSavingsProducts,
|
||||
GetPendingSavingsAccountEdits,
|
||||
GetPendingCurrentAccountEdits
|
||||
]
|
||||
})
|
||||
export class TasksRoutingModule {}
|
||||
|
||||
Reference in New Issue
Block a user