Skip to content

Collections

The apps.collections module manages delinquency tracking, collection queues, collector assignment, dunning sequences, and collection actions.

Delinquency Engine

A daily Celery task (runs at 2:30 AM) processes all active loans:

  1. Recalculate days_past_due for each loan based on payment history
  2. Update delinquency_bucket on threshold crossings
  3. Fire webhook events (delinquency.changed) on bucket transitions
  4. Assess late fees per fee schedule rules (see Fee Management)
  5. Place loans on non-accrual when exceeding configured DPD threshold

Delinquency Buckets

Bucket DPD Range Description
current 0 No past-due payments
dpd_1_29 1--29 Early delinquency
dpd_30_59 30--59 30-day delinquency
dpd_60_89 60--89 60-day delinquency
dpd_90_119 90--119 90-day delinquency
dpd_120_plus 120+ Severe delinquency

Delinquency Record

Each delinquent loan has a DelinquencyRecord:

Field Description
loan FK to the delinquent loan
days_past_due Current DPD count
delinquency_bucket Current bucket
amount_past_due Total amount past due (MoneyField)
entered_delinquency_at When the loan first became delinquent
assigned_collector FK to assigned collector user

Non-Accrual

When a loan's DPD exceeds a configurable threshold (typically 90+):

  1. Loan is placed on non-accrual (is_non_accrual = True)
  2. Interest income recognition stops
  3. Previously accrued but uncollected interest is reversed via GL entry:
    • DR Interest Income, CR Interest Receivable
  4. Interest is recognized only on a cash basis (when actually received) until the loan is cured

Non-accrual status is evaluated daily and cleared automatically when the loan returns to current status.

Collection Queues

Collection queues organize delinquent loans for collector workload management:

Field Description
name Queue name (e.g., "Early Stage", "Late Stage")
priority Numeric priority (lower = higher priority)
assigned_collector Default collector for this queue
assignment_rules JSONB rules for auto-assignment (DPD range, balance range, product, risk)
is_active Whether the queue is operational

Auto-Assignment

Loans are automatically assigned to queues based on configurable rules matching:

  • DPD range
  • Balance range
  • Loan product
  • Risk criteria

Within a queue, loans are assigned to collectors via round-robin distribution.

Collection Actions

Every collection interaction is recorded:

Action Type Examples
Phone (outbound/inbound) Right-party contact, left message, no answer, wrong number
Email Sent, no response
Letter Mailed
SMS Delivered
Field visit In-person contact
Skip trace Address/phone lookup via third-party
Agency referral Outsource to collection agency

Each action records:

  • Action type and result
  • Notes from the collector
  • Next scheduled action date
  • Whether it produced a promise to pay

Dunning

Automated collection communication sequences per lending program:

Dunning Schedule Configuration

Field Description
program FK to lending program
dpd_trigger Days past due that triggers this step
channel Communication channel (email, SMS, letter, in-app)
template_name Reference to communication template
suppress_during Array of sub-statuses that suppress this step

Suppression Rules

Dunning is suppressed during:

  • Forbearance (in_forbearance)
  • Deferment (in_deferment)
  • Bankruptcy (in_bankruptcy)
  • Dispute resolution

Execution

A daily Celery task (4:00 AM) evaluates all delinquent loans against dunning schedules:

  1. Check each loan's DPD against schedule triggers
  2. Skip if suppressed by sub-status
  3. Skip if borrower has do_not_contact = True
  4. Route delivery through the communications module
  5. Log with triggered_by = "dunning"

Pre-Delinquency Rules

Early warning rules enable proactive borrower outreach before delinquency occurs:

Field Description
trigger_type What triggers the rule
dpd_threshold DPD level that activates the rule
action What action to take (send communication, create task, etc.)

Collection Agencies

External collection agency records for outsourced collections:

Field Description
name Agency name
commission_type Flat fee or percentage
commission_rate Commission percentage or amount
Contact information Phone, email, address

do_not_contact Enforcement

The do_not_contact flag on borrowers is enforced throughout the collections process:

  • Dunning communications are never sent
  • Automated outbound contacts are blocked
  • Manual actions must be explicitly overridden
  • Flag is checked at every communication touchpoint

See Also