# Sequential Bill Payment Order

## Setting

| Code | Table | Column | Values |
|------|-------|--------|--------|
| `BILL_PAY_BY_ORDER` | `settings` | `booleanValue` | `1` = enforced, `0` = any order |

**SQL to enable:**
```sql
INSERT INTO settings (code, booleanValue) VALUES ('BILL_PAY_BY_ORDER', 1);
```

---

## Behavior

**When disabled (0):** Bills can be paid in any order. No change from current behavior.

**When enabled (1):** Bills must be paid in chronological order (`year_value ASC, month_value ASC`). If a student has unpaid January, February, March — they cannot pay March before January.

---

## Validation Logic

1. Group submitted bills by student (`student_id` / `new_student_id`)
2. For each student, fetch all unpaid bills ordered by `year_value`, `month_value`
3. Walk through the ordered list:
   - If a bill is in the submission: OK, continue
   - If a bill is NOT in the submission (gap): mark it
   - If a later bill IS in the submission after a gap: **throw error**

**Error message:**
```
Tagihan harus dibayar berurutan. [BillType] [Month] [Year] harus dibayar terlebih dahulu.
```

**HTTP response (422):**
```json
{
  "message": "Tagihan harus dibayar berurutan. SPP Januari 2025 harus dibayar terlebih dahulu.",
  "error": "Tagihan harus dibayar berurutan. SPP Januari 2025 harus dibayar terlebih dahulu."
}
```

---

## Examples

### Unpaid bills: Jan, Feb, Mar

| Request | Setting=0 | Setting=1 |
|---------|-----------|-----------|
| Pay Jan | OK | OK |
| Pay Jan + Feb | OK | OK |
| Pay Jan + Feb + Mar | OK | OK |
| Pay Feb | OK | Error: "SPP Januari harus dibayar terlebih dahulu" |
| Pay Mar | OK | Error: "SPP Januari harus dibayar terlebih dahulu" |
| Pay Jan + Mar (skip Feb) | OK | Error: "SPP Februari harus dibayar terlebih dahulu" |

### Installments

Installment payments follow the same rule. You can pay an installment for January, but cannot pay February (full or installment) until January is fully paid.

### Multiple students in one request

Each student is validated independently. Student A's order doesn't affect Student B.

---

## Files Changed

| File | Change |
|------|--------|
| `app/Services/TransactionService.php` | Added `validateBillPaymentOrder()` method, called in `payBills()` step 1b |

No controller, route, or BillService changes needed.

---

## Testing

**1. Insert setting:**
```sql
INSERT INTO settings (code, booleanValue) VALUES ('BILL_PAY_BY_ORDER', 1);
```

**2. Try skipping a month:**
```json
{
  "bill_payments": [
    { "bill_id": 3 }
  ],
  "transaction_mode_value": 2,
  "admin_employee_id": 5,
  "coa_kas_id": 10
}
```
Where bill #3 is March and bill #1 (January) is still unpaid → should return 422.

**3. Pay in order:**
```json
{
  "bill_payments": [
    { "bill_id": 1 },
    { "bill_id": 2 },
    { "bill_id": 3 }
  ],
  "transaction_mode_value": 2,
  "admin_employee_id": 5,
  "coa_kas_id": 10
}
```
Should succeed.

**4. Disable and retry skip:**
```sql
UPDATE settings SET booleanValue = 0 WHERE code = 'BILL_PAY_BY_ORDER';
```
Same skip request → should succeed.
