From df96be9a0e9a2612c3b91d54b7da2e17ee559618 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Fri, 22 May 2026 14:02:40 +0530 Subject: [PATCH] feat: add Pending Account and Reject Account tabs to Approval Center - Added Pending Account tab showing savings/FD/RD/current accounts with status=pending (100) - Added Reject Account tab showing accounts with status=rejected (500) - Each tab displays: account no, client name, product, type badge, office, field officer, submitted/rejected date, status - Bulk approve with correct endpoint per deposit type (savings/FD/RD/current) - Resolvers use forkJoin to fetch savings + current accounts in parallel - Office name resolved via /offices map; field officer name taken directly from API response Co-Authored-By: Claude Sonnet 4.6 --- .../pending-account.component.html | 120 ++++++++++++ .../pending-account.component.scss | 171 +++++++++++++++++ .../pending-account.component.ts | 178 ++++++++++++++++++ .../rejected-account.component.html | 98 ++++++++++ .../rejected-account.component.scss | 138 ++++++++++++++ .../rejected-account.component.ts | 87 +++++++++ .../checker-inbox-and-tasks.component.html | 24 +++ .../getPendingAccounts.resolver.ts | 49 +++++ .../getRejectedAccounts.resolver.ts | 51 +++++ src/app/tasks/tasks-routing.module.ts | 24 ++- src/app/tasks/tasks.service.ts | 70 +++++++ 11 files changed, 1009 insertions(+), 1 deletion(-) create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.html create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.scss create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.html create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.scss create mode 100644 src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.ts create mode 100644 src/app/tasks/common-resolvers/getPendingAccounts.resolver.ts create mode 100644 src/app/tasks/common-resolvers/getRejectedAccounts.resolver.ts diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.html b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.html new file mode 100644 index 000000000..f5fc70de0 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.html @@ -0,0 +1,120 @@ + + +
+ @if (showData) { +
+ + search + + +
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Account No{{ account.accountNo }}Client Name{{ account.clientName }}Product{{ account.savingsProductName || account.productName }}Type + + {{ account.accountType }} + + Office{{ account.officeName }}Field Officer{{ account.fieldOfficerName || '—' }}Submitted On + {{ formatDate(account.timeline?.submittedOnDate) }} + Status + {{ account.status?.value }} +
+
+ } + + @if (!showData) { +
+ +

No pending accounts

+

There are no savings accounts awaiting approval at this time.

+
+ } +
diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.scss b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.scss new file mode 100644 index 000000000..0ddbf0f4c --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.scss @@ -0,0 +1,171 @@ +/** + * 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/. + */ + +$brand: #1353a0; +$border: #e2e8f0; +$text-muted: #64748b; + +.cv-tab-content { + padding: 16px 0; +} + +.cv-action-bar { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 16px; + flex-wrap: wrap; +} + +.cv-search-field { + flex: 1; + min-width: 200px; + max-width: 320px; + + ::ng-deep { + .mat-mdc-form-field-flex { + height: 36px; + } + + .mat-mdc-form-field-infix { + padding: 6px 0; + min-height: 36px; + } + + .mat-mdc-form-field-subscript-wrapper { + height: 0; + min-height: 0; + } + + .mdc-notched-outline { + .mdc-notched-outline__leading { + border-radius: 8px 0 0 8px; + } + + .mdc-notched-outline__trailing { + border-radius: 0 8px 8px 0; + } + } + + .mat-mdc-form-field-icon-prefix { + padding: 0 6px 0 8px; + color: $text-muted; + font-size: 16px; + } + + input { + font-size: 13px; + } + } +} + +.cv-action-buttons { + display: flex; + gap: 8px; + margin-left: auto; + flex-shrink: 0; +} + +.cv-btn { + font-size: 12px; + font-weight: 600; + border-radius: 8px !important; + height: 36px; + padding: 0 16px; + font-family: 'DM Sans', Roboto, sans-serif; + + fa-icon { + margin-right: 4px; + font-size: 11px; + } +} + +.cv-btn-approve { + border-color: #16a34a; + color: #16a34a; + + &:hover { + background: #f0fdf4; + } +} + +.type-badge { + display: inline-flex; + align-items: center; + padding: 2px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: 600; + background: #dbeafe; + color: #1e40af; + + &--current { + background: #ede9fe; + color: #5b21b6; + } + + &--fd { + background: #fef3c7; + color: #92400e; + } + + &--rd { + background: #d1fae5; + color: #065f46; + } +} + +.status-badge { + display: inline-flex; + align-items: center; + padding: 2px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: 600; + background: #fef9c3; + color: #854d0e; + + &--pending { + background: #fef9c3; + color: #854d0e; + } +} + +.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; + } +} diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts new file mode 100644 index 000000000..fde54a567 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts @@ -0,0 +1,178 @@ +/** + * 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 { SelectionModel } from '@angular/cdk/collections'; +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 { MatCheckbox } from '@angular/material/checkbox'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; + +import { TasksService } from '../../tasks.service'; +import { SettingsService } from 'app/settings/settings.service'; +import { Dates } from 'app/core/utils/dates'; +import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component'; +import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base'; +import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base'; +import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; + +@Component({ + selector: 'mifosx-pending-account', + templateUrl: './pending-account.component.html', + styleUrls: ['./pending-account.component.scss'], + imports: [ + ...STANDALONE_SHARED_IMPORTS, + FaIconComponent, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCheckbox, + MatCellDef, + MatCell, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + MatIcon + ] +}) +export class PendingAccountComponent { + private route = inject(ActivatedRoute); + private router = inject(Router); + private dialog = inject(MatDialog); + private dateUtils = inject(Dates); + private settingsService = inject(SettingsService); + private tasksService = inject(TasksService); + + dataSource: MatTableDataSource; + selection: SelectionModel; + showData = false; + + displayedColumns: string[] = [ + 'select', + 'accountNo', + 'clientName', + 'productName', + 'accountType', + 'officeName', + 'fieldOfficerName', + 'submittedOnDate', + 'status' + ]; + + constructor() { + this.route.data.subscribe((data: { pendingAccountsData: any }) => { + // status 100 = submitted and pending approval only; exclude active/approved/etc. + const items = (data.pendingAccountsData?.pageItems || []).filter((a: any) => a.status?.id === 100); + this.showData = items.length > 0; + this.dataSource = new MatTableDataSource(items); + this.selection = new SelectionModel(true, []); + }); + } + + isAllSelected() { + return this.selection.selected.length === this.dataSource.data.length; + } + + masterToggle() { + this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach((row) => this.selection.select(row)); + } + + checkboxLabel(row?: any): string { + if (!row) return `${this.isAllSelected() ? 'deselect' : 'select'} all`; + return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row`; + } + + applyFilter(filterValue: string = '') { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + approveAccounts() { + const formfields: FormfieldBase[] = [ + new DatepickerBase({ + controlName: 'approvedOnDate', + label: 'Approved On Date', + value: new Date(), + type: 'datetime-local', + required: true + }) + ]; + const dialogRef = this.dialog.open(FormDialogComponent, { + data: { + title: 'Enter Approval Date', + layout: { addButtonText: 'Confirm' }, + formfields + } + }); + dialogRef.afterClosed().subscribe((response: any) => { + if (response?.data) { + this.bulkApprove(response.data); + } + }); + } + + 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; + 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(); + } + }); + }); + } + + formatDate(date: any): string { + if (!date) return ''; + if (Array.isArray(date)) { + const d = new Date(date[0], date[1] - 1, date[2]); + return d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }); + } + return date; + } + + reload() { + const url = this.router.url; + this.router + .navigateByUrl('/checker-inbox-and-tasks', { skipLocationChange: true }) + .then(() => this.router.navigate([url])); + } +} diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.html b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.html new file mode 100644 index 000000000..d35bc289b --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.html @@ -0,0 +1,98 @@ + + +
+ @if (showData) { +
+ + search + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Account No{{ account.accountNo }}Client Name{{ account.clientName }}Product{{ account.savingsProductName || account.productName }}Type + + {{ account.accountType }} + + Office{{ account.officeName }}Field Officer{{ account.fieldOfficerName || '—' }}Submitted On + {{ formatDate(account.timeline?.submittedOnDate) }} + Rejected On + {{ formatDate(account.timeline?.rejectedOnDate) }} + Status + {{ account.status?.value }} +
+
+ } + + @if (!showData) { +
+ +

No rejected accounts

+

There are no rejected savings accounts to display.

+
+ } +
diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.scss b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.scss new file mode 100644 index 000000000..6bf43adb7 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.scss @@ -0,0 +1,138 @@ +/** + * 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; + +.cv-tab-content { + padding: 16px 0; +} + +.cv-action-bar { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 16px; + flex-wrap: wrap; +} + +.cv-search-field { + flex: 1; + min-width: 200px; + max-width: 320px; + + ::ng-deep { + .mat-mdc-form-field-flex { + height: 36px; + } + + .mat-mdc-form-field-infix { + padding: 6px 0; + min-height: 36px; + } + + .mat-mdc-form-field-subscript-wrapper { + height: 0; + min-height: 0; + } + + .mdc-notched-outline { + .mdc-notched-outline__leading { + border-radius: 8px 0 0 8px; + } + + .mdc-notched-outline__trailing { + border-radius: 0 8px 8px 0; + } + } + + .mat-mdc-form-field-icon-prefix { + padding: 0 6px 0 8px; + color: $text-muted; + font-size: 16px; + } + + input { + font-size: 13px; + } + } +} + +.type-badge { + display: inline-flex; + align-items: center; + padding: 2px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: 600; + background: #dbeafe; + color: #1e40af; + + &--current { + background: #ede9fe; + color: #5b21b6; + } + + &--fd { + background: #fef3c7; + color: #92400e; + } + + &--rd { + background: #d1fae5; + color: #065f46; + } +} + +.status-badge { + display: inline-flex; + align-items: center; + padding: 2px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: 600; + + &--rejected { + background: #fee2e2; + color: #991b1b; + } +} + +.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; + } +} diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.ts b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.ts new file mode 100644 index 000000000..04fe2ad91 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component.ts @@ -0,0 +1,87 @@ +/** + * 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 } from '@angular/router'; +import { + MatTableDataSource, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCellDef, + MatCell, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow +} from '@angular/material/table'; +import { MatIcon } from '@angular/material/icon'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; +import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; + +@Component({ + selector: 'mifosx-rejected-account', + templateUrl: './rejected-account.component.html', + styleUrls: ['./rejected-account.component.scss'], + imports: [ + ...STANDALONE_SHARED_IMPORTS, + FaIconComponent, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCellDef, + MatCell, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + MatIcon + ] +}) +export class RejectedAccountComponent { + private route = inject(ActivatedRoute); + + dataSource: MatTableDataSource; + showData = false; + + displayedColumns: string[] = [ + 'accountNo', + 'clientName', + 'productName', + 'accountType', + 'officeName', + 'fieldOfficerName', + 'submittedOnDate', + 'rejectedOnDate', + 'status' + ]; + + constructor() { + this.route.data.subscribe((data: { rejectedAccountsData: any }) => { + // status 500 = rejected only; strip out any non-rejected records + const items = (data.rejectedAccountsData?.pageItems || []).filter((a: any) => a.status?.id === 500); + 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 ''; + if (Array.isArray(date)) { + const d = new Date(date[0], date[1] - 1, date[2]); + return d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }); + } + return date; + } +} diff --git a/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html b/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html index da6dc75d5..264703328 100644 --- a/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html +++ b/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html @@ -82,6 +82,30 @@ Reschedule Loan + + + Pending Account + + + + Reject Account + diff --git a/src/app/tasks/common-resolvers/getPendingAccounts.resolver.ts b/src/app/tasks/common-resolvers/getPendingAccounts.resolver.ts new file mode 100644 index 000000000..c6e10dbca --- /dev/null +++ b/src/app/tasks/common-resolvers/getPendingAccounts.resolver.ts @@ -0,0 +1,49 @@ +/** + * 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, forkJoin, of } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { TasksService } from '../tasks.service'; + +@Injectable() +export class GetPendingAccounts implements Resolve { + private tasksService = inject(TasksService); + + resolve(): Observable { + return forkJoin({ + savings: this.tasksService.getPendingSavingsAccounts().pipe(catchError(() => of({ pageItems: [] }))), + current: this.tasksService.getPendingCurrentAccounts().pipe(catchError(() => of([]))), + offices: this.tasksService.getAllOffices().pipe(catchError(() => of([]))) + }).pipe( + map((results) => { + const officeMap: Record = {}; + (results.offices || []).forEach((o: any) => { + officeMap[o.id] = o.name; + }); + + const savingsItems = (results.savings?.pageItems || []).map((a: any) => ({ + ...a, + officeName: officeMap[a.officeId] || a.officeName || '', + fieldOfficerName: a.fieldOfficerName || '', + accountType: a.depositType?.value || 'Savings' + })); + + const currentItems = (Array.isArray(results.current) ? results.current : results.current?.pageItems || []).map( + (a: any) => ({ ...a, accountType: 'Current' }) + ); + + return { pageItems: [ + ...savingsItems, + ...currentItems + ] }; + }) + ); + } +} diff --git a/src/app/tasks/common-resolvers/getRejectedAccounts.resolver.ts b/src/app/tasks/common-resolvers/getRejectedAccounts.resolver.ts new file mode 100644 index 000000000..526c9f658 --- /dev/null +++ b/src/app/tasks/common-resolvers/getRejectedAccounts.resolver.ts @@ -0,0 +1,51 @@ +/** + * 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, forkJoin, of } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { TasksService } from '../tasks.service'; + +@Injectable() +export class GetRejectedAccounts implements Resolve { + private tasksService = inject(TasksService); + + resolve(): Observable { + return forkJoin({ + savings: this.tasksService.getRejectedSavingsAccounts().pipe(catchError(() => of({ pageItems: [] }))), + current: this.tasksService.getRejectedCurrentAccounts().pipe(catchError(() => of([]))), + offices: this.tasksService.getAllOffices().pipe(catchError(() => of([]))) + }).pipe( + map((results) => { + const officeMap: Record = {}; + (results.offices || []).forEach((o: any) => { + officeMap[o.id] = o.name; + }); + + const savingsItems = (results.savings?.pageItems || []) + .filter((a: any) => a.status?.id === 500) + .map((a: any) => ({ + ...a, + officeName: officeMap[a.officeId] || a.officeName || '', + fieldOfficerName: a.fieldOfficerName || '', + accountType: a.depositType?.value || 'Savings' + })); + + const currentItems = (Array.isArray(results.current) ? results.current : results.current?.pageItems || []) + .filter((a: any) => a.status?.id === 500) + .map((a: any) => ({ ...a, accountType: 'Current' })); + + return { pageItems: [ + ...savingsItems, + ...currentItems + ] }; + }) + ); + } +} diff --git a/src/app/tasks/tasks-routing.module.ts b/src/app/tasks/tasks-routing.module.ts index d7c17a779..2316adfec 100644 --- a/src/app/tasks/tasks-routing.module.ts +++ b/src/app/tasks/tasks-routing.module.ts @@ -20,6 +20,8 @@ import { ClientApprovalComponent } from './checker-inbox-and-tasks-tabs/client-a import { LoanApprovalComponent } from './checker-inbox-and-tasks-tabs/loan-approval/loan-approval.component'; import { LoanDisbursalComponent } from './checker-inbox-and-tasks-tabs/loan-disbursal/loan-disbursal.component'; import { RescheduleLoanComponent } from './checker-inbox-and-tasks-tabs/reschedule-loan/reschedule-loan.component'; +import { PendingAccountComponent } from './checker-inbox-and-tasks-tabs/pending-account/pending-account.component'; +import { RejectedAccountComponent } from './checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component'; import { ViewCheckerInboxComponent } from './view-checker-inbox/view-checker-inbox.component'; /** Custom Resolvers */ @@ -31,6 +33,8 @@ import { GetLoansToBeDisbursed } from './common-resolvers/getLoansToBeDisbursed. import { GetRescheduleLoans } from './common-resolvers/getRescheduleLoans.resolver'; import { MakerCheckerTemplate } from './common-resolvers/makerCheckerTemplate.resolver'; import { GetCheckerInboxDetailResolver } from './common-resolvers/getCheckerInboxDetail.resolver'; +import { GetPendingAccounts } from './common-resolvers/getPendingAccounts.resolver'; +import { GetRejectedAccounts } from './common-resolvers/getRejectedAccounts.resolver'; /** Tasks Routes */ const routes: Routes = [ @@ -81,6 +85,22 @@ const routes: Routes = [ resolve: { rescheduleLoansData: GetRescheduleLoans } + }, + { + path: 'pending-account', + component: PendingAccountComponent, + data: { title: 'Pending Account' }, + resolve: { + pendingAccountsData: GetPendingAccounts + } + }, + { + path: 'rejected-account', + component: RejectedAccountComponent, + data: { title: 'Rejected Account' }, + resolve: { + rejectedAccountsData: GetRejectedAccounts + } } ] }, @@ -111,7 +131,9 @@ const routes: Routes = [ GetLoansToBeDisbursed, GetRescheduleLoans, MakerCheckerTemplate, - GetCheckerInboxDetailResolver + GetCheckerInboxDetailResolver, + GetPendingAccounts, + GetRejectedAccounts ] }) export class TasksRoutingModule {} diff --git a/src/app/tasks/tasks.service.ts b/src/app/tasks/tasks.service.ts index b3f28f0a3..38f128e0c 100644 --- a/src/app/tasks/tasks.service.ts +++ b/src/app/tasks/tasks.service.ts @@ -102,6 +102,76 @@ export class TasksService { return this.http.get('/rescheduleloans', { params: httpParams }); } + /** + * Get savings accounts submitted and pending approval (status 100) + */ + getPendingSavingsAccounts(): Observable { + const httpParams = new HttpParams() + .set('limit', '1000') + .set('status', 'submittedAndPendingApproval') + .set('sqlSearch', 's.status_enum = 100'); + return this.http.get('/savingsaccounts', { params: httpParams }); + } + + /** + * Get current accounts submitted and pending approval (status 100) + */ + getPendingCurrentAccounts(): Observable { + const httpParams = new HttpParams().set('limit', '1000').set('status', 'submittedAndPendingApproval'); + return this.http.get('/currentaccounts', { params: httpParams }); + } + + /** + * Get savings accounts that have been rejected (status 500) + */ + getRejectedSavingsAccounts(): Observable { + const httpParams = new HttpParams() + .set('limit', '1000') + .set('status', 'rejected') + .set('sqlSearch', 's.status_enum = 500'); + return this.http.get('/savingsaccounts', { params: httpParams }); + } + + /** + * Get current accounts that have been rejected (status 500) + */ + getRejectedCurrentAccounts(): Observable { + const httpParams = new HttpParams().set('limit', '1000').set('status', 'rejected'); + return this.http.get('/currentaccounts', { params: httpParams }); + } + + /** + * Approve a savings account + */ + approveSavingsAccount(accountId: any, data: any): Observable { + const httpParams = new HttpParams().set('command', 'approve'); + return this.http.post(`/savingsaccounts/${accountId}`, data, { params: httpParams }); + } + + /** + * Approve a fixed deposit account + */ + approveFDAccount(accountId: any, data: any): Observable { + const httpParams = new HttpParams().set('command', 'approve'); + return this.http.post(`/fixeddepositaccounts/${accountId}`, data, { params: httpParams }); + } + + /** + * Approve a recurring deposit account + */ + approveRDAccount(accountId: any, data: any): Observable { + const httpParams = new HttpParams().set('command', 'approve'); + return this.http.post(`/recurringdepositaccounts/${accountId}`, data, { params: httpParams }); + } + + /** + * Approve a current account + */ + approveCurrentAccount(accountId: any, data: any): Observable { + const httpParams = new HttpParams().set('command', 'approve'); + return this.http.post(`/currentaccounts/${accountId}`, data, { params: httpParams }); + } + /** * Submit data in batches. * @param {data} Data to be submitted