Merge remote-tracking branch 'origin/uate' into uate
This commit is contained in:
+36
@@ -238,6 +238,42 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets transient address-tab state for a brand-new client.
|
||||
*
|
||||
* This app's RouteReusableStrategy (core/route/route-reusable-strategy.ts) keeps this SAME
|
||||
* component instance alive across repeat visits to /clients/create, so `ngOnInit` never
|
||||
* re-runs for a second "create new client" session — the previous client's address forms,
|
||||
* selected proof-of-address chip and uploaded files would otherwise leak into the new one.
|
||||
* Called by CreateClientComponent.resetForNewClient() whenever a fresh create session begins.
|
||||
*/
|
||||
resetForNewClient(): void {
|
||||
this.permanentForm.reset({ country: 'India' });
|
||||
this.currentForm.reset({ country: 'India' });
|
||||
this.officeForm.reset({ country: 'India' });
|
||||
this.correspondenceForm.reset({ country: 'India' });
|
||||
this.activeTab = 0;
|
||||
this.sameAsPermanent = false;
|
||||
this.pinStatus = {
|
||||
permanent: { loading: false, found: false, error: false, message: '' },
|
||||
current: { loading: false, found: false, error: false, message: '' },
|
||||
office: { loading: false, found: false, error: false, message: '' },
|
||||
correspondence: { loading: false, found: false, error: false, message: '' }
|
||||
};
|
||||
this.localityOptions = { permanent: [], current: [], office: [], correspondence: [] };
|
||||
this.selectedAddrProof = null;
|
||||
this.addrFiles = { front: null, back: null };
|
||||
this.addrMergedFile = null;
|
||||
this.addrMergedPreview = null;
|
||||
this.existingAddressProofIdentifierId = null;
|
||||
this.existingAddressProofDocuments = [];
|
||||
this.addressLoaded = false;
|
||||
// Re-fetch rather than re-filter `addressProofs` in place — if the previous session's
|
||||
// isMinor filtering already reduced it (e.g. down to Aadhaar/Passport only), filtering
|
||||
// that reduced list again can never recover the items it already removed.
|
||||
this.loadProofTypes();
|
||||
}
|
||||
|
||||
private loadProofTypes(): void {
|
||||
this.loadingProofs = true;
|
||||
this.clientsService.getKycProofTypes().subscribe({
|
||||
|
||||
@@ -161,6 +161,17 @@
|
||||
}
|
||||
</button>
|
||||
}
|
||||
@if (aadhaarOtpSent && aadhaarVerifyStatus !== 'VERIFIED') {
|
||||
<button
|
||||
mat-stroked-button
|
||||
type="button"
|
||||
class="change-number-btn"
|
||||
[disabled]="readOnly"
|
||||
(click)="changeAadhaarNumber()"
|
||||
>
|
||||
<mat-icon>edit</mat-icon> Change Number
|
||||
</button>
|
||||
}
|
||||
@if (aadhaarVerifyStatus === 'VERIFIED') {
|
||||
<span class="verify-chip verified"><fa-icon icon="check-circle"></fa-icon> Verified</span>
|
||||
}
|
||||
|
||||
@@ -266,6 +266,23 @@
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.change-number-btn {
|
||||
font-size: 12px !important;
|
||||
font-weight: 600 !important;
|
||||
padding: 0 14px !important;
|
||||
height: 36px !important;
|
||||
border-radius: 6px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
mat-icon {
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.verify-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -462,15 +462,16 @@ export class ClientKycStepComponent implements OnInit, OnChanges, OnDestroy {
|
||||
form15FY: ['']
|
||||
});
|
||||
|
||||
/** RBI OVDs a minor cannot hold: Voter ID and Driving Licence require adult age,
|
||||
* PAN and NREGA job cards are issued to adults. Aadhaar, Passport and NPR letters
|
||||
* are unaffected by age and stay available. */
|
||||
private static readonly MINOR_INELIGIBLE_DOC_KEYWORDS = [
|
||||
'pan',
|
||||
'driving',
|
||||
'voter',
|
||||
'nrega'
|
||||
];
|
||||
/** RBI-accepted OVDs for a minor client — mirrors the backend's minor branch in
|
||||
* ClientKycApiResource.getRequiredDocuments(). Voter ID, Driving Licence, PAN and NREGA
|
||||
* all require adult eligibility; National Population Register Letter is deliberately
|
||||
* excluded too (not offered as a minor OVD in this system). */
|
||||
private static readonly MINOR_ELIGIBLE_DOC_CODES = new Set([
|
||||
'AADHAAR',
|
||||
'PASSPORT',
|
||||
'BIRTH_CERTIFICATE',
|
||||
'SCHOOL_ID_CARD'
|
||||
]);
|
||||
|
||||
/** Birth Certificate / School ID Card are minor-specific OVDs — not relevant once the
|
||||
* client is an adult, so they're hidden the other direction. */
|
||||
@@ -481,27 +482,13 @@ export class ClientKycStepComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
private filterDocTypesForMinor<T extends { name: string; code?: string }>(docs: T[]): T[] {
|
||||
if (this.isMinor) {
|
||||
return docs.filter((d) => {
|
||||
const text = `${d.name || ''} ${d.code || ''}`.toLowerCase();
|
||||
return !ClientKycStepComponent.MINOR_INELIGIBLE_DOC_KEYWORDS.some((k) => text.includes(k));
|
||||
});
|
||||
return docs.filter((d) => ClientKycStepComponent.MINOR_ELIGIBLE_DOC_CODES.has((d.code || '').toUpperCase()));
|
||||
}
|
||||
return docs.filter((d) => !ClientKycStepComponent.MINOR_ONLY_DOC_CODES.has((d.code || '').toUpperCase()));
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// Seed defaults immediately so the picker has options before clientId is set
|
||||
// (template API requires clientId; user can still pick a type pre-save).
|
||||
if (!this.kycDocumentTypes.length) {
|
||||
this.kycDocumentTypes = this.filterDocTypesForMinor(
|
||||
this.defaultDocumentTypes.map((d) => ({
|
||||
name: d.name,
|
||||
code: d.code,
|
||||
mandatory: false
|
||||
}))
|
||||
);
|
||||
this.rebuildKycDocPicker();
|
||||
}
|
||||
this.seedDefaultDocTypes();
|
||||
this.loadExistingKycIfNeeded();
|
||||
this.loadKycTemplate();
|
||||
if (this.isNonIndividual && this.constitutionMeta) {
|
||||
@@ -509,6 +496,92 @@ export class ClientKycStepComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
/** Seed the document-type picker from defaults, filtered by the current isMinor input.
|
||||
* Only seeds when the list is empty — the template API (loadKycTemplate) takes over once
|
||||
* a clientId is available. */
|
||||
private seedDefaultDocTypes(): void {
|
||||
if (this.kycDocumentTypes.length) return;
|
||||
this.kycDocumentTypes = this.filterDocTypesForMinor(
|
||||
this.defaultDocumentTypes.map((d) => ({
|
||||
name: d.name,
|
||||
code: d.code,
|
||||
mandatory: false
|
||||
}))
|
||||
);
|
||||
this.rebuildKycDocPicker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets transient KYC-tab state for a brand-new client.
|
||||
*
|
||||
* This app's RouteReusableStrategy (core/route/route-reusable-strategy.ts) keeps this SAME
|
||||
* component instance alive across repeat visits to /clients/create, so `ngOnInit` never
|
||||
* re-runs for a second "create new client" session. Without this, the document-type picker
|
||||
* (and any PAN/Aadhaar verification state, uploaded photo/signature) would otherwise leak
|
||||
* from whatever client was created in the previous session into the new one. Called by
|
||||
* CreateClientComponent.resetForNewClient() whenever a fresh create session begins.
|
||||
*/
|
||||
resetForNewClient(): void {
|
||||
this.kycForm.reset({
|
||||
hasPan: true,
|
||||
riskCategory: 1,
|
||||
amlCheckStatus: 'CLEAR',
|
||||
bannedEntityMatch: 'NO',
|
||||
willfulDefaulter: 'NO',
|
||||
ecgcSalFlag: 'NO',
|
||||
dormantFlag: 'ACTIVE',
|
||||
accountStatus: 'ACTIVE',
|
||||
form60Type: 'FORM_60',
|
||||
form15Type: '15G'
|
||||
});
|
||||
this.kycId = '';
|
||||
this.kycLoaded = false;
|
||||
this.kycStatus = 0;
|
||||
this.kycTemplate = null;
|
||||
this.kycTemplateLoaded = false;
|
||||
this.kycDocumentTypes = [];
|
||||
this.selectedKycDoc = null;
|
||||
this.kycDocFiles = { front: null, back: null };
|
||||
this.kycDocMergedFile = null;
|
||||
this.kycDocMergedPreview = null;
|
||||
this.existingKycIdentifierId = null;
|
||||
this.existingKycDocuments = [];
|
||||
this.photoSigTouched = false;
|
||||
this.panVerifyStatus = 'NONE';
|
||||
this.panVerifying = false;
|
||||
this.panVerifyError = '';
|
||||
this.panVerifyName = '';
|
||||
this.panVerifiedOn = '';
|
||||
this.aadhaarVerifyStatus = 'NONE';
|
||||
this.aadhaarVerifying = false;
|
||||
this.aadhaarVerifyError = '';
|
||||
this.aadhaarVerifyName = '';
|
||||
this.aadhaarVisible = false;
|
||||
this.aadhaarOtpSent = false;
|
||||
this.resetOtpDigits();
|
||||
this.aadhaarOtpReferenceId = '';
|
||||
this.panAadhaarSeedingStatus = '';
|
||||
this.entPanVerifyStatus = 'NONE';
|
||||
this.entPanVerifying = false;
|
||||
this.entPanVerifyName = '';
|
||||
this.entPanVerifiedOn = '';
|
||||
this.gstinVerifyStatus = 'NONE';
|
||||
this.gstinVerifying = false;
|
||||
this.gstinVerifyName = '';
|
||||
this.gstinVerifiedOn = '';
|
||||
this.gstinVerifyState = '';
|
||||
this.cinVerifyStatus = 'NONE';
|
||||
this.cinVerifying = false;
|
||||
this.cinVerifiedOn = '';
|
||||
this.cinCompanyName = '';
|
||||
this.photographFile = null;
|
||||
this.photographPreview = null;
|
||||
this.signatureFile = null;
|
||||
this.signaturePreview = null;
|
||||
this.existingSignatureDocId = '';
|
||||
this.seedDefaultDocTypes();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.cinProgressTimer) clearInterval(this.cinProgressTimer);
|
||||
if (this.resendTimer) clearInterval(this.resendTimer);
|
||||
@@ -1375,6 +1448,21 @@ export class ClientKycStepComponent implements OnInit, OnChanges, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
/** Lets the user go back and fix a wrong Aadhaar number after an OTP was already sent —
|
||||
* unlocks the (readonly-while-OTP-pending) input and discards the in-flight OTP session,
|
||||
* since it was requested for the now-being-corrected number. */
|
||||
changeAadhaarNumber(): void {
|
||||
this.aadhaarOtpSent = false;
|
||||
this.aadhaarVerifyError = '';
|
||||
this.aadhaarOtpReferenceId = '';
|
||||
this.resetOtpDigits();
|
||||
this.resendCountdown = 0;
|
||||
if (this.resendTimer) {
|
||||
clearInterval(this.resendTimer);
|
||||
this.resendTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify Aadhaar OTP */
|
||||
verifyAadhaarOtp() {
|
||||
if (!this.aadhaarOtp || !this.clientId || !this.kycId) return;
|
||||
|
||||
@@ -139,6 +139,8 @@ export class CreateClientComponent {
|
||||
this.validationError = '';
|
||||
this.prefillData = null;
|
||||
this.clientGeneralStep?.resetForNewClient();
|
||||
this.clientKycStep?.resetForNewClient();
|
||||
this.clientIndiaAddressStep?.resetForNewClient();
|
||||
}
|
||||
|
||||
/** Check if a tab is in read-only mode (completed tab navigated back to) */
|
||||
|
||||
Reference in New Issue
Block a user