# BTM Koperasi - Services Documentation

This document provides an overview of all services in the BTM Koperasi application.

---

## 1. MemberService

**File:** `app/Services/MemberService.php`

**Purpose:** Handles member registration, profile management, verification, and member data queries.

### Key Features:

- **Member Registration**
  - Validates ID number uniqueness before registration
  - Creates member with branch association
  - Automatically creates default savings account (if default product exists)
  - Uses database transactions for data integrity
  - Logs all registration activities

- **Profile Update**
  - Updates member information (name, phone, email, address)
  - Validates ID number changes to prevent duplicates
  - Maintains audit trail for all updates

- **Member Verification**
  - Marks members as verified
  - Prevents duplicate verification
  - Logs verification action

- **Member Search**
  - Filter by name (partial match)
  - Filter by ID number (partial match)
  - Filter by branch ID
  - Filter by verification status
  - Returns paginated results with relationships loaded

- **Member Summary**
  - Total savings accounts count
  - Active savings accounts count
  - Total savings balance
  - Active financings count
  - Total financing balance
  - Overdue financing count (collectibility score > 1)

---

## 2. SavingsService

**File:** `app/Services/SavingsService.php`

**Purpose:** Manages savings accounts, deposits, withdrawals, and account operations.

### Key Features:

- **Deposit**
  - Validates account is active
  - Validates positive amount
  - Records transaction with before/after balances
  - Updates account balance
  - Creates double-entry journal entries (debit Cash, credit Member Savings)
  - Generates unique transaction number (format: `TRX-YYYYMMDD-NNNNNN`)
  - Logs deposit activity

- **Withdrawal**
  - Validates account is active
  - Validates positive amount
  - Checks sufficient balance (balance - hold amount)
  - Records transaction with before/after balances
  - Updates account balance
  - Creates double-entry journal entries (debit Member Savings, credit Cash)
  - Generates unique transaction number
  - Logs withdrawal activity

- **Open Account**
  - Creates new savings account for member
  - Generates unique account number (format: `YYYY-BB-NNNNNN`)
  - Associates with savings product
  - Sets initial balance to zero
  - Logs account creation

- **Close Account**
  - Validates account can be closed (not already closed)
  - Requires zero balance before closing
  - Records closure reason
  - Logs closure activity

### Transaction Numbers:
- **Transaction Number:** `TRX-YYYYMMDD-NNNNNN` (e.g., TRX-20260201-000001)
- **Account Number:** `YYYY-BB-NNNNNN` (e.g., 2026-01-000001)

---

## 3. AccountingService

**File:** `app/Services/AccountingService.php`

**Purpose:** Handles double-entry accounting, journal entries, and account balance management.

### Key Features:

- **Create Journal Entry**
  - Validates debits equal credits (double-entry rule)
  - Creates journal entry with unique voucher number
  - Creates individual journal lines for each debit/credit
  - Updates account balances automatically
  - Prevents posting to header accounts (only detail accounts)
  - Generates voucher number (format: `JV-YYYYMMDD-NNNNNN`)
  - Logs journal entry creation

- **Update Account Balance**
  - Calculates balance change (debit - credit)
  - Updates account balance immediately
  - Validates account is not a header account

- **Void Journal Entry**
  - Reverses journal entry balances
  - Can only void within configured window (default: 24 hours)
  - Marks journal as void
  - Records void reason and user
  - Logs void action

### Double-Entry Accounting:
- Every transaction must have equal debits and credits
- Debits increase asset accounts (Cash, Receivables)
- Credits increase liability and equity accounts (Member Savings, Revenue)
- All journal entries update account balances in real-time

### Voucher Numbers:
- **Journal Voucher:** `JV-YYYYMMDD-NNNNNN` (e.g., JV-20260201-000001)

---

## 4. FinancingService

**File:** `app/Services/FinancingService.php`

**Purpose:** Manages financing products, proposals, approvals, disbursements, payments, and collectibility.

### Key Features:

- **Propose Financing**
  - Creates financing application with status "proposed"
  - Calculates margin amount based on product rate
  - Calculates total repayment amount
  - Calculates daily installment amount
  - Generates unique financing account number (format: `FIN-YYYY-BB-NNNNNN`)
  - Logs proposal activity

- **Approve Financing**
  - Validates financing is in "proposed" status
  - Updates status to "approved"
  - Records approval date and approver
  - Stores approval notes
  - Logs approval activity

- **Disburse Financing**
  - Validates financing is "approved"
  - Creates journal entry (debit Financing Receivable, credit Cash)
  - Updates status to "active"
  - Records disbursement date
  - Calculates due date (installment_count days from disbursement)
  - Generates installment schedule (100 days, skipping Sundays)
  - Uses bulk insert for performance (100 installments at once)
  - Logs disbursement activity

- **Record Payment**
  - Validates positive payment amount
  - Calculates principal and margin allocation (pro-rata)
  - Creates payment record
  - Creates journal entry:
    - Debit Cash
    - Credit Financing Receivable (principal portion)
    - Credit Margin Revenue (margin portion)
  - Allocates payment to installments (oldest overdue first)
  - Updates financing balances
  - Auto-sets status to "paid_off" when balance <= 0.01
  - Generates unique payment number (format: `PAY-YYYYMMDD-NNNNNN`)
  - Logs payment activity

- **Update Collectibility Score**
  - Calculates days past due from due_date
  - Assigns collectibility score:
    - Score 1: Current (not overdue)
    - Score 2: Special Mention (1-30 days overdue)
    - Score 3: Substandard (31-60 days overdue)
    - Score 4: Doubtful (61-90 days overdue)
    - Score 5: Loss (90+ days overdue)

- **Write Off Financing**
  - Validates financing is "active"
  - Updates status to "written_off"
  - Records write-off reason
  - Logs write-off activity with remaining balance

### Installment Schedule Generation:
- Daily installments for the specified duration
- Skips Sundays (moves to Monday)
- Bulk insert for performance (single database operation)
- Each installment includes: principal, margin, total amount, due date

### Payment Allocation:
- Allocates to oldest overdue installments first
- Pro-rata allocation between principal and margin
- Updates installment status (pending → partial → paid)
- Handles partial payments

### Account Numbers:
- **Financing Account:** `FIN-YYYY-BB-NNNNNN` (e.g., FIN-2026-01-000001)
- **Payment Number:** `PAY-YYYYMMDD-NNNNNN` (e.g., PAY-20260201-000001)

---

## Cross-Service Dependencies

```
MemberService
    └── uses → SavingsService (optional)

SavingsService
    └── uses → AccountingService

FinancingService
    └── uses → AccountingService
```

---

## Common Patterns Across All Services

### Database Transactions
- All operations use `DB::transaction()` for atomicity
- Either all operations succeed or all fail
- No partial updates allowed

### Audit Logging
- All significant operations logged via `AuditLog::log()`
- Includes user ID who performed the action
- Records relevant context data

### Error Handling
- Validates business rules before execution
- Throws descriptive exceptions for invalid states
- Prevents data corruption

### Number Generation
- Unique numbers generated for all records
- Format includes date for sorting and identification
- Sequential numbering resets daily
- Padded with zeros for fixed-width sorting

---

## Configuration References

All services use configuration values from `config/accounting.php`:
- `accounting.accounts.cash` - Cash account ID
- `accounting.accounts.member_savings` - Member savings account ID
- `accounting.accounts.financing_receivable` - Financing receivable account ID
- `accounting.accounts.margin_revenue` - Margin revenue account ID
- `accounting.void_window_hours` - Hours allowed for voiding journal entries

---

## Compliance & OJK Requirements

### Financial Transaction Atomicity
- All financial operations wrapped in database transactions
- Double-entry accounting ensures balanced books
- No partial updates allowed

### Audit Trail
- Every action logged with user, timestamp, and context
- Journal entries preserve complete transaction history
- Soft deletes preserve record history

### Collectibility Monitoring
- Automatic scoring based on days overdue
- Supports OJK risk classification (Lancar, Kurang Lancar, Diragukan, Macet, Loss)
- Enables proactive risk management

---
