feat: add KYC document renewal alerts, Aadhaar/PAN exceptions, and AML recurring alerts UI; remove old journal AML marking
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
<!--
|
||||
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="pan-decl">
|
||||
<div class="pan-decl__header">
|
||||
<mat-icon class="pan-decl__header-icon">assignment_late</mat-icon>
|
||||
<div>
|
||||
<div class="pan-decl__title">PAN Verification Failed — Take Declaration</div>
|
||||
<div class="pan-decl__subtitle">PAN {{ data.panNumber }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-dialog-content class="pan-decl__body">
|
||||
<div class="pan-decl__reason">
|
||||
<mat-icon>info</mat-icon>
|
||||
<span>{{ data.failureMessage }}</span>
|
||||
</div>
|
||||
|
||||
@if (!data.unverifiable) {
|
||||
<p class="pan-decl__intro">
|
||||
The Income Tax check matches on <strong>name and date of birth together</strong> and does not report which of
|
||||
the two differs. Enter the details exactly as printed on the customer's PAN card so the declaration records what
|
||||
actually does not match.
|
||||
</p>
|
||||
|
||||
<!-- Comparison: what we submitted vs what the PAN card says -->
|
||||
<div class="pan-decl__compare">
|
||||
<div class="pan-decl__compare-head">
|
||||
<span class="lbl"></span>
|
||||
<span class="col">Submitted</span>
|
||||
<span class="col">As on PAN card</span>
|
||||
<span class="res"></span>
|
||||
</div>
|
||||
|
||||
<div class="pan-decl__compare-row" [class.mismatch]="nameMismatch">
|
||||
<span class="lbl">Name</span>
|
||||
<span class="col submitted">{{ data.submittedName || '—' }}</span>
|
||||
<span class="col">
|
||||
<mat-form-field appearance="outline" class="pan-decl__field">
|
||||
<mat-label>Name on PAN</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[(ngModel)]="nameOnPan"
|
||||
(ngModelChange)="onCompare()"
|
||||
placeholder="e.g. RAJESH KUMAR SHARMA"
|
||||
maxlength="200"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</span>
|
||||
<span class="res">
|
||||
@if (compared && nameOnPan.trim()) {
|
||||
@if (nameMismatch) {
|
||||
<mat-icon class="res-icon res-icon--bad" aria-label="Does not match">cancel</mat-icon>
|
||||
} @else {
|
||||
<mat-icon class="res-icon res-icon--ok" aria-label="Matches">check_circle</mat-icon>
|
||||
}
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="pan-decl__compare-row" [class.mismatch]="dobMismatch">
|
||||
<span class="lbl">Date of Birth</span>
|
||||
<span class="col submitted">{{ data.submittedDob || '—' }}</span>
|
||||
<span class="col">
|
||||
<mat-form-field appearance="outline" class="pan-decl__field">
|
||||
<mat-label>DOB on PAN</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="dobPicker"
|
||||
[max]="today"
|
||||
[(ngModel)]="dobOnPan"
|
||||
(ngModelChange)="onCompare()"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="dobPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #dobPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</span>
|
||||
<span class="res">
|
||||
@if (compared && dobOnPan) {
|
||||
@if (dobMismatch) {
|
||||
<mat-icon class="res-icon res-icon--bad" aria-label="Does not match">cancel</mat-icon>
|
||||
} @else {
|
||||
<mat-icon class="res-icon res-icon--ok" aria-label="Matches">check_circle</mat-icon>
|
||||
}
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- What the declaration will state -->
|
||||
<div
|
||||
class="pan-decl__verdict"
|
||||
[class.pan-decl__verdict--pending]="!comparisonComplete"
|
||||
[class.pan-decl__verdict--clean]="nothingToDeclare"
|
||||
>
|
||||
<span class="pan-decl__verdict-label">Does not match:</span>
|
||||
<span class="pan-decl__verdict-value">{{ mismatchLabel }}</span>
|
||||
</div>
|
||||
|
||||
@if (!comparisonComplete) {
|
||||
<p class="pan-decl__note">Enter both PAN-card values to see exactly which detail differs.</p>
|
||||
}
|
||||
|
||||
@if (nothingToDeclare) {
|
||||
<p class="pan-decl__warn">
|
||||
<mat-icon>warning</mat-icon>
|
||||
The PAN-card details you entered are the same as the ones submitted, so there is nothing to declare. Correct
|
||||
the client's name or date of birth on the General step and verify PAN again.
|
||||
</p>
|
||||
}
|
||||
} @else {
|
||||
<p class="pan-decl__intro">
|
||||
PAN could not be checked against the Income Tax records. Record the declaration taken from the customer so the
|
||||
client can be created without a KYC exception being raised for PAN.
|
||||
</p>
|
||||
}
|
||||
|
||||
<!-- The signed paper is the declaration; it is uploaded, not described. -->
|
||||
<div class="pan-decl__upload">
|
||||
<div class="pan-decl__upload-label">Signed declaration</div>
|
||||
<p class="pan-decl__upload-help">
|
||||
Get the declaration signed by the customer and upload the scanned copy. It is filed against the client as the
|
||||
proof that holds the PAN exception off.
|
||||
</p>
|
||||
|
||||
@if (!hasDeclarationFile) {
|
||||
<label class="pan-decl__dropzone">
|
||||
<input type="file" [accept]="acceptedTypes" (change)="onDeclarationFile($event)" hidden />
|
||||
<mat-icon class="pan-decl__dropzone-icon">cloud_upload</mat-icon>
|
||||
<span class="pan-decl__dropzone-text">Click to upload signed declaration</span>
|
||||
<span class="pan-decl__dropzone-hint">PDF, JPG or PNG — up to 5 MB</span>
|
||||
</label>
|
||||
} @else {
|
||||
<div class="pan-decl__file">
|
||||
<mat-icon class="pan-decl__file-icon">description</mat-icon>
|
||||
<span class="pan-decl__file-meta">
|
||||
<span class="pan-decl__file-name">{{ fileName }}</span>
|
||||
<span class="pan-decl__file-sub">{{ fileSizeLabel }}</span>
|
||||
</span>
|
||||
<label class="pan-decl__file-replace">
|
||||
<input type="file" [accept]="acceptedTypes" (change)="onDeclarationFile($event)" hidden />
|
||||
Replace
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
class="pan-decl__file-remove"
|
||||
aria-label="Remove file"
|
||||
(click)="removeDeclarationFile()"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (fileError) {
|
||||
<p class="pan-decl__file-error">
|
||||
<mat-icon>error_outline</mat-icon>
|
||||
<span>{{ fileError }}</span>
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end" class="pan-decl__actions">
|
||||
<button mat-stroked-button mat-dialog-close type="button">Cancel</button>
|
||||
<button mat-flat-button color="primary" type="button" [disabled]="!canSubmit" (click)="submit()">
|
||||
Save Declaration
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
||||
Reference in New Issue
Block a user