Loan Reschedule Transaction
Overview
A Loan Reschedule (also called Loan Restructuring or Loan Modification) is a transaction where the terms of an existing loan are modified to help a borrower who is experiencing financial difficulty. This typically involves extending the loan term, reducing the interest rate, or changing the repayment schedule.
Key Characteristics
- Purpose: Modify loan terms to avoid default and support borrower recovery
- Transaction Type:
RSCH(Reschedule) - Complexity: Very High - Creates new schedule while preserving old schedule history
- Multi-Entity Impact: LoanAccount, old LoanSchedules (SUPERSEDED), new LoanSchedules (ACTIVE)
- Critical Requirement: Old schedule supersession with full audit trail, new schedule creation
Reschedule vs Other Loan Transactions
| Aspect | Reschedule | Refinance | Write-Off |
|---|---|---|---|
| Loan Account | Same loan modified | New loan created | Loan removed from books |
| Outstanding Balance | Preserved | Transferred to new loan | Written off |
| Schedule | Old SUPERSEDED, new ACTIVE | Old closed, new created | All WRITTEN_OFF |
| Purpose | Help struggling borrower | Better terms/consolidation | Recognize bad debt |
| Payment History | Preserved | Starts fresh | Ended |
Transaction Flow
Entities Impacted
Scenario 1: Term Extension with Rate Reduction
Context:
- Loan: NGN 1,000,000 principal, 22% annual interest, 36 months
- Current Status: 18 months paid, NGN 500,000 principal remaining
- Financial Hardship: Borrower income reduced by 40%
- Current Monthly Payment: NGN 55,000
- Restructure Request: Extend to 48 months total (30 remaining), reduce rate to 18%
Old Schedule:
- 18 schedules paid (1-18): NGN 55,000/month
- 18 schedules outstanding (19-36): ACTIVE, NGN 55,000/month each
New Schedule Calculation:
Outstanding Balance = 500,000 (principal) + 90,000 (accrued interest) = 590,000
New Interest Rate = 18% (reduced from 22%)
New Term = 30 months (extended from 18 remaining)
New Monthly Payment = 590,000 / 30 + (590,000 × 0.18 / 12) = 19,667 + 8,850 = 28,517
Restructuring Fee = 1% of outstanding = 5,900
```text
**Entities Impacted** (32 ImpactedEntity records):
```typescript
{
transactionId: "RSCH-001",
transactionType: "Loan Reschedule",
rescheduleDate: "2025-12-28",
rescheduleReason: "Borrower income reduced 40%, requesting payment relief",
impactedEntities: [
// 1-18: Old Schedule Supersession (18 outstanding schedules)
// Schedule 19 (example)
{
entityType: "LoanSchedule",
entityId: 219,
entityKey: "SCH-219",
fieldName: "State",
oldValue: "ACTIVE",
newValue: "SUPERSEDED",
deltaAmount: 0
},
{
entityType: "LoanSchedule",
entityId: 219,
fieldName: "SupersededDate",
oldValue: null,
newValue: "2025-12-28",
deltaAmount: 0
},
{
entityType: "LoanSchedule",
entityId: 219,
fieldName: "SupersededByTransactionId",
oldValue: null,
newValue: "RSCH-001",
deltaAmount: 0
},
// ... (17 more old schedules, each with 3 field changes = 51 records)
// 19-48: New Schedule Creation (30 new schedules)
// New Schedule 1 (example)
{
entityType: "LoanSchedule",
entityId: 501, // New ID
entityKey: "SCH-501",
fieldName: "ScheduleNumber",
oldValue: null,
newValue: "19", // Continues from old schedule numbering
deltaAmount: 0
},
{
entityType: "LoanSchedule",
entityId: 501,
fieldName: "DueDate",
oldValue: null,
newValue: "2026-01-28",
deltaAmount: 0
},
{
entityType: "LoanSchedule",
entityId: 501,
fieldName: "PrincipalDue",
oldValue: null,
newValue: 19667.00,
deltaAmount: +19667.00
},
{
entityType: "LoanSchedule",
entityId: 501,
fieldName: "InterestDue",
oldValue: null,
newValue: 8850.00,
deltaAmount: +8850.00
},
{
entityType: "LoanSchedule",
entityId: 501,
fieldName: "State",
oldValue: null,
newValue: "ACTIVE",
deltaAmount: 0
},
{
entityType: "LoanSchedule",
entityId: 501,
fieldName: "CreatedByTransactionId",
oldValue: null,
newValue: "RSCH-001",
deltaAmount: 0
},
// ... (29 more new schedules, each with 6 field changes = 174 records)
// 49-55: LoanAccount impacts
{
entityType: "LoanAccount",
entityId: 101,
entityKey: "LOAN-101",
fieldName: "InterestRate",
oldValue: 22.00,
newValue: 18.00,
deltaAmount: -4.00
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "TermMonths",
oldValue: 36,
newValue: 48,
deltaAmount: +12
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "MaturityDate",
oldValue: "2026-12-15",
newValue: "2028-12-28",
deltaAmount: 0
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "RescheduleCount",
oldValue: 0,
newValue: 1,
deltaAmount: +1
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "LastRescheduleDate",
oldValue: null,
newValue: "2025-12-28",
deltaAmount: 0
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "MonthlyInstallment",
oldValue: 55000.00,
newValue: 28517.00,
deltaAmount: -26483.00
},
{
entityType: "LoanAccount",
entityId: 101,
fieldName: "ScheduleCount",
oldValue: 36,
newValue: 48, // 18 paid + 30 new
deltaAmount: +12
},
// 56-57: GL Account impacts (restructuring fee)
{
entityType: "GLAccount",
entityKey: "4106-LOAN-RESTRUCTURING-INCOME",
fieldName: "CreditAmount",
deltaAmount: +5900.00
},
{
entityType: "GLAccount",
entityKey: "2101-CUSTOMER-DEPOSITS",
fieldName: "DebitAmount",
deltaAmount: +5900.00 // Deducted from customer account
}
]
}
```text
**Key Point**: Old schedule 19-36 marked SUPERSEDED (not deleted), new schedule 19-48 created as ACTIVE. Payment history on schedules 1-18 preserved.
---
## Reschedule Calculation Algorithm
:::warning[Code Removed]
**Implementation details removed for security.**
Contact support for implementation guidance.
:::text
---
## Reschedule Execution
:::warning[Code Removed]
**Implementation details removed for security.**
Contact support for implementation guidance.
:::text
---
## Best Practices
### For Product Managers
1. **Reschedule Policy**:
- Define clear eligibility criteria (financial hardship documentation)
- Limit reschedules per loan (e.g., maximum 2 reschedules)
- Set restructuring fees (typically 1-2% of outstanding balance)
2. **Risk Management**:
- Track reschedule count per borrower (indicator of credit risk)
- Monitor NPL rates for rescheduled loans
- Provisioning requirements may increase for rescheduled loans
3. **Customer Support**:
- Offer payment relief without harming credit history
- Balance bank profitability with customer retention
- Communicate new terms clearly
### For Developers
1. **Schedule Supersession**:
- NEVER delete old schedules (audit trail required)
- Mark old schedules as SUPERSEDED with link to reschedule transaction
- Preserve all payment history on paid schedules
2. **Impact Tracking**:
- Track EVERY old schedule supersession
- Track EVERY new schedule creation
- Link old and new schedules via transaction ID
3. **Concurrent Safety**:
- Lock loan account during reschedule
- Verify no payments pending on old schedules
- Use database transactions
### For Bank Operations
1. **Approval Process**:
- Credit committee review required
- Verify financial hardship documentation
- Assess borrower's ability to service new terms
2. **Documentation**:
- Signed reschedule agreement from borrower
- Updated loan contract with new terms
- Notification of new payment schedule
3. **Monitoring**:
- Track performance of rescheduled loans
- Early warning if second reschedule needed
- Provisioning requirements
---
## V2 API Commands
### Architecture Overview
The V2 loan reschedule command follows the **Delegation Pattern**:
- **V2 Facade**: `InitiateLoanRescheduleCommand` (BPMCore compatible)
- **V1 Implementation**: Delegates to existing V1 `LoanRescheduleCommand` with full business logic
- **BPM Integration**: Accepts parameters via `BpmUtil.GetPropertyValue()`
**Implementation**: `CB.Administration.Api/Commands/BPMCore/Loans/AdministrationCoreLoanCommandHandlers.Transactions.cs`
---
### InitiateLoanRescheduleCommand
**Purpose**: Reschedule loan payment terms (modify schedule, extend term, adjust amount)
**Command**: `InitiateLoanRescheduleCommand`
**Delegation**: → `LoanRescheduleCommand` (V1 implementation)
#### BPM Parameters
```json
{
"commandName": "InitiateLoanRescheduleCommand",
"data": {
"accountEncodedKey": "string (mandatory)",
"clientEncodedKey": "string (mandatory)",
"newTermMonths": "int (optional)",
"newInstallmentAmount": "decimal (optional)",
"rescheduleReason": "string (optional)",
"transactionDate": "DateTime (optional)",
"notes": "string (optional)"
}
}
Parameter Details
| Parameter | Type | Required | Description |
|---|---|---|---|
accountEncodedKey | string | ✅ Yes | Loan account to reschedule |
clientEncodedKey | string | ✅ Yes | Client/borrower encoded key |
newTermMonths | int | ⌠No | New loan term in months |
newInstallmentAmount | decimal | ⌠No | New installment amount |
rescheduleReason | string | ⌠No | Reason code (e.g., "FINANCIAL_DIFFICULTY") |
transactionDate | DateTime | ⌠No | Reschedule date (defaults to today) |
notes | string | ⌠No | Reschedule notes/remarks |
Impact
Loan Account:
- ✅ Old schedules closed/modified
- ✅ New schedules generated with revised terms
- ✅ Loan term extended (if applicable)
- ✅ Installment amount reduced (if applicable)
- ✅ Reschedule history tracked
Example Response
{
"isSuccessful": true,
"transactionId": "TXN-LOAN-RSCH-20251229-0001",
"transactionState": "SETTLED",
"message": "Loan rescheduled successfully",
"data": {
"loanAccountKey": "8a8080827f23loan017f23def456",
"oldTermMonths": 36,
"newTermMonths": 48,
"oldInstallmentAmount": 50000.00,
"newInstallmentAmount": 37500.00,
"schedulesModified": 24,
"schedulesCreated": 12
}
}
Implementation Checklist
Phase 1: Calculation
- Implement
CalculateRescheduleTermsAsync - Add schedule generation for new terms
- Calculate restructuring fees
- Unit tests (5+ scenarios)
Phase 2: Execution
- Implement
ProcessLoanRescheduleAsync - Add old schedule supersession logic
- Add new schedule creation
- Integration tests
Phase 3: API
- Create reschedule calculation endpoint
- Create reschedule execution endpoint
- Add validation rules
- API tests
Phase 4: Testing
- End-to-end tests (3+ scenarios)
- Audit trail verification
- Production deployment
Developer Resources
For API implementation details, see:
Document Version: 1.0
Last Updated: December 28, 2025
Related Documents: