A
This commit is contained in:
@@ -1142,6 +1142,46 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Risk profile. These are determinations about the customer rather than about anything they
|
||||
transacted, and the re-rating policy reads them directly: a PEP or a sanctions match holds the
|
||||
rating at High however ordinary the period's activity looks, and the declared income is what
|
||||
turnover is measured against. Until they are recorded the policy has nothing to test. -->
|
||||
<div class="full-span kyc-doc-fields">
|
||||
<div class="kyc-doc-fields__head">
|
||||
<h4 class="kyc-doc-fields__title">Risk Profile</h4>
|
||||
<span class="kyc-doc-fields__hint">Used by the periodic risk review</span>
|
||||
</div>
|
||||
|
||||
<div class="kyc-risk-flags">
|
||||
<mat-checkbox formControlName="isPep">
|
||||
Politically Exposed Person
|
||||
<span class="kyc-risk-hint">Holds the rating at High; never lowered on ordinary activity</span>
|
||||
</mat-checkbox>
|
||||
<mat-checkbox formControlName="sanctionsMatch">
|
||||
Sanctions / watch-list match
|
||||
<span class="kyc-risk-hint">UNSC, MHA or internal watch list</span>
|
||||
</mat-checkbox>
|
||||
<mat-checkbox formControlName="adverseMediaMatch">
|
||||
Adverse media / regulatory action
|
||||
<span class="kyc-risk-hint">FIR, court proceedings or published action</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="kyc-doc-fields__grid">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Declared annual income (₹)</mat-label>
|
||||
<input matInput type="number" min="0" formControlName="declaredAnnualIncome" />
|
||||
<mat-hint>As stated by the customer</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Declared annual turnover (₹)</mat-label>
|
||||
<input matInput type="number" min="0" formControlName="declaredAnnualTurnover" />
|
||||
<mat-hint>For a business customer</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Officially Valid Document. Shown when one is on file or the alert is asking for
|
||||
it, so re-collecting an expired document is done on this form rather than
|
||||
sending the officer somewhere else. -->
|
||||
|
||||
@@ -1807,3 +1807,28 @@
|
||||
color: #15803d;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Risk profile ────────────────────────────────────────────────────────────
|
||||
Determinations about the customer, which the periodic risk review reads directly. Grouped with
|
||||
the document block so the form reads as "what we know about them" rather than scattering a PEP
|
||||
flag among the identifier fields. */
|
||||
|
||||
.kyc-doc-fields__hint {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.kyc-risk-flags {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 4px 0 14px;
|
||||
}
|
||||
|
||||
/* Sits under its checkbox label: the consequence of ticking the box matters more than the box. */
|
||||
.kyc-risk-hint {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,13 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
1,
|
||||
[Validators.required]
|
||||
],
|
||||
// Risk profile. Determinations about the customer, which the periodic risk review reads directly - a PEP or a
|
||||
// sanctions match holds the rating at High whatever the period's activity looks like.
|
||||
isPep: [false],
|
||||
sanctionsMatch: [false],
|
||||
adverseMediaMatch: [false],
|
||||
declaredAnnualIncome: [null],
|
||||
declaredAnnualTurnover: [null],
|
||||
// The officially valid document, so a lapsed one can be re-collected on this form. The
|
||||
// backend has always accepted these four; only the fields were missing.
|
||||
kycDocumentName: [''],
|
||||
@@ -224,6 +231,11 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
this.kycForm.patchValue({
|
||||
kycType: data.kycType || 1,
|
||||
riskCategory: data.riskCategory || 1,
|
||||
isPep: !!data.isPep,
|
||||
sanctionsMatch: !!data.sanctionsMatch,
|
||||
adverseMediaMatch: !!data.adverseMediaMatch,
|
||||
declaredAnnualIncome: data.declaredAnnualIncome ?? null,
|
||||
declaredAnnualTurnover: data.declaredAnnualTurnover ?? null,
|
||||
panNumber: data.panNumber || '',
|
||||
// Aadhaar is stored masked on the server; user must re-enter
|
||||
// the full 12-digit number to re-verify, so don't pre-fill.
|
||||
@@ -449,6 +461,28 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* The customer's risk profile, as every save has to carry it.
|
||||
*
|
||||
* <p>
|
||||
* Sent from every path that writes the KYC record rather than only the main Save, because the form holds one set of
|
||||
* values: a save triggered from the PAN declaration or the Aadhaar receipt would otherwise write the record without
|
||||
* these and silently clear a PEP flag the officer had just ticked.
|
||||
*/
|
||||
private buildRiskProfileFields() {
|
||||
const v = this.kycForm.value;
|
||||
return {
|
||||
isPep: !!v.isPep,
|
||||
sanctionsMatch: !!v.sanctionsMatch,
|
||||
adverseMediaMatch: !!v.adverseMediaMatch,
|
||||
// Blank stays null rather than becoming zero: an income nobody asked for is unknown, and a zero would read as a
|
||||
// customer who declared no income at all.
|
||||
declaredAnnualIncome: v.declaredAnnualIncome === '' || v.declaredAnnualIncome == null ? null : v.declaredAnnualIncome,
|
||||
declaredAnnualTurnover:
|
||||
v.declaredAnnualTurnover === '' || v.declaredAnnualTurnover == null ? null : v.declaredAnnualTurnover
|
||||
};
|
||||
}
|
||||
|
||||
private buildExceptionFields() {
|
||||
const panVerified = this.verificationStatus.pan === 'VERIFIED' || this.kycData?.panVerified === true;
|
||||
const aadhaarVerified = this.verificationStatus.aadhaar === 'VERIFIED' || this.kycData?.aadhaarVerified === true;
|
||||
@@ -487,7 +521,8 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
// dateFormat is required so the backend can parse exceptionResolvedOn when an exception closes.
|
||||
dateFormat: 'dd MMMM yyyy',
|
||||
...this.buildDocumentFields(),
|
||||
...this.buildExceptionFields()
|
||||
...this.buildRiskProfileFields(),
|
||||
...this.buildExceptionFields()
|
||||
};
|
||||
|
||||
if (!this.kycId) {
|
||||
@@ -533,6 +568,7 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
remarks: this.kycForm.value.remarks || null,
|
||||
riskCategory: this.kycForm.value.riskCategory || 1,
|
||||
dateFormat: 'dd MMMM yyyy',
|
||||
...this.buildRiskProfileFields(),
|
||||
...this.buildExceptionFields()
|
||||
};
|
||||
|
||||
@@ -732,7 +768,8 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
dateFormat,
|
||||
riskCategory: this.kycForm.value.riskCategory || 1,
|
||||
...declarationFields,
|
||||
...this.buildExceptionFields()
|
||||
...this.buildRiskProfileFields(),
|
||||
...this.buildExceptionFields()
|
||||
};
|
||||
|
||||
this.clientsService
|
||||
@@ -892,7 +929,8 @@ export class KycTabComponent implements OnInit, OnDestroy {
|
||||
dateFormat,
|
||||
riskCategory: this.kycForm.value.riskCategory || 1,
|
||||
...receiptFields,
|
||||
...this.buildExceptionFields()
|
||||
...this.buildRiskProfileFields(),
|
||||
...this.buildExceptionFields()
|
||||
};
|
||||
|
||||
this.clientsService
|
||||
|
||||
Reference in New Issue
Block a user