Files
cbsnexora/src/app/clients/clients-view/general-tab/general-tab.component.html
T
nitesh f0e059c621
Publish Image in Docker Hub / build (push) Canceled after 0s
Playwright E2E Tests / Run Playwright Tests (push) Canceled after 0s
Tests / testRigor (push) Canceled after 0s
build-run / Run Lint, Build and Deploy (push) Canceled after 0s
feat(deposits): FD Renewal History tab, redesigned Payment action, and renewal-aware Transactions/certificate
WHAT THIS CHANGES
==================
Frontend counterpart to the backend FD in-place renewal, senior-citizen
rate, and Payment action work.

1. RENEWAL HISTORY TAB (new) -- fixed-deposit-account-view/renewal-history-tab/.
   A vertical timeline, one card per term of the FD, oldest first. Backend
   data arrives as a list of lowercase-keyed maps (Postgres unquoted SQL
   aliases), which the component normalises. Includes term-rate-chart-dialog,
   a popup showing one term's full rate-by-tenure chart, including the
   senior-citizen column, with an "Applied" badge on the rate that was
   actually used. Route added in fixed-deposits-routing.module.ts, tab
   link added in fixed-deposit-account-view.component.html (shown only
   when the account has renewal history).

2. PAYMENT DIALOG (new) -- fixed-deposit-account-view/custom-dialogs/payment-dialog/.
   Card-based picker for the four supported closure types (Transfer to
   Savings, Re-Invest Principal and Interest, Re-Invest Principal Only,
   Partial Re-Invest), with Withdraw Deposit filtered out client-side.
   Fetches its own template via a new fixedDepositsService method
   (getFixedDepositsAccountPaymentTemplate, command=payment) rather than
   reusing the Close template, since the Payment template is the only one
   the backend includes PARTIAL_REINVEST in.
   The Partial Re-Invest amount cap is date-dependent: the backend bounds
   it against the account balance AFTER posting interest to the chosen
   closed-on date, which lands on the maturity amount on or after
   maturity and on the current balance before it. The dialog mirrors this
   (reinvestCap / processingOnOrAfterMaturity) so the shown split actually
   adds up and the client-side validator agrees with the server. This was
   wrong in an earlier pass of this work (compared against a fixed figure
   regardless of date) and was caught and fixed via a real reconciliation
   check (77000 + 23000 did not equal the displayed total) before this
   commit.
   Added: a loading-failure state (previously the spinner ran forever on
   a failed template fetch), an inline submit-error message (previously a
   failed POST left the dialog open with no feedback), an empty-savings-
   accounts hint, and accessibility attributes on the option cards
   (role="radio", aria-checked, a visible check icon, focus-visible
   outline) since selection was previously colour-only.

3. TRANSACTIONS TAB -- merges synthetic "FD Renewed" marker rows into the
   real transaction list, since an in-place renewal posts no actual
   ledger transaction and would otherwise look like the balance changed
   for no reason.

4. INTEREST RATE CHART TAB -- added the senior-citizen rate column.

5. DEPOSIT CERTIFICATE DIALOG -- lists the full renewal history on FD
   certificates. renewalCount is renewalHistory.length - 1 (the first
   row is the original term, not a renewal); an earlier version of this
   used the raw row count and overstated the renewal count by one on a
   customer-facing document, caught and fixed before this commit.

6. CLIENTS GENERAL TAB -- fixedDepositAccountsForDisplay folds a renewed
   FD's superseded terms out of the account list (each renewal used to
   show as two unrelated accounts, one Closed and one Active). Memoised
   on the source array's identity so it does not rebuild, and rebind the
   table, on every change-detection tick. Only rewrites FD rows; Savings,
   RD, Current, and Share account rows pass through this getter
   untouched, and the RD/Savings sections of the template were left
   bound directly to the original savingAccounts array.

KNOWN CAVEATS
=============
  - This depends on the paired backend commit (same date, "feat(deposits):
    FD in-place renewal, senior-citizen rate persistence, and Payment
    action"). Deploying this frontend without that backend change means
    the Payment dialog and Renewal History tab will call endpoints that
    do not exist yet.
  - Renewal-history rows rely on the backend returning lowercase column
    keys (a Postgres-specific behaviour of unquoted SQL aliases via
    JdbcTemplate). Confirmed correct against this project's Postgres
    dev database; if this project ever runs on a different database
    engine, that assumption would need re-checking.
  - src/environments/.env.ts is intentionally excluded from this commit;
    it is a local build-version stamp file that should never be
    committed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 16:46:22 +05:30

1248 lines
56 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 class="section-header__right">
<button mat-raised-button color="primary" (click)="toggleRecurringAccountsOverview()">
{{ viewAccountsLabel(showClosedRecurringAccounts) | translate }}
</button>
</div>
</div>
@if (!showClosedRecurringAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="savingAccounts | accountsFilter: 'saving' : 'open' : '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="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.submittedAndPendingApproval && !element.status.active) {
<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]="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 Recurring 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]="['../', 'recurring-deposits-accounts', row.id, 'general']"
class="select-row"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'open' : 'isRecurring')?.length === 0 ? ['no-data'] : []
"
></tr>
</table>
</div>
}
<!-- Closed Recurring Deposit Accounts -->
@if (showClosedRecurringAccounts) {
<div class="table-wrapper">
<table mat-table [dataSource]="savingAccounts | accountsFilter: 'saving' : 'closed' : '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="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 Recurring 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]="['../', 'recurring-deposits-accounts', row.id, 'general']"
class="select-row"
></tr>
<tr
mat-footer-row
*matFooterRowDef="
(savingAccounts | accountsFilter: 'saving' : 'closed' : '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>