> ## Documentation Index
> Fetch the complete documentation index at: https://help.agatabo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Loan Disbursement Workflow

> Process for creating and disbursing loans

## Overview

The **Loan Disbursement Workflow** in Agatabo describes the process of creating loans, ensuring proper validation, and recording disbursement with accurate accounting.

<Note>
  **Current implementation**: Loan creation and disbursement happen **simultaneously** in one API call. The loan is created with status `ACTIVE` and disbursed immediately.

  **PENDING status exists** in the database schema but is not currently used by the API. A multi-stage approval workflow may be added in future versions.
</Note>

***

## Workflow Overview

```
Preparation → Creation & Validation → Automatic Disbursement → Monitoring
```

***

## Stage 1: Pre-Loan Preparation

**Who**: Loan Officer or Administrator

**Before creating loan in system**:

<Steps>
  <Step title="Verify member eligibility">
    * Member has required savings balance (typically 20-30% of loan amount)
    * Member has no existing ACTIVE or DEFAULTED loans
    * Member has "member" role assigned (required for loan eligibility)
    * Member is active in organization
  </Step>

  <Step title="Assess repayment capacity">
    * Review member's income sources
    * Check member's loan history (past defaults?)
    * Verify member can afford installment payments
    * Assess overall creditworthiness
  </Step>

  <Step title="Collect securities">
    * **Guarantors**: Other active members who co-sign
    * **Collateral**: Physical assets (property, equipment) with estimated values
    * **Savings requirement**: Minimum savings balance member must maintain
    * **Documents**: Photos, titles, appraisals, agreements
  </Step>

  <Step title="Calculate loan terms">
    * Determine principal amount (within organization limits)
    * Decide loan period (months)
    * Set interest rate (per organization policy)
    * Choose interest calculation method
    * Calculate estimated installments
  </Step>
</Steps>

**Checklist before system entry**:

* ✅ Member eligible for loan
* ✅ Securities adequate to cover loan amount
* ✅ Loan terms comply with organization policies
* ✅ Required documentation collected
* ✅ Loan committee approval obtained (if required by organization)

***

## Stage 2: Loan Creation & Disbursement

**Who**: User with `loans:write` permission

**API Endpoint**: `POST /loans`

### Request

```http theme={null}
POST /loans
Headers:
  x-organization-id: {organizationId}
  x-idempotency-key: {unique-key}
Body:
{
  "organizationUserId": "orguser-123",
  "principalAmount": 500000,
  "period": 12,
  "interestRate": 10,
  "interestRateType": "YEARLY",
  "interestCalculationType": "REDUCING_BALANCE",
  "interestPaymentTiming": "WITH_INSTALLMENTS",
  "installmentType": "EQUAL_TOTAL",
  "paymentAllocationOrder": "INTEREST_FIRST",
  "startDate": "2026-06-01",
  "purpose": "Business expansion",
  "bankAccountId": "bank-456",
  "loanSecurities": [
    {
      "type": "GUARANTOR",
      "organizationUserId": "orguser-789",
      "description": "John Doe - Co-signer"
    },
    {
      "type": "COLLATERAL",
      "value": 600000,
      "description": "Motorcycle - 2020 model"
    }
  ],
  "disbursementFeePercentage": 1.0,
  "disbursementFeeType": "PERCENTAGE"
}
```

**Required fields**:

| Field                     | Type   | Description                                                                       |
| ------------------------- | ------ | --------------------------------------------------------------------------------- |
| `organizationUserId`      | string | Borrower (must have "member" role, be active, no existing ACTIVE/DEFAULTED loans) |
| `principalAmount`         | number | Loan amount                                                                       |
| `period`                  | number | Loan term in months                                                               |
| `interestRate`            | number | Interest rate percentage                                                          |
| `interestRateType`        | enum   | "MONTHLY" or "YEARLY"                                                             |
| `interestCalculationType` | enum   | "SIMPLE", "COMPOUND", or "REDUCING\_BALANCE"                                      |
| `startDate`               | string | Loan start date (ISO format)                                                      |
| `bankAccountId`           | string | Bank account for disbursement                                                     |

**Optional fields**:

| Field                        | Type    | Default           | Description                                              |
| ---------------------------- | ------- | ----------------- | -------------------------------------------------------- |
| `interestPaymentTiming`      | enum    | From org settings | "IN\_ADVANCE" or "WITH\_INSTALLMENTS"                    |
| `installmentType`            | enum    | From org settings | "EQUAL\_PRINCIPAL" or "EQUAL\_TOTAL"                     |
| `paymentAllocationOrder`     | enum    | From org settings | "INTEREST\_FIRST", "PRINCIPAL\_FIRST", or "PROPORTIONAL" |
| `purpose`                    | string  | null              | Loan purpose description                                 |
| `loanSecurities`             | array   | \[]               | Guarantors, collateral, savings requirements             |
| `disbursementFeeType`        | enum    | From org settings | "PERCENTAGE" or "FIXED\_AMOUNT"                          |
| `disbursementFeePercentage`  | number  | From org settings | Fee percentage (e.g., 1.0 = 1%)                          |
| `disbursementFeeFixedAmount` | number  | From org settings | Fixed fee amount                                         |
| `bankChargeAmount`           | number  | null              | Bank transfer charges                                    |
| `skipNegativeBalanceCheck`   | boolean | false             | Allow negative balances (use with caution)               |

***

### What Happens Automatically

When loan is created, the system performs these actions **atomically** in one database transaction:

<Steps>
  <Step title="Validate member eligibility">
    * Member exists in organization
    * Member is active
    * Member has "member" role assigned
    * Member has no existing ACTIVE or DEFAULTED loans

    **Error if**: Member ineligible or already has active loan
  </Step>

  <Step title="Validate organization policies">
    * Principal amount within configured limits
    * Period within maximum allowed (if configured)
    * Principal ≤ (member savings × max\_loan\_percentage)
    * Amount scale matches organization currency settings

    **Error if**: Violates organization loan policies
  </Step>

  <Step title="Validate securities">
    * Total security value ≥ loan amount
    * Guarantors are active members
    * Savings requirement doesn't exceed member's available savings
    * All security values use correct decimal precision

    **Error if**: Insufficient securities
  </Step>

  <Step title="Calculate installments">
    * Computes EMI (Equated Monthly Installment)
    * Generates installment schedule
    * Calculates total interest
    * Applies configured rounding rules

    **Installments created** with due dates based on period
  </Step>

  <Step title="Create loan record">
    * Status set to **ACTIVE** (not PENDING)
    * Loan assigned unique account number
    * Installment schedule locked
    * Securities stored as JSON

    **Result**: Loan immediately active and disbursed
  </Step>

  <Step title="Create ledger accounts">
    * LOAN\_RECEIVABLE account (principal tracking)
    * INTEREST\_RECEIVABLE account (interest tracking)
    * PENALTY\_RECEIVABLE account (penalty tracking)

    **Result**: Dedicated ledger accounts for this loan
  </Step>

  <Step title="Post disbursement journal entry">
    **Basic entry** (interest with installments, fee from cash):

    ```
    Dr LOAN_RECEIVABLE           500,000
    Dr INTEREST_RECEIVABLE       total_interest
    Cr CASH (bank account)       500,000 - fee
    Cr INTEREST_INCOME           total_interest
    Cr DISBURSEMENT_FEE_INCOME   fee_amount
    ```

    **Variations**:

    * If fee deducted from savings: Separate DISBURSEMENT\_FEE\_PAYMENT entry
    * If interest paid in advance from savings: Separate INTEREST\_PAID\_IN\_ADVANCE entry
    * If interest paid in advance from cash: INTEREST\_RECEIVABLE not debited, CASH reduced by interest
    * If bank charge: Additional BANK\_CHARGE entry

    **Result**: Loan disbursed, accounts updated
  </Step>

  <Step title="Send notification">
    If organization has email/SMS enabled:

    * Email sent to borrower with loan details
    * SMS sent with loan approval message
    * Message includes installment amount and schedule

    **Message example**: "Your loan of 500,000 RWF has been approved! 12 monthly installments of 45,000 RWF each."
  </Step>
</Steps>

***

### Response

**Success (201 Created)**:

```json theme={null}
{
  "message": "Loan created successfully",
  "data": {
    "id": "loan-123",
    "accountNumber": "L-00042",
    "organizationUserId": "orguser-123",
    "principalAmount": 500000,
    "period": 12,
    "interestRate": 10,
    "interestRateType": "YEARLY",
    "status": "ACTIVE",
    "startDate": "2026-06-01T00:00:00.000Z",
    "disbursementFee": 5000,
    "loanReceivableLedgerAccountId": "acc-456",
    "interestReceivableLedgerAccountId": "acc-457",
    "penaltyReceivableLedgerAccountId": "acc-458",
    "createdAt": "2026-06-13T10:30:00.000Z"
  }
}
```

***

### Errors

| Status | Error                                                                            | Cause                                           |
| ------ | -------------------------------------------------------------------------------- | ----------------------------------------------- |
| 400    | "x-idempotency-key header is required"                                           | Missing idempotency key                         |
| 404    | "Organization user not found, inactive, or does not belong to this organization" | Invalid organizationUserId or member not active |
| 409    | "Organization user already has an active or defaulted loan"                      | Member already has ACTIVE or DEFAULTED loan     |
| 400    | "Loan period cannot exceed X month(s)"                                           | Period exceeds organization max\_period setting |
| 400    | "Principal exceeds max allowed from max loan percentage rule"                    | Principal > (savings × max\_loan\_percentage)   |
| 400    | "Insufficient security coverage"                                                 | Total securities \< loan amount                 |
| 400    | Various validation errors                                                        | Invalid data, decimal precision issues, etc.    |

***

## Stage 3: Post-Disbursement

**Who**: Loan Officer, Treasurer

### Immediate Actions

<Steps>
  <Step title="Disburse funds to member">
    **Method 1: Deduct from savings** (if fee/interest deducted from savings):

    * System already deducted from member's savings account
    * Member receives cash: Principal - (fee if from cash) - (interest if from cash and in advance)
    * Count cash with member present
    * Member signs receipt

    **Method 2: Bank transfer**:

    * Transfer from organization bank account to member's account
    * Record bank reference number
    * Amount: Principal - (fees/interest deducted from cash)

    **Method 3: Cash from office**:

    * Withdraw from organization bank
    * Give cash to member
    * Member signs receipt
  </Step>

  <Step title="File loan documentation">
    * Signed loan agreement
    * Collateral documents (titles, appraisals, photos)
    * Guarantor agreements
    * Disbursement receipt
    * Security documents
  </Step>

  <Step title="Provide member with payment schedule">
    * Export installment schedule from system
    * Print and give to member
    * Explain payment methods
    * Confirm due dates understood
    * Provide treasurer contact information
  </Step>

  <Step title="Set up payment reminders">
    * Add loan to monitoring list
    * Set up automatic payment reminders (3-5 days before due date)
    * Note first payment due date
    * Configure penalty rules if applicable
  </Step>
</Steps>

***

### Ongoing Monitoring

<Steps>
  <Step title="Track payments">
    * Monitor installment due dates
    * Send reminders before due dates
    * Record payments promptly using `POST /loans/{loanId}/repay`
    * Update payment status (on-time, late, missed)
  </Step>

  <Step title="Manage delinquencies">
    * Identify overdue payments immediately
    * Follow up with member (phone call, visit)
    * Apply penalties per organization policy
    * Escalate to loan committee if needed
    * Consider restructuring for hardship cases
  </Step>

  <Step title="Monitor loan health">
    * Review arrears regularly (Loans Outstanding report)
    * Track days overdue
    * Classify loans (current, 1-30 days, 31-90 days, 90+ days)
    * Update status to DEFAULTED if necessary
  </Step>
</Steps>

***

## Disbursement Fee & Interest Payment Options

### Fee Deduction Options

**Option 1: Fee deducted from cash** (default):

```
Dr LOAN_RECEIVABLE           500,000
Cr CASH                      495,000  (500,000 - 5,000 fee)
Cr DISBURSEMENT_FEE_INCOME     5,000
```

Member receives: 495,000 RWF

**Option 2: Fee deducted from savings** (if `disbursementFeeFromSavings: true`):

```
Main entry:
Dr LOAN_RECEIVABLE           500,000
Cr CASH                      500,000

Separate fee entry:
Dr SAVINGS (member)            5,000
Cr DISBURSEMENT_FEE_INCOME     5,000
```

Member receives: 500,000 RWF in cash, but 5,000 deducted from savings

***

### Interest Payment Timing Options

**Option 1: Interest paid with installments** (default):

```
Dr LOAN_RECEIVABLE            500,000
Dr INTEREST_RECEIVABLE         60,000
Cr CASH                       500,000
Cr INTEREST_INCOME             60,000
```

Member pays interest gradually with each installment.

**Option 2: Interest paid in advance from cash** (if `interestPaymentTiming: "IN_ADVANCE"`):

```
Dr LOAN_RECEIVABLE            500,000
Cr CASH                       440,000  (500,000 - 60,000 interest)
Cr INTEREST_INCOME             60,000
```

Member receives: 440,000 RWF (interest deducted upfront)

**Option 3: Interest paid in advance from savings** (if `interestPaymentTiming: "IN_ADVANCE"` and `advanceInterestFromSavings: true`):

```
Main entry:
Dr LOAN_RECEIVABLE            500,000
Cr CASH                       500,000

Advance interest entry:
Dr SAVINGS (member)            60,000
Cr INTEREST_RECEIVABLE         60,000
```

Member receives: 500,000 RWF in cash, but 60,000 deducted from savings

***

## Configuration from Organization Settings

Several loan parameters default to organization-wide settings (from `loanSettings` field):

| Setting                                | Default              | Description                                              |
| -------------------------------------- | -------------------- | -------------------------------------------------------- |
| `interest_payment_timing`              | "WITH\_INSTALLMENTS" | When interest is paid                                    |
| `installment_type`                     | "EQUAL\_PRINCIPAL"   | How installments calculated                              |
| `payment_allocation_order`             | "INTEREST\_FIRST"    | How payments allocated                                   |
| `max_loan_percentage`                  | (none)               | Max loan as multiple of savings (e.g., 3.0 = 3× savings) |
| `max_period`                           | (none)               | Maximum loan term in months                              |
| `disbursement_fee_percentage`          | 0                    | Default fee percentage                                   |
| `disbursement_fee_type`                | "PERCENTAGE"         | "PERCENTAGE" or "FIXED\_AMOUNT"                          |
| `disbursement_fee_fixed_amount`        | 0                    | Fixed fee amount                                         |
| `deduct_disbursement_fee_from_savings` | false                | Deduct fee from savings instead of cash                  |
| `deduct_advance_interest_from_savings` | false                | Deduct advance interest from savings instead of cash     |

These settings apply automatically unless overridden in the loan creation request.

***

## Complete Workflow Checklist

### Pre-Creation

* ✅ Member eligibility verified (savings, loan history, active status)
* ✅ Securities documented (guarantors, collateral, documents)
* ✅ Loan terms calculated and comply with policies
* ✅ Required documents collected
* ✅ Loan committee approval obtained (if required by organization)
* ✅ Member understands repayment terms

### During Creation (via API)

* ✅ `x-idempotency-key` header provided
* ✅ All required fields in request body
* ✅ Loan amount within policy limits
* ✅ Securities adequate to cover loan
* ✅ Member has no existing ACTIVE/DEFAULTED loans
* ✅ API call succeeds (201 response)

### Post-Disbursement

* ✅ Funds disbursed to member (cash or bank transfer)
* ✅ Member signs disbursement receipt
* ✅ Loan documents filed
* ✅ Payment schedule provided to member
* ✅ Member added to payment reminder list
* ✅ First payment reminder scheduled

### Ongoing

* ✅ Payments recorded promptly
* ✅ Overdue payments followed up immediately
* ✅ Penalties applied per policy
* ✅ Loan status updated as needed (COMPLETED, DEFAULTED)

***

## Common Issues

<AccordionGroup>
  <Accordion title="Member already has active loan">
    **Error**: "Organization user already has an active or defaulted loan"

    **Cause**: Member currently has a loan with status ACTIVE or DEFAULTED

    **Solution**:

    * Wait until existing loan is fully repaid (status = COMPLETED)
    * Or default the existing loan if appropriate (POST /loans/{id}/default)
    * Cannot have multiple simultaneous loans per member
  </Accordion>

  <Accordion title="Insufficient securities">
    **Error**: "Insufficient security coverage"

    **Cause**: Total value of securities \< loan principal amount

    **Solution**:

    * Add more guarantors
    * Increase collateral value
    * Reduce loan amount
    * Require higher savings balance
  </Accordion>

  <Accordion title="Principal exceeds max allowed">
    **Error**: "Principal exceeds max allowed from max loan percentage rule"

    **Cause**: Loan amount > (member savings × max\_loan\_percentage)

    **Example**: Savings = 100,000, max\_loan\_percentage = 3.0, max allowed = 300,000

    **Solution**:

    * Reduce loan amount
    * Ask member to save more first
    * Request organization to increase max\_loan\_percentage setting
  </Accordion>

  <Accordion title="Period exceeds maximum">
    **Error**: "Loan period cannot exceed X month(s)"

    **Cause**: Loan period > organization's max\_period setting

    **Solution**:

    * Reduce loan period
    * Request organization to increase max\_period setting
  </Accordion>

  <Accordion title="Need to cancel loan after creation">
    **Situation**: Loan created but member wants to cancel

    **If just created (same day)**:

    * Member can repay full principal immediately
    * Record payment: POST /loans/{id}/repay
    * Loan status changes to COMPLETED

    **If already days/weeks later**:

    * Member must repay according to schedule
    * Or negotiate restructuring with loan officer
    * Cannot delete disbursed loan (funds already given)
  </Accordion>

  <Accordion title="Loan settings not applying">
    **Problem**: Defaults from organization settings not being used

    **Check**:

    * Are organization `loanSettings` configured?
    * Do request body fields override settings?
    * Verify settings with GET /organizations/{id}

    **Note**: Request body parameters take precedence over organization defaults
  </Accordion>
</AccordionGroup>

***

## Future Enhancement: Multi-Stage Workflow

**PENDING status** exists in the database but is not currently used. A future version may implement:

1. **POST /loans** with status=PENDING (draft loan application)
2. **PUT /loans/{id}/approve** endpoint to change PENDING → ACTIVE
3. **DELETE /loans/{id}** to cancel PENDING loans
4. Workflow states and approval process

This would enable:

* Loan applications submitted for review
* Committee approval before disbursement
* Separation of application and disbursement
* Cancellation of unapproved loans

**Currently**: All loans created via API are immediately ACTIVE and disbursed.

***

## Related Topics

<CardGroup cols={2}>
  <Card title="Creating Loans" icon="plus" href="/tontines/loans/creating-loans">
    Detailed loan API documentation
  </Card>

  <Card title="Loan Rules" icon="gavel" href="/tontines/loans/loan-rules-explained">
    Interest calculations and installment types
  </Card>

  <Card title="Recording Payments" icon="money-bill-wave" href="/tontines/loans/recording-payments">
    How to record loan repayments
  </Card>

  <Card title="Loans Outstanding" icon="list-check" href="/tontines/reports/loans-outstanding">
    Monitor loan portfolio
  </Card>
</CardGroup>
