Update client KYC and address handling
This commit is contained in:
Generated
+26
@@ -78,6 +78,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
||||||
"@typescript-eslint/parser": "^8.48.1",
|
"@typescript-eslint/parser": "^8.48.1",
|
||||||
"@vendure/ngx-translate-extract": "^9.4.0",
|
"@vendure/ngx-translate-extract": "^9.4.0",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"cypress": "^13.17.0",
|
"cypress": "^13.17.0",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"git-describe": "^4.1.1",
|
"git-describe": "^4.1.1",
|
||||||
@@ -3560,6 +3561,13 @@
|
|||||||
"url": "https://github.com/sponsors/JounQin"
|
"url": "https://github.com/sponsors/JounQin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@epic-web/invariant": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.25.9",
|
"version": "0.25.9",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
|
||||||
@@ -11702,6 +11710,24 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@epic-web/invariant": "^1.0.0",
|
||||||
|
"cross-spawn": "^7.0.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "dist/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|||||||
+5
-4
@@ -15,10 +15,10 @@
|
|||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"build": "node version.js && npm run env -s && ng build --configuration production --output-hashing=none",
|
"build": "node version.js && npm run env -s && ng build --configuration production --output-hashing=none",
|
||||||
"build:prod": "node version.js && node --max-old-space-size=16384 ./node_modules/@angular/cli/bin/ng build --configuration production --output-hashing=none --base-href=/web-app/",
|
"build:prod": "node version.js && node --max-old-space-size=16384 ./node_modules/@angular/cli/bin/ng build --configuration production --output-hashing=none --base-href=/web-app/",
|
||||||
"start": "npm run env -s && ng serve --proxy-config proxy.localhost.conf.js",
|
"start": "npm run env -s && cross-env NODE_OPTIONS=\"--max_old_space_size=16384\" ng serve --proxy-config proxy.localhost.conf.js",
|
||||||
"start:share": "npm run env -s && ng serve --host 0.0.0.0 --proxy-config proxy.localhost.conf.js",
|
"start:share": "npm run env -s && cross-env NODE_OPTIONS=\"--max_old_space_size=16384\" ng serve --host 0.0.0.0 --proxy-config proxy.localhost.conf.js",
|
||||||
"start:demo": "npm run env -s && ng serve --proxy-config proxy.conf.js",
|
"start:demo": "npm run env -s && cross-env NODE_OPTIONS=\"--max_old_space_size=16384\" ng serve --proxy-config proxy.conf.js",
|
||||||
"serve:dev": "npm run env -s && ng serve --source-map --proxy-config proxy.localhost.conf.js",
|
"serve:dev": "npm run env -s && cross-env NODE_OPTIONS=\"--max_old_space_size=16384\" ng serve --source-map --proxy-config proxy.localhost.conf.js",
|
||||||
"serve:sw": "npm run build -s && npx http-server ./dist -p 4200",
|
"serve:sw": "npm run build -s && npx http-server ./dist -p 4200",
|
||||||
"lint": "eslint . && stylelint \"src/**/*.scss\" && prettier . --check && htmlhint \"src\" --config .htmlhintrc",
|
"lint": "eslint . && stylelint \"src/**/*.scss\" && prettier . --check && htmlhint \"src\" --config .htmlhintrc",
|
||||||
"test": "jest --config jest.config.ts",
|
"test": "jest --config jest.config.ts",
|
||||||
@@ -107,6 +107,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
||||||
"@typescript-eslint/parser": "^8.48.1",
|
"@typescript-eslint/parser": "^8.48.1",
|
||||||
"@vendure/ngx-translate-extract": "^9.4.0",
|
"@vendure/ngx-translate-extract": "^9.4.0",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"cypress": "^13.17.0",
|
"cypress": "^13.17.0",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"git-describe": "^4.1.1",
|
"git-describe": "^4.1.1",
|
||||||
|
|||||||
+6
-1
@@ -263,6 +263,7 @@
|
|||||||
<mat-form-field appearance="outline" class="name-field last-name">
|
<mat-form-field appearance="outline" class="name-field last-name">
|
||||||
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
|
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>person</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>person</mat-icon></span>
|
||||||
|
<<<<<<< Updated upstream
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
required
|
required
|
||||||
@@ -271,6 +272,9 @@
|
|||||||
(blur)="capitalizeControl('lastname')"
|
(blur)="capitalizeControl('lastname')"
|
||||||
style="text-transform: capitalize"
|
style="text-transform: capitalize"
|
||||||
/>
|
/>
|
||||||
|
=======
|
||||||
|
<input matInput required formControlName="lastname" autocomplete="off" (input)="formatName('lastname')" />
|
||||||
|
>>>>>>> Stashed changes
|
||||||
@if (createClientForm.controls.lastname.hasError('required')) {
|
@if (createClientForm.controls.lastname.hasError('required')) {
|
||||||
<mat-error>Last name is <strong>required</strong></mat-error>
|
<mat-error>Last name is <strong>required</strong></mat-error>
|
||||||
} @else if (createClientForm.controls.lastname.hasError('pattern')) {
|
} @else if (createClientForm.controls.lastname.hasError('pattern')) {
|
||||||
@@ -854,7 +858,8 @@
|
|||||||
<div class="guardian-result-item__info">
|
<div class="guardian-result-item__info">
|
||||||
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
||||||
<span class="guardian-result-item__meta"
|
<span class="guardian-result-item__meta"
|
||||||
>ID: {{ result.id }} · A/C: {{ result.accountNumber }} ·
|
>ID: {{ result.id }} · A/C: {{ result.accountNumber }}
|
||||||
|
·
|
||||||
{{ result.officeName }}
|
{{ result.officeName }}
|
||||||
@if (result.dateOfBirth) {
|
@if (result.dateOfBirth) {
|
||||||
· DOB: {{ result.dateOfBirth | dateFormat }}
|
· DOB: {{ result.dateOfBirth | dateFormat }}
|
||||||
|
|||||||
@@ -2590,6 +2590,28 @@ export class ClientGeneralStepComponent implements OnInit, OnDestroy, OnChanges
|
|||||||
dormantFlag: 'ACTIVE'
|
dormantFlag: 'ACTIVE'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically capitalizes the first letter of each word and lowercases the rest.
|
||||||
|
* e.g., "sri rAm" -> "Sri Ram"
|
||||||
|
*/
|
||||||
|
formatName(controlName: string): void {
|
||||||
|
const control = this.createClientForm.get(controlName);
|
||||||
|
if (!control || typeof control.value !== 'string') return;
|
||||||
|
|
||||||
|
const val = control.value;
|
||||||
|
const formatted = val
|
||||||
|
.split(' ')
|
||||||
|
.map((word: string) => {
|
||||||
|
if (!word) return '';
|
||||||
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
if (formatted !== val) {
|
||||||
|
control.setValue(formatted, { emitEvent: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+52
-9
@@ -122,8 +122,41 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<div class="addr-proof-field">
|
<div class="addr-proof-field">
|
||||||
<label class="addr-proof-label"><mat-icon>description</mat-icon> Document type</label>
|
<div
|
||||||
<div class="addr-chip-wrap" [class.addr-chip-wrap--locked]="readOnly">
|
class="addr-proof-label-row"
|
||||||
|
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px"
|
||||||
|
>
|
||||||
|
<label class="addr-proof-label" style="margin-bottom: 0"
|
||||||
|
><mat-icon>description</mat-icon> Document type</label
|
||||||
|
>
|
||||||
|
@if (isAddressProofLinkedToKyc && !readOnly) {
|
||||||
|
<div
|
||||||
|
class="addr-proof-linked-note"
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: #059669;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
background: #ecfdf5;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<mat-icon style="font-size: 16px; width: 16px; height: 16px">link</mat-icon>
|
||||||
|
Automatically linked from KYC step
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
(click)="unlinkAddressProof()"
|
||||||
|
matTooltip="Provide a different address proof"
|
||||||
|
style="width: 24px; height: 24px; padding: 0; line-height: 24px"
|
||||||
|
>
|
||||||
|
<mat-icon style="font-size: 16px; color: #047857">edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="addr-chip-wrap" [class.addr-chip-wrap--locked]="readOnly || isAddressProofLinkedToKyc">
|
||||||
@for (group of addressGroups; track group.label; let last = $last) {
|
@for (group of addressGroups; track group.label; let last = $last) {
|
||||||
<div class="addr-chip-group-label"><mat-icon>folder_open</mat-icon> {{ group.label }}</div>
|
<div class="addr-chip-group-label"><mat-icon>folder_open</mat-icon> {{ group.label }}</div>
|
||||||
<div class="addr-chip-grid">
|
<div class="addr-chip-grid">
|
||||||
@@ -131,11 +164,11 @@
|
|||||||
<span
|
<span
|
||||||
class="addr-chip"
|
class="addr-chip"
|
||||||
[class.addr-chip--sel]="isAddrProofSelected(p)"
|
[class.addr-chip--sel]="isAddrProofSelected(p)"
|
||||||
[class.addr-chip--locked]="readOnly && !isAddrProofSelected(p)"
|
[class.addr-chip--locked]="(readOnly || isAddressProofLinkedToKyc) && !isAddrProofSelected(p)"
|
||||||
[attr.aria-disabled]="readOnly ? 'true' : null"
|
[attr.aria-disabled]="readOnly || isAddressProofLinkedToKyc ? 'true' : null"
|
||||||
(click)="readOnly ? null : selectAddrProof(p)"
|
(click)="readOnly || isAddressProofLinkedToKyc ? null : selectAddrProof(p)"
|
||||||
(keydown.enter)="readOnly ? null : selectAddrProof(p)"
|
(keydown.enter)="readOnly || isAddressProofLinkedToKyc ? null : selectAddrProof(p)"
|
||||||
[attr.tabindex]="readOnly ? -1 : 0"
|
[attr.tabindex]="readOnly || isAddressProofLinkedToKyc ? -1 : 0"
|
||||||
role="button"
|
role="button"
|
||||||
>
|
>
|
||||||
<mat-icon class="addr-chip__icon">
|
<mat-icon class="addr-chip__icon">
|
||||||
@@ -167,14 +200,24 @@
|
|||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
formControlName="documentKey"
|
formControlName="documentKey"
|
||||||
|
[readonly]="readOnly || isAddressProofLinkedToKyc"
|
||||||
[placeholder]="selectedAddrProof.documentKeyPlaceholder || ''"
|
[placeholder]="selectedAddrProof.documentKeyPlaceholder || ''"
|
||||||
/>
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@if (selectedAddrProof.requiresDate) {
|
@if (selectedAddrProof.requiresDate) {
|
||||||
<mat-form-field appearance="outline" class="addr-ff">
|
<mat-form-field appearance="outline" class="addr-ff">
|
||||||
<mat-label>Issue / bill date</mat-label>
|
<mat-label>Issue / bill date</mat-label>
|
||||||
<input matInput [matDatepicker]="addrIssueDatePicker" formControlName="issueDate" />
|
<input
|
||||||
<mat-datepicker-toggle matSuffix [for]="addrIssueDatePicker"></mat-datepicker-toggle>
|
matInput
|
||||||
|
[matDatepicker]="addrIssueDatePicker"
|
||||||
|
formControlName="issueDate"
|
||||||
|
[readonly]="readOnly || isAddressProofLinkedToKyc"
|
||||||
|
/>
|
||||||
|
<mat-datepicker-toggle
|
||||||
|
matSuffix
|
||||||
|
[for]="addrIssueDatePicker"
|
||||||
|
[disabled]="readOnly || isAddressProofLinkedToKyc"
|
||||||
|
></mat-datepicker-toggle>
|
||||||
<mat-datepicker #addrIssueDatePicker></mat-datepicker>
|
<mat-datepicker #addrIssueDatePicker></mat-datepicker>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
}
|
}
|
||||||
|
|||||||
+111
-10
@@ -55,9 +55,22 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
* NPR/Birth Certificate/School ID) from the proof-of-address picker; a company's registered
|
* NPR/Birth Certificate/School ID) from the proof-of-address picker; a company's registered
|
||||||
* office address is evidenced by utility bills, GST/rent documents etc., not a person's ID. */
|
* office address is evidenced by utility bills, GST/rent documents etc., not a person's ID. */
|
||||||
@Input() isNonIndividual = false;
|
@Input() isNonIndividual = false;
|
||||||
|
/** KYC form data passed down from the parent wizard so we can pre-fill address proof */
|
||||||
|
@Input() kycData: any;
|
||||||
|
/** KYC document code for robust matching */
|
||||||
|
@Input() kycDocCode: string | undefined;
|
||||||
|
/** KYC document files passed down to avoid re-uploading */
|
||||||
|
@Input() kycDocFiles: { front: File | null; back: File | null } | null = null;
|
||||||
|
/** Combined preview string for KYC document */
|
||||||
|
@Input() kycDocMergedPreview: string | null = null;
|
||||||
|
/** Existing server documents from KYC step (used in Edit mode) */
|
||||||
|
@Input() existingKycDocSides: { front: any | null; back: any | null } | null = null;
|
||||||
|
/** Identifier ID for existing server documents */
|
||||||
|
@Input() existingKycIdentifierId: string | null = null;
|
||||||
|
|
||||||
activeTab = 0;
|
activeTab = 0;
|
||||||
sameAsPermanent = false;
|
sameAsPermanent = false;
|
||||||
|
isAddressProofLinkedToKyc = false;
|
||||||
|
|
||||||
permanentForm: UntypedFormGroup = this.fb.group({
|
permanentForm: UntypedFormGroup = this.fb.group({
|
||||||
addressLine1: [
|
addressLine1: [
|
||||||
@@ -240,6 +253,8 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
/** Address type name → tab mapping for loading existing data */
|
/** Address type name → tab mapping for loading existing data */
|
||||||
private typeToTab: Record<string, string> = {};
|
private typeToTab: Record<string, string> = {};
|
||||||
|
|
||||||
|
private existingAddressProofCheckComplete = false;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.loadProofTypes();
|
this.loadProofTypes();
|
||||||
if (this.clientId) {
|
if (this.clientId) {
|
||||||
@@ -247,6 +262,73 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private findMatchingProof(targetName: string | undefined): any {
|
||||||
|
if (!targetName) return undefined;
|
||||||
|
const cleanStr = (s: string) => (s || '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
||||||
|
const n = cleanStr(targetName);
|
||||||
|
return this.addressProofs.find((p) => {
|
||||||
|
const pname = cleanStr(p.name);
|
||||||
|
return pname === n || n.includes(pname) || pname.includes(n);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private tryLinkKycData(): void {
|
||||||
|
if (!this.kycData || !this.kycData.kycDocumentName) return;
|
||||||
|
|
||||||
|
if (this.clientId && !this.existingAddressProofCheckComplete) return;
|
||||||
|
|
||||||
|
if (this.isAddressProofLinkedToKyc || !this.permanentForm.get('documentKey')?.value) {
|
||||||
|
let matchedProof = undefined;
|
||||||
|
if (this.kycDocCode) {
|
||||||
|
matchedProof = this.addressProofs.find((p) => p.code === this.kycDocCode);
|
||||||
|
}
|
||||||
|
if (!matchedProof) {
|
||||||
|
matchedProof = this.findMatchingProof(this.kycData.kycDocumentName);
|
||||||
|
}
|
||||||
|
if (matchedProof) {
|
||||||
|
this.isAddressProofLinkedToKyc = true;
|
||||||
|
this.selectAddrProof(matchedProof);
|
||||||
|
this.permanentForm.patchValue({
|
||||||
|
documentKey: this.kycData.kycDocumentNumber,
|
||||||
|
issueDate: this.kycData.kycDocIssueDate
|
||||||
|
});
|
||||||
|
this.currentForm.patchValue({
|
||||||
|
documentKey: this.kycData.kycDocumentNumber,
|
||||||
|
issueDate: this.kycData.kycDocIssueDate
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sync uploaded images if they exist in KYC step
|
||||||
|
if (this.kycDocFiles && (this.kycDocFiles.front || this.kycDocFiles.back)) {
|
||||||
|
this.addrFiles = { front: this.kycDocFiles.front || null, back: this.kycDocFiles.back || null };
|
||||||
|
if (this.kycDocMergedPreview) {
|
||||||
|
this.addrMergedPreview = this.kycDocMergedPreview;
|
||||||
|
}
|
||||||
|
} else if (this.existingKycDocSides && (this.existingKycDocSides.front || this.existingKycDocSides.back)) {
|
||||||
|
this.existingAddressProofDocuments = [];
|
||||||
|
if (this.existingKycDocSides.front) this.existingAddressProofDocuments.push(this.existingKycDocSides.front);
|
||||||
|
if (this.existingKycDocSides.back) this.existingAddressProofDocuments.push(this.existingKycDocSides.back);
|
||||||
|
if (this.existingKycDocSides.front?.previewUrl) {
|
||||||
|
this.addrMergedPreview = this.existingKycDocSides.front.previewUrl;
|
||||||
|
} else if (this.existingKycDocSides.back?.previewUrl) {
|
||||||
|
this.addrMergedPreview = this.existingKycDocSides.back.previewUrl;
|
||||||
|
}
|
||||||
|
this.existingAddressProofIdentifierId = this.existingKycIdentifierId;
|
||||||
|
}
|
||||||
|
} else if (this.isAddressProofLinkedToKyc) {
|
||||||
|
// If it was linked but the KYC document changed to something not allowed for address (e.g. PAN for non-individuals), unlink.
|
||||||
|
this.unlinkAddressProof();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unlinkAddressProof(): void {
|
||||||
|
this.isAddressProofLinkedToKyc = false;
|
||||||
|
this.permanentForm.patchValue({ documentKey: '', issueDate: null });
|
||||||
|
this.currentForm.patchValue({ documentKey: '', issueDate: null });
|
||||||
|
this.addrFiles = { front: null, back: null };
|
||||||
|
this.addrMergedPreview = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets transient address-tab state for a brand-new client.
|
* Resets transient address-tab state for a brand-new client.
|
||||||
*
|
*
|
||||||
@@ -277,6 +359,7 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
this.existingAddressProofIdentifierId = null;
|
this.existingAddressProofIdentifierId = null;
|
||||||
this.existingAddressProofDocuments = [];
|
this.existingAddressProofDocuments = [];
|
||||||
this.addressLoaded = false;
|
this.addressLoaded = false;
|
||||||
|
this.existingAddressProofCheckComplete = false;
|
||||||
// Re-fetch rather than re-filter `addressProofs` in place — if the previous session's
|
// 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
|
// 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.
|
// that reduced list again can never recover the items it already removed.
|
||||||
@@ -293,6 +376,7 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
);
|
);
|
||||||
this.addressGroups = groupProofsByCategory(this.addressProofs);
|
this.addressGroups = groupProofsByCategory(this.addressProofs);
|
||||||
this.loadingProofs = false;
|
this.loadingProofs = false;
|
||||||
|
this.tryLinkKycData();
|
||||||
},
|
},
|
||||||
error: () => {
|
error: () => {
|
||||||
this.loadingProofs = false;
|
this.loadingProofs = false;
|
||||||
@@ -426,6 +510,17 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (changes['kycData'] || changes['existingKycDocSides']) {
|
||||||
|
this.tryLinkKycData();
|
||||||
|
}
|
||||||
|
if (changes['existingKycIdentifierId']) {
|
||||||
|
if (
|
||||||
|
this.existingAddressProofIdentifierId &&
|
||||||
|
this.existingAddressProofIdentifierId === this.existingKycIdentifierId
|
||||||
|
) {
|
||||||
|
this.isAddressProofLinkedToKyc = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (changes['readOnly']) {
|
if (changes['readOnly']) {
|
||||||
const forms = [
|
const forms = [
|
||||||
this.permanentForm,
|
this.permanentForm,
|
||||||
@@ -544,19 +639,25 @@ export class ClientIndiaAddressStepComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
this.clientsService.getClientIdentifiers(this.clientId).subscribe({
|
this.clientsService.getClientIdentifiers(this.clientId).subscribe({
|
||||||
next: (identifiers: any[]) => {
|
next: (identifiers: any[]) => {
|
||||||
if (!identifiers || identifiers.length === 0) return;
|
if (!identifiers || identifiers.length === 0) {
|
||||||
const proofNames = new Set(this.addressProofs.map((p) => p.name?.toLowerCase()).filter(Boolean));
|
this.existingAddressProofCheckComplete = true;
|
||||||
const identifier = identifiers.find((i: any) => {
|
this.tryLinkKycData();
|
||||||
const n = i?.documentType?.name?.toLowerCase();
|
return;
|
||||||
return n && proofNames.has(n);
|
}
|
||||||
});
|
const identifier = identifiers.find((i: any) => this.findMatchingProof(i?.documentType?.name));
|
||||||
if (!identifier?.id) return;
|
if (!identifier?.id) {
|
||||||
|
this.existingAddressProofCheckComplete = true;
|
||||||
|
this.tryLinkKycData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.existingAddressProofCheckComplete = true;
|
||||||
this.existingAddressProofIdentifierId = identifier.id.toString();
|
this.existingAddressProofIdentifierId = identifier.id.toString();
|
||||||
|
if (this.existingKycIdentifierId && this.existingKycIdentifierId === this.existingAddressProofIdentifierId) {
|
||||||
|
this.isAddressProofLinkedToKyc = true;
|
||||||
|
}
|
||||||
// Restore selected chip + form values
|
// Restore selected chip + form values
|
||||||
const matchedProof = this.addressProofs.find(
|
const matchedProof = this.findMatchingProof(identifier.documentType?.name);
|
||||||
(p) => p.name?.toLowerCase() === identifier.documentType?.name?.toLowerCase()
|
|
||||||
);
|
|
||||||
if (matchedProof) {
|
if (matchedProof) {
|
||||||
this.selectedAddrProof = matchedProof;
|
this.selectedAddrProof = matchedProof;
|
||||||
this.permanentForm.patchValue({
|
this.permanentForm.patchValue({
|
||||||
|
|||||||
@@ -153,6 +153,12 @@
|
|||||||
[isMinor]="clientGeneralStep?.isMinor || false"
|
[isMinor]="clientGeneralStep?.isMinor || false"
|
||||||
[isNonIndividual]="legalFormType === 2"
|
[isNonIndividual]="legalFormType === 2"
|
||||||
[readOnly]="isTabReadOnly(addressTabIdx)"
|
[readOnly]="isTabReadOnly(addressTabIdx)"
|
||||||
|
[kycData]="clientKycStep?.kycForm?.value"
|
||||||
|
[kycDocCode]="clientKycStep?.selectedKycDoc?.code"
|
||||||
|
[kycDocFiles]="clientKycStep?.kycDocFiles || null"
|
||||||
|
[kycDocMergedPreview]="clientKycStep?.kycDocMergedPreview || null"
|
||||||
|
[existingKycDocSides]="clientKycStep?.existingKycDocSides || null"
|
||||||
|
[existingKycIdentifierId]="clientKycStep?.existingKycIdentifierId || null"
|
||||||
></mifosx-client-india-address-step>
|
></mifosx-client-india-address-step>
|
||||||
</div>
|
</div>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|||||||
@@ -289,6 +289,12 @@
|
|||||||
[isMinor]="clientGeneralStep?.isMinor || false"
|
[isMinor]="clientGeneralStep?.isMinor || false"
|
||||||
[isNonIndividual]="legalFormType === 2"
|
[isNonIndividual]="legalFormType === 2"
|
||||||
[readOnly]="isTabReadOnly(addressTabIdx)"
|
[readOnly]="isTabReadOnly(addressTabIdx)"
|
||||||
|
[kycData]="clientKyc?.kycForm?.value"
|
||||||
|
[kycDocCode]="clientKyc?.selectedKycDoc?.code"
|
||||||
|
[kycDocFiles]="clientKyc?.kycDocFiles || null"
|
||||||
|
[kycDocMergedPreview]="clientKyc?.kycDocMergedPreview || null"
|
||||||
|
[existingKycDocSides]="clientKyc?.existingKycDocSides || null"
|
||||||
|
[existingKycIdentifierId]="clientKyc?.existingKycIdentifierId || null"
|
||||||
></mifosx-client-india-address-step>
|
></mifosx-client-india-address-step>
|
||||||
</div>
|
</div>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
export default {
|
export default {
|
||||||
'mifos_x': {
|
'mifos_x': {
|
||||||
'version': '260814',
|
'version': '260813',
|
||||||
'hash': '997e8920'
|
'hash': '5a6fb1f9'
|
||||||
},
|
},
|
||||||
'allow_switching_backend_instance': true
|
'allow_switching_backend_instance': true
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user