diff --git a/src/app/loan-origination/application-detail/application-detail.component.html b/src/app/loan-origination/application-detail/application-detail.component.html index d965e5b1a..a3e4e80e2 100644 --- a/src/app/loan-origination/application-detail/application-detail.component.html +++ b/src/app/loan-origination/application-detail/application-detail.component.html @@ -17,7 +17,10 @@ @if (application; as a) {
-
CREDIT · LOAN ORIGINATION · {{ a.branchName | uppercase }}
+
+ + CREDIT · LOAN ORIGINATION · {{ a.branchName | uppercase }} +

{{ a.applicationNo }} — {{ a.applicantName }} {{ statusLabels[a.overallStatus] }} @@ -40,6 +43,28 @@ } @else if (saveFailed) { Not saved — check connection } +

@@ -120,92 +145,597 @@ - - -
- Approved by - + } @else { + + @if (guarantorSlotSearching === i) { + @if (searchingGuarantor) { +

Searching…

+ } @else if (guarantorSearchText.length >= 2 && guarantorSearchResults.length === 0) { +

No clients found.

+ } + @if (guarantorSearchResults.length > 0) { +
+ @for (client of guarantorSearchResults; track client.id) { + + } +
+ } + } +

+ Guarantor {{ i + 1 }} is not named yet. Search and select an existing bank client — a name alone isn't + enough. +

+ } +
+ }
+ + + + @if (grantedApprovals(app).length) { +
+
+ + + + + Approved by +
+
+ @for (ap of grantedApprovals(app); track ap.label) { +
+ ✓ + {{ ap.label }} — {{ ap.approverName }} ({{ ap.role }}) · + {{ ap.date }} + @if (ap.exception) { + On exception + } + @if (ap.remarks) { + “{{ ap.remarks }}” + } +
+ } +
+
+ } +
+ - @if (approvalRequest(a, field); as req) { -
- ⏳ Sent for approval — by {{ req.submittedBy }} on {{ req.submittedOn }} - @if (req.requestedDecision === 'EXCEPTION_APPROVED') { - (on exception) + @if (isStageApproved(a, field); as ap) { +
+
+
+ + + + +
+
+
+ Approved by {{ ap.approverName }} + + {{ ap.decision === 'EXCEPTION_APPROVED' ? 'Approved on Exception' : 'Approved' }} + +
+
+ Role: {{ ap.approverRole || role }} · Approved on {{ ap.date }} +
+
+
+ @if (ap.remarks) { +
+ + + + Approver Remarks: “{{ ap.remarks }}” +
} - · awaiting {{ role }}. - @if (req.remarks) { -
“{{ req.remarks }}” + @if (nextStageOf(a); as nxt) { +
+ +
}
- @if (req.checklist?.length) { -
- What {{ req.submittedBy }} verified before sending ({{ req.submittedOn }}) -
    - @for (check of req.checklist; track check.label) { -
  • {{ check.ok ? '✓' : '✗' }} {{ check.label }}
  • - } -
-
- } + } @else if (approvalRequest(a, field); as req) { @if (isMyRequest(req)) { -

- You sent this request, so you cannot approve it. A different user has to approve or reject it. -

+
+
+
+ + + + +
+
+
+ Sent for approval · awaiting {{ role }} + @if (req.requestedDecision === 'EXCEPTION_APPROVED') { + On exception + } +
+
+ Submitted by {{ req.submittedBy }} on {{ req.submittedOn }} +
+ @if (req.previousRevokeRemarks) { +
+ Re-submitted after correction (Previous note: “{{ req.previousRevokeRemarks }}”) +
+ } +
+
+ @if (req.remarks) { +
+ + + + “{{ req.remarks }}” +
+ } +
+ + @if (req.checklist?.length && !(field === 'creditCommitteeApproval' && isDepositLoan(a))) { +
+
+
+ + + + +
+
+
What you verified before sending
+
Completed on {{ req.submittedOn }}
+
+
+
+ @for (check of req.checklist; track check.label) { +
+ {{ check.ok ? '✓' : '✕' }} + {{ check.label }} +
+ } +
+
+ } + +
+ + + + + + You sent this request, so you cannot approve it. A different user has to approve, reject or revoke + it. +
} @else { -
- Your verification — tick each row you have checked ({{ checkerCount(a, field, req) }}) + + @if (req.previousRevokeRemarks) { +
+ + + + + +
+
Re-submitted after correction
+
+ Previous reason for return: “{{ req.previousRevokeRemarks }}” +
+
+
+ } + @if (req.checklist?.length && !(field === 'creditCommitteeApproval' && isDepositLoan(a))) { +
+
+
+ + + + +
+
+
What {{ req.submittedBy }} verified before sending
+
Completed on {{ req.submittedOn }}
+
+
+
+ @for (check of req.checklist; track check.label) { +
+ {{ check.ok ? '✓' : '✕' }} + {{ check.label }} +
+ } +
+ @if (req.remarks) { +
+ + + + Sender's Remarks: “{{ req.remarks }}” +
+ } +
+ } + @if (autoChecked(a, field)) { + @for (item of checkerItems(a, field, req); track item.label) { - @if (item.ok) { - - } @else { -

- ✗ {{ item.label }} — the sender did not verify this, so it cannot be approved. -

+ @if (!item.ok) { +
+ ✕ + {{ item.label }} — this check has not passed, so it cannot be approved. +
} } -
-
- - -
- @if (!checkerReady(a, field, req)) { -

Approve opens after you tick every row above.

+ } @else { +
+
+
+
+ + + + +
+
+
+ Your verification — tick each row you have checked + {{ checkerCount(a, field, req) }} +
+
+ Review checkpoints and documents below to approve, or return with remarks for rectification +
+
+
+
+
+ @for (item of checkerItems(a, field, req); track item.label) { + @if (item.ok) { + + } @else { +
+ ✕ + {{ item.label }} — the sender did not verify this, so it cannot be approved. +
+ } + } +
+
} +
+
+ +
+
+ + + +
+ @if (!checkerReady(a, field, req) && !autoChecked(a, field)) { +
+ + + + + Approve opens after you tick every row above. Revoke / Return is always available with remarks. +
+ } +
} } @else { + @if (latestRevokedRequest(a, field); as revReq) { +
+
+
+ + + + + +
+
+
+ Returned for Correction by {{ revReq.decidedBy || 'Approver' }} + Needs Correction +
+
+ Returned on {{ revReq.decidedOn }} · Stage unlocked for document/data updates +
+
+
+ @if (revReq.revokeRemarks || revReq.remarks) { +
+
Approver's Revoke Remarks / Error Noted:
+
“{{ revReq.revokeRemarks || revReq.remarks }}”
+
+ } +
+ + + + + + Please review the error note above, correct or re-upload the documents/data, and click + Re-submit for Approval below. +
+
+ }
@if (exception) { } @else {
{{ stepMarker(a, s) }} - {{ stageLabels[s] }} + {{ stageLabel(a, s) }}
} } @@ -305,6 +874,28 @@
@if (a.fineractLoanAccountNo) { A/C {{ a.fineractLoanAccountNo }} + @if (loanAccount) { + + } + } @else if (loanAccount) { + A/C {{ loanAccount.accountNo }} · {{ loanAccount.status }} + } @else { Mock disbursement only — no core banking account } @@ -374,6 +965,382 @@ }
} @else { + + @if (loanAccount && a.currentStage !== 'CUSTOMER_SIGNING' && !showAccountCard(a)) { + + } + @if (showAccountCard(a) && accountOverview; as ov) { +
+
+ Loan account {{ loanAccount?.accountNo }} + {{ + loanAccount?.status + }} + +
+
+
+

Account Details

+
+ @for (row of ov.account; track row.label) { +
+
{{ row.label }}
+
{{ row.value }}
+
+ } +
+
+
+

Approved By

+
+
+
Account approved by
+
{{ ov.approval.by }}
+
+
+
Approved on
+
{{ ov.approval.on }}
+
+
+
Approved amount
+
{{ ov.approval.amount }}
+
+
+
+
+

Approved Items

+
+ @for (row of approvedItems(a); track row.label) { +
+
{{ row.label }}
+
{{ row.value }}
+
+ } +
+
+
+

Added Items (charges)

+
+ @for (c of ov.charges; track c.name) { +
+
{{ c.name }}
+
+ {{ c.amount }} · {{ c.when }} + {{ + c.added ? 'Added' : 'Product' + }} +
+
+ } @empty { +
+
Charges
+
None
+
+ } +
+
+
+

GL Accounts (from the product)

+
+ @for (row of ov.glAccounts; track row.label) { +
+
{{ row.label }}
+
{{ row.value }}
+
+ } +
+ @if (ov.posting) { +

{{ ov.posting }}

+ } +
+
+ +
+ @if (loanAccount?.active) { + ✓ Disbursed. Completing the application… + } @else if (!loanAccountReady) { + The loan account has to be approved before it can be disbursed. + } @else if (a.currentStage !== 'DISBURSED') { + Disbursement can be sent for approval once the post-disbursement check is done. + } @else { + @switch (disbursementState(a)) { + @case ('NONE') { + + } + @case ('MINE_PENDING') { + + ⏳ Sent for disbursement approval by you. Another user has to approve it; the loan is disbursed as + soon as they do. + + + } + @case ('OTHER_PENDING') { + + Disbursement approval requested by {{ disbursementRequestedBy(a) }}. Debit {{ accountOverview?.glAccounts?.[1]?.value }}, credit + {{ accountOverview?.glAccounts?.[0]?.value }}. + + + + + } + @case ('APPROVED') { + + ✓ Disbursement approved{{ + a.disbursementApproval?.approverName ? ' by ' + a.disbursementApproval?.approverName : '' + }}. + {{ executingDisbursement ? 'Disbursing…' : 'Disbursing the loan…' }} + + + } + } + } +
+
+ } + + +
+

+ The purpose decides whether the loan counts as priority sector lending (RBI Master Directions, 2025) and + whether the borrower is a weaker section. It is needed before the sanction is approved. +

+ + +
+
Priority sector
+

+ Product setting: {{ a.productName }} is + {{ + isPrioritySectorProduct(a) ? 'a priority sector product' : 'not a priority sector product' + }}. +

+ + @if (pslOverridden(a)) { + + } + @if (pslChoice(a) === 'yes') { + + @if (a.prioritySectorCategory) { + + @if (pslDocType && !pslLocked(a)) { + + } + @for (stored of pslDocs('PSL'); track stored.id) { +
+ ✓ {{ stored.description || stored.name }} — {{ stored.fileName }} + + @if (!pslLocked(a)) { + + } +
+ } + } + } +
+ +
+
Weaker section (overlapping tag, RBI para 17)
+ + @if (a.weakerSection === 'yes') { + + + @if (weakerDocType && !pslLocked(a)) { + + } + @for (stored of pslDocs('WEAKER'); track stored.id) { +
+ ✓ {{ stored.description || stored.name }} — {{ stored.fileName }} + + @if (!pslLocked(a)) { + + } +
+ } + } +
+ + @if (pslHint(a)) { +

{{ pslHint(a) }}

+ } @else { + Purpose and priority sector classification complete + } +
+
+ + @if (showPslCard(a)) { +
+ + +
+ } @if (a.currentStage === 'APPLICATION') {
@@ -420,49 +1387,375 @@ } @else {
- Aadhaar -
+
+ Aadhaar {{ a.aadhaarVerified ? 'Verified' : 'Not Verified' }} - @if (realKyc?.aadhaarNumberMasked) { - {{ realKyc.aadhaarNumberMasked }} - }
- + @if (realKyc?.aadhaarNumberMasked) { + {{ realKyc.aadhaarNumberMasked }} + } + @if (hasAadhaarPhotos()) { +
+ + @if (hasAadhaarFront()) { + + } @else { + + } + + + @if (hasAadhaarBack()) { + + } @else { + + } +
+ } @else { + + }
- PAN -
+
+ PAN {{ a.panVerified ? 'Verified' : 'Not Verified' }} - @if (realKyc?.panNumber) { - {{ maskPan(realKyc.panNumber) }} - }
- + @if (realKyc?.panNumber) { + {{ maskPan(realKyc.panNumber) }} + } + @if (hasPanPhotos()) { + @if (hasPanFront() && hasPanBack()) { +
+ + + + + +
+ } @else { + +
+ +
+ } + } @else { + + }
- Income Proof - +
+ + Income Proof @if (isDepositLoan(a)) { - · optional + optional } - + + @if (a.incomeProofSubmitted || findDocument('income')) { + Submitted + } @else { + Missing + } +
@if (findDocument('income'); as incomeDoc) { - Submitted {{ incomeDoc.name || incomeDoc.fileName }} - } @else { + @if (!!a.productDocuments) {
Loan-Specific Documents — {{ a.productName }}
+ @if (a.productDocuments.length === 0) { +

+ {{ a.productName }} lists no required documents. Add any document the officer needs from the + customer. +

+ }
@for (doc of a.productDocuments; track doc.key) { @if (doc.key === 'coOwnerKyc') {
- {{ doc.label }} +
+ {{ doc.label }} + @if (doc.submitted) { + + {{ coOwnerCapture.hasCoOwner ? 'Verified' : 'Not Applicable' }} + + } @else { + Missing + } +
@if (doc.hint) { {{ doc.hint }} } @@ -1183,29 +2519,29 @@
} - @if (doc.submitted) { - - {{ coOwnerCapture.hasCoOwner ? 'Verified' : 'Not Applicable' }} - - } @else { - Missing - }
} @else {
- - {{ doc.label }} - @if (doc.custom) { - +
+ + {{ doc.label }} + @if (doc.custom) { + + } + + @if (doc.submitted) { + Submitted + } @else { + Missing } - +
@if (doc.hint) { {{ doc.hint }} } @@ -1230,17 +2566,25 @@ @if (capture.previewUrl) { {{ doc.label }} } @else { - View file + + + + + View } } }
- @if (doc.submitted) { - Submitted - } @else { - Missing - }
} } @@ -1258,259 +2602,269 @@
} - - @if (!isRevolving(a)) { + + @if (!isDepositLoan(a)) { - @if (amountOutOfRange(a)) { -

- {{ a.productName }} allows ₹{{ productLimitsFor(a)?.minAmt | number: '1.0-0' }} – ₹{{ - productLimitsFor(a)?.maxAmt | number: '1.0-0' - }} - — this amount won't be saved until it's in range. -

- } - - @if (tenureOutOfRange(a)) { -

- {{ a.productName }} allows {{ productLimitsFor(a)?.minTenure }}–{{ productLimitsFor(a)?.maxTenure }} - months — this tenure won't be saved until it's in range. -

- } - } -

- Eligible Loan Amount preview: ₹{{ eligiblePreview(a) | number: '1.0-0' }} -

- @if (isRevolving(a)) { -

- {{ a.productName }} is a revolving/renewable limit — repaid on demand, no fixed EMI. -

- } @else { -

- Estimated EMI: ₹{{ emiPreview(a) | number: '1.0-0' }} / month ({{ - emiToIncomePctPreview(a) | number: '1.0-1' - }}% of monthly income) -

- @if (emiToIncomePctPreview(a) > 40) { - @if (a.coBorrowerRequired && coBorrowerDetailsComplete(a) && combinedEligibilityOk(a)) { -

- EMI exceeds 40% of the applicant's own income, but the Co-Borrower added below already covers it — - see the Co-Borrower section. -

- } @else { + @if (!isRevolving(a)) { + + @if (amountOutOfRange(a)) {

- EMI exceeds 40% of monthly income — add a Co-Borrower, reduce the loan amount, or increase the - tenure before proceeding. + {{ a.productName }} allows ₹{{ productLimitsFor(a)?.minAmt | number: '1.0-0' }} – ₹{{ + productLimitsFor(a)?.maxAmt | number: '1.0-0' + }} + — this amount won't be saved until it's in range. +

+ } + + @if (tenureOutOfRange(a)) { +

+ {{ a.productName }} allows {{ productLimitsFor(a)?.minTenure }}–{{ productLimitsFor(a)?.maxTenure }} + months — this tenure won't be saved until it's in range.

} } - } -
- -
- @if (a.monthlyIncome > 0) { -
-
-
Monthly Income (Last Assessed)
-
₹{{ a.monthlyIncome | number: '1.0-0' }}
-
-
-
Eligible Loan Amount
-
₹{{ a.eligibleLoanAmount | number: '1.0-0' }}
-
-
-
Estimated EMI
-
- @if (isRevolving(a)) { - No fixed EMI (revolving limit) - } @else { - ₹{{ emiAmountFor(a) | number: '1.0-0' }} / month - } -
-
-
- } - @if (!isRevolving(a)) { -
-
EMI Calculation Basis
-
+

+ Eligible Loan Amount preview: ₹{{ eligiblePreview(a) | number: '1.0-0' }} +

+ @if (isRevolving(a)) { +

+ {{ a.productName }} is a revolving/renewable limit — repaid on demand, no fixed EMI. +

+ } @else { +

+ Estimated EMI: ₹{{ emiPreview(a) | number: '1.0-0' }} / month ({{ + emiToIncomePctPreview(a) | number: '1.0-1' + }}% of monthly income) +

+ @if (emiToIncomePctPreview(a) > 40) { + @if (a.coBorrowerRequired && coBorrowerDetailsComplete(a) && combinedEligibilityOk(a)) { +

+ EMI exceeds 40% of the applicant's own income, but the Co-Borrower added below already covers it — + see the Co-Borrower section. +

+ } @else { +

+ EMI exceeds 40% of monthly income — add a Co-Borrower, reduce the loan amount, or increase the + tenure before proceeding. +

+ } + } + } +
+ +
+ @if (a.monthlyIncome > 0) { +
-
Principal (Loan Amount)
-
₹{{ a.requestedAmount | number: '1.0-0' }}
+
Monthly Income (Last Assessed)
+
₹{{ a.monthlyIncome | number: '1.0-0' }}
-
Interest Rate
-
{{ a.interestRate }}% p.a. ({{ a.interestRate / 12 | number: '1.2-2' }}% / month)
+
Eligible Loan Amount
+
₹{{ a.eligibleLoanAmount | number: '1.0-0' }}
-
Tenure
-
{{ a.tenureMonths }} months
-
-
-
Total Interest Payable
-
₹{{ totalInterestFor(a) | number: '1.0-0' }}
-
-
-
Total Amount Payable
-
₹{{ totalPayableFor(a) | number: '1.0-0' }}
+
Estimated EMI
+
+ @if (isRevolving(a)) { + No fixed EMI (revolving limit) + } @else { + ₹{{ emiAmountFor(a) | number: '1.0-0' }} / month + } +
-

- Reducing-balance EMI formula: EMI = [P × r × (1+r)n] / [(1+r)n − 1] — where P = - Principal, r = Monthly Interest Rate, n = Tenure in months. On P = ₹{{ - a.requestedAmount | number: '1.0-0' - }}, r = {{ a.interestRate / 12 / 100 | number: '1.4-4' }}, n = {{ a.tenureMonths }} → EMI = ₹{{ - emiAmountFor(a) | number: '1.0-0' - }} - / month. -

-
- } - @if (a.coBorrowerRequired || isDepositLoan(a)) { -
-
- Co-Borrower - @if (isDepositLoan(a)) { - (optional) - } @else { - (raises household eligibility) - } + } + @if (!isRevolving(a)) { +
+
EMI Calculation Basis
+
+
+
Principal (Loan Amount)
+
₹{{ a.requestedAmount | number: '1.0-0' }}
+
+
+
Interest Rate
+
{{ a.interestRate }}% p.a. ({{ a.interestRate / 12 | number: '1.2-2' }}% / month)
+
+
+
Tenure
+
{{ a.tenureMonths }} months
+
+
+
Total Interest Payable
+
₹{{ totalInterestFor(a) | number: '1.0-0' }}
+
+
+
Total Amount Payable
+
₹{{ totalPayableFor(a) | number: '1.0-0' }}
+
+
+

+ Reducing-balance EMI formula: EMI = [P × r × (1+r)n] / [(1+r)n − 1] — where P + = Principal, r = Monthly Interest Rate, n = Tenure in months. On P = ₹{{ + a.requestedAmount | number: '1.0-0' + }}, r = {{ a.interestRate / 12 / 100 | number: '1.4-4' }}, n = {{ a.tenureMonths }} → EMI = ₹{{ + emiAmountFor(a) | number: '1.0-0' + }} + / month. +

- - @if (a.coBorrowerWanted) { - - - -

Upload the co-borrower's last 3 months' salary slips:

-
- @for (doc of coBorrowerCapture.salarySlips; track $index) { - - @if (doc.file || hasStoredDoc('COBORROWER:salarySlip:' + $index)) { - - } + } + @if (a.coBorrowerRequired || isDepositLoan(a)) { +
+
+ Co-Borrower + @if (isDepositLoan(a)) { + (optional) + } @else { + (raises household eligibility) }
- @if (coBorrowerDetailsComplete(a)) { -
-
Combined Household Eligibility Calculation
-
-
-
Applicant's Monthly Income
-
₹{{ a.monthlyIncome | number: '1.0-0' }}
-
-
-
Applicant's EMI Capacity (40%)
-
₹{{ applicantEmiCapacity(a) | number: '1.0-0' }}
-
-
-
Co-Borrower's Monthly Income
-
₹{{ a.coBorrowerMonthlyIncome | number: '1.0-0' }}
-
-
-
Co-Borrower's EMI Capacity (40%)
-
₹{{ coBorrowerEmiCapacity(a) | number: '1.0-0' }}
-
-
-
Combined Household EMI Capacity
-
₹{{ combinedEmiCapacity(a) | number: '1.0-0' }}
-
-
-
Estimated EMI (this loan)
-
₹{{ emiAmountFor(a) | number: '1.0-0' }}
-
-
-

- Combined Capacity = (40% × ₹{{ a.monthlyIncome | number: '1.0-0' }} applicant) + (40% × ₹{{ - a.coBorrowerMonthlyIncome | number: '1.0-0' - }} - co-borrower) = ₹{{ applicantEmiCapacity(a) | number: '1.0-0' }} + ₹{{ - coBorrowerEmiCapacity(a) | number: '1.0-0' - }} - = ₹{{ combinedEmiCapacity(a) | number: '1.0-0' }}. Estimated EMI ₹{{ - emiAmountFor(a) | number: '1.0-0' - }} - is {{ combinedEligibilityOk(a) ? 'within' : 'above' }} this combined capacity. -

- @if (combinedEligibilityOk(a)) { - Eligible with Co-Borrower - } @else { - Still not eligible — increase co-borrower income, reduce the amount, or extend tenure + + @if (a.coBorrowerWanted) { + + + +

Upload the co-borrower's last 3 months' salary slips:

+
+ @for (doc of coBorrowerCapture.salarySlips; track $index) { + + @if (doc.file || hasStoredDoc('COBORROWER:salarySlip:' + $index)) { + + } }
- } - } - @if (!affordabilityOk(a)) { -

- @if (!coBorrowerDetailsComplete(a)) { - @if (!a.coBorrowerWanted) { - Check "Add a Co-Borrower" and complete their details to proceed. - } @else { - Add the co-borrower's name, relationship, monthly income and all 3 salary slips to proceed. - } - } @else { - Combined household income still doesn't cover the EMI at 40% — adjust the amount, tenure, or - co-borrower before proceeding. + @if (coBorrowerDetailsComplete(a)) { +

+
Combined Household Eligibility Calculation
+
+
+
Applicant's Monthly Income
+
₹{{ a.monthlyIncome | number: '1.0-0' }}
+
+
+
Applicant's EMI Capacity (40%)
+
₹{{ applicantEmiCapacity(a) | number: '1.0-0' }}
+
+
+
Co-Borrower's Monthly Income
+
₹{{ a.coBorrowerMonthlyIncome | number: '1.0-0' }}
+
+
+
Co-Borrower's EMI Capacity (40%)
+
₹{{ coBorrowerEmiCapacity(a) | number: '1.0-0' }}
+
+
+
Combined Household EMI Capacity
+
₹{{ combinedEmiCapacity(a) | number: '1.0-0' }}
+
+
+
Estimated EMI (this loan)
+
₹{{ emiAmountFor(a) | number: '1.0-0' }}
+
+
+

+ Combined Capacity = (40% × ₹{{ a.monthlyIncome | number: '1.0-0' }} applicant) + (40% × ₹{{ + a.coBorrowerMonthlyIncome | number: '1.0-0' + }} + co-borrower) = ₹{{ applicantEmiCapacity(a) | number: '1.0-0' }} + ₹{{ + coBorrowerEmiCapacity(a) | number: '1.0-0' + }} + = ₹{{ combinedEmiCapacity(a) | number: '1.0-0' }}. Estimated EMI ₹{{ + emiAmountFor(a) | number: '1.0-0' + }} + is {{ combinedEligibilityOk(a) ? 'within' : 'above' }} this combined capacity. +

+ @if (combinedEligibilityOk(a)) { + Eligible with Co-Borrower + } @else { + Still not eligible — increase co-borrower income, reduce the amount, or extend tenure + } +
} -

- } -
+ } + @if (!affordabilityOk(a)) { +

+ @if (!coBorrowerDetailsComplete(a)) { + @if (!a.coBorrowerWanted) { + Check "Add a Co-Borrower" and complete their details to proceed. + } @else { + Add the co-borrower's name, relationship, monthly income and all 3 salary slips to proceed. + } + } @else { + Combined household income still doesn't cover the EMI at 40% — adjust the amount, tenure, or + co-borrower before proceeding. + } +

+ } +
+ } } + @if (a.guarantorsRequiredCount !== undefined && guarantorsNeeded(a) > 0) { + + } +
+
Purpose & Priority Sector
+ +
} @@ -2241,84 +3617,171 @@ @if (a.currentStage === 'CREDIT_COMMITTEE') {
- +
-
-
Full Application Report — For the Committee
-

- Everything captured on this application — KYC, CIC score, Field Investigation, property valuation, agent - report, meeting and stage history — as one PDF for every committee member to review before deciding. -

-
- - + @if (isDepositLoan(a)) { +
+
Loan Application
+

+ The bank's loan application form, filled from this application: applicant particulars, occupation and + income, accounts and existing loans, the deposit offered as security and the declaration. After it + come the sanction checks and every document on file: the eKYC documents (Aadhaar, PAN), the lien + documents, the deposit documents and the legal documents. +

+
+ + +
-
+ } @else { +
+
Full Application Report — For the Committee
+

+ Everything captured on this application — KYC, CIC score, Field Investigation, property valuation, + agent report, meeting and stage history — as one PDF for every committee member to review before + deciding. +

+
+ + +
+
+ } -

Reports Required — present below reports, then complete.

-
- @if (!isDepositLoan(a)) { + + @if (!isDepositLoan(a)) { +

Reports Required — present below reports, then complete.

+
+ @if (!isDepositLoan(a)) { + + } + @if (a.secured) { + + } + + @if (!isDepositLoan(a)) { + + } + @if (!isDepositLoan(a)) { + + } + @if (!isDepositLoan(a)) { + + } + + @if (a.secured) { + + } +
+ } + @if (isDepositLoan(a)) { + + @for (check of depositRiskChecks(a); track check.label) { + @if (!check.ok) { +

{{ check.label }}

+ } } - - @if (a.secured) { - + @if (guarantorsNeeded(a) > 0) { + } - - @if (!isDepositLoan(a)) { - - } - @if (!isDepositLoan(a)) { - - } - @if (!isDepositLoan(a)) { - - } - - @if (a.secured) { - + } +
+
Purpose & priority sector
+
+
+
Purpose of the loan
+
{{ a.loanPurpose || '—' }}
+
+
+
Priority sector
+
+ {{ pslChoice(a) === 'yes' ? 'Yes — ' + (a.prioritySectorCategory || 'category not chosen') : 'No' }} +
+
+
+
Weaker section
+
+ {{ + a.weakerSection === 'yes' + ? 'Yes — ' + (a.weakerSectionType || 'type not chosen') + : a.weakerSection === 'no' + ? 'No' + : '—' + }} +
+
+
+ @if (pslHint(a)) { +

+ {{ pslHint(a) }} Complete the "Purpose & Priority Sector" card at the top of this page. +

}
- -
+ + @if (!approvalRequest(a, 'creditCommitteeApproval') && !isStageApproved(a, 'creditCommitteeApproval')) { - -
- @if (committeeReportsReady(a) && !committeeCanApprove(a)) { -

- Enter the Resolution No. and Resolution Date the committee passed this decision under before approving. -

+ } + @if (!isDepositLoan(a)) { +
+ + +
+ @if (committeeReportsReady(a) && !committeeCanApprove(a)) { +

+ Enter the Resolution No. and Resolution Date the committee passed this decision under before + approving. +

+ } } + @if (isDepositLoan(a)) { +
+
Sanction letter
+ @if (isStageApproved(a, 'creditCommitteeApproval')) { +

✓ Sanction approved — the sanction letter is released.

+
+ + +
+ } @else { +

+ Prepare the loan application above and send it to the manager for sanction approval. The sanction + letter is released as soon as the manager approves. +

+ } +
+ }
} @@ -2378,70 +3862,21 @@ - + @if (a.guarantorsRequiredCount === undefined) { + + } @else { + + }
- @if (a.guarantorRequired) { -
-
Guarantor — Must Be an Existing Share Member
- @if (!a.guarantorClientId) { - - @if (searchingGuarantor) { -

Searching…

- } @else if (guarantorSearchText.length >= 2 && guarantorSearchResults.length === 0) { -

No clients found.

- } - @if (guarantorSearchResults.length > 0) { -
- @for (client of guarantorSearchResults; track client.id) { - - } -
- } -

- The guarantor must already be a bank client with an active share account — search and select them - above, a name alone isn't enough. -

- } @else { - - @if (loadingGuarantorShareCheck) { -

Checking share membership…

- } @else if (a.guarantorHasShareAccount) { - Share Member — Verified - - } @else { - No Share Account Found -

- This client has no active share account — a guarantor must already be a bank member. Pick a - different guarantor. -

- } - } -
+ @if (guarantorsNeeded(a) > 0) { + }
} + + + @if (isDepositLoan(a)) { +
+ + +
+ } +
+ @if (!isDepositLoan(a)) { + + } + @if (a.secured) { + + } + + @if (!isDepositLoan(a)) { + + } +
+ + @if (a.legalDocuments.length > 0) { +
+ @if (approvalRequest(a, 'legalApproval')) { +

+ 🔒 Sent for approval — the documents can be viewed but not added, replaced or removed. To change + anything, withdraw the request first. +

+ } + + + @if (!approvalRequest(a, 'legalApproval')) { +
+ + +
+ } +
+ } +
+ @if (a.currentStage === 'LEGAL_APPROVAL') {
- @if (isDepositLoan(a)) { -
- - -
- } -
- @if (!isDepositLoan(a)) { - - } - @if (a.secured) { - - } -