Four independent, self-contained changes bundled from this session's work:
1. Auto-derive Senior Citizen / Minor / Customer Segment instead of manual entry
Senior Citizen was a manual, staff-editable checkbox on FD/RD account
creation with no validation against the client's actual age -- this let
non-senior clients get the senior-citizen interest rate by mistake (found
twice on live test accounts, where m_savings_account.is_senior_citizen
was true despite the client being confirmed non-senior at the client
record level). Likewise "minor" client classification was hardcoded to
the age-18 threshold with no single source of truth, and FD/RD account
creation's "Customer Segment" (Individual / Non-Individual) had no
connection to the Individual/Non-Individual Legal Form already captured
at client creation.
- New src/app/clients/shared/client-age.util.ts centralises age/DOB
derivation: MINOR_AGE_THRESHOLD (now 10, was 18), SENIOR_CITIZEN_AGE_
THRESHOLD (60), AGE_OF_MAJORITY (18, kept separate from the minor
threshold -- majority date math is unrelated to the minor/adult
classification threshold), calculateAge/isMinorAge/isSeniorCitizenAge/
isIndividualClient/deriveSeniorCitizenStatus.
- FD/RD interest-rate-chart steps: Senior Citizen checkbox is now derived
from the client's DOB (age >= 60, individual clients only) and
disabled for manual editing; a hint explains why it is checked/
unchecked.
- Client general step and all four account-details-steps (savings,
current, FD, RD): replaced hardcoded 18/60 literals with the shared
helpers; "Must be below 18" hints now read the actual threshold.
- FD/RD account-details-steps: Customer Segment auto-selects to match
the client's Legal Form (exact match, not substring -- a substring
match would misclassify "Individual" as matching "Non-Individual").
- RD preview step: fixed a pre-existing display bug that always showed
the product's default Customer Segment instead of what was actually
selected on the account.
2. Fix wrong Account Name / Account Type on Disbursement Review screens
Clerk disbursement review and "My Disbursement Requests" showed the
account NUMBER instead of the holder's name, and always labelled the
account type "SAVINGS" regardless of the real account type (FD/RD/
Share/Loan), because transaction-entry.component.ts's account-type
mapping only checked for CA/CB and its account-name fallback chain
never tried clientName. Added creditEntryAccountType() covering
GL/CA/CB/FD/RD/SHR/LA, and accountTypeLabel() display helpers on both
review screens.
3. Stop reversed transactions from distorting displayed running balances
Passbook and Transactions tabs were including reversed transactions in
their client-side running-balance recalculation, so a reversed posting
(visible struck-through) still shifted the balance shown for every
transaction after it. Both now filter out txn.reversed before computing
running balances; Transactions tab also defaults "Hide Reversed" to on.
4. New Interest Schedule dialog on the FD account view
Added custom-dialogs/interest-schedule-dialog, opened from the FD
General tab, showing the account's period-by-period interest schedule.
Excludes src/environments/.env.ts (auto-generated build version/hash
stamp, regenerated on every build -- not meaningful to hand-commit).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
546 lines
23 KiB
HTML
546 lines
23 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="fdrc-wrapper">
|
||
<!-- ══ Chart Header Card ════════════════════════════════════════════════ -->
|
||
@if (interestRateChartData.length > 0) {
|
||
<div class="fdrc-header-card">
|
||
<div class="fdrc-header-card__left">
|
||
<div class="fdrc-header-card__icon">
|
||
<i class="fas fa-chart-line"></i>
|
||
</div>
|
||
<div>
|
||
<div class="fdrc-header-card__title">{{ chartName || 'Interest Rate Chart' }}</div>
|
||
@if (chartDescription) {
|
||
<div class="fdrc-header-card__desc">{{ chartDescription }}</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
<div class="fdrc-header-card__meta">
|
||
<span class="fdrc-pill" [class.fdrc-pill--active]="isActive" [class.fdrc-pill--inactive]="!isActive">
|
||
<i class="fas" [class.fa-check-circle]="isActive" [class.fa-times-circle]="!isActive"></i>
|
||
{{ isActive ? 'Active' : 'Inactive' }}
|
||
</span>
|
||
@if (fdType) {
|
||
<span
|
||
class="fdrc-pill fdrc-pill--type"
|
||
[class.fdrc-pill--single]="fdType === 'SINGLE'"
|
||
[class.fdrc-pill--double]="fdType === 'DOUBLE'"
|
||
[class.fdrc-pill--special]="fdType === 'SPECIAL'"
|
||
>
|
||
<i class="fas fa-tag"></i>
|
||
{{ fdTypeLabel }}
|
||
</span>
|
||
}
|
||
<div class="fdrc-header-card__dates">
|
||
<span class="fdrc-meta-item">
|
||
<i class="fas fa-calendar-check"></i>
|
||
From: <strong>{{ chartFromDate | dateFormat }}</strong>
|
||
</span>
|
||
@if (chartEndDate) {
|
||
<span class="fdrc-meta-item">
|
||
<i class="fas fa-calendar-times"></i>
|
||
To: <strong>{{ chartEndDate | dateFormat }}</strong>
|
||
</span>
|
||
}
|
||
</div>
|
||
@if (isPrimaryGroupingByAmount) {
|
||
<span class="fdrc-pill fdrc-pill--amount"> <i class="fas fa-layer-group"></i> Grouped by Amount </span>
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- ══ FD Type Rule Banner ══════════════════════════════════════════════ -->
|
||
@if (fdType) {
|
||
<div
|
||
class="fdrc-rule-banner"
|
||
[class.fdrc-rule-banner--single]="fdType === 'SINGLE'"
|
||
[class.fdrc-rule-banner--double]="fdType === 'DOUBLE'"
|
||
[class.fdrc-rule-banner--special]="fdType === 'SPECIAL'"
|
||
>
|
||
<div class="fdrc-rule-banner__icon">
|
||
@if (fdType === 'SINGLE') {
|
||
<i class="fas fa-hourglass-start"></i>
|
||
}
|
||
@if (fdType === 'DOUBLE') {
|
||
<i class="fas fa-hourglass-end"></i>
|
||
}
|
||
@if (fdType === 'SPECIAL') {
|
||
<i class="fas fa-star"></i>
|
||
}
|
||
</div>
|
||
<div class="fdrc-rule-banner__content">
|
||
@if (fdType === 'SINGLE') {
|
||
<strong>FD Single — Short Term</strong>
|
||
<span>Tenure must be less than 1 year (1 to 364 days). Enter tenure in Days only.</span>
|
||
}
|
||
@if (fdType === 'DOUBLE') {
|
||
<strong>FD Double — Long Term</strong>
|
||
<span>Tenure must be 1 year or more. Enter tenure in Months or Years (minimum 12 months).</span>
|
||
}
|
||
@if (fdType === 'SPECIAL') {
|
||
<strong>FD Special — Monthly Interest Payout</strong>
|
||
<span
|
||
>Interest is paid out monthly. Enter your principal to estimate monthly income. Any tenure is allowed.</span
|
||
>
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- ══ Tenure Calculator ════════════════════════════════════════════════ -->
|
||
<div class="fdrc-calc-card">
|
||
<div class="fdrc-calc-card__header">
|
||
<div class="fdrc-calc-card__header-left">
|
||
<div class="fdrc-calc-icon">
|
||
<i class="fas fa-calculator"></i>
|
||
</div>
|
||
<div>
|
||
<span class="fdrc-calc-card__title">Rate Calculator</span>
|
||
<span class="fdrc-calc-card__sub">Enter your deposit tenure to find the applicable interest rate</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="fdrc-calc-card__body">
|
||
<div class="fdrc-calc-inputs">
|
||
<!-- Tenure Value -->
|
||
<div class="fdrc-calc-field">
|
||
<label class="fdrc-calc-label">Deposit Tenure</label>
|
||
<div class="fdrc-tenure-row">
|
||
<input
|
||
type="number"
|
||
class="fdrc-tenure-input"
|
||
[(ngModel)]="tenureValue"
|
||
[min]="1"
|
||
placeholder="Enter value"
|
||
(keyup.enter)="calculateRate()"
|
||
/>
|
||
<!-- Period Unit Selector -->
|
||
@if (allowedPeriodUnits.length === 1) {
|
||
<span class="fdrc-period-badge">{{ allowedPeriodUnits[0] }}</span>
|
||
} @else {
|
||
<div class="fdrc-period-tabs">
|
||
@for (unit of allowedPeriodUnits; track unit) {
|
||
<button
|
||
type="button"
|
||
class="fdrc-period-tab"
|
||
[class.fdrc-period-tab--active]="tenurePeriodUnit === unit"
|
||
(click)="tenurePeriodUnit = unit; onPeriodUnitChange()"
|
||
>
|
||
{{ unit }}
|
||
</button>
|
||
}
|
||
</div>
|
||
}
|
||
</div>
|
||
<!-- FD type constraint hint -->
|
||
@if (fdType === 'SINGLE') {
|
||
<span class="fdrc-calc-hint"><i class="fas fa-info-circle"></i> Max 364 days allowed</span>
|
||
}
|
||
@if (fdType === 'DOUBLE') {
|
||
<span class="fdrc-calc-hint"><i class="fas fa-info-circle"></i> Minimum 12 months required</span>
|
||
}
|
||
</div>
|
||
|
||
<!-- Principal Amount (all FD types) -->
|
||
<div class="fdrc-calc-field">
|
||
<label class="fdrc-calc-label">
|
||
Deposit Amount
|
||
<span class="fdrc-calc-optional">(optional — to calculate maturity amount)</span>
|
||
</label>
|
||
<div class="fdrc-amount-row">
|
||
<span class="fdrc-amount-prefix">₹</span>
|
||
<input
|
||
type="number"
|
||
class="fdrc-tenure-input fdrc-tenure-input--amount"
|
||
[(ngModel)]="principalAmount"
|
||
[min]="1"
|
||
placeholder="e.g. 100000"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Senior Citizen -->
|
||
<div class="fdrc-calc-field fdrc-calc-field--senior">
|
||
<label class="fdrc-senior-label">
|
||
<input type="checkbox" [ngModel]="isSeniorCitizen" [disabled]="true" />
|
||
<span class="fdrc-senior-text">
|
||
<i class="fas fa-user-shield"></i>
|
||
Senior Citizen
|
||
</span>
|
||
<span class="fdrc-senior-hint">{{ seniorCitizenHint }}</span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="fdrc-calc-actions">
|
||
<button type="button" class="fdrc-calc-btn" (click)="calculateRate()">
|
||
<i class="fas fa-search"></i> Find Rate
|
||
</button>
|
||
@if (tenureValue || matchResult) {
|
||
<button type="button" class="fdrc-calc-reset" (click)="resetCalculator()">
|
||
<i class="fas fa-times"></i> Reset
|
||
</button>
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Validation Warning -->
|
||
@if (validationWarning) {
|
||
<div class="fdrc-alert fdrc-alert--warn">
|
||
<i class="fas fa-exclamation-triangle"></i>
|
||
<span>{{ validationWarning }}</span>
|
||
</div>
|
||
}
|
||
|
||
<!-- Match Result -->
|
||
@if (matchResult) {
|
||
<div class="fdrc-result-card">
|
||
<div class="fdrc-result-card__body">
|
||
<!-- Tenure Banner -->
|
||
<div class="fdrc-tenure-banner">
|
||
<i class="fas fa-calendar-check"></i>
|
||
<div class="fdrc-tenure-banner__content">
|
||
<span class="fdrc-tenure-banner__label">Your Selected FD Tenure</span>
|
||
<span class="fdrc-tenure-banner__value">{{ tenureValue }} {{ tenurePeriodUnit }}</span>
|
||
</div>
|
||
<span class="fdrc-tenure-banner__saved"><i class="fas fa-save"></i> Will be saved</span>
|
||
</div>
|
||
|
||
<!-- Senior Citizen Status — always shown when checked -->
|
||
@if (isSeniorCitizen) {
|
||
@if ((matchResult.slab.seniorCitizenRate ?? 0) > 0) {
|
||
<div class="fdrc-sc-status fdrc-sc-status--applied">
|
||
<i class="fas fa-user-shield fdrc-sc-status__icon"></i>
|
||
<span class="fdrc-sc-status__text">Senior Citizen Rate Applied</span>
|
||
<span class="fdrc-sc-status__bonus">
|
||
+{{
|
||
(matchResult.slab.seniorCitizenRate ?? 0) - (matchResult.slab.annualInterestRate ?? 0)
|
||
| number: '1.2-2'
|
||
}}% bonus
|
||
</span>
|
||
</div>
|
||
} @else {
|
||
<div class="fdrc-sc-status fdrc-sc-status--notice">
|
||
<i class="fas fa-info-circle fdrc-sc-status__icon"></i>
|
||
<span class="fdrc-sc-status__text"
|
||
>Senior Citizen selected — no additional rate configured for this slab, normal rate applied</span
|
||
>
|
||
</div>
|
||
}
|
||
}
|
||
|
||
<!-- Rate Display -->
|
||
@if (isSeniorCitizen && (matchResult.slab.seniorCitizenRate ?? 0) > 0) {
|
||
<!-- Before / After comparison -->
|
||
<div class="fdrc-rate-compare">
|
||
<div class="fdrc-rate-compare__block">
|
||
<span class="fdrc-rate-compare__tag">Normal Rate</span>
|
||
<span class="fdrc-rate-compare__val fdrc-rate-compare__val--strike"
|
||
>{{ matchResult.slab.annualInterestRate | number: '1.2-2' }}%</span
|
||
>
|
||
<span class="fdrc-rate-compare__sub">p.a.</span>
|
||
</div>
|
||
<div class="fdrc-rate-compare__arrow"><i class="fas fa-long-arrow-alt-right"></i></div>
|
||
<div class="fdrc-rate-compare__block fdrc-rate-compare__block--sc">
|
||
<span class="fdrc-rate-compare__tag fdrc-rate-compare__tag--sc"
|
||
><i class="fas fa-user-shield"></i> Sr. Citizen Rate</span
|
||
>
|
||
<span class="fdrc-rate-compare__val fdrc-rate-compare__val--sc"
|
||
>{{ matchResult.appliedRate | number: '1.2-2' }}%</span
|
||
>
|
||
<span class="fdrc-rate-compare__sub">p.a.</span>
|
||
</div>
|
||
</div>
|
||
} @else {
|
||
<div class="fdrc-result-rate">
|
||
<span class="fdrc-result-rate__value">{{ matchResult.appliedRate | number: '1.2-2' }}%</span>
|
||
<span class="fdrc-result-rate__label">Annual Interest Rate p.a.</span>
|
||
</div>
|
||
}
|
||
|
||
<!-- Slab Info -->
|
||
<div class="fdrc-result-meta">
|
||
<div class="fdrc-result-meta__item">
|
||
<i class="fas fa-layer-group"></i>
|
||
<span
|
||
>Applicable Slab:
|
||
<strong
|
||
>{{ matchResult.slab.fromPeriod }}–{{ matchResult.slab.toPeriod ?? '∞' }}
|
||
{{ matchResult.slab.periodType?.value }}</strong
|
||
></span
|
||
>
|
||
</div>
|
||
@if (matchResult.slab.description) {
|
||
<div class="fdrc-result-meta__item">
|
||
<i class="fas fa-tag"></i>
|
||
<span>{{ matchResult.slab.description }}</span>
|
||
</div>
|
||
}
|
||
@if (matchResult.slab.amountRangeFrom || matchResult.slab.amountRangeTo) {
|
||
<div class="fdrc-result-meta__item">
|
||
<i class="fas fa-coins"></i>
|
||
<span
|
||
>Amount Range:
|
||
<strong
|
||
>{{ matchResult.slab.amountRangeFrom | number }}–{{
|
||
matchResult.slab.amountRangeTo | number
|
||
}}</strong
|
||
></span
|
||
>
|
||
</div>
|
||
}
|
||
</div>
|
||
|
||
<!-- Maturity Summary -->
|
||
@if (matchResult.maturityAmount) {
|
||
<div class="fdrc-maturity-card">
|
||
<div class="fdrc-maturity-card__header">
|
||
<i class="fas fa-coins"></i>
|
||
<span>Maturity Summary</span>
|
||
@if (isSeniorCitizen && (matchResult.slab.seniorCitizenRate ?? 0) > 0) {
|
||
<span class="fdrc-sc-tag"><i class="fas fa-user-shield"></i> Sr. Citizen Rate</span>
|
||
}
|
||
</div>
|
||
<div class="fdrc-maturity-card__body">
|
||
<div class="fdrc-maturity-row">
|
||
<span class="fdrc-maturity-row__label">Deposit Amount</span>
|
||
<span class="fdrc-maturity-row__value">₹ {{ principalAmount | number: '1.2-2' }}</span>
|
||
</div>
|
||
<div class="fdrc-maturity-row">
|
||
<span class="fdrc-maturity-row__label">Tenure</span>
|
||
<span class="fdrc-maturity-row__value">{{ tenureValue }} {{ tenurePeriodUnit }}</span>
|
||
</div>
|
||
<div
|
||
class="fdrc-maturity-row"
|
||
[class.fdrc-maturity-row--sc]="isSeniorCitizen && (matchResult.slab.seniorCitizenRate ?? 0) > 0"
|
||
>
|
||
<span class="fdrc-maturity-row__label">
|
||
@if (isSeniorCitizen && (matchResult.slab.seniorCitizenRate ?? 0) > 0) {
|
||
<i class="fas fa-user-shield"></i> Sr. Citizen Rate
|
||
} @else {
|
||
Interest Rate
|
||
}
|
||
</span>
|
||
<span class="fdrc-maturity-row__value">{{ matchResult.appliedRate | number: '1.2-2' }}% p.a.</span>
|
||
</div>
|
||
<div class="fdrc-maturity-row fdrc-maturity-row--interest">
|
||
<span class="fdrc-maturity-row__label">Interest Earned</span>
|
||
<span class="fdrc-maturity-row__value">₹ {{ matchResult.interestEarned | number: '1.2-2' }}</span>
|
||
</div>
|
||
@if (isSpecial && matchResult.estimatedMonthlyPayout) {
|
||
<div class="fdrc-maturity-row">
|
||
<span class="fdrc-maturity-row__label">Monthly Payout</span>
|
||
<span class="fdrc-maturity-row__value fdrc-maturity-row__value--highlight">
|
||
₹ {{ matchResult.estimatedMonthlyPayout | number: '1.2-2' }} / month
|
||
</span>
|
||
</div>
|
||
}
|
||
<div class="fdrc-maturity-row fdrc-maturity-row--total">
|
||
<span class="fdrc-maturity-row__label">
|
||
@if (isSpecial) {
|
||
Principal at Maturity
|
||
} @else {
|
||
Maturity Amount
|
||
}
|
||
</span>
|
||
<span class="fdrc-maturity-row__value fdrc-maturity-row__value--big">
|
||
₹ {{ (isSpecial ? principalAmount : matchResult.maturityAmount) | number: '1.2-2' }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
@if (!matchResult.maturityAmount) {
|
||
<div class="fdrc-payout-hint">
|
||
<i class="fas fa-lightbulb"></i>
|
||
Enter a deposit amount above to see the maturity calculation.
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ══ Rate Chart Table ══════════════════════════════════════════════════ -->
|
||
<div class="fdrc-table-card">
|
||
<div class="fdrc-table-card__header">
|
||
<div class="fdrc-table-card__title-row">
|
||
<i class="fas fa-table"></i>
|
||
<span class="fdrc-table-card__title">Interest Rate Slabs</span>
|
||
@if (interestRateChartData.length) {
|
||
<span class="fdrc-slab-count"
|
||
>{{ interestRateChartData.length }} slab{{ interestRateChartData.length !== 1 ? 's' : '' }}</span
|
||
>
|
||
}
|
||
</div>
|
||
@if (matchResult) {
|
||
<span class="fdrc-highlight-note"> <i class="fas fa-highlighter"></i> Matched slab is highlighted </span>
|
||
}
|
||
</div>
|
||
|
||
<div class="fdrc-table-wrap">
|
||
<table mat-table [dataSource]="interestRateChartData" #chartsTable multiTemplateDataRows class="fdrc-table">
|
||
<!-- Period Column -->
|
||
<ng-container matColumnDef="period">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">Period</th>
|
||
<td mat-cell *matCellDef="let slab" class="fdrc-td fdrc-td--period">
|
||
<span class="fdrc-period-range">
|
||
{{ slab.fromPeriod }}
|
||
@if (slab.toPeriod !== null) {
|
||
– {{ slab.toPeriod }}
|
||
} @else {
|
||
+
|
||
}
|
||
</span>
|
||
<span class="fdrc-period-type">{{ slab.periodType?.value }}</span>
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Amount Range Column -->
|
||
<ng-container matColumnDef="amountRange">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">Amount Range</th>
|
||
<td mat-cell *matCellDef="let slab" class="fdrc-td">
|
||
@if (slab.amountRangeFrom || slab.amountRangeTo) {
|
||
<span>{{ slab.amountRangeFrom | number }} – {{ slab.amountRangeTo | number }}</span>
|
||
} @else {
|
||
<span class="fdrc-td--na">—</span>
|
||
}
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Interest Column -->
|
||
<ng-container matColumnDef="interest">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">Interest Rate</th>
|
||
<td mat-cell *matCellDef="let slab" class="fdrc-td">
|
||
<span class="fdrc-rate-badge">{{ slab.annualInterestRate | number: '1.2-2' }}%</span>
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Senior Citizen Rate Column -->
|
||
<ng-container matColumnDef="seniorCitizenRate">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">
|
||
<i class="fas fa-user-shield" style="margin-right: 4px; color: #6366f1"></i>Sr. Citizen Rate
|
||
</th>
|
||
<td mat-cell *matCellDef="let slab" class="fdrc-td">
|
||
@if (slab.seniorCitizenRate > 0) {
|
||
<span class="fdrc-rate-badge fdrc-rate-badge--senior"
|
||
>{{ slab.seniorCitizenRate | number: '1.2-2' }}%</span
|
||
>
|
||
} @else {
|
||
<span class="fdrc-td--na">—</span>
|
||
}
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Description Column -->
|
||
<ng-container matColumnDef="description">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">Description</th>
|
||
<td mat-cell *matCellDef="let slab" class="fdrc-td">
|
||
{{ slab.description || '—' }}
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Actions Column -->
|
||
<ng-container matColumnDef="actions">
|
||
<th mat-header-cell *matHeaderCellDef class="fdrc-th">Incentives</th>
|
||
<td mat-cell *matCellDef="let slab; let i = dataIndex" class="fdrc-td">
|
||
@if (slab.incentives?.length) {
|
||
<button
|
||
type="button"
|
||
class="fdrc-incentive-btn"
|
||
(click)="expandChartSlabIndex = expandChartSlabIndex === i ? null : i"
|
||
>
|
||
<i
|
||
class="fas"
|
||
[class.fa-eye]="expandChartSlabIndex !== i"
|
||
[class.fa-eye-slash]="expandChartSlabIndex === i"
|
||
></i>
|
||
{{ expandChartSlabIndex === i ? 'Hide' : 'View' }} ({{ slab.incentives.length }})
|
||
</button>
|
||
} @else {
|
||
<span class="fdrc-td--na">None</span>
|
||
}
|
||
</td>
|
||
</ng-container>
|
||
|
||
<!-- Incentives Expanded Row -->
|
||
<ng-container matColumnDef="incentives">
|
||
<td
|
||
mat-cell
|
||
*matCellDef="let slab; let i = dataIndex"
|
||
[attr.colspan]="chartSlabsDisplayedColumns.length"
|
||
class="fdrc-incentives-cell"
|
||
>
|
||
<div
|
||
class="fdrc-incentives-wrap"
|
||
[@expandChartSlab]="i === expandChartSlabIndex ? 'expanded' : 'collapsed'"
|
||
>
|
||
@if (slab.incentives?.length) {
|
||
<div class="fdrc-incentives-inner">
|
||
<div class="fdrc-incentives-title"><i class="fas fa-gift"></i> Incentives for this slab</div>
|
||
<table mat-table [dataSource]="slab.incentives" class="fdrc-incentives-table">
|
||
<ng-container matColumnDef="entityType">
|
||
<th mat-header-cell *matHeaderCellDef>Entity Type</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.entityType?.value }}</td>
|
||
</ng-container>
|
||
<ng-container matColumnDef="attributeName">
|
||
<th mat-header-cell *matHeaderCellDef>Attribute</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.attributeName?.value }}</td>
|
||
</ng-container>
|
||
<ng-container matColumnDef="conditionType">
|
||
<th mat-header-cell *matHeaderCellDef>Condition</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.conditionType?.value | titlecase }}</td>
|
||
</ng-container>
|
||
<ng-container matColumnDef="attributeValue">
|
||
<th mat-header-cell *matHeaderCellDef>Value</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.attributeValueDesc }}</td>
|
||
</ng-container>
|
||
<ng-container matColumnDef="incentiveType">
|
||
<th mat-header-cell *matHeaderCellDef>Type</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.incentiveType?.value }}</td>
|
||
</ng-container>
|
||
<ng-container matColumnDef="amount">
|
||
<th mat-header-cell *matHeaderCellDef>Amount</th>
|
||
<td mat-cell *matCellDef="let inc">{{ inc.amount }}</td>
|
||
</ng-container>
|
||
<tr mat-header-row *matHeaderRowDef="incentivesDisplayedColumns"></tr>
|
||
<tr mat-row *matRowDef="let row; columns: incentivesDisplayedColumns"></tr>
|
||
</table>
|
||
</div>
|
||
}
|
||
</div>
|
||
</td>
|
||
</ng-container>
|
||
|
||
<tr mat-header-row *matHeaderRowDef="chartSlabsDisplayedColumns" class="fdrc-header-row"></tr>
|
||
<tr
|
||
mat-row
|
||
*matRowDef="let row; columns: chartSlabsDisplayedColumns; let i = dataIndex"
|
||
class="fdrc-data-row"
|
||
[class.fdrc-data-row--matched]="isMatchedSlab(i)"
|
||
></tr>
|
||
<tr
|
||
mat-row
|
||
*matRowDef="let row; columns: chartSlabsIncentivesDisplayedColumns"
|
||
class="fdrc-incentives-row"
|
||
></tr>
|
||
</table>
|
||
|
||
@if (!interestRateChartData.length) {
|
||
<div class="fdrc-empty">
|
||
<i class="fas fa-chart-bar"></i>
|
||
<span>No interest rate slabs defined for this product.</span>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
</div>
|