Skip to content

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 pending to denied
  • 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:

effective_rate = min(
    max(standard_rate - promo_discounts, 0),
    lowest_rate_cap
)
  • Standard rate: The loan's interest_rate field
  • Promo discounts: Active PromoRate records with date-range validity
  • Rate caps: RateCap records 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