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>
577 lines
24 KiB
HTML
577 lines
24 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="personal-data-container mat-typography">
|
|
<!-- Personal Information -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-user"></i>
|
|
<h3>{{ 'labels.heading.Personal Information' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
@if (clientViewData.displayName) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Display Name' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.displayName }}</div>
|
|
</div>
|
|
}
|
|
@if (isPerson()) {
|
|
@if (clientViewData.salutation) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Salutation</div>
|
|
<div class="pd-field__value">{{ clientViewData.salutation.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.firstname) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.First Name' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.firstname }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.middlename) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Middle Name' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.middlename }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.lastname) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Last Name' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.lastname }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.dateOfBirth) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Date of Birth' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat: 'DD-MMMM-YYYY' }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.ageYears !== null) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Age</div>
|
|
<div class="pd-field__value">
|
|
{{ clientViewData.ageYears }}y {{ clientViewData.ageMonths || 0 }}m {{ clientViewData.ageDays || 0 }}d
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.gender) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Gender' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.gender.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.maritalStatus) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Marital Status</div>
|
|
<div class="pd-field__value">{{ clientViewData.maritalStatus.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.educationLevel) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Education Level</div>
|
|
<div class="pd-field__value">{{ clientViewData.educationLevel.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.degreeQualification) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Degree / Qualification</div>
|
|
<div class="pd-field__value">{{ clientViewData.degreeQualification.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.religion) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Religion</div>
|
|
<div class="pd-field__value">{{ clientViewData.religion.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.socialCategory) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Social Category</div>
|
|
<div class="pd-field__value">{{ clientViewData.socialCategory.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.isMinor !== null) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Minor</div>
|
|
<div class="pd-field__value">
|
|
<span
|
|
class="pd-verify-badge"
|
|
[class.pd-verify-badge--verified]="!clientViewData.isMinor"
|
|
[class.pd-verify-badge--pending]="clientViewData.isMinor"
|
|
>
|
|
{{ clientViewData.isMinor ? 'Yes' : 'No' }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Is staff' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
<span
|
|
class="pd-verify-badge"
|
|
[class.pd-verify-badge--verified]="clientViewData.isStaff"
|
|
[class.pd-verify-badge--pending]="!clientViewData.isStaff"
|
|
>
|
|
{{ clientViewData.isStaff ? 'Yes' : 'No' }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (isLegalEntity()) {
|
|
@if (clientViewData.fullname) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Entity Name' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.fullname }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.dateOfBirth) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Date' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat: 'DD-MM-YYYY' }}</div>
|
|
</div>
|
|
}
|
|
}
|
|
@if (clientViewData.legalForm) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Legal Form' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.legalForm.id === 1 ? 'Individual' : 'Non-Individual' }}</div>
|
|
</div>
|
|
}
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Nationality</div>
|
|
<div class="pd-field__value">
|
|
{{ clientViewData.nationalityId || clientViewData.nationality || 'Indian' }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Account Information -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-id-card"></i>
|
|
<h3>{{ 'labels.heading.Account Information' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Account No' | translate }}</div>
|
|
<div class="pd-field__value monospace">{{ clientViewData.accountNo || '-' }}</div>
|
|
</div>
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.CIF Number' | translate }}</div>
|
|
<div class="pd-field__value monospace">{{ clientViewData.cifNumber || '-' }}</div>
|
|
</div>
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Office' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.officeName || '-' }}</div>
|
|
</div>
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Staff' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.staffName || ('labels.inputs.Unassigned' | translate) }}</div>
|
|
</div>
|
|
@if (clientViewData.savingsAccountNo) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Default Savings Account' | translate }}</div>
|
|
<div class="pd-field__value monospace">{{ clientViewData.savingsAccountNo }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Non-Person Details Section (for Legal Entities) -->
|
|
@if (isLegalEntity() && clientViewData.clientNonPersonDetails) {
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-building"></i>
|
|
<h3>{{ 'labels.heading.Entity Details' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
@if (clientViewData.clientNonPersonDetails.constitution) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Constitution' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.constitution.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientNonPersonDetails.mainBusinessLine) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Main Business Line' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.mainBusinessLine.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientNonPersonDetails.incorpValidityTillDate) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Validity Till Date' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
{{ clientViewData.clientNonPersonDetails.incorpValidityTillDate | dateFormat: 'DD-MM-YYYY' }}
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientNonPersonDetails.incorpNumber) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation No' | translate }}</div>
|
|
<div class="pd-field__value monospace">{{ clientViewData.clientNonPersonDetails.incorpNumber }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientNonPersonDetails.dateOfRegistration) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Date' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
{{ clientViewData.clientNonPersonDetails.dateOfRegistration | dateFormat: 'DD-MM-YYYY' }}
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientNonPersonDetails.remarks) {
|
|
<div class="pd-field full-width">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Remarks' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.remarks }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- Contact Details -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-phone"></i>
|
|
<h3>Contact Details</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Mobile Number' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
<span class="pd-contact-icon"><i class="fa fa-mobile"></i> {{ clientViewData.mobileNo || '-' }}</span>
|
|
</div>
|
|
</div>
|
|
@if (clientViewData.alternateMobileNo) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Alternate Mobile No</div>
|
|
<div class="pd-field__value">
|
|
<span class="pd-contact-icon"><i class="fa fa-mobile"></i> {{ clientViewData.alternateMobileNo }}</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Email' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
<span class="pd-contact-icon"
|
|
><i class="fa fa-envelope-o"></i> {{ clientViewData.emailAddress || '-' }}</span
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DIP & Sanctions Verification -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-shield"></i>
|
|
<h3>DIP & Sanctions Verification</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
<!--
|
|
Primary Mobile DIP. Driven by dipLiveStatus — the latest lookup — not by dipVerified,
|
|
which is frozen at onboarding and would keep reporting "Verified" long after the number
|
|
was reported for fraud or reassigned to someone else.
|
|
-->
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Mobile DIP Status</div>
|
|
<div class="pd-field__value">
|
|
@if (isDipFlagged(clientViewData.dipLiveStatus)) {
|
|
<span class="pd-verify-badge pd-verify-badge--flagged">
|
|
<i class="fa fa-exclamation-triangle"></i> {{ dipStatusLabel(clientViewData) }}
|
|
</span>
|
|
} @else if (isDipClear(clientViewData)) {
|
|
<span class="pd-verify-badge pd-verify-badge--verified">
|
|
<i class="fa fa-check-circle"></i> Verified
|
|
</span>
|
|
} @else {
|
|
<span class="pd-verify-badge pd-verify-badge--pending">
|
|
<i class="fa fa-clock-o"></i> {{ dipStatusLabel(clientViewData) }}
|
|
</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (isDipFlagged(clientViewData.dipLiveStatus)) {
|
|
<div class="pd-field pd-field--full">
|
|
<div class="pd-dip-alert">
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
<div>
|
|
<strong>This mobile number is flagged on the DoT Digital Intelligence Platform.</strong>
|
|
<div class="pd-dip-alert__detail">
|
|
OTPs and SMS alerts to this number are blocked. Contact the customer through an alternate channel and
|
|
obtain a new number. Account operations are not restricted.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
<!--
|
|
A sanctions alert raised after onboarding is far more serious than a DIP hit and must be
|
|
impossible to miss on the customer's own page, not only in the Principal Officer's queue.
|
|
-->
|
|
@if (clientViewData.sanctionsAlertStatus) {
|
|
<div class="pd-field pd-field--full">
|
|
<div
|
|
class="pd-dip-alert"
|
|
[class.pd-dip-alert--review]="clientViewData.sanctionsAlertStatus === 'PENDING_REVIEW'"
|
|
>
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
<div>
|
|
<strong>{{ sanctionsAlertHeadline(clientViewData) }}</strong>
|
|
<div class="pd-dip-alert__detail">{{ sanctionsAlertDetail(clientViewData) }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.dipTimestamp) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">DIP Verified On</div>
|
|
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.dipTimestamp) }}</div>
|
|
</div>
|
|
}
|
|
<!-- Alternate Mobile DIP -->
|
|
@if (clientViewData.alternateMobileNo) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Alternate Mobile DIP Status</div>
|
|
<div class="pd-field__value">
|
|
@if (isDipFlagged(clientViewData.alternateDipLiveStatus)) {
|
|
<span class="pd-verify-badge pd-verify-badge--flagged">
|
|
<i class="fa fa-exclamation-triangle"></i> {{ alternateDipStatusLabel(clientViewData) }}
|
|
</span>
|
|
} @else if (
|
|
clientViewData.alternateDipLiveStatus === 'CLEAN' ||
|
|
clientViewData.alternateDipVerified === true ||
|
|
clientViewData.alternateDipVerified === 'true' ||
|
|
clientViewData.alternateDipVerified === 1
|
|
) {
|
|
<span class="pd-verify-badge pd-verify-badge--verified">
|
|
<i class="fa fa-check-circle"></i> Verified
|
|
</span>
|
|
} @else {
|
|
<span class="pd-verify-badge pd-verify-badge--pending"> <i class="fa fa-clock-o"></i> Pending </span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (clientViewData.alternateDipTimestamp) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Alternate DIP Verified On</div>
|
|
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.alternateDipTimestamp) }}</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
<!-- Sanctions / Name Screening -->
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Name Screening (Sanctions)</div>
|
|
<div class="pd-field__value">
|
|
@if (
|
|
clientViewData.nameVerified === true ||
|
|
clientViewData.nameVerified === 'true' ||
|
|
clientViewData.nameVerified === 1
|
|
) {
|
|
<span class="pd-verify-badge pd-verify-badge--verified"><i class="fa fa-check-circle"></i> Clear</span>
|
|
} @else if (
|
|
clientViewData.nameVerified === false ||
|
|
clientViewData.nameVerified === 'false' ||
|
|
clientViewData.nameVerified === 0
|
|
) {
|
|
<span class="pd-verify-badge pd-verify-badge--danger"
|
|
><i class="fa fa-exclamation-triangle"></i> Match Found</span
|
|
>
|
|
} @else {
|
|
<span class="pd-verify-badge pd-verify-badge--pending"><i class="fa fa-clock-o"></i> Pending</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Financial & Classification (Individual only) -->
|
|
@if (clientViewData?.legalForm?.id !== 2) {
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-chart-line"></i>
|
|
<h3>Financial & Classification</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Monthly Income</div>
|
|
<div class="pd-field__value">
|
|
@if (clientViewData.monthlyIncome !== null && clientViewData.monthlyIncome !== '') {
|
|
<span class="monospace">₹ {{ clientViewData.monthlyIncome | number }}</span>
|
|
} @else {
|
|
-
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Annual Turnover (Last FY)</div>
|
|
<div class="pd-field__value">
|
|
@if (clientViewData.annualTurnover !== null && clientViewData.annualTurnover !== '') {
|
|
<span class="monospace">₹ {{ clientViewData.annualTurnover | number }}</span>
|
|
} @else {
|
|
-
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (clientViewData.clientType) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Client Type' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.clientType.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.clientClassification) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Client Classification' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.clientClassification.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.occupationCategory) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Occupation Category' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.occupationCategory.name }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.occupation) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Occupation' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.occupation.name }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- Guardian Details (Minor) -->
|
|
@if (clientViewData.isMinor && clientViewData.guardianClientId) {
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-user-shield"></i>
|
|
<h3>Guardian Details</h3>
|
|
<span class="pd-section__badge pd-section__badge--minor">Minor</span>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Guardian Name</div>
|
|
<div class="pd-field__value">{{ clientViewData.guardianClientDisplayName || '-' }}</div>
|
|
</div>
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Guardian Client ID</div>
|
|
<div class="pd-field__value monospace">{{ clientViewData.guardianClientId }}</div>
|
|
</div>
|
|
@if (clientViewData.guardianRelation) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">Relationship</div>
|
|
<div class="pd-field__value">{{ clientViewData.guardianRelation }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- Group Membership -->
|
|
@if (clientViewData.groups && clientViewData.groups.length > 0) {
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-users"></i>
|
|
<h3>{{ 'labels.heading.Group Membership' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
@for (group of clientViewData.groups; track group) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Group' | translate }}</div>
|
|
<div class="pd-field__value">{{ group.name }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- Important Dates -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-calendar"></i>
|
|
<h3>{{ 'labels.heading.Important Dates' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
@if (clientViewData.timeline?.submittedOnDate) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Submitted On' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.timeline.submittedOnDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.activationDate) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Activation Date' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.activationDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.timeline?.closedOnDate) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Closed Date' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.timeline.closedOnDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status -->
|
|
<div class="pd-section">
|
|
<div class="pd-section__header">
|
|
<i class="fa fa-info-circle"></i>
|
|
<h3>{{ 'labels.heading.Status' | translate }}</h3>
|
|
</div>
|
|
<div class="pd-section__body">
|
|
<div class="pd-grid">
|
|
@if (clientViewData.status) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Client Status' | translate }}</div>
|
|
<div class="pd-field__value">
|
|
<span
|
|
class="pd-field__value status-badge"
|
|
[class.status-active]="clientViewData.status.value === 'Active'"
|
|
[class.status-closed]="clientViewData.status.value === 'Closed'"
|
|
[class.status-pending]="
|
|
clientViewData.status.value !== 'Active' && clientViewData.status.value !== 'Closed'
|
|
"
|
|
>
|
|
{{ 'labels.status.' + clientViewData.status.value | translate }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (clientViewData.subStatus) {
|
|
<div class="pd-field">
|
|
<div class="pd-field__label">{{ 'labels.inputs.Sub Status' | translate }}</div>
|
|
<div class="pd-field__value">{{ clientViewData.subStatus.name }}</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|