# Payment Allocation System Audit

## User Request
Implement intelligent payment rollover logic:
1. B2C to Suspense if no matching nationalID ✓ (implemented)
2. Payment allocation with intelligent rollover:
   - If amount < installment: pay partial, leave balance
   - If amount = installment: pay and clear
   - If amount > installment: roll over to next installment of same loan
   - If still balance: roll to next active loan's installments
   - If all paid and balance remains: add to guarantee_deposit

## Current Implementation Status

### Implemented Components:
1. **RepaymentService::recordLoanPayment()** - Allocates payment across loan's installments
2. **RepaymentService::recordPaymentForUserActiveLoans()** - Allocates across user's active loans
3. **SuspenseService::reassignAndApply()** - Applies suspense to loans with rollover
4. **C2B Confirmation** - Routes to suspense if no user match

### Entry Points to Verify:
1. C2B confirmation callback - uses recordPaymentForUserActiveLoans ✓
2. Repayment controller - needs verification
3. Suspense reassignment - needs verification
4. Fee payment - separate logic, doesn't need rollover
5. API payment endpoints - needs verification

### Implementation Completed:

1. **Updated RepaymentService::recordPayment()**
   - Added `allowRollover=true` parameter (default)
   - Calls recordLoanPayment for intelligent allocation
   - Falls back to single repayment if allowRollover=false

2. **Updated RepaymentService::applyPaymentFromTransaction()**
   - Added `allowRollover=true` parameter
   - Uses recordLoanPayment for intelligent rollover
   - Supports both rollover and non-rollover modes

3. **Fixed RepaymentService::recordLoanPayment()**
   - Calls recordPayment with allowRollover=false to prevent recursion
   - Properly iterates through installments and rolls over balance

4. **Updated Admin RepaymentController::storePayment()**
   - Removed amount_due max limit
   - Now allows payment up to total loan balance
   - Added success message noting intelligent rollover

### Payment Flow (All Entry Points):

**C2B No User Match:**
- Suspense Account ✓

**C2B With User Match:**
- recordPaymentForUserActiveLoans → rolls to next loans → guarantee_deposit ✓

**Manual Payment (User/Admin):**
- recordPayment (allowRollover=true) → recordLoanPayment → next installments ✓

**STK Callback:**
- processMpesaPaymentCallback → applyPaymentFromTransaction (allowRollover=true) → recordLoanPayment ✓

**Suspense Reassignment:**
- recordLoanPayment directly → next installments → guarantee_deposit ✓

### Files Modified:
1. `app/Services/RepaymentService.php` - Added rollover logic and recursion guard
2. `app/Http/Controllers/Admin/RepaymentController.php` - Updated validation for rollover
3. Created `PAYMENT_ALLOCATION_IMPLEMENTATION.md` - Complete documentation

### Key Changes:
- recordPayment() now defaults to allowRollover=true
- recordLoanPayment() calls recordPayment with allowRollover=false to prevent recursion
- applyPaymentFromTransaction() now supports rollover
- Admin payment validation allows up to total loan balance
- All entry points now use intelligent rollover automatically

### Testing Recommendation:
1. Test C2B with unmatched bill ref → confirm goes to suspense
2. Test C2B with matched bill ref → confirm allocates correctly
3. Test manual admin payment > installment amount → confirm rolls over
4. Test overpayment with extra → confirm adds to guarantee_deposit
