Files
cbsnexora/src/app/clients/shared/aadhaar-receipt-dialog/aadhaar-receipt-dialog.component.ts
T
keshav 7b895a0e2b
build-run / Run Lint, Build and Deploy (push) Canceled after 0s
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
feat: add KYC document renewal alerts, Aadhaar/PAN exceptions, and AML recurring alerts UI; remove old journal AML marking
2026-08-11 11:11:18 +05:30

152 lines
5.2 KiB
TypeScript

/**
* 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/.
*/
import { Component, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
MAT_DIALOG_DATA,
MatDialogRef,
MatDialogContent,
MatDialogActions,
MatDialogClose
} from '@angular/material/dialog';
import { MatIcon } from '@angular/material/icon';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
export interface AadhaarReceiptDialogData {
/** Client name, shown so the officer can check the slip belongs to the right person. */
clientName: string;
/** Message the Aadhaar step came back with, or why the officer is recording a receipt. */
reason: string;
/** Existing receipt, when the officer re-opens one already taken. */
existing?: AadhaarReceiptResult | null;
}
export interface AadhaarReceiptResult {
/** 14-digit enrolment number as printed on the slip, separators kept. */
enrolmentId: string;
enrolmentDate: Date | null;
remarks: string;
}
/**
* Records the UIDAI enrolment receipt accepted in place of a verified Aadhaar.
*
* A customer who has applied for Aadhaar but has not been issued one holds only an enrolment slip.
* There is no Aadhaar number to send to the OTP flow, so no amount of retrying will clear the
* check — the same dead end the PAN declaration resolves. Recording the slip lets the client be
* created and waives the Aadhaar exception, while Aadhaar itself stays unverified.
*
* Only the 14-digit enrolment number is taken. The date and time printed beside it on the slip are
* captured by the enrolment-date field, so asking for them again in the same box would just be a
* second chance to mistype them.
*
* The number is validated on digit count rather than an exact layout: slips print it with varying
* separators, and rejecting one because of a slash or a space would block a customer over
* formatting rather than substance.
*/
@Component({
selector: 'mifosx-aadhaar-receipt-dialog',
templateUrl: './aadhaar-receipt-dialog.component.html',
styleUrls: ['./aadhaar-receipt-dialog.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
FormsModule,
MatIcon,
MatDialogContent,
MatDialogActions,
MatDialogClose
]
})
export class AadhaarReceiptDialogComponent {
data = inject<AadhaarReceiptDialogData>(MAT_DIALOG_DATA);
private dialogRef = inject(MatDialogRef<AadhaarReceiptDialogComponent>);
enrolmentId = '';
enrolmentDate: Date | null = null;
remarks = '';
/** The officer confirms the original slip was sighted — nothing is saved without it. */
sighted = false;
today = new Date();
constructor() {
const existing = this.data.existing;
if (existing) {
this.enrolmentId = existing.enrolmentId || '';
this.enrolmentDate = existing.enrolmentDate || null;
this.remarks = existing.remarks || '';
}
}
/** Digits only — separators on the printed slip are cosmetic and vary between forms. */
private get enrolmentDigits(): string {
return (this.enrolmentId || '').replace(/\D/g, '');
}
get enrolmentIdEntered(): boolean {
return this.enrolmentDigits.length > 0;
}
/** UIDAI's enrolment number is 14 digits — the timestamp beside it is not part of it. */
get enrolmentIdValid(): boolean {
return this.enrolmentDigits.length === 14;
}
/** How many digits are still missing, so the officer is told what to fix, not just that it failed. */
get enrolmentIdHint(): string {
const count = this.enrolmentDigits.length;
if (!count) {
return 'The 14-digit enrolment number only, e.g. 1234/56789/01234';
}
return `${count} of 14 digits`;
}
/** A slip dated in the future is a keying error, not a valid enrolment. */
get enrolmentDateValid(): boolean {
return !!this.enrolmentDate && this.enrolmentDate.getTime() <= this.today.getTime();
}
/** Whole months since enrolment — shown because a receipt is temporary by nature. */
get monthsSinceEnrolment(): number | null {
if (!this.enrolmentDate) {
return null;
}
const months =
(this.today.getFullYear() - this.enrolmentDate.getFullYear()) * 12 +
(this.today.getMonth() - this.enrolmentDate.getMonth()) -
(this.today.getDate() < this.enrolmentDate.getDate() ? 1 : 0);
return Math.max(0, months);
}
/**
* An enrolment normally completes well inside six months, so an older slip is a prompt to chase
* the customer for the Aadhaar itself. It is a warning, not a block: the branch may have good
* reason to accept it, and the record shows the age either way.
*/
get receiptIsStale(): boolean {
const months = this.monthsSinceEnrolment;
return months !== null && months >= 6;
}
get canSubmit(): boolean {
return this.enrolmentIdValid && this.enrolmentDateValid && !!this.remarks.trim() && this.sighted;
}
submit(): void {
if (!this.canSubmit) {
return;
}
this.dialogRef.close({
enrolmentId: this.enrolmentId.trim(),
enrolmentDate: this.enrolmentDate,
remarks: this.remarks.trim()
} as AadhaarReceiptResult);
}
}