Loan Lifecycle¶
The loan lifecycle covers the full journey of a loan from application through payoff or charge-off. Each lending program type defines its own set of allowed states and transitions.
Loan States¶
Installment Loan Lifecycle¶
pending → approved → active → paid_off
│ │ │
│ │ └──→ defaulted → charged_off → written_off
│ └──→ denied
└──→ cancelled
Lease Lifecycle¶
Adds returned and buyout states:
pending → approved → active → returned
│ │ │ │
│ │ │ └──→ buyout → paid_off
│ │ └──→ defaulted → charged_off → written_off
│ └──→ denied
└──→ cancelled
Line of Credit Lifecycle¶
Lines of credit support draw/repay cycles with a revolving balance.
Lifecycle Actions¶
Approve¶
Moves a loan from pending to approved:
- Runs all configured compliance checks (see Compliance)
- Hard compliance failures block approval
- Soft failures produce warnings but allow approval
- Records the approving user and timestamp
Deny¶
Rejects a loan application:
- Moves status from
pendingtodenied - Triggers an adverse action notice via the communications module
- Records denial reason
Disburse¶
Funds the loan, transitioning from approved to active:
- Generates the amortization schedule via the lending program's
generate_schedule()method - Posts GL entries: DR Loans Receivable, CR Cash (see General Ledger)
- Assesses origination fee if configured on the loan product (see Fee Management)
- Records disbursement details (amount, method, recipient)
Cancel¶
Voids a loan before disbursement. Only valid from pending or approved status.
Charge-Off¶
Recognizes a loss on a defaulted loan:
- Posts GL entries: DR Provision for Losses, CR Allowance for Losses
- Posts write-off entries: DR Allowance for Losses, CR Loans Receivable
- Records charge-off amount and date
Default Detection¶
A daily Celery task auto-transitions loans to defaulted when days_past_due exceeds a configurable threshold per lending program. See Collections for the delinquency engine.
Sub-Statuses¶
Active loans can carry a sub-status that modifies system behavior:
| Sub-Status | Effect |
|---|---|
in_forbearance |
Suppresses collections and dunning |
in_deferment |
Payments deferred, maturity extended |
in_modification |
Loan terms being restructured |
in_bankruptcy |
All automated contact suppressed |
in_collections |
Loan assigned to collection queue |
Sub-statuses are set and cleared by the corresponding servicing operations (see Servicing Operations).
Behavioral Flags¶
Frozen (is_frozen)¶
A frozen loan is excluded from all daily batch processing:
- No interest accrual
- No delinquency updates
- No automated fee assessment
- No dunning communications
Used for loans under investigation or dispute resolution.
Accelerated (is_accelerated)¶
Makes the full remaining balance immediately due. Typically triggered as part of a default or charge-off workflow.
Non-Accrual (is_non_accrual)¶
When a loan is placed on non-accrual (typically at 90+ DPD):
- Interest income recognition stops
- Previously accrued but uncollected interest is reversed via GL entry (DR Interest Income, CR Interest Receivable)
- Interest is recognized only on a cash basis (when actually received) until the loan is cured
See Collections for non-accrual triggers.
Effective Interest Rate¶
The effective rate applied to a loan considers multiple factors:
- Standard rate: The loan's
interest_ratefield - Promo discounts: Active
PromoRaterecords with date-range validity - Rate caps:
RateCaprecords for regulatory or contractual limits
Loan Data Model¶
Core Fields¶
| Field | Type | Description |
|---|---|---|
loan_number |
String | Unique identifier |
borrower |
FK | Primary borrower |
program |
FK | Lending program |
product |
FK | Loan product |
principal_amount |
MoneyField | Original principal |
current_balance |
MoneyField | Current outstanding balance |
interest_rate |
Decimal | Current interest rate (decimal) |
term_months |
Integer | Loan term in months |
status |
TextChoices | Current lifecycle status |
sub_status |
TextChoices | Current sub-status |
assigned_officer |
FK | Assigned loan officer |
Tracking Fields¶
| Field | Type | Description |
|---|---|---|
days_past_due |
Integer | Days since last missed payment |
delinquency_bucket |
TextChoices | Current DPD bucket |
current_period |
Integer | Current amortization period |
periods_past_due |
Integer | Number of overdue periods |
periods_remaining |
Integer | Remaining amortization periods |
next_due_date |
Date | Next payment due date |
maturity_date |
Date | Loan maturity date |
Line of Credit Extensions¶
| Field | Type | Description |
|---|---|---|
Draw.draw_number |
String | Unique draw identifier |
Draw.amount |
MoneyField | Draw amount |
Draw.current_balance |
MoneyField | Outstanding draw balance |
Purchase |
Model | Individual purchases on a draw |
PurchaseDispute |
Model | Disputes against purchases |
Loan Boarding¶
Existing loans from external systems can be imported via the board_loan API action. This creates a loan in active status with pre-set balances and history, bypassing the normal origination flow.
See Also¶
- Amortization --- Schedule generation and period management
- Payment Processing --- Payment allocation and processing
- Fee Management --- Fee assessment triggers
- Servicing Operations --- Modifications, forbearance, deferment
- Collections --- Delinquency tracking and default detection
- General Ledger --- GL entries for lifecycle events
- Compliance --- Compliance checks at lifecycle transitions