152 lines
5.2 KiB
TypeScript
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);
|
|
}
|
|
}
|