@if (loadingApplication) {
Loading application…
}
@if (application; as a) {
CREDIT · LOAN ORIGINATION · {{ a.branchName | uppercase }}
{{ a.applicationNo }} — {{ a.applicantName }}
{{ statusLabels[a.overallStatus] }}
{{ a.productName }} · ₹{{ a.requestedAmount | number: '1.0-0' }} · Applied {{ a.applicationDate }} ·
{{ progress(a) }}% through the sanctioning workflow.
@if (uploadingDocs > 0) {
Uploading {{ uploadingDocs }} file{{ uploadingDocs > 1 ? 's' : '' }}…
} @else if (docUploadFailed) {
File upload failed
}
@if (saving) {
Saving…
} @else if (saveFailed) {
Not saved — check connection
}
‹ Back to Pipeline
Branch
{{ a.branchName }}
Channel
{{ a.channel === 'BC' ? a.bcAgentName : a.channel === 'SELF_APPLY' ? 'Self-Apply (Digital)' : 'Branch' }}
Customer Type
{{ a.customerType === 'EXISTING' ? 'Existing Customer' : 'New Customer' }}
Tenure / Rate
{{ a.tenureMonths }} months @ {{ a.interestRate }}%
Monthly Income / Eligible Amount
₹{{ a.monthlyIncome | number: '1.0-0' }} / ₹{{ a.eligibleLoanAmount | number: '1.0-0' }}
Sanctioning Authority
{{ sanctioningAuthorityOf(a) }}
Share Member
@if (a.clientId) {
@if (loadingShareAccounts) {
Checking membership…
} @else if (realShareAccounts.length > 0) {
@for (sa of realShareAccounts; track sa.id) {
{{ sa.accountNo }} — {{ sa.productName }}
}
} @else {
Not a Member
Allot Shares
}
} @else if (a.isShareMember) {
Yes — {{ a.shareCertNo }} (since {{ a.shareMemberSince }})
} @else {
Not a Member
Allot Shares
}
@if (a.coBorrowerRequired) {
Co-Borrower
{{ a.coBorrowerName }}
@if (a.coBorrowerWanted && a.coBorrowerRelationship) {
({{ a.coBorrowerRelationship }})
}
}
@if (a.guarantorRequired) {
Guarantor
{{ a.guarantorName }}
}
Approved by
@for (ap of grantedApprovals(app); track ap.label) {
✓ {{ ap.label }} — {{ ap.approverName }} · {{ ap.date }}
@if (ap.exception) {
(on exception)
}
}
@if (approvalRequest(a, field); as req) {
⏳ Sent for approval — by {{ req.submittedBy }} on {{ req.submittedOn }}
@if (req.requestedDecision === 'EXCEPTION_APPROVED') {
(on exception)
}
· awaiting {{ role }}.
@if (req.remarks) {
“{{ req.remarks }}”
}
@if (req.checklist?.length) {
What {{ req.submittedBy }} verified before sending ({{ req.submittedOn }})
@for (check of req.checklist; track check.label) {
{{ check.ok ? '✓' : '✗' }} {{ check.label }}
}
}
@if (isMyRequest(req)) {
You sent this request, so you cannot approve it. A different user has to approve or reject it.
Withdraw request
} @else {
Your verification — tick each row you have checked ({{ checkerCount(a, field, req) }})
@for (item of checkerItems(a, field, req); track item.label) {
@if (item.ok) {
{{ item.label }}
} @else {
✗ {{ item.label }} — the sender did not verify this, so it cannot be approved.
}
}
Approve
Reject
@if (!checkerReady(a, field, req)) {
Approve opens after you tick every row above.
}
}
} @else {
Send for Approval
@if (exception) {
Send for Approval on Exception
}
}
Sanctioning Workflow Progress
@for (s of visibleStages(a); track s) {
@if (canJumpToStage(a, s)) {
{{ stepMarker(a, s) }}
{{ stageLabels[s] }}
} @else {
{{ stepMarker(a, s) }}
{{ stageLabels[s] }}
}
}
@if (a.overallStatus === 'REJECTED') {
Application Rejected — at {{ stageLabels[a.currentStage] }}
See the approval summary below for the recorded reason.
} @else if (a.overallStatus === 'ON_HOLD') {
Personal Discussion — {{ discrepancyLabels[a.discrepancyType] }}
} @else if (a.overallStatus === 'DISBURSED') {
Disbursed
Disbursement Date
{{ a.disbursementDate }}
Mode
{{ a.disbursementMode }}
@if (!isDepositLoan(a)) {
ACH Confirmation
{{ a.achConfirmationRef }}
}
@if (!isDepositLoan(a)) {
EMI Activation Confirmation
{{ a.emiActivationConfirmed ? 'Confirmed on ' + a.emiActivationDate : 'Pending' }}
}
Core Banking Loan Account
@if (a.fineractLoanAccountNo) {
A/C {{ a.fineractLoanAccountNo }}
} @else {
Mock disbursement only — no core banking account
}
EMI Repayment Schedule
@if (isRevolving(a)) {
{{ a.productName }} is a revolving/renewable limit — repaid on demand and renewed annually, not on a fixed
EMI schedule.
} @else {
Loan Amount
₹{{ a.requestedAmount | number: '1.0-0' }}
{{ a.tenureMonths }} months @ {{ a.interestRate }}%
Monthly EMI
₹{{ emiAmountFor(a) | number: '1.0-0' }}
Reducing balance
Total Interest Payable
₹{{ totalInterestFor(a) | number: '1.0-0' }}
over the full tenure
Total Amount Payable
₹{{ totalPayableFor(a) | number: '1.0-0' }}
principal + interest
}
} @else {
@if (a.currentStage === 'APPLICATION') {
Application Received
Received via
{{ a.channel === 'BC' ? a.bcAgentName : a.channel === 'SELF_APPLY' ? 'Self-Apply (Digital)' : 'Branch' }}
on {{ a.applicationDate }}.
Proceed to KYC & Document Collection
}
@if (a.currentStage === 'KYC_DOCUMENTS') {
KYC & Document Collection — OVD (RBI KYC Master Direction)
@if (isDepositLoan(a)) {
Loan against a deposit — the deposit is the security. Income proof, bank statement, address proof and a
co-borrower are optional , and no credit bureau (CIBIL) check is done. Only Aadhaar and PAN
verification are required.
}
@if (a.clientId) {
@if (loadingKyc) {
Loading KYC record…
} @else {
Aadhaar
{{ a.aadhaarVerified ? 'Verified' : 'Not Verified' }}
@if (realKyc?.aadhaarNumberMasked) {
{{ realKyc.aadhaarNumberMasked }}
}
View Document
PAN
{{ a.panVerified ? 'Verified' : 'Not Verified' }}
@if (realKyc?.panNumber) {
{{ maskPan(realKyc.panNumber) }}
}
View Document
Income Proof
@if (isDepositLoan(a)) {
· optional
}
@if (findDocument('income'); as incomeDoc) {
Submitted
{{ incomeDoc.name || incomeDoc.fileName }}
View
} @else {
Employment Type
Salaried
Business / Self-Employed
@if (newKycCapture.incomeProof.employmentType === 'SALARIED') {
@for (doc of newKycCapture.incomeProof.salaried; track $index) {
@if (doc.previewUrl) {
} @else {
View file
}
✕
}
@for (stored of storedDocsFor('KYC:incomeProof:salaried'); track stored.id) {
View file
✕
}
{{ salariedFileCount ? '+ Add More' : 'Upload Form 16 / Salary Slips' }}
{{ salariedFileCount }} file{{ salariedFileCount === 1 ? '' : 's' }} · Form 16 and last 3
months' salary slips — select several files at once.
} @else {
Last 3 years' Income Tax Returns:
@for (doc of newKycCapture.incomeProof.itr; track $index) {
@if (doc.exception) {
Exception Remark — Year {{ $index + 1 }}
}
}
}
@if (a.incomeProofSubmitted) {
@if (itrHasException) {
Submitted — with exception(s)
} @else {
Submitted
}
} @else {
Missing
}
}
Bank Statement
@if (isDepositLoan(a)) {
· optional
}
@if (findDocument('bank statement'); as bankDoc) {
Submitted
{{ bankDoc.name || bankDoc.fileName }}
View
} @else {
{{ newKycCapture.bankStatement.file ? 'Statement ✓' : 'Upload Bank Statement' }}
@if (newKycCapture.bankStatement.file || hasStoredDoc('KYC:bankStatement')) {
@if (newKycCapture.bankStatement.previewUrl) {
} @else {
View file
}
@if (canReopenBankStatementAnalysis()) {
📊 Re-check Analysis
}
✕ Remove
}
@if (a.bankStatementSubmitted) {
Submitted
} @else {
Missing
}
}
Electricity Bill (Address Proof)
@if (isDepositLoan(a)) {
· optional
}
@if (findDocument('electricity') || findDocument('address proof'); as billDoc) {
Submitted
{{ billDoc.name || billDoc.fileName }}
View
} @else {
Bill Date
@if (electricityBillTooOld) {
Must not be older than 3 months.
}
@if (a.electricityBillSubmitted) {
Submitted
} @else {
Missing
}
}
}
} @else {
Captured for this application — final Aadhaar/PAN verification happens when the customer's CBS client
profile is created.
Aadhaar
{{ newKycCapture.aadhaar.front ? 'Front ✓' : 'Upload Front' }}
{{ newKycCapture.aadhaar.back ? 'Back ✓' : 'Upload Back' }}
@if (newKycCapture.aadhaar.front || newKycCapture.aadhaar.back) {
@if (newKycCapture.aadhaar.front) {
@if (newKycCapture.aadhaar.frontPreviewUrl) {
} @else {
Front file
}
}
@if (newKycCapture.aadhaar.back) {
@if (newKycCapture.aadhaar.backPreviewUrl) {
} @else {
Back file
}
}
}
@if (newKycCapture.aadhaar.verified) {
Aadhaar Verified
} @else {
}
PAN
{{ newKycCapture.pan.front ? 'Front ✓' : 'Upload Front' }}
{{ newKycCapture.pan.back ? 'Back ✓' : 'Upload Back' }}
@if (newKycCapture.pan.front || newKycCapture.pan.back) {
@if (newKycCapture.pan.front) {
@if (newKycCapture.pan.frontPreviewUrl) {
} @else {
Front file
}
}
@if (newKycCapture.pan.back) {
@if (newKycCapture.pan.backPreviewUrl) {
} @else {
Back file
}
}
}
@if (newKycCapture.pan.verified) {
PAN Verified
} @else {
Verify PAN
}
Income Proof
@if (isDepositLoan(a)) {
· optional
}
Employment Type
Salaried
Business / Self-Employed
@if (newKycCapture.incomeProof.employmentType === 'SALARIED') {
@for (doc of newKycCapture.incomeProof.salaried; track $index) {
@if (doc.previewUrl) {
} @else {
View file
}
✕
}
@for (stored of storedDocsFor('KYC:incomeProof:salaried'); track stored.id) {
View file
✕
}
{{ salariedFileCount ? '+ Add More' : 'Upload Form 16 / Salary Slips' }}
{{ salariedFileCount }} file{{ salariedFileCount === 1 ? '' : 's' }} · Form 16 and last 3 months'
salary slips — select several files at once.
} @else {
Last 3 years' Income Tax Returns:
@for (doc of newKycCapture.incomeProof.itr; track $index) {
@if (doc.exception) {
Exception Remark — Year {{ $index + 1 }}
}
}
}
@if (a.incomeProofSubmitted) {
@if (itrHasException) {
Submitted — with exception(s)
} @else {
Submitted
}
} @else {
Missing
}
Bank Statement
@if (isDepositLoan(a)) {
· optional
}
{{ newKycCapture.bankStatement.file ? 'Statement ✓' : 'Upload Bank Statement' }}
@if (newKycCapture.bankStatement.file) {
@if (newKycCapture.bankStatement.previewUrl) {
} @else {
View file
}
@if (isCsvFile(newKycCapture.bankStatement.file)) {
📊 Re-check Analysis
}
✕ Remove
}
@if (a.bankStatementSubmitted) {
Submitted
} @else {
Missing
}
Electricity Bill (Address Proof)
@if (isDepositLoan(a)) {
· optional
}
Bill Date
@if (electricityBillTooOld) {
Must not be older than 3 months.
}
@if (a.electricityBillSubmitted) {
Submitted
} @else {
Missing
}
}
@if (a.productDocuments.length > 0) {
Loan-Specific Documents — {{ a.productName }}
@for (doc of a.productDocuments; track doc.key) {
@if (doc.key === 'coOwnerKyc') {
{{ doc.label }}
@if (doc.hint) {
{{ doc.hint }}
}
This property has a co-owner
@if (coOwnerCapture.hasCoOwner) {
{{ coOwnerCapture.aadhaar.verified ? 'Aadhaar ✓ Verified' : 'Verify Co-Owner Aadhaar' }}
{{ coOwnerCapture.pan.verified ? 'PAN ✓ Verified' : 'Verify Co-Owner PAN' }}
}
@if (doc.submitted) {
{{ coOwnerCapture.hasCoOwner ? 'Verified' : 'Not Applicable' }}
} @else {
Missing
}
} @else {
{{ doc.label }}
@if (doc.custom) {
✕
}
@if (doc.hint) {
{{ doc.hint }}
}
@if (doc.submitted) {
Submitted
} @else {
Missing
}
}
}
+ Add Custom Document
}
Monthly Income (₹)
@if (!isRevolving(a)) {
Requested Loan Amount (₹)
@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.
}
Tenure (Months)
@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 {
EMI exceeds 40% of monthly income — add a Co-Borrower, reduce the loan amount, or increase the
tenure before proceeding.
}
}
}
{{ a.monthlyIncome > 0 ? 'Update Income & Terms' : 'Assess Income & Calculate Eligible Amount' }}
@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
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.coBorrowerRequired || isDepositLoan(a)) {
Co-Borrower
@if (isDepositLoan(a)) {
(optional)
} @else {
(raises household eligibility)
}
Add a Co-Borrower to increase eligibility
@if (a.coBorrowerWanted) {
Co-Borrower Name
Relationship with Applicant
Select
Father
Mother
Wife
Husband
Son
Daughter
Other
Co-Borrower Monthly Income (₹)
Upload the co-borrower's last 3 months' salary slips:
@for (doc of coBorrowerCapture.salarySlips; track $index) {
{{
doc.file
? 'Salary Slip — Month ' + ($index + 1) + ' ✓'
: 'Upload Salary Slip — Month ' + ($index + 1)
}}
@if (doc.file || hasStoredDoc('COBORROWER:salarySlip:' + $index)) {
@if (doc.previewUrl) {
} @else {
View file
}
}
}
@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.
}
}
}
{{ isDepositLoan(a) ? 'Complete KYC & Proceed' : 'Proceed to CIC / Credit Bureau Check' }}
}
@if (a.currentStage === 'CIC_CHECK') {
CIC / Credit Bureau Check — {{ a.cicBureau }}
Customer Consent — Credit Bureau Check
RBI's Fair Practices Code requires the customer's signed consent before a credit bureau pull. Generate
the declaration letter below, get it signed by the customer, then upload the signed copy.
@if (a.channel === 'BRANCH') {
Print Declaration Letter
} @else {
Download Declaration Letter
Share (Email / WhatsApp / Drive…)
Email
WhatsApp
}
{{ cicConsentCapture.file ? 'Signed Declaration ✓' : 'Upload Signed Declaration' }}
@if (cicConsentCapture.file || hasStoredDoc('CIC:consent')) {
@if (cicConsentCapture.previewUrl) {
} @else {
View file
}
}
@if (a.cicConsentSigned) {
Signed Declaration Uploaded
} @else {
Awaiting Signed Declaration
}
CIC Check Charge — ₹{{ cicCheckCharge }}
@if (a.clientId && realDebitableAccounts.length > 0) {
Select which account to debit the ₹{{ cicCheckCharge }} charge from:
@for (acc of realDebitableAccounts; track acc.id) {
{{ acc.kind }}
{{ acc.accountNo }} — {{ acc.productName }}
Balance: ₹{{ acc.accountBalance | number: '1.0-0' }}
}
} @else {
@if (a.clientId && loadingShareAccounts) {
Loading accounts…
} @else {
@if (a.clientId) {
No open savings/current account on file for this customer — collect the charge via payment link
instead.
}
@if (!a.cicPaymentLinkUrl || a.cicPaymentLinkUrl === '—') {
Generate Payment Link
} @else {
{{ a.cicPaymentLinkUrl }}
Copy Link
Email
WhatsApp
@if (!a.cicChargeCollected) {
Payment Reference No. (from customer)
Confirm Payment Received
}
}
}
}
@if (a.cicChargeCollected) {
Charge Collected —
{{ a.cicChargeMode === 'ACCOUNT_DEBIT' ? a.cicChargeAccountLabel : 'Ref ' + a.cicPaymentReference }}
} @else {
Charge Not Collected
}
@if (a.cibilScore === 0) {
Bureau
@for (bureau of cicBureaus; track bureau) {
{{ bureau }}
}
Check Credit Score
@if (!a.cicConsentSigned || !a.cicChargeCollected) {
Print/share the declaration and get it signed, and collect the ₹{{ cicCheckCharge }} check charge,
before checking the credit score.
}
} @else {
= 750"
[class.loi-cic-score-badge--good]="a.cibilScore >= 650 && a.cibilScore < 750"
[class.loi-cic-score-badge--fair]="a.cibilScore >= 550 && a.cibilScore < 650"
[class.loi-cic-score-badge--poor]="a.cibilScore < 550"
>
{{ a.cibilScore }}
{{ cibilBandOf(a.cibilScore) }}
Credit Bureau
{{ a.cicBureau }}
Uploaded Report File
{{
a.cicReportUploaded ? a.cicReportFileName : 'Not uploaded yet'
}}
Field Inquiry Status
{{
a.fiRequestPushed
? 'Pushed to ' + a.fiAgencyAssigned + ' (' + a.fiRequestDate + ')'
: 'Not pushed yet'
}}
@if (a.cicReportUploaded) {
📊 View Analysis
@if (hasStoredDoc('CIC:report')) {
View file
}
}
}
@if (a.cibilScore > 0) {
{{
a.cicReportUploaded ? '📄 Re-upload PDF Report' : 'Upload ' + a.cicBureau + ' Report (PDF)'
}}
@if (a.cicReportUploaded && !a.fiRequestPushed) {
Push Field Inquiry to Agency
} @else if (a.cicReportUploaded && a.fiRequestPushed) {
Proceed to Field Investigation
}
}
}
@if (a.currentStage === 'FIELD_INVESTIGATION') {
Field Investigation (FI) — Agent Report
@if (a.clientId) {
Registered Addresses on File (Fineract)
@if (loadingAddresses) {
Loading addresses…
} @else if (realAddresses.length === 0) {
No addresses on file for this client.
} @else {
@for (addr of realAddresses; track $index) {
{{ addr.addressType || 'Address' }}
{{ formatRealAddress(addr) }}
}
}
}
Applicant has a shop / business premises
@for (key of fiRows(a); track key) {
{{ fiCheckLabels[key] }}
@if (a[key].officerAssigned === '—') {
Assign Field Officer
Select an officer
@for (staffMember of fiStaffOptions; track staffMember.id) {
{{ staffMember.displayName }}
}
Assign Officer
} @else {
Assigned to {{ a[key].officerAssigned }} on {{ a[key].assignedDate }}
@if (a[key].status === 'PENDING') {
@if (fiIsOverdue(a, key)) {
⚠ {{ fiSlaLabel(a, key) }} — this visit is overdue.
} @else {
{{ fiSlaLabel(a, key) }}
}
Latitude
Longitude
Site Photos ({{ fiPhotoCapture[key].length }}):
Mark Verified — Address Correct
@if (!fiCanVerify(a, key)) {
Capture latitude, longitude and at least one site photo before marking Verified.
}
Reject — Remark (if address is incorrect)
Reject with Remark
} @else if (a[key].status === 'VERIFIED') {
Verified
📋 View Full Details
} @else {
Failed
📋 View Full Details
Re-Assign a New Field Officer
Select an officer
@for (staffMember of fiStaffOptions; track staffMember.id) {
{{ staffMember.displayName }}
}
Re-Assign Officer
}
}
}
@if (a.secured) {
}
Agent Report
{{ a.agentReportUploaded ? a.agentReportFileName : 'Not uploaded yet' }}
@if (a.agentReportUploaded) {
Report Remark
{{ a.agentReportRemark }}
}
@if (a.agentReportUploaded && hasStoredDoc('FI:agentReport')) {
View file
}
@if (!a.agentReportUploaded) {
Agent Report Reference / Remark
Upload Agent Report
}
Record FI & Proceed to Personal Discussion
}
@if (a.currentStage === 'PERSONAL_DISCUSSION' && isDepositLoan(a)) {
Personal Discussion with Manager — Loan Plan
@if (loanPlan(a); as plan) {
The plan below is what the customer is offered. Download or print it, share it with the customer, then
proceed.
Applicant {{ a.applicantName }}
Loan amount ₹{{ plan.amount | number: '1.0-0' }}
Tenure {{ plan.tenure }} months
Interest rate {{ plan.rate | number: '1.2-2' }}% p.a.
@if (plan.rateFromDeposit) {
(deposit {{ plan.depositRate }}% + {{ plan.spread }}%)
}
Interest per month (estimate) ₹{{ plan.monthlyInterest | number: '1.0-0' }}
Total interest over the tenure ₹{{ plan.totalInterest | number: '1.0-0' }}
Total payable at the end ₹{{ plan.totalPayable | number: '1.0-0' }}
Repayment {{ plan.repayment }}
Deposit pledged {{ plan.accounts }}
Security value · limit ₹{{ plan.securityValue | number: '1.0-0' }} · {{ plan.limitPct }}% = ₹{{
plan.eligible | number: '1.0-0'
}}
Lien {{ plan.lienRequired ? 'Marked ' + plan.lienStage : 'Not required' }}
Penal interest {{ plan.penal }}
Pre-closure · Renewal {{ plan.preclosure }} · {{ plan.renewal }}
⬇️ Download Loan Plan (PDF)
🖨️ Print Loan Plan
Proceed to Loan Committee
}
}
@if (a.currentStage === 'PERSONAL_DISCUSSION' && !isDepositLoan(a)) {
Personal Discussion with Manager
Briefing Report — For the Meeting
Everything captured so far — KYC, CIC score, Field Investigation, property valuation, agent report and
the full stage history — as one PDF for whoever takes this meeting.
🖨️ Print Summary Report
⬇️ Download Summary Report
Meeting Scheduler
Meeting Date
Meeting Time
Mode of Meeting
Select
Offline (In-Branch)
Online (Video Call)
Phone Call
Bank Officer Taking the Meeting
Select
@for (m of meetingManagers; track m) {
{{ m }}
}
{{ a.meetingScheduled ? 'Update Schedule' : 'Schedule Meeting' }}
@if (a.meetingScheduled) {
Scheduled with {{ a.meetingWith }} on {{ a.meetingDate }} at {{ a.meetingTime }} ({{
a.meetingMode === 'ONLINE' ? 'Online' : a.meetingMode === 'CALL' ? 'Phone Call' : 'Offline'
}})
}
@if (a.meetingScheduled) {
Discrepancy (if any)
No Discrepancy
Document Discrepancy
Name Mismatch
Office Verification Failed
Property Discrepancy
FI Report Discrepancy
Fake Declaration Suspected
Discussion Report
@if (discrepancySelection === 'NONE') {
Clear, Take Declaration & Proceed to Loan Committee
} @else {
Flag Discrepancy — Hold Application
}
} @else {
Schedule the meeting above before recording the discussion report.
}
}
@if (a.currentStage === 'CREDIT_COMMITTEE') {
Loan Committee Approval — {{ sanctioningAuthorityOf(a) }}
}
@if (a.currentStage === 'RISK_APPROVAL') {
Risk Approval — Verification Checklist
}
@if (a.currentStage === 'LEGAL_APPROVAL') {
Legal Approval — Fees & Legal Documents
}
@if (a.currentStage === 'CUSTOMER_SIGNING') {
Customer Signing Slot — {{ a.agreementSigningSlot }}
Loan Agreement and Sanction Letter ready for the customer's acknowledgement and signature.
@if (isDepositLoan(a)) {
Download Sanction Letter (PDF)
Print Sanction Letter
}
Mark Signed by Customer
}
@if (a.currentStage === 'CHEQUE_ACH') {
Cheque Received / ACH Sign
@if (isDepositLoan(a)) {
Not required for a loan against a deposit — the bank recovers by set-off against the lien.
} @else {
Cheque Received
ACH Mandate Signed
}
Confirm & Proceed to Post-Disbursement Check
}
@if (a.currentStage === 'POST_CHECK') {
Post-Disbursement Check — Final Compliance Gate
}
@if (a.currentStage === 'DISBURSED') {
Ready for Disbursement
Disbursement Mode
Account Credit
NEFT
RTGS
@if (!isDepositLoan(a)) {
Disbursing also confirms EMI Activation for this account in the same step.
}
@if (a.customerType === 'EXISTING' && a.clientId) {
A real Fineract loan account will be created, approved and disbursed in Core Banking at the same time.
} @else {
This is a mock disbursement only — no Core Banking account exists until this customer is fully onboarded
as a client.
}
@if (a.fineractLoanError) {
{{ a.fineractLoanError }}
}
@if (isDepositLoan(a)) {
@if (disbursementLienIssue(a); as issue) {
{{ issue }}
} @else {
✓ On disbursement the lien is marked on {{ a.depositSelection?.accountNos?.join(', ') }} for ₹{{
a.requestedAmount | number: '1.0-0'
}}.
}
}
@if (creatingRealLoan) {
Creating Real Loan Account in Core Banking…
} @else if (a.fineractLoanError) {
{{ isDepositLoan(a) ? 'Retry Disburse' : 'Retry Disburse & Confirm EMI Activation' }}
} @else {
{{ isDepositLoan(a) ? 'Disburse Now' : 'Disburse Now & Confirm EMI Activation' }}
}
}
}
@if (a.currentStage === 'DEPOSIT_SELECTION') {
Deposit Selection & Eligibility
@if (loadingDeposits) {
Loading the customer's deposits…
} @else if (realDeposits.length === 0) {
No active {{ a.productCode === 'RD' ? 'Recurring' : 'Fixed' }} Deposit found for this customer.
} @else {
@if (depositRules(a).allowThirdParty) {
Pledge a third-party deposit (someone else's) — consent letter needed
}
@if (!depositRules(a).allowMultiple) {
This product allows one deposit per loan.
}
@if (depositCalc(a); as calc) {
Security value (balance + accrued interest) {{ calc.rows.length ? '₹' + (calc.value | number: '1.0-0') : '—' }}
Normal limit — {{ calc.limitPct }}% {{ calc.rows.length ? '₹' + (calc.normalLimit | number: '1.0-0') : '—' }}
{{ calc.rateLabel }} {{ calc.rows.length ? calc.rateText : '—' }}
{{ calc.tenureLabel }} {{ calc.rows.length ? calc.maxTenure + ' months' : '—' }}
Eligible loan amount {{
calc.rows.length
? '₹' + (calc.eligible | number: '1.0-0') + ' (' + (depositOver85 ? '100' : calc.limitPct) + '%)'
: '—'
}}
Requested Amount (₹) *
Tenure (Months) *
Interest Rate (% p.a.)
Sanction above {{ calc.limitPct }}% (up to 100%) at the sanctioning officer's discretion
@if (depositOver85) {
Reason for going above {{ calc.limitPct }}% *
}
@for (err of calc.errors; track err) {
{{ err }}
}
@if (calc.ok) {
✓ ₹{{ a.requestedAmount | number: '1.0-0' }} for {{ a.tenureMonths }} months at
{{ calc.rate | number: '1.2-2' }}% is within the limit.
}
{{ a.depositSelection?.saved ? '✓ Saved' : 'Save Deposit & Terms' }}
}
}
}
@if (showLienCard(a)) {
Lien Marking
A lien blocks withdrawal, premature closure and renewal in another name until the loan is repaid.
Deposits under lien {{ a.depositSelection?.accountNos?.join(', ') || 'Select and save a deposit above' }}
Lien amount ₹{{ a.requestedAmount | number: '1.0-0' }}
Letter of lien and set-off
Download Letter (PDF)
Print Letter
@if (!canMakeLienLetter(a)) {
Select a deposit above to create the letter.
}
Signed by the depositor (and all joint holders)
@if (lienLetterStored) {
Received
@for (stored of storedDocsFor('LIEN:letter'); track stored.id) {
View file
✕
}
} @else {
Pending
Upload
}
@if (a.lien?.marked && depositRules(a).certificateRequired) {
LIEN CERTIFICATE
No. {{ a.lien?.certificateNo }} · Date {{ a.lien?.markedOn }}
A lien of ₹{{ a.lien?.amount | number: '1.0-0' }} is noted on deposit
{{ a.lien?.accountNos?.join(', ') }} in favour of the bank against loan application {{ a.applicationNo }}.
Lien marked
} @else if (lienAtDisbursement(a)) {
This product marks the lien at disbursement . The lien is placed on the deposit automatically when
the loan is disbursed, so there is nothing to mark now. Before that: save the deposit selection and upload
the signed letter of lien and set-off.
Lien not marked yet — at disbursement
} @else {
Mark Lien
@if (!lienReady(a)) {
Save the deposit selection and upload the letter of lien and set-off to enable Mark Lien.
}
}
}
@if (a.currentStage === 'DEPOSIT_SELECTION') {
Complete Deposit Selection
Order: choose the deposit and save it, then download the letter of lien and set-off, get it signed, and
upload it. Then proceed.
@if (depositStageIssue(a); as issue) {
{{ issue }}
} @else {
✓ Deposit saved and the signed letter is on file. Ready to proceed.
}
Complete Deposit Selection & Proceed
}
Approval Tracking
@for (tile of approvalTiles; track tile.field) {
@if (approvalOf(a, tile.field); as ap) {
{{ tile.label }}
@if (approvalRequestAny(a, tile.field); as req) {
@if (req.status === 'PENDING') {
⏳ AWAITING APPROVAL
Sent by {{ req.submittedBy }} · {{ req.submittedOn }}
@if (req.requestedDecision === 'EXCEPTION_APPROVED') {
On exception
}
@if (req.remarks) {
“{{ req.remarks }}”
}
} @else if (req.status === 'WITHDRAWN') {
WITHDRAWN
Sent by {{ req.submittedBy }} · {{ req.submittedOn }}, then withdrawn
} @else {
{{ ap.decision }}
Sent by {{ req.submittedBy }} · {{ req.submittedOn }}
{{ ap.decision === 'REJECTED' ? 'Rejected' : 'Approved' }} by {{ ap.approverName }} ·
{{ ap.date }}
@if (req.checkerChecklist?.length) {
Checker verified {{ checkerSummary(req) }}
}
{{ ap.remarks }}
}
} @else {
{{ ap.decision }}
@if (ap.decision === 'PENDING') {
Not sent for approval yet
} @else {
{{ ap.approverName }} · {{ ap.date }}
{{ ap.remarks }}
}
}
}
}
Application Journey — Date-wise Audit Trail
@for (h of a.stageHistory; track h.date + h.stage + h.outcome) {
{{ stepMarker(a, h.stage) }}
{{ stageLabels[h.stage] }} — {{ h.outcome }}
{{ h.date }}
{{ h.actionBy }}
} @empty {
No activity recorded yet.
}
} @else {
Application Not Found
‹ Back to Pipeline
}