feat: non-individual entity UI improvements — hide individual-only sections, fix legal form display, send extended fields to API

- Hide Family Members tab/section for non-individual entities in client view, create flow, and preview
- Hide Financial & Classification section for non-individual entities in personal data and preview
- Fix legal form column in clients list — fetch legalForm from client API for correct display
- Add person/business icon before client name in list rows
- Remove unsupportedNpd filter — send authorizedSignatory, additionalInfo, dateOfRegistration to API
- Add registration number format hint (mat-hint) based on constitution type
- Add spacing between verification row and constitution type dropdowns
- Reduce table cell padding and prevent action buttons from being clipped
- Add missing MPL-2.0 license headers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-04-04 15:10:51 +05:30
co-authored by Claude Opus 4.6
parent ab01111424
commit b890d24bb7
522 changed files with 51991 additions and 21885 deletions
@@ -0,0 +1,678 @@
<!--
Copyright since 2025 Mifos Initiative
-->
<div class="ec-page">
<!-- Header -->
<div class="step-header">
<div class="step-header__left">
<fa-icon icon="building" class="step-header__icon"></fa-icon>
<div>
<h3 class="step-header__title">Scheme &amp; Sector Classification</h3>
<p class="step-header__sub">Regulatory scheme flags, sector classification &amp; compliance identifiers</p>
</div>
</div>
</div>
<!-- Active Chips -->
<div class="ec-chips-label">Active Classifications</div>
<div class="ec-chips">
@if (enabledCount === 0) {
<span class="ec-no-chip">No classifications enabled — toggle categories below</span>
}
@for (cat of enabledCategories; track cat.id) {
<span class="ec-chip" [style.background]="cat.tagBg" [style.color]="cat.tagColor">
{{ cat.label }}
<mat-icon class="ec-chip-close" (click)="removeCategory(cat.id)">close</mat-icon>
</span>
}
</div>
<!-- ═══ CATEGORY: MSME ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['msme']">
<div class="ec-card-head" (click)="toggleExpand('msme')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#E6F4F6;color:#0A5C6B;">Udyam / MSME</span>
<div>
<div class="ec-card-title">MSME</div>
<div class="ec-card-desc">Micro, Small &amp; Medium Enterprise — Ministry of MSME / Udyam Registration</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['msme']" (change)="toggleCategory('msme')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['msme']">expand_more</mat-icon>
</div>
</div>
@if (expanded['msme']) {
<div class="ec-card-body" [formGroup]="msmeForm">
<div class="ec-sub-title">Udyam Registration</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Udyam Registration Number</mat-label>
<input matInput formControlName="udyamRegistrationNumber" placeholder="UDYAM-MP-00-0000000"
maxlength="19" style="text-transform:uppercase"
(input)="msmeForm.get('udyamRegistrationNumber')?.setValue($any($event.target).value.toUpperCase(), {emitEvent:false})" /></mat-form-field>
<mat-form-field appearance="outline" (click)="msmeRegDatePicker.open()"><mat-label>Registration Date</mat-label>
<input matInput [matDatepicker]="msmeRegDatePicker" formControlName="registrationDate" />
<mat-datepicker-toggle matSuffix [for]="msmeRegDatePicker"></mat-datepicker-toggle><mat-datepicker #msmeRegDatePicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Registration Status</mat-label>
<mat-select formControlName="registrationStatus">
<mat-option value="ACTIVE">Active</mat-option>
<mat-option value="SUSPENDED">Suspended</mat-option>
<mat-option value="CANCELLED">Cancelled</mat-option>
<mat-option value="PENDING">Pending Verification</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>MSME Classification</mat-label>
<mat-select formControlName="msmeClassification">
<mat-option value="MICRO">Micro (T/O ≤ ₹5 Cr, Inv ≤ ₹1 Cr)</mat-option>
<mat-option value="SMALL">Small (T/O ≤ ₹50 Cr, Inv ≤ ₹10 Cr)</mat-option>
<mat-option value="MEDIUM">Medium (T/O ≤ ₹250 Cr, Inv ≤ ₹50 Cr)</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Enterprise Type</mat-label>
<mat-select formControlName="enterpriseType">
<mat-option value="MANUFACTURING">Manufacturing</mat-option>
<mat-option value="SERVICES">Services</mat-option>
<mat-option value="TRADING">Trading</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>NIC Activity Code</mat-label>
<input matInput formControlName="nicActivityCode" placeholder="e.g. 13111" maxlength="10" /></mat-form-field>
</div>
<div class="ec-sub-title">Financial Thresholds (as per Udyam Portal)</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Annual Turnover — Last FY (₹ Cr)</mat-label>
<input matInput type="number" formControlName="annualTurnover" placeholder="0.00" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Investment — Plant &amp; Machinery / Equipment (₹ Cr)</mat-label>
<input matInput type="number" formControlName="investmentPlantMachinery" placeholder="0.00" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Financial Year of Last Assessment</mat-label>
<mat-select formControlName="financialYearAssessment">
<mat-option value="2025-26">2025-26</mat-option>
<mat-option value="2024-25">2024-25</mat-option>
<mat-option value="2023-24">2023-24</mat-option>
<mat-option value="2022-23">2022-23</mat-option>
<mat-option value="2021-22">2021-22</mat-option>
<mat-option value="2020-21">2020-21</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-sub-title">Owner / Promoter Details</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Social Category of Owner</mat-label>
<mat-select formControlName="socialCategoryOwner">
<mat-option value="GENERAL">General</mat-option>
<mat-option value="SC">Scheduled Caste (SC)</mat-option>
<mat-option value="ST">Scheduled Tribe (ST)</mat-option>
<mat-option value="OBC">Other Backward Class (OBC)</mat-option>
<mat-option value="MINORITY">Minority</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Gender of Primary Owner</mat-label>
<mat-select formControlName="genderPrimaryOwner">
<mat-option value="MALE">Male</mat-option>
<mat-option value="FEMALE">Female</mat-option>
<mat-option value="OTHER">Other</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>No. of Employees (approx.)</mat-label>
<input matInput type="number" formControlName="noOfEmployees" placeholder="0" /></mat-form-field>
</div>
<div class="ec-flags">
<div class="ec-flag-row">
<div><span class="ec-flag-label">Women-led Enterprise</span><span class="ec-flag-sub">Majority ownership / management by women entrepreneur</span></div>
<mat-slide-toggle formControlName="womenLedEnterprise"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">Divyang (PWD) Owned</span><span class="ec-flag-sub">Persons with Disability — eligible for special scheme benefits</span></div>
<mat-slide-toggle formControlName="divyangPwdOwned"></mat-slide-toggle>
</div>
</div>
<div class="ec-reg-note">
<strong>MSMED Act 2006 (Revised):</strong> Classification based on composite criteria of investment in plant &amp; machinery AND annual turnover. Udyam Registration is mandatory for availing PSL benefits, government procurement preference, and CGSS coverage.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['msme']" (click)="saveCategory('msme')">
@if (saving['msme']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['msme']) { <mat-icon>check</mat-icon> Saved }
@else { Save MSME }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 1: STARTUP INDIA ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['startup']">
<div class="ec-card-head" (click)="toggleExpand('startup')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#EAF2FB;color:#1A5FAB;">DPIIT</span>
<div>
<div class="ec-card-title">Startup India Registered</div>
<div class="ec-card-desc">DPIIT recognition under Startup India initiative</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['startup']" (change)="toggleCategory('startup')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['startup']">expand_more</mat-icon>
</div>
</div>
@if (expanded['startup']) {
<div class="ec-card-body" [formGroup]="startupForm">
<div class="ec-sub-title">Registration Details</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>DPIIT Recognition Number</mat-label>
<input matInput formControlName="dpiitRecognitionNumber" placeholder="DIPP12345" style="text-transform:uppercase" /></mat-form-field>
<mat-form-field appearance="outline" (click)="recDatePicker.open()"><mat-label>Recognition Date</mat-label>
<input matInput [matDatepicker]="recDatePicker" formControlName="recognitionDate" />
<mat-datepicker-toggle matSuffix [for]="recDatePicker"></mat-datepicker-toggle><mat-datepicker #recDatePicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline" (click)="certExpPicker.open()"><mat-label>Certificate Expiry Date</mat-label>
<input matInput [matDatepicker]="certExpPicker" formControlName="certificateExpiryDate" />
<mat-datepicker-toggle matSuffix [for]="certExpPicker"></mat-datepicker-toggle><mat-datepicker #certExpPicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Entity Stage</mat-label>
<mat-select formControlName="entityStage">
<mat-option value="EARLY">Early (0–2 years)</mat-option>
<mat-option value="GROWTH">Growth (2–5 years)</mat-option>
<mat-option value="SCALE">Scale (5+ years)</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Sector as per DPIIT</mat-label>
<mat-select formControlName="sectorAsDpiit">
<mat-option value="Fintech">Fintech</mat-option>
<mat-option value="Agritech">Agritech</mat-option>
<mat-option value="Edtech">Edtech</mat-option>
<mat-option value="Healthtech">Healthtech</mat-option>
<mat-option value="Logistics">Logistics</mat-option>
<mat-option value="Manufacturing">Manufacturing</mat-option>
<mat-option value="SaaS / B2B Tech">SaaS / B2B Tech</mat-option>
<mat-option value="Information Technology">Information Technology</mat-option>
<mat-option value="Other">Other</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>NIC Industry Code</mat-label>
<input matInput formControlName="nicIndustryCode" placeholder="e.g. 62013" maxlength="10" /></mat-form-field>
</div>
<div class="ec-sub-title">Government Scheme Benefits Availed</div>
<div class="ec-check-grid">
<mat-checkbox formControlName="taxExemption80iac">80IAC Tax Exemption</mat-checkbox>
<mat-checkbox formControlName="sidbiFund">SIDBI Startup Fund</mat-checkbox>
<mat-checkbox formControlName="selfCertification">Self-Certification (Labour / Env.)</mat-checkbox>
<mat-checkbox formControlName="fastTrackPatent">Fast-track Patent / IPR</mat-checkbox>
<mat-checkbox formControlName="govtTenderExemption">Government Tender Exemption</mat-checkbox>
<mat-checkbox formControlName="creditGuaranteeCgss">Credit Guarantee Scheme (CGSS)</mat-checkbox>
</div>
<div class="ec-sub-title">PSL Linkage</div>
<div class="ec-grid-2">
<mat-form-field appearance="outline"><mat-label>Loan Limit for PSL Eligibility (Cr)</mat-label>
<input matInput type="number" formControlName="pslLoanLimit" placeholder="Max 50 Cr" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>PSL Sub-category</mat-label>
<mat-select formControlName="pslSubCategory">
<mat-option value="Others (Startup India)">Others (Startup India)</mat-option>
<mat-option value="MSME - Micro">MSME — Micro</mat-option>
<mat-option value="MSME - Small">MSME — Small</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-reg-note">
<strong>RBI Circular RBI/2023-24/62:</strong> DPIIT-recognized startups eligible for PSL classification up to ₹50 Cr. Recognition certificate to be retained in document management system.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['startup']" (click)="saveCategory('startup')">
@if (saving['startup']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['startup']) { <mat-icon>check</mat-icon> Saved }
@else { Save Startup India }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 2: MUDRA BORROWER ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['mudra']">
<div class="ec-card-head" (click)="toggleExpand('mudra')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#FEF3DC;color:#8A5A00;">PMMY</span>
<div>
<div class="ec-card-title">Mudra Borrower</div>
<div class="ec-card-desc">Pradhan Mantri Mudra Yojana — SIDBI / Mudra scheme borrower</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['mudra']" (change)="toggleCategory('mudra')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['mudra']">expand_more</mat-icon>
</div>
</div>
@if (expanded['mudra']) {
<div class="ec-card-body" [formGroup]="mudraForm">
<div class="ec-sub-title">Loan Classification</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Mudra Category</mat-label>
<mat-select formControlName="mudraCategory">
<mat-option value="SHISHU">Shishu (up to ₹50,000)</mat-option>
<mat-option value="KISHORE">Kishore (₹50,001 – ₹5,00,000)</mat-option>
<mat-option value="TARUN">Tarun (₹5,00,001 – ₹10,00,000)</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Mudra Loan Account No.</mat-label>
<input matInput formControlName="mudraLoanAccountNo" placeholder="Lender's loan account number" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Lending Institution Name</mat-label>
<input matInput formControlName="lendingInstitutionName" placeholder="Bank / NBFC / MFI name" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Sanctioned Amount (₹)</mat-label>
<input matInput type="number" formControlName="sanctionedAmount" placeholder="0.00" /></mat-form-field>
<mat-form-field appearance="outline" (click)="mudraDispPicker.open()"><mat-label>Disbursement Date</mat-label>
<input matInput [matDatepicker]="mudraDispPicker" formControlName="disbursementDate" />
<mat-datepicker-toggle matSuffix [for]="mudraDispPicker"></mat-datepicker-toggle><mat-datepicker #mudraDispPicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Loan Purpose</mat-label>
<mat-select formControlName="loanPurpose">
<mat-option value="Manufacturing">Manufacturing</mat-option>
<mat-option value="Trading">Trading</mat-option>
<mat-option value="Services">Services</mat-option>
<mat-option value="Agriculture Allied Activity">Agriculture Allied Activity</mat-option>
<mat-option value="Transport">Transport</mat-option>
<mat-option value="Working Capital">Working Capital</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-sub-title">Scheme Details</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>MUDRA Card Number</mat-label>
<input matInput formControlName="mudraCardNumber" placeholder="16-digit card number" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Current Outstanding (₹)</mat-label>
<input matInput type="number" formControlName="currentOutstanding" placeholder="0.00" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Repayment Status</mat-label>
<mat-select formControlName="repaymentStatus">
<mat-option value="REGULAR">Regular</mat-option>
<mat-option value="OVERDUE_1_30">Overdue (1–30 days)</mat-option>
<mat-option value="OVERDUE_31_90">Overdue (31–90 days)</mat-option>
<mat-option value="NPA">NPA</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">NPA Flag</span><span class="ec-flag-sub">Mark if account classified as Non-Performing Asset</span></div>
<mat-slide-toggle formControlName="npaFlag"></mat-slide-toggle>
</div>
<div class="ec-reg-note">
<strong>PSL Tagging:</strong> Mudra loans must be tagged at both entity and account level for FIDD PSL returns. NPA flag mandatory for RBI quarterly reporting.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['mudra']" (click)="saveCategory('mudra')">
@if (saving['mudra']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['mudra']) { <mat-icon>check</mat-icon> Saved }
@else { Save Mudra Borrower }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 3: EXPORT ORIENTED UNIT ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['eou']">
<div class="ec-card-head" (click)="toggleExpand('eou')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#E8F5EE;color:#1B7A4A;">EOU</span>
<div>
<div class="ec-card-title">Export Oriented Unit</div>
<div class="ec-card-desc">Customs-registered EOU under DGFT / Ministry of Commerce</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['eou']" (change)="toggleCategory('eou')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['eou']">expand_more</mat-icon>
</div>
</div>
@if (expanded['eou']) {
<div class="ec-card-body" [formGroup]="eouForm">
<div class="ec-sub-title">EOU Registration</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>EOU Registration Number</mat-label>
<input matInput formControlName="eouRegistrationNumber" placeholder="EOU/MUM/2023/0001" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Registered DC Zone</mat-label>
<mat-select formControlName="registeredDcZone">
<mat-option value="Mumbai (SEEPZ)">Mumbai (SEEPZ)</mat-option>
<mat-option value="Delhi (NSEZ)">Delhi (NSEZ)</mat-option>
<mat-option value="Chennai (MEPZ)">Chennai (MEPZ)</mat-option>
<mat-option value="Bangalore (BEPZ)">Bangalore (BEPZ)</mat-option>
<mat-option value="Kolkata (FALTA)">Kolkata (FALTA)</mat-option>
<mat-option value="Hyderabad (VSEZ)">Hyderabad (VSEZ)</mat-option>
<mat-option value="Cochin (CSEZ)">Cochin (CSEZ)</mat-option>
<mat-option value="Other">Other</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Bond / LUT Number</mat-label>
<input matInput formControlName="bondLutNumber" placeholder="Bond reference number" /></mat-form-field>
<mat-form-field appearance="outline" (click)="eouFromPicker.open()"><mat-label>Validity From</mat-label>
<input matInput [matDatepicker]="eouFromPicker" formControlName="validityFrom" />
<mat-datepicker-toggle matSuffix [for]="eouFromPicker"></mat-datepicker-toggle><mat-datepicker #eouFromPicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline" (click)="eouToPicker.open()"><mat-label>Validity To</mat-label>
<input matInput [matDatepicker]="eouToPicker" formControlName="validityTo" />
<mat-datepicker-toggle matSuffix [for]="eouToPicker"></mat-datepicker-toggle><mat-datepicker #eouToPicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>GSTIN under EOU Scheme</mat-label>
<input matInput formControlName="gstinEou" placeholder="15-character GSTIN" maxlength="15" style="text-transform:uppercase" /></mat-form-field>
</div>
<div class="ec-sub-title">Export Obligation &amp; Compliance</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Annual Export Obligation (₹ Cr)</mat-label>
<input matInput type="number" formControlName="annualExportObligation" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>NFE Target (₹ Cr)</mat-label>
<input matInput type="number" formControlName="nfeTarget" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>SoftEx Filing Status</mat-label>
<mat-select formControlName="softexFilingStatus">
<mat-option value="FILED">Current</mat-option><mat-option value="PENDING">Pending</mat-option><mat-option value="NA">Not Applicable</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>BRC Submission Status</mat-label>
<mat-select formControlName="brcSubmissionStatus">
<mat-option value="SUBMITTED">Current</mat-option><mat-option value="PENDING">Pending</mat-option><mat-option value="NA">Not Applicable</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>AD Category Bank Code</mat-label>
<input matInput formControlName="adCategoryBankCode" placeholder="AD Bank IFSC / Code" /></mat-form-field>
<mat-form-field appearance="outline" (click)="femaPicker.open()"><mat-label>FEMA Declaration Date</mat-label>
<input matInput [matDatepicker]="femaPicker" formControlName="femaDeclarationDate" />
<mat-datepicker-toggle matSuffix [for]="femaPicker"></mat-datepicker-toggle><mat-datepicker #femaPicker></mat-datepicker></mat-form-field>
</div>
<div class="ec-reg-note">
<strong>FEMA / RBI:</strong> EOU accounts must be tagged for FEMA compliance on forex receipts. AD Category-I bank declaration mandatory. EDPMS reporting required for all export proceeds.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['eou']" (click)="saveCategory('eou')">
@if (saving['eou']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['eou']) { <mat-icon>check</mat-icon> Saved }
@else { Save EOU }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 4: IMPORT EXPORT ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['importexport']">
<div class="ec-card-head" (click)="toggleExpand('importexport')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#F0EBF8;color:#5B3A8A;">DGFT / IEC</span>
<div>
<div class="ec-card-title">Import Export Business</div>
<div class="ec-card-desc">Entity with valid DGFT Importer Exporter Code</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['importexport']" (change)="toggleCategory('importexport')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['importexport']">expand_more</mat-icon>
</div>
</div>
@if (expanded['importexport']) {
<div class="ec-card-body" [formGroup]="importexportForm">
<div class="ec-sub-title">IEC Registration</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>IEC Code (10-digit)</mat-label>
<input matInput formControlName="iecCode" placeholder="AABCA1234F" maxlength="10" style="text-transform:uppercase" /></mat-form-field>
<mat-form-field appearance="outline" (click)="iecDatePicker.open()"><mat-label>IEC Issue Date</mat-label>
<input matInput [matDatepicker]="iecDatePicker" formControlName="iecIssueDate" />
<mat-datepicker-toggle matSuffix [for]="iecDatePicker"></mat-datepicker-toggle><mat-datepicker #iecDatePicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>IEC Status</mat-label>
<mat-select formControlName="iecStatus">
<mat-option value="ACTIVE">Active</mat-option><mat-option value="SUSPENDED">Suspended</mat-option>
<mat-option value="CANCELLED">Cancelled</mat-option><mat-option value="DEACTIVATED">Deactivated</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Trade Type</mat-label>
<mat-select formControlName="tradeType">
<mat-option value="EXPORT">Export Only</mat-option><mat-option value="IMPORT">Import Only</mat-option>
<mat-option value="BOTH">Both Import &amp; Export</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Primary HS Code (Commodity)</mat-label>
<input matInput formControlName="primaryHsCode" placeholder="e.g. 5208 — Cotton fabrics" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Key Trading Countries</mat-label>
<input matInput formControlName="keyTradingCountries" placeholder="e.g. UAE, USA, Singapore" /></mat-form-field>
</div>
<div class="ec-sub-title">Banking &amp; Compliance</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>AD Category Bank Code</mat-label>
<input matInput formControlName="adCategoryBankCode" placeholder="AD Bank IFSC / RBI code" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>ECGC Policy Number</mat-label>
<input matInput formControlName="ecgcPolicyNumber" placeholder="ECGC policy reference" /></mat-form-field>
<mat-form-field appearance="outline" (click)="ecgcExpPicker.open()"><mat-label>ECGC Policy Expiry</mat-label>
<input matInput [matDatepicker]="ecgcExpPicker" formControlName="ecgcPolicyExpiry" />
<mat-datepicker-toggle matSuffix [for]="ecgcExpPicker"></mat-datepicker-toggle><mat-datepicker #ecgcExpPicker></mat-datepicker></mat-form-field>
</div>
<div class="ec-flags">
<div class="ec-flag-row">
<div><span class="ec-flag-label">EEFC Account Required</span><span class="ec-flag-sub">Exchange Earners Foreign Currency account</span></div>
<mat-slide-toggle formControlName="eefcAccountRequired"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">PCFC Facility Required</span><span class="ec-flag-sub">Pre-shipment Credit in Foreign Currency</span></div>
<mat-slide-toggle formControlName="pcfcFacilityRequired"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">FEMA Declaration Obtained</span><span class="ec-flag-sub">Form A2 / LRS declaration on file</span></div>
<mat-slide-toggle formControlName="femaDeclarationObtained"></mat-slide-toggle>
</div>
</div>
<div class="ec-reg-note">
<strong>RBI / FEMA:</strong> IEC mandatory before any import/export transaction. AD bank must report all export proceeds via EDPMS and import payments via IDPMS. ECGC cover recommended for high-risk countries.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['importexport']" (click)="saveCategory('importexport')">
@if (saving['importexport']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['importexport']) { <mat-icon>check</mat-icon> Saved }
@else { Save Import/Export }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 5: PRIORITY SECTOR ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['psl']">
<div class="ec-card-head" (click)="toggleExpand('psl')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#FCEAEA;color:#7B1F1F;">RBI PSL</span>
<div>
<div class="ec-card-title">Priority Sector Borrower</div>
<div class="ec-card-desc">Eligible under RBI Priority Sector Lending guidelines</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['psl']" (change)="toggleCategory('psl')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['psl']">expand_more</mat-icon>
</div>
</div>
@if (expanded['psl']) {
<div class="ec-card-body" [formGroup]="pslForm">
<div class="ec-sub-title">PSL Classification</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>PSL Category</mat-label>
<mat-select formControlName="pslCategory">
<mat-option value="AGRICULTURE">Agriculture</mat-option>
<mat-option value="MICRO_ENTERPRISE">MSME</mat-option>
<mat-option value="HOUSING">Housing</mat-option>
<mat-option value="EDUCATION">Education</mat-option>
<mat-option value="SOCIAL_INFRA">Social Infrastructure</mat-option>
<mat-option value="RENEWABLE">Renewable Energy</mat-option>
<mat-option value="EXPORT_CREDIT">Export Credit</mat-option>
<mat-option value="WEAKER_SECTION">Weaker Section</mat-option>
<mat-option value="OTHERS">Others</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>PSL Sub-category</mat-label>
<mat-select formControlName="pslSubCategory">
<mat-option value="Direct Agriculture - Crop Loan">Direct Agriculture — Crop Loan</mat-option>
<mat-option value="Direct Agriculture - Investment">Direct Agriculture — Investment</mat-option>
<mat-option value="Allied Agriculture">Allied Agriculture</mat-option>
<mat-option value="Micro Enterprise">Micro Enterprise</mat-option>
<mat-option value="Small Enterprise">Small Enterprise</mat-option>
<mat-option value="Medium Enterprise">Medium Enterprise</mat-option>
<mat-option value="Housing">Housing (up to ₹35L)</mat-option>
<mat-option value="Education Loan">Education Loan</mat-option>
<mat-option value="Weaker Section - SC/ST">Weaker Section — SC/ST</mat-option>
<mat-option value="Weaker Section - Minorities">Weaker Section — Minorities</mat-option>
<mat-option value="Export Credit">Export Credit</mat-option>
<mat-option value="Others - Startup India">Others — Startup India</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>PSL Loan Purpose Code</mat-label>
<input matInput formControlName="pslLoanPurposeCode" placeholder="RBI purpose code e.g. 111" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>PSL Eligibility Basis</mat-label>
<input matInput formControlName="pslEligibilityBasis" placeholder="e.g. Udyam Reg / Kisan Credit Card" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>FIDD Reporting Code</mat-label>
<input matInput formControlName="fiddReportingCode" placeholder="FIDD sector code" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>PSL Sanctioned Limit (₹)</mat-label>
<input matInput type="number" formControlName="pslSanctionedLimit" /></mat-form-field>
</div>
<!-- MSME Sub-section -->
@if (pslForm.get('pslCategory')?.value === 'MICRO_ENTERPRISE') {
<div class="ec-sub-title">MSME Sub-classification</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>MSME Classification</mat-label>
<mat-select formControlName="msmeClassification">
<mat-option value="MICRO">Micro (T/O ≤ ₹5 Cr, Inv ≤ ₹1 Cr)</mat-option>
<mat-option value="SMALL">Small (T/O ≤ ₹50 Cr, Inv ≤ ₹10 Cr)</mat-option>
<mat-option value="MEDIUM">Medium (T/O ≤ ₹250 Cr, Inv ≤ ₹50 Cr)</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Udyam Registration Number</mat-label>
<input matInput formControlName="udyamRegistrationNumber" placeholder="UDYAM-MP-00-0000000" style="text-transform:uppercase" /></mat-form-field>
<mat-form-field appearance="outline" (click)="udyamDatePicker.open()"><mat-label>Udyam Registration Date</mat-label>
<input matInput [matDatepicker]="udyamDatePicker" formControlName="udyamRegistrationDate" />
<mat-datepicker-toggle matSuffix [for]="udyamDatePicker"></mat-datepicker-toggle><mat-datepicker #udyamDatePicker></mat-datepicker></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Annual Turnover (₹ Cr)</mat-label>
<input matInput type="number" formControlName="annualTurnover" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Investment — Plant &amp; Machinery (₹ Cr)</mat-label>
<input matInput type="number" formControlName="investmentPlantMachinery" /></mat-form-field>
</div>
}
<div class="ec-sub-title">Special Category Flags</div>
<div class="ec-flags">
<div class="ec-flag-row">
<div><span class="ec-flag-label">Weaker Section Flag</span><span class="ec-flag-sub">SHG, JLG, SC/ST, OBC, Minorities, PWD borrowers</span></div>
<mat-slide-toggle formControlName="weakerSectionFlag"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">SC / ST Borrower Flag</span><span class="ec-flag-sub">Scheduled Caste or Scheduled Tribe classification</span></div>
<mat-slide-toggle formControlName="scStBorrowerFlag"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">Women Entrepreneur Flag</span><span class="ec-flag-sub">Majority-owned / managed by women</span></div>
<mat-slide-toggle formControlName="womenEntrepreneurFlag"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">Minority Community Flag</span><span class="ec-flag-sub">As defined by Ministry of Minority Affairs</span></div>
<mat-slide-toggle formControlName="minorityCommunityFlag"></mat-slide-toggle>
</div>
</div>
<div class="ec-reg-note">
<strong>RBI FIDD Circular:</strong> PSL tagging mandatory at entity AND loan account level. MSME classification must be verified from Udyam portal — self-declaration not acceptable. Weaker section loans reported separately in FIDD quarterly returns.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['psl']" (click)="saveCategory('psl')">
@if (saving['psl']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['psl']) { <mat-icon>check</mat-icon> Saved }
@else { Save Priority Sector }
</button>
</div>
</div>
}
</div>
<!-- ═══ CATEGORY 6: NON-PRIORITY SECTOR ═══ -->
<div class="ec-card" [class.ec-card--open]="enabled['nps']">
<div class="ec-card-head" (click)="toggleExpand('nps')">
<div class="ec-card-head-left">
<span class="ec-tag" style="background:#F1EFE8;color:#444441;">General</span>
<div>
<div class="ec-card-title">Non-Priority Sector</div>
<div class="ec-card-desc">Standard corporate / retail borrower — no special priority sector classification</div>
</div>
</div>
<div class="ec-card-toggle">
<mat-slide-toggle [checked]="!!enabled['nps']" (change)="toggleCategory('nps')" (click)="$event.stopPropagation()"></mat-slide-toggle>
<mat-icon class="ec-chevron" [class.open]="expanded['nps']">expand_more</mat-icon>
</div>
</div>
@if (expanded['nps']) {
<div class="ec-card-body" [formGroup]="npsForm">
<div class="ec-sub-title">Sector Classification</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Industry Sector</mat-label>
<mat-select formControlName="industrySector">
<mat-option value="Large Corporate">Large Corporate</mat-option>
<mat-option value="Mid-Market Corporate">Mid-Market Corporate</mat-option>
<mat-option value="HNI">High Net Worth Individual (HNI)</mat-option>
<mat-option value="Retail - Salaried">Retail — Salaried</mat-option>
<mat-option value="Retail - Self Employed">Retail — Self Employed</mat-option>
<mat-option value="Government / PSU">Government / PSU</mat-option>
<mat-option value="Trust / NGO / Society">Trust / NGO / Society</mat-option>
<mat-option value="Real Estate">Real Estate</mat-option>
<mat-option value="Other">Other</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>NIC Code (5-digit)</mat-label>
<input matInput formControlName="nicCode" placeholder="e.g. 13111" maxlength="5" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Industry Description</mat-label>
<input matInput formControlName="industryDescription" placeholder="Brief sector description" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Annual Revenue Band</mat-label>
<mat-select formControlName="annualRevenueBand">
<mat-option value="BELOW_1CR">Below ₹1 Cr</mat-option>
<mat-option value="1CR_TO_10CR">₹1 Cr – ₹10 Cr</mat-option>
<mat-option value="10CR_TO_100CR">₹10 Cr – ₹100 Cr</mat-option>
<mat-option value="100CR_TO_500CR">₹100 Cr – ₹500 Cr</mat-option>
<mat-option value="ABOVE_500CR">Above ₹500 Cr</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-sub-title">Risk Classification</div>
<div class="ec-grid-3">
<mat-form-field appearance="outline"><mat-label>Risk Category</mat-label>
<mat-select formControlName="riskCategory">
<mat-option value="LOW">Low Risk</mat-option>
<mat-option value="MEDIUM">Medium Risk</mat-option>
<mat-option value="HIGH">High Risk</mat-option>
</mat-select></mat-form-field>
<mat-form-field appearance="outline"><mat-label>Customer Risk Score</mat-label>
<input matInput type="number" formControlName="customerRiskScore" placeholder="0–100" min="0" max="100" /></mat-form-field>
<mat-form-field appearance="outline"><mat-label>AML Risk Classification</mat-label>
<mat-select formControlName="amlRiskClassification">
<mat-option value="SDD">Standard Due Diligence (SDD)</mat-option>
<mat-option value="CDD">Customer Due Diligence (CDD)</mat-option>
<mat-option value="EDD">Enhanced Due Diligence (EDD)</mat-option>
</mat-select></mat-form-field>
</div>
<div class="ec-flags">
<div class="ec-flag-row">
<div><span class="ec-flag-label">PEP Flag — Politically Exposed Person</span><span class="ec-flag-sub">Requires mandatory EDD as per RBI KYC Master Circular</span></div>
<mat-slide-toggle formControlName="pepFlag"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">AML Watchlist Match</span><span class="ec-flag-sub">UN Sanctions / OFAC / EU / MHA match detected</span></div>
<mat-slide-toggle formControlName="amlWatchlistMatch"></mat-slide-toggle>
</div>
<div class="ec-flag-row">
<div><span class="ec-flag-label">Adverse Media Flag</span><span class="ec-flag-sub">Negative news screening result — requires review</span></div>
<mat-slide-toggle formControlName="adverseMediaFlag"></mat-slide-toggle>
</div>
</div>
<div class="ec-reg-note">
<strong>RBI KYC Master Circular 2023:</strong> PEP flag triggers mandatory EDD regardless of transaction size. AML watchlist match must be escalated to MLRO within 24 hours. Risk score reviewed annually for High Risk customers.
</div>
<div class="ec-card-actions">
<button mat-raised-button color="primary" [disabled]="!clientId || saving['nps']" (click)="saveCategory('nps')">
@if (saving['nps']) { <mat-progress-spinner diameter="16" mode="indeterminate"></mat-progress-spinner> Saving... }
@else if (saved['nps']) { <mat-icon>check</mat-icon> Saved }
@else { Save Non-Priority Sector }
</button>
</div>
</div>
}
</div>
@if (!clientId) {
<div class="ec-info-banner">
<fa-icon icon="info-circle"></fa-icon>
<span>Saving classifications requires client to be created first. Complete General tab and click Next.</span>
</div>
}
</div>
@@ -0,0 +1,206 @@
/**
* Entity Classification — Scheme & Sector Classification
*/
.ec-page { padding: 0; }
.step-header {
background: #0f172a;
padding: 16px 24px;
border-radius: 10px 10px 0 0;
margin-bottom: 20px;
&__left { display: flex; align-items: center; gap: 12px; }
&__icon { font-size: 18px; color: #60a5fa; }
&__title { font-size: 16px; font-weight: 600; color: #fff; margin: 0; }
&__sub { font-size: 11px; color: rgba(255,255,255,0.5); margin: 2px 0 0; }
}
.ec-chips-label {
font-size: 11px;
font-weight: 600;
color: #94a3b8;
letter-spacing: 0.06em;
text-transform: uppercase;
margin-bottom: 8px;
}
.ec-chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 20px;
min-height: 28px;
}
.ec-no-chip { font-size: 12px; color: #94a3b8; padding: 4px 0; }
.ec-chip {
padding: 4px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 500;
display: flex;
align-items: center;
gap: 5px;
}
.ec-chip-close {
font-size: 14px !important;
width: 14px !important;
height: 14px !important;
cursor: pointer;
opacity: 0.6;
&:hover { opacity: 1; }
}
.ec-card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 10px;
margin-bottom: 12px;
overflow: hidden;
transition: border-color 0.2s;
&--open { border-color: #93c5fd; }
}
.ec-card-head {
padding: 14px 20px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
user-select: none;
transition: background 0.15s;
&:hover { background: #f8fafc; }
}
.ec-card-head-left { display: flex; align-items: center; gap: 12px; }
.ec-tag {
padding: 3px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.03em;
white-space: nowrap;
}
.ec-card-title { font-size: 14px; font-weight: 600; color: #1e293b; }
.ec-card-desc { font-size: 12px; color: #64748b; margin-top: 2px; }
.ec-card-toggle { display: flex; align-items: center; gap: 10px; }
.ec-chevron {
transition: transform 0.25s;
color: #94a3b8;
&.open { transform: rotate(180deg); }
}
.ec-card-body {
border-top: 1px solid #f1f5f9;
padding: 20px;
}
.ec-grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px 16px;
margin-bottom: 8px;
mat-form-field { width: 100%; }
}
.ec-grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px 16px;
margin-bottom: 8px;
mat-form-field { width: 100%; }
}
.ec-sub-title {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.07em;
color: #94a3b8;
text-transform: uppercase;
margin: 16px 0 12px;
padding-top: 12px;
border-top: 1px dashed #e2e8f0;
&:first-child { margin-top: 0; padding-top: 0; border-top: none; }
}
.ec-check-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
margin-bottom: 8px;
mat-checkbox {
padding: 8px 12px;
border: 1px solid #e2e8f0;
border-radius: 6px;
font-size: 12px;
transition: background 0.12s, border-color 0.12s;
&:hover { background: #f8fafc; border-color: #93c5fd; }
}
}
.ec-flags {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 8px;
}
.ec-flag-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
background: #f8fafc;
border: 1px solid #f1f5f9;
border-radius: 6px;
}
.ec-flag-label { font-size: 13px; font-weight: 500; color: #1e293b; display: block; }
.ec-flag-sub { font-size: 11px; color: #94a3b8; display: block; margin-top: 1px; }
.ec-reg-note {
margin-top: 16px;
padding: 10px 14px;
background: #f0f9ff;
border-left: 3px solid #0ea5e9;
border-radius: 0 6px 6px 0;
font-size: 12px;
color: #0c4a6e;
line-height: 1.6;
strong { font-weight: 600; }
}
.ec-card-actions {
display: flex;
justify-content: flex-end;
margin-top: 16px;
padding-top: 12px;
border-top: 1px solid #f1f5f9;
button { display: flex; align-items: center; gap: 6px; }
}
.ec-info-banner {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
background: #fffbeb;
border: 1px solid #fde68a;
border-radius: 8px;
font-size: 12px;
color: #92400e;
margin-top: 12px;
}
@media (max-width: 900px) { .ec-grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) {
.ec-grid-3, .ec-grid-2 { grid-template-columns: 1fr; }
.ec-check-grid { grid-template-columns: 1fr; }
.ec-card-head { padding: 12px 14px; }
.ec-card-body { padding: 14px; }
}
@@ -0,0 +1,311 @@
/**
* Copyright since 2025 Mifos Initiative
*/
import { Component, Input, OnInit, OnChanges, SimpleChanges, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatCheckbox } from '@angular/material/checkbox';
import { MatIcon } from '@angular/material/icon';
import { MatTooltip } from '@angular/material/tooltip';
import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { MatSlideToggle } from '@angular/material/slide-toggle';
import { ClientsService } from '../../clients.service';
import { SettingsService } from 'app/settings/settings.service';
import { Dates } from 'app/core/utils/dates';
export interface CategoryMeta {
id: string;
label: string;
tag: string;
tagColor: string;
tagBg: string;
desc: string;
icon: string;
}
@Component({
selector: 'mifosx-client-entity-kyc-step',
templateUrl: './client-entity-kyc-step.component.html',
styleUrls: ['./client-entity-kyc-step.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
FaIconComponent,
MatCheckbox,
MatIcon,
MatTooltip,
MatProgressSpinner,
MatSlideToggle
]
})
export class ClientEntityKycStepComponent implements OnInit, OnChanges {
private fb = inject(UntypedFormBuilder);
private clientService = inject(ClientsService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
@Input() clientId: string = '';
@Input() constitutionType: string = '';
/** Read-only mode — disables form editing until user clicks edit icon */
@Input() readOnly = false;
today = new Date();
/** Category metadata */
categories: CategoryMeta[] = [
{ id: 'msme', label: 'MSME', tag: 'Udyam / MSME', tagColor: '#0A5C6B', tagBg: '#E6F4F6', desc: 'Micro, Small & Medium Enterprise — Ministry of MSME / Udyam Registration', icon: 'cogs' },
{ id: 'startup', label: 'Startup India Registered', tag: 'DPIIT', tagColor: '#1A5FAB', tagBg: '#EAF2FB', desc: 'DPIIT recognition under Startup India initiative', icon: 'rocket' },
{ id: 'mudra', label: 'Mudra Borrower', tag: 'PMMY', tagColor: '#8A5A00', tagBg: '#FEF3DC', desc: 'Pradhan Mantri Mudra Yojana — SIDBI / Mudra scheme', icon: 'hand-holding-usd' },
{ id: 'eou', label: 'Export Oriented Unit', tag: 'EOU', tagColor: '#1B7A4A', tagBg: '#E8F5EE', desc: 'Customs-registered EOU under DGFT / Ministry of Commerce', icon: 'ship' },
{ id: 'importexport', label: 'Import Export Business', tag: 'DGFT / IEC', tagColor: '#5B3A8A', tagBg: '#F0EBF8', desc: 'Entity with valid DGFT Importer Exporter Code', icon: 'exchange-alt' },
{ id: 'psl', label: 'Priority Sector Borrower', tag: 'RBI PSL', tagColor: '#7B1F1F', tagBg: '#FCEAEA', desc: 'Eligible under RBI Priority Sector Lending guidelines', icon: 'bullseye' },
{ id: 'nps', label: 'Non-Priority Sector', tag: 'General', tagColor: '#444441', tagBg: '#F1EFE8', desc: 'Standard corporate — no special priority sector classification', icon: 'building' }
];
/** Toggle & expand state per category */
enabled: Record<string, boolean> = {};
expanded: Record<string, boolean> = {};
/** Forms per category */
msmeForm!: UntypedFormGroup;
startupForm!: UntypedFormGroup;
mudraForm!: UntypedFormGroup;
eouForm!: UntypedFormGroup;
importexportForm!: UntypedFormGroup;
pslForm!: UntypedFormGroup;
npsForm!: UntypedFormGroup;
/** Saving state */
saving: Record<string, boolean> = {};
saved: Record<string, boolean> = {};
ngOnInit() {
this.initForms();
if (this.clientId) {
this.loadExisting();
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['readOnly']) {
const forms = [this.msmeForm, this.startupForm, this.mudraForm, this.eouForm, this.importexportForm, this.pslForm, this.npsForm];
for (const form of forms) {
if (!form) continue;
if (this.readOnly) {
form.disable({ emitEvent: false });
} else {
form.enable({ emitEvent: false });
}
}
}
}
private initForms() {
this.msmeForm = this.fb.group({
udyamRegistrationNumber: [''],
registrationDate: [''],
registrationStatus: [''],
msmeClassification: [''],
enterpriseType: [''],
nicActivityCode: [''],
annualTurnover: [''],
investmentPlantMachinery: [''],
financialYearAssessment: [''],
socialCategoryOwner: [''],
genderPrimaryOwner: [''],
noOfEmployees: [''],
womenLedEnterprise: [false],
divyangPwdOwned: [false]
});
this.startupForm = this.fb.group({
dpiitRecognitionNumber: [''],
recognitionDate: [''],
certificateExpiryDate: [''],
entityStage: [''],
sectorAsDpiit: [''],
nicIndustryCode: [''],
taxExemption80iac: [false],
sidbiFund: [false],
selfCertification: [false],
fastTrackPatent: [false],
govtTenderExemption: [false],
creditGuaranteeCgss: [false],
pslLoanLimit: [''],
pslSubCategory: ['']
});
this.mudraForm = this.fb.group({
mudraCategory: [''],
mudraLoanAccountNo: [''],
lendingInstitutionName: [''],
sanctionedAmount: [''],
disbursementDate: [''],
loanPurpose: [''],
mudraCardNumber: [''],
currentOutstanding: [''],
repaymentStatus: [''],
npaFlag: [false]
});
this.eouForm = this.fb.group({
eouRegistrationNumber: [''],
registeredDcZone: [''],
bondLutNumber: [''],
validityFrom: [''],
validityTo: [''],
gstinEou: [''],
annualExportObligation: [''],
nfeTarget: [''],
softexFilingStatus: [''],
brcSubmissionStatus: [''],
adCategoryBankCode: [''],
femaDeclarationDate: ['']
});
this.importexportForm = this.fb.group({
iecCode: [''],
iecIssueDate: [''],
iecStatus: [''],
tradeType: [''],
primaryHsCode: [''],
keyTradingCountries: [''],
adCategoryBankCode: [''],
ecgcPolicyNumber: [''],
ecgcPolicyExpiry: [''],
eefcAccountRequired: [false],
pcfcFacilityRequired: [false],
femaDeclarationObtained: [false]
});
this.pslForm = this.fb.group({
pslCategory: [''],
pslSubCategory: [''],
pslLoanPurposeCode: [''],
pslEligibilityBasis: [''],
fiddReportingCode: [''],
pslSanctionedLimit: [''],
msmeClassification: [''],
udyamRegistrationNumber: [''],
udyamRegistrationDate: [''],
annualTurnover: [''],
investmentPlantMachinery: [''],
weakerSectionFlag: [false],
scStBorrowerFlag: [false],
womenEntrepreneurFlag: [false],
minorityCommunityFlag: [false]
});
this.npsForm = this.fb.group({
industrySector: [''],
nicCode: [''],
industryDescription: [''],
annualRevenueBand: [''],
riskCategory: [''],
customerRiskScore: [''],
amlRiskClassification: [''],
pepFlag: [false],
amlWatchlistMatch: [false],
adverseMediaFlag: [false]
});
}
getForm(categoryId: string): UntypedFormGroup {
switch (categoryId) {
case 'msme': return this.msmeForm;
case 'startup': return this.startupForm;
case 'mudra': return this.mudraForm;
case 'eou': return this.eouForm;
case 'importexport': return this.importexportForm;
case 'psl': return this.pslForm;
case 'nps': return this.npsForm;
default: return this.fb.group({});
}
}
toggleCategory(id: string) {
this.enabled[id] = !this.enabled[id];
if (this.enabled[id]) {
this.expanded[id] = true;
}
}
toggleExpand(id: string) {
this.expanded[id] = !this.expanded[id];
}
get enabledCategories(): CategoryMeta[] {
return this.categories.filter(c => this.enabled[c.id]);
}
get enabledCount(): number {
return this.enabledCategories.length;
}
removeCategory(id: string) {
this.enabled[id] = false;
this.expanded[id] = false;
}
/** Save a single category */
saveCategory(categoryId: string) {
if (!this.clientId) return;
this.saving[categoryId] = true;
const form = this.getForm(categoryId);
const payload: any = { ...form.value, enabled: true, locale: 'en', dateFormat: this.settingsService.dateFormat };
// Format date fields
for (const key of Object.keys(payload)) {
if (payload[key] instanceof Date) {
payload[key] = this.dateUtils.formatDate(payload[key], this.settingsService.dateFormat);
}
}
this.clientService.saveEntityClassification(this.clientId, categoryId, payload).subscribe({
next: () => {
this.saving[categoryId] = false;
this.saved[categoryId] = true;
setTimeout(() => this.saved[categoryId] = false, 3000);
},
error: () => {
this.saving[categoryId] = false;
}
});
}
/** Load existing classifications */
private loadExisting() {
this.clientService.getEntityClassifications(this.clientId).subscribe({
next: (data: any) => {
if (!data) return;
for (const cat of this.categories) {
const catData = data[cat.id];
if (catData && catData.enabled) {
this.enabled[cat.id] = true;
this.getForm(cat.id).patchValue(catData);
}
}
}
});
}
/** Get all classification data for parent */
get classificationData(): any {
const result: any = {};
for (const cat of this.categories) {
if (this.enabled[cat.id]) {
result[cat.id] = { ...this.getForm(cat.id).value, enabled: true };
}
}
return result;
}
get hasClassificationData(): boolean {
return this.enabledCount > 0;
}
// Keep old getter for backward compatibility
get entityKycData(): any { return this.classificationData; }
get hasEntityKycData(): boolean { return this.hasClassificationData; }
}