Files
cbsnexora/src/app/clients/clients-view/general-tab/general-tab.component.html
T

1204 lines
54 KiB
HTML

<!--
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="general-tab-container mat-typography">
<!-- Performance History - KPI Stat Cards -->
<section class="performance-section">
<h3 class="performance-title">{{ 'labels.heading.Performance History' | translate }}</h3>
<div class="stat-cards-grid">
<div class="stat-card stat-card--orange">
<div class="stat-card__icon">
<i class="fa fa-university"></i>
</div>
<div class="stat-card__content">
<span class="stat-card__label">{{ 'labels.inputs.Total Savings' | translate }}</span>
<span class="stat-card__value">{{ performanceHistory.totalSavings | formatNumber }}</span>
</div>
</div>
<div class="stat-card stat-card--teal">
<div class="stat-card__icon">
<i class="fa fa-piggy-bank"></i>
</div>
<div class="stat-card__content">
<span class="stat-card__label">{{ 'labels.inputs.No. of Active Savings' | translate }}</span>
<span class="stat-card__value">{{ performanceHistory.activeSavings }}</span>
</div>
</div>
<div class="stat-card stat-card--blue">
<div class="stat-card__icon">
<i class="fa fa-refresh"></i>
</div>
<div class="stat-card__content">
<span class="stat-card__label">{{ 'labels.inputs.No. Of Loan Cycles' | translate }}</span>
<span class="stat-card__value">{{ performanceHistory.loanCycle }}</span>
</div>
</div>
<div class="stat-card stat-card--green">
<div class="stat-card__icon">
<i class="fa fa-credit-card"></i>
</div>
<div class="stat-card__content">
<span class="stat-card__label">{{ 'labels.inputs.No. of Active Loans' | translate }}</span>
<span class="stat-card__value">{{ performanceHistory.activeLoans }}</span>
</div>
</div>
<div class="stat-card stat-card--purple">
<div class="stat-card__icon">
<i class="fa fa-money"></i>
</div>
<div class="stat-card__content">
<span class="stat-card__label">{{ 'labels.inputs.Last Loan Amount' | translate }}</span>
<span class="stat-card__value">{{ performanceHistory.lastLoanAmount | formatNumber }}</span>
</div>
</div>
</div>
</section>
<!-- Saving Accounts -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-bank section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Saving Accounts' | translate }}</h3>
<span class="section-header__badge">{{ pureSavingsCount }}</span>
</div>
<div class="section-header__right">
<button mat-raised-button color="primary" (click)="toggleSavingAccountsOverview()">
{{ viewAccountsLabel(showClosedSavingAccounts) | translate }}
</button>
</div>
</div>
@if (!showClosedSavingAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="savingAccounts | accountsFilter: 'saving' : 'open' : 'isSavings'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Savings Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Last Active">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Last Active' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.accountBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
@if (element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'savings-accounts', element.id, 'actions', 'Deposit']"
>
<i class="fa fa-arrow-up"></i>
</button>
}
@if (element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'savings-accounts', element.id, 'actions', 'Withdrawal']"
>
<i class="fa fa-arrow-down"></i>
</button>
}
@if (element.status.submittedAndPendingApproval) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'savings-accounts', element.id, 'actions', 'Approve']"
>
<i class="fa fa-check"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
[routerLink]="['../', 'savings-accounts', element.id, 'actions', 'Undo Approval']"
>
<i class="fa fa-undo"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
[routerLink]="['../', 'savings-accounts', element.id, 'actions', 'Activate']"
>
<i class="fa fa-check-circle"></i>
</button>
}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="openSavingsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Active Saving Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="openSavingsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: openSavingsColumns"
[routerLink]="['../', 'savings-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'open' : 'isSavings')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
<!-- Closed Saving Accounts -->
@if (showClosedSavingAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="savingAccounts | accountsFilter: 'saving' : 'closed' : 'isSavings'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Savings Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Closed Date' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.timeline.closedOnDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="closedSavingsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Closed Saving Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="closedSavingsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: closedSavingsColumns"
[routerLink]="['../', 'savings-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'closed' : 'isSavings')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
</section>
<!-- Current Accounts -->
@if (currentAccounts?.length > 0) {
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-credit-card section-header__icon"></i>
<h3 class="section-header__title">Current Accounts</h3>
<span class="section-header__badge">{{ currentAccounts?.length || 0 }}</span>
</div>
</div>
<div class="table-wrapper">
<table mat-table [dataSource]="currentAccounts">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>Current Account Product</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Last Active">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Last Active' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.accountBalance | currency: element.currency?.code || 'INR' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
@if (element.status.submittedAndPendingApproval) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'current-accounts', element.id, 'actions', 'Approve']"
>
<i class="fa fa-check"></i>
</button>
}
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'current-accounts', element.id, 'general']"
>
<i class="fa fa-eye"></i>
</button>
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="openSavingsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">No Active Current Accounts Available</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="openSavingsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: openSavingsColumns"
[routerLink]="['../', 'current-accounts', row.id, 'general']"
></tr>
<tr mat-footer-row *matFooterRowDef="currentAccounts?.length === 0 ? ['no-data'] : []"></tr>
</table>
</div>
</section>
}
<!-- Upcoming Charges -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-bolt section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Upcoming Charges' | translate }}</h3>
<span class="section-header__badge">{{ upcomingCharges?.length || 0 }}</span>
</div>
<div class="section-header__right">
<button
mat-raised-button
color="primary"
[routerLink]="['../', 'charges', 'overview']"
*mifosxHasPermission="'READ_CLIENTCHARGE'"
>
{{ 'labels.buttons.Charges Overview' | translate }}
</button>
</div>
</div>
<div class="table-wrapper">
<table mat-table [dataSource]="upcomingCharges">
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="!(element.isWaived || element.isPaid) | statusLookup"></i>
{{ element.name }}
</td>
</ng-container>
<ng-container matColumnDef="Due as of">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Due as of' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.dueDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Due">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Due' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">{{ element.amount | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="Paid">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Paid' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">{{ element.amountPaid | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="Waived">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Waived' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">{{ element.amountWaived | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="Outstanding">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Outstanding' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">{{ element.amountOutstanding | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'charges', element.id, 'pay']"
*mifosxHasPermission="'PAY_CLIENTCHARGE'"
>
<i class="fa fa-dollar"></i>
</button>
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event); waiveCharge(element.id, element.clientId)"
*mifosxHasPermission="'WAIVE_CLIENTCHARGE'"
>
<i class="fa fa-flag"></i>
</button>
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="upcomingChargesColumns.length">
<div class="table-empty-state">
<i class="fa fa-inbox table-empty-state__icon"></i>
<p class="table-empty-state__text">{{ 'labels.messages.No Upcoming Charges Available' | translate }}</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="upcomingChargesColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: upcomingChargesColumns"
[routerLink]="['../', 'charges', row.id]"
></tr>
<tr mat-footer-row *matFooterRowDef="upcomingCharges?.length === 0 ? ['no-data'] : []"></tr>
</table>
</div>
</section>
<!-- Fixed Deposit Accounts -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-lock section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Fixed Deposit Accounts' | translate }}</h3>
</div>
<div class="section-header__right">
<button mat-raised-button color="primary" (click)="toggleFixedAccountsOverview()">
{{ viewAccountsLabel(showClosedFixedAccounts) | translate }}
</button>
</div>
</div>
@if (!showClosedFixedAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="fixedDepositAccountsForDisplay | accountsFilter: 'saving' : 'open' : 'isFixed'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number
accountNo="{{ element.fdAccountNumber || element.accountNo }}"
></mifosx-account-number>
@if (element.renewalCycleNo) {
<span class="fd-renewal-badge">Renewal {{ element.renewalCycleNo }}</span>
}
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Fixed Deposit Product' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.productName }}</td>
</ng-container>
<ng-container matColumnDef="Last Active">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Last Active' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.accountBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
@if (element.status.submittedAndPendingApproval) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'fixed-deposits-accounts', element.id, 'actions', 'Approve']"
>
<i class="fa fa-check"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
[routerLink]="['../', 'fixed-deposits-accounts', element.id, 'actions', 'Undo Approval']"
>
<i class="fa fa-undo"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
[routerLink]="['../', 'fixed-deposits-accounts', element.id, 'actions', 'Activate']"
>
<i class="fa fa-check-circle"></i>
</button>
}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="openSavingsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Active Fixed Deposit Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="openSavingsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: openSavingsColumns"
[routerLink]="['../', 'fixed-deposits-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'open' : 'isFixed')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
<!-- Closed Fixed Deposit Accounts -->
@if (showClosedFixedAccounts) {
<div class="table-wrapper">
<table
mat-table
[dataSource]="fixedDepositAccountsForDisplay | accountsFilter: 'saving' : 'closed' : 'isFixed'"
>
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number
accountNo="{{ element.fdAccountNumber || element.accountNo }}"
></mifosx-account-number>
@if (element.renewalCycleNo) {
<span class="fd-renewal-badge">Renewal {{ element.renewalCycleNo }}</span>
}
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Fixed Deposit Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Closed Date' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.timeline.closedOnDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="closedSavingsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Closed Fixed Deposit Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="closedSavingsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: closedSavingsColumns"
[routerLink]="['../', 'fixed-deposits-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'closed' : 'isFixed')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
</section>
<!-- Recurring Deposit Accounts -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-calendar section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Recurring Deposit Accounts' | translate }}</h3>
</div>
</div>
<!-- Active and ended recurring deposits share one table; the Status column says how each one ended (matured or
closed early), so the client's RD history stays visible without switching views. -->
@if (savingAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="savingAccounts | accountsFilter: 'saving' : 'all' : 'isRecurring'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Saving Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Recurring Deposit Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Status">
<th mat-header-cell *matHeaderCellDef>Status</th>
<td mat-cell *matCellDef="let element">
<span class="rd-status" [class.rd-status--ended]="element.timeline?.closedOnDate">{{ rdStatusLabel(element) }}</span>
@if (element.timeline?.closedOnDate) {
<div class="rd-status__date">on {{ element.timeline.closedOnDate | dateFormat }}</div>
}
</td>
</ng-container>
<ng-container matColumnDef="Last Active">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Last Active' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.accountBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
@if (element.status.submittedAndPendingApproval) {
<button
class="account-action-button"
mat-raised-button
*mifosxHasPermission="'APPROVE_SAVINGSACCOUNT'"
[routerLink]="['../', 'recurring-deposits-accounts', element.id, 'actions', 'Approve']"
color="primary"
>
<i class="fa fa-check"></i>
</button>
}
@if (element.status.approved) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
*mifosxHasPermission="'APPROVALUNDO_SAVINGSACCOUNT'"
[routerLink]="['../', 'recurring-deposits-accounts', element.id, 'actions', 'Undo Approval']"
>
<i class="fa fa-undo"></i>
</button>
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
*mifosxHasPermission="'ACTIVATE_SAVINGSACCOUNT'"
[routerLink]="['../', 'recurring-deposits-accounts', element.id, 'actions', 'Activate']"
>
<i class="fa fa-check-circle"></i>
</button>
}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="recurringColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Active Recurring Deposit Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="recurringColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: recurringColumns"
[routerLink]="['../', 'recurring-deposits-accounts', row.id, 'general']"
class="select-row"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'all' : 'isRecurring')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
</section>
<!-- Loan Accounts -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-credit-card section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Loan Accounts' | translate }}</h3>
<span class="section-header__badge">{{ loanAccounts?.length || 0 }}</span>
</div>
<div class="section-header__right">
<button mat-raised-button color="primary" (click)="toggleLoanAccountsOverview()">
{{ viewAccountsLabel(showClosedLoanAccounts) | translate }}
</button>
</div>
</div>
@if (!showClosedLoanAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="loanAccounts | accountsFilter: 'loan'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i
class="fa fa-stop"
[ngClass]="element.inArrears ? 'status-active-overdue' : (element.status.code | statusLookup)"
></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Loan Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Original Loan">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
<td mat-cell *matCellDef="let element">
{{ element.originalLoan | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Loan Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Loan Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.loanBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Amount Paid">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Amount Paid' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.amountPaid | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Type">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
<i
class="fa fa-large"
[ngClass]="element.loanType.value === 'Individual' ? 'fa-user' : 'fa-group'"
matTooltip="{{ element.loanType.value }}"
matTooltipPosition="above"
></i>
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
<!-- Print Icon -->
<button
class="account-action-button"
mat-raised-button
color="accent"
matTooltip="{{ 'tooltips.Print Loan Application' | translate }}"
matTooltipPosition="above"
aria-label="{{ 'tooltips.Print Loan Application' | translate }}"
(click)="openLoanApplicationReport($event, element.id)"
>
<i class="fa fa-print"></i>
</button>
@if (element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
matTooltip="{{ 'tooltips.Make Repayment' | translate }}"
matTooltipPosition="above"
(click)="routeEdit($event)"
[routerLink]="['../', 'loans-accounts', element.id, 'actions', 'Make Repayment']"
>
<i class="fa fa-dollar"></i>
</button>
}
@if (element.status.pendingApproval) {
<span>
<button
class="account-action-button"
mat-raised-button
color="primary"
matTooltip="{{ 'tooltips.Approve' | translate }}"
matTooltipPosition="above"
*mifosxHasPermission="'APPROVE_LOAN'"
(click)="routeEdit($event)"
[routerLink]="['../', 'loans-accounts', element.id, 'actions', 'Approve']"
>
<i class="fa fa-check"></i>
</button>
</span>
}
@if (!element.status.pendingApproval && !element.status.active && !element.status.overpaid) {
<span>
<button
class="account-action-button"
mat-raised-button
color="primary"
matTooltip="{{ 'tooltips.Disburse' | translate }}"
matTooltipPosition="above"
*mifosxHasPermission="'DISBURSE_LOAN'"
(click)="routeEdit($event)"
[routerLink]="['../', 'loans-accounts', element.id, 'actions', 'Disburse']"
>
<i class="fa fa-flag"></i>
</button>
</span>
}
@if (!element.status.pendingApproval && !element.status.active && element.status.overpaid) {
<span>
<button
class="account-action-button"
mat-raised-button
color="primary"
matTooltip="{{ 'tooltips.Transfer Funds' | translate }}"
matTooltipPosition="above"
*mifosxHasPermission="'DISBURSE_LOAN'"
(click)="routeEdit($event); routeTransferFund(element.id)"
>
<i class="fa fa-exchange"></i>
</button>
</span>
}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="openLoansColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Active Loan Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="openLoansColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: openLoansColumns"
[routerLink]="['../', 'loans-accounts', row.id, 'general']"
class="select-row"
></tr>
<tr
mat-footer-row
*matFooterRowDef="(loanAccounts | accountsFilter: 'loan')?.length === 0 ? ['no-data'] : []"
></tr>
</table>
</div>
}
<!-- Closed Loan Accounts -->
@if (showClosedLoanAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="loanAccounts | accountsFilter: 'loan' : 'closed'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i
class="fa fa-stop"
[ngClass]="element.inArrears ? 'status-active-overdue' : (element.status.code | statusLookup)"
></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Loan Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Original Loan">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Loan Balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Loan Balance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.loanBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Amount Paid">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Amount Paid' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{ element.accountBalance | currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2' }}
</td>
</ng-container>
<ng-container matColumnDef="Type">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
<i
class="fa fa-large"
[ngClass]="element.loanType.value === 'Individual' ? 'fa-user' : 'fa-group'"
matTooltip=" {{ element.loanType.value }}"
matTooltipPosition="above"
></i>
</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Closed Date' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.timeline.closedOnDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
<!-- Print Icon -->
<button
class="account-action-button"
mat-raised-button
color="accent"
matTooltip="{{ 'tooltips.Print Loan Application' | translate }}"
matTooltipPosition="above"
(click)="openLoanApplicationReport($event, element.id)"
>
<i class="fa fa-print"></i>
</button>
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="closedLoansColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Closed Loan Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="closedLoansColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: closedLoansColumns"
[routerLink]="['../', 'loans-accounts', row.id, 'general']"
class="select-row"
></tr>
<tr
mat-footer-row
*matFooterRowDef="(loanAccounts | accountsFilter: 'loan' : 'closed')?.length === 0 ? ['no-data'] : []"
></tr>
</table>
</div>
}
</section>
<!-- Collateral Data -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-shield section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.heading.Collateral Data' | translate }}</h3>
<span class="section-header__badge">{{ collaterals?.length || 0 }}</span>
</div>
<div class="section-header__right">
<button mat-raised-button color="primary" disabled>
{{ 'labels.buttons.View Collaterals' | translate }}
</button>
</div>
</div>
<div class="table-wrapper">
<table mat-table [dataSource]="collaterals">
<ng-container matColumnDef="ID">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.ID' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.collateralId }}</td>
</ng-container>
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
</ng-container>
<ng-container matColumnDef="Quantity">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Quantity' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">{{ element.quantity | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="Total Value">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Total Value' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{
element.basePrice * element.quantity
| currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2'
}}
</td>
</ng-container>
<ng-container matColumnDef="Total Collateral Value">
<th mat-header-cell class="r-amount" *matHeaderCellDef>
{{ 'labels.inputs.Total Collateral Value' | translate }}
</th>
<td mat-cell class="r-amount" *matCellDef="let element">
{{
(element.pctToBase * element.basePrice * element.quantity) / 100
| currency: element.currency?.code || 'USD' : 'symbol-narrow' : '1.2-2'
}}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="collateralsColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">{{ 'labels.messages.No Collateral Data Available' | translate }}</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="collateralsColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: collateralsColumns"
[routerLink]="['../', 'client-collateral', row.collateralId]"
></tr>
<tr mat-footer-row *matFooterRowDef="collaterals?.length === 0 ? ['no-data'] : []"></tr>
</table>
</div>
</section>
<!-- Shares Accounts -->
<section class="account-section">
<div class="section-header">
<div class="section-header__left">
<i class="fa fa-pie-chart section-header__icon"></i>
<h3 class="section-header__title">{{ 'labels.inputs.Shares Accounts' | translate }}</h3>
<span class="section-header__badge">{{ shareAccounts?.length || 0 }}</span>
</div>
<div class="section-header__right">
<button mat-raised-button color="primary" (click)="toggleShareAccountsOverview()">
{{ viewAccountsLabel(showClosedShareAccounts) | translate }}
</button>
</div>
</div>
@if (!showClosedShareAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="shareAccounts | accountsFilter: 'share'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Share Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Share Product' | translate }}</th>
<td mat-cell *matCellDef="let element">
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
</td>
</ng-container>
<ng-container matColumnDef="Approved Shares">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Approved Shares' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.totalApprovedShares }}</td>
</ng-container>
<ng-container matColumnDef="Pending For Approval Shares">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Pending For Approval Shares' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.totalPendingForApprovalShares }}</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let element">
@if (element.status.submittedAndPendingApproval) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'shares-accounts', element.id, 'actions', 'Approve']"
>
<i class="fa fa-check"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'shares-accounts', element.id, 'actions', 'Undo Approval']"
>
<i class="fa fa-undo"></i>
</button>
}
@if (!element.status.submittedAndPendingApproval && !element.status.active) {
<button
class="account-action-button"
mat-raised-button
color="primary"
(click)="routeEdit($event)"
[routerLink]="['../', 'shares-accounts', element.id, 'actions', 'Activate']"
>
<i class="fa fa-check-circle"></i>
</button>
}
</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="openSharesColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Active Share Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="openSharesColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: openSharesColumns"
[routerLink]="['../', 'shares-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="(shareAccounts | accountsFilter: 'share')?.length === 0 ? ['no-data'] : []"
></tr>
</table>
</div>
}
<!-- Closed Share Accounts -->
@if (showClosedShareAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="shareAccounts | accountsFilter: 'share' : 'closed'">
<ng-container matColumnDef="Account No">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Account No' | translate }}</th>
<td mat-cell *matCellDef="let element">
<i class="fa fa-stop" [ngClass]="element.status.code | statusLookup"></i>
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
</td>
</ng-container>
<ng-container matColumnDef="Share Account">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Share Product' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.productName }}</td>
</ng-container>
<ng-container matColumnDef="Approved Shares">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Approved Shares' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.totalApprovedShares }}</td>
</ng-container>
<ng-container matColumnDef="Pending For Approval Shares">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Pending For Approval Shares' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.totalPendingForApprovalShares }}</td>
</ng-container>
<ng-container matColumnDef="Closed Date">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Closed Date' | translate }}</th>
<td mat-cell *matCellDef="let element">{{ element.timeline.closedOnDate | dateFormat }}</td>
</ng-container>
<ng-container matColumnDef="no-data">
<td mat-footer-cell *matFooterCellDef [attr.colspan]="closedSharesColumns.length">
<div class="table-empty-state">
<i class="fa fa-folder-open-o table-empty-state__icon"></i>
<p class="table-empty-state__text">
{{ 'labels.messages.No Closed Share Accounts Available' | translate }}
</p>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="closedSharesColumns"></tr>
<tr
mat-row
*matRowDef="let row; columns: closedSharesColumns"
[routerLink]="['../', 'shares-accounts', row.id, 'general']"
></tr>
<tr
mat-footer-row
*matFooterRowDef="(shareAccounts | accountsFilter: 'share' : 'closed')?.length === 0 ? ['no-data'] : []"
></tr>
</table>
</div>
}
</section>
<!-- PDF Viewer Modal -->
<div *ngIf="showPdf" class="pdf-modal-overlay">
<div class="pdf-modal-content">
<button mat-icon-button class="pdf-modal-close" (click)="closePdf()" aria-label="Close PDF">
<span aria-hidden="true">&times;</span>
</button>
<embed [src]="pdfUrl" type="application/pdf" width="100%" height="600px" />
</div>
</div>
</div>