feat: Pending and Rejected account tabs in Approval Center with tasks service
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
b7d009b22a
commit
38c4a7d9e9
+16
-3
@@ -19,9 +19,22 @@
|
|||||||
/>
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<div class="cv-action-buttons">
|
<div class="cv-action-buttons">
|
||||||
<button mat-stroked-button class="cv-btn cv-btn-approve" (click)="approveAccounts()">
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="cv-btn cv-btn-approve"
|
||||||
|
[disabled]="!selection.hasValue()"
|
||||||
|
(click)="approveAccounts()"
|
||||||
|
>
|
||||||
<fa-icon icon="check" class="m-r-10"></fa-icon>Approve
|
<fa-icon icon="check" class="m-r-10"></fa-icon>Approve
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="cv-btn cv-btn-reject"
|
||||||
|
[disabled]="!selection.hasValue()"
|
||||||
|
(click)="rejectAccounts()"
|
||||||
|
>
|
||||||
|
<fa-icon icon="ban" class="m-r-10"></fa-icon>Reject
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -103,8 +116,8 @@
|
|||||||
<tr
|
<tr
|
||||||
mat-row
|
mat-row
|
||||||
*matRowDef="let row; columns: displayedColumns"
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
(click)="selection.toggle(row)"
|
(click)="navigateToAccount(row)"
|
||||||
class="table-row"
|
class="table-row clickable-row"
|
||||||
></tr>
|
></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+26
-1
@@ -89,9 +89,34 @@ $text-muted: #64748b;
|
|||||||
border-color: #16a34a;
|
border-color: #16a34a;
|
||||||
color: #16a34a;
|
color: #16a34a;
|
||||||
|
|
||||||
&:hover {
|
&:hover:not([disabled]) {
|
||||||
background: #f0fdf4;
|
background: #f0fdf4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-btn-reject {
|
||||||
|
border-color: #dc2626;
|
||||||
|
color: #dc2626;
|
||||||
|
|
||||||
|
&:hover:not([disabled]) {
|
||||||
|
background: #fef2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable-row {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover td {
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.type-badge {
|
.type-badge {
|
||||||
|
|||||||
+72
@@ -107,7 +107,25 @@ export class PendingAccountComponent {
|
|||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigateToAccount(account: any): void {
|
||||||
|
const clientId = account.clientId;
|
||||||
|
const accountId = account.id;
|
||||||
|
const depositTypeId = account.depositType?.id;
|
||||||
|
let path: string;
|
||||||
|
if (account.accountType === 'Current') {
|
||||||
|
path = `/clients/${clientId}/current-accounts/${accountId}`;
|
||||||
|
} else if (depositTypeId === 200) {
|
||||||
|
path = `/clients/${clientId}/fixed-deposits-accounts/${accountId}`;
|
||||||
|
} else if (depositTypeId === 300) {
|
||||||
|
path = `/clients/${clientId}/recurring-deposits-accounts/${accountId}`;
|
||||||
|
} else {
|
||||||
|
path = `/clients/${clientId}/savings-accounts/${accountId}`;
|
||||||
|
}
|
||||||
|
this.router.navigate([path]);
|
||||||
|
}
|
||||||
|
|
||||||
approveAccounts() {
|
approveAccounts() {
|
||||||
|
if (!this.selection.hasValue()) return;
|
||||||
const formfields: FormfieldBase[] = [
|
const formfields: FormfieldBase[] = [
|
||||||
new DatepickerBase({
|
new DatepickerBase({
|
||||||
controlName: 'approvedOnDate',
|
controlName: 'approvedOnDate',
|
||||||
@@ -131,6 +149,60 @@ export class PendingAccountComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rejectAccounts() {
|
||||||
|
if (!this.selection.hasValue()) return;
|
||||||
|
const formfields: FormfieldBase[] = [
|
||||||
|
new DatepickerBase({
|
||||||
|
controlName: 'rejectedOnDate',
|
||||||
|
label: 'Rejected On Date',
|
||||||
|
value: new Date(),
|
||||||
|
type: 'datetime-local',
|
||||||
|
required: true
|
||||||
|
})
|
||||||
|
];
|
||||||
|
const dialogRef = this.dialog.open(FormDialogComponent, {
|
||||||
|
data: {
|
||||||
|
title: 'Enter Rejection Date',
|
||||||
|
layout: { addButtonText: 'Confirm' },
|
||||||
|
formfields
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe((response: any) => {
|
||||||
|
if (response?.data) {
|
||||||
|
this.bulkReject(response.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private bulkReject(submittedData: any) {
|
||||||
|
const dateFormat = this.settingsService.dateFormat;
|
||||||
|
const locale = this.settingsService.language.code;
|
||||||
|
const rejectedOnDate = this.dateUtils.formatDate(submittedData.value.rejectedOnDate, dateFormat);
|
||||||
|
const payload = { rejectedOnDate, dateFormat, locale };
|
||||||
|
|
||||||
|
const selected = this.selection.selected;
|
||||||
|
let done = 0;
|
||||||
|
selected.forEach((account: any) => {
|
||||||
|
const depositTypeId = account.depositType?.id;
|
||||||
|
let reject$;
|
||||||
|
if (account.accountType === 'Current') {
|
||||||
|
reject$ = this.tasksService.rejectCurrentAccount(account.id, payload);
|
||||||
|
} else if (depositTypeId === 200) {
|
||||||
|
reject$ = this.tasksService.rejectFDAccount(account.id, payload);
|
||||||
|
} else if (depositTypeId === 300) {
|
||||||
|
reject$ = this.tasksService.rejectRDAccount(account.id, payload);
|
||||||
|
} else {
|
||||||
|
reject$ = this.tasksService.rejectSavingsAccount(account.id, payload);
|
||||||
|
}
|
||||||
|
reject$.subscribe(() => {
|
||||||
|
done++;
|
||||||
|
if (done === selected.length) {
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private bulkApprove(submittedData: any) {
|
private bulkApprove(submittedData: any) {
|
||||||
const dateFormat = this.settingsService.dateFormat;
|
const dateFormat = this.settingsService.dateFormat;
|
||||||
const locale = this.settingsService.language.code;
|
const locale = this.settingsService.language.code;
|
||||||
|
|||||||
+6
-1
@@ -83,7 +83,12 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row"></tr>
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
(click)="navigateToAccount(row)"
|
||||||
|
class="table-row"
|
||||||
|
></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -63,6 +63,14 @@ $text-muted: #64748b;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-row {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover td {
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.type-badge {
|
.type-badge {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
+19
-1
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import {
|
import {
|
||||||
MatTableDataSource,
|
MatTableDataSource,
|
||||||
MatTable,
|
MatTable,
|
||||||
@@ -47,6 +47,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|||||||
})
|
})
|
||||||
export class RejectedAccountComponent {
|
export class RejectedAccountComponent {
|
||||||
private route = inject(ActivatedRoute);
|
private route = inject(ActivatedRoute);
|
||||||
|
private router = inject(Router);
|
||||||
|
|
||||||
dataSource: MatTableDataSource<any>;
|
dataSource: MatTableDataSource<any>;
|
||||||
showData = false;
|
showData = false;
|
||||||
@@ -72,6 +73,23 @@ export class RejectedAccountComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigateToAccount(account: any): void {
|
||||||
|
const clientId = account.clientId;
|
||||||
|
const accountId = account.id;
|
||||||
|
const depositTypeId = account.depositType?.id;
|
||||||
|
let path: string;
|
||||||
|
if (account.accountType === 'Current') {
|
||||||
|
path = `/clients/${clientId}/current-accounts/${accountId}`;
|
||||||
|
} else if (depositTypeId === 200) {
|
||||||
|
path = `/clients/${clientId}/fixed-deposits-accounts/${accountId}`;
|
||||||
|
} else if (depositTypeId === 300) {
|
||||||
|
path = `/clients/${clientId}/recurring-deposits-accounts/${accountId}`;
|
||||||
|
} else {
|
||||||
|
path = `/clients/${clientId}/savings-accounts/${accountId}`;
|
||||||
|
}
|
||||||
|
this.router.navigate([path]);
|
||||||
|
}
|
||||||
|
|
||||||
applyFilter(filterValue: string = '') {
|
applyFilter(filterValue: string = '') {
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,38 @@ export class TasksService {
|
|||||||
return this.http.post(`/currentaccounts/${accountId}`, data, { params: httpParams });
|
return this.http.post(`/currentaccounts/${accountId}`, data, { params: httpParams });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject a savings account
|
||||||
|
*/
|
||||||
|
rejectSavingsAccount(accountId: any, data: any): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'reject');
|
||||||
|
return this.http.post(`/savingsaccounts/${accountId}`, data, { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject a fixed deposit account
|
||||||
|
*/
|
||||||
|
rejectFDAccount(accountId: any, data: any): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'reject');
|
||||||
|
return this.http.post(`/fixeddepositaccounts/${accountId}`, data, { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject a recurring deposit account
|
||||||
|
*/
|
||||||
|
rejectRDAccount(accountId: any, data: any): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'reject');
|
||||||
|
return this.http.post(`/recurringdepositaccounts/${accountId}`, data, { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject a current account
|
||||||
|
*/
|
||||||
|
rejectCurrentAccount(accountId: any, data: any): Observable<any> {
|
||||||
|
const httpParams = new HttpParams().set('command', 'reject');
|
||||||
|
return this.http.post(`/currentaccounts/${accountId}`, data, { params: httpParams });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit data in batches.
|
* Submit data in batches.
|
||||||
* @param {data} Data to be submitted
|
* @param {data} Data to be submitted
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
export default {
|
export default {
|
||||||
'mifos_x': {
|
'mifos_x': {
|
||||||
'version': '260522',
|
'version': '260525',
|
||||||
'hash': '64c76a98'
|
'hash': 'ad6f629c'
|
||||||
},
|
},
|
||||||
'allow_switching_backend_instance': true
|
'allow_switching_backend_instance': true
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user