---
description: >-
  Dokumentasi lengkap arsitektur sistem, database schema, dan komponen aplikasi 
  Laravel Koperasi MSJ Framework.
---

# Dokumentasi

Dokumentasi ini menjelaskan arsitektur sistem, struktur database, dan komponen-komponen utama dalam aplikasi Laravel Koperasi MSJ. Dokumentasi ini ditujukan untuk developer yang ingin memahami struktur internal aplikasi.

## Daftar Isi

1. [Gambaran Umum](documentation.md#gambaran-umum)
2. [Tech Stack](documentation.md#tech-stack)
3. [Arsitektur Sistem](documentation.md#arsitektur-sistem)
4. [Controllers](documentation.md#controllers)
5. [Helpers](documentation.md#helpers)
6. [Models & Relationships](documentation.md#models--relationships)
7. [API Endpoints](documentation.md#api-endpoints)
8. [Database Schema](documentation.md#database-schema)
9. [Security & Authorization](documentation.md#security--authorization)
10. [File Structure](documentation.md#file-structure)
11. [Cara Penggunaan](documentation.md#cara-penggunaan)

***

## Gambaran Umum

Aplikasi Koperasi MSJ Framework adalah sistem manajemen koperasi karyawan yang komprehensif, dibangun menggunakan Laravel 12 dengan MSJ Framework. Sistem ini dirancang untuk mengelola seluruh operasional koperasi mulai dari keanggotaan hingga laporan keuangan.

### Fitur Utama

* **Manajemen Anggota**: Pendaftaran, profil, upload KTP, integrasi dengan master karyawan, dan manajemen akses login
* **Pengajuan Pinjaman**: Proses pengajuan (baru & top-up), multi-level approval workflow, perhitungan cicilan otomatis, dan pencairan dana
* **Sistem Cicilan**: Auto-generate jadwal cicilan, perhitungan bunga, tracking pembayaran, dan pelacakan status real-time
* **Pelunasan**: Pengajuan pelunasan manual oleh anggota, approval workflow, dan auto-update status cicilan
* **Potongan Gaji**: Generate potongan bulanan otomatis dari cicilan jatuh tempo, manajemen simpanan wajib, dan export untuk payroll
* **SHU (Sisa Hasil Usaha)**: Perhitungan berdasarkan simpanan dan bunga, distribusi tahunan, dan laporan per anggota
* **Debit Kredit**: Manajemen transaksi keuangan koperasi, auto-convert ke stock paket, dan upload bukti transaksi
* **Laporan**: Dashboard multi-role, laporan keuangan, statistik real-time, dan export Excel/PDF
* **Stock Paket**: Manajemen paket pinjaman, tracking availability, dan validasi otomatis

### Business Process Flow

```
Anggota → Pengajuan Pinjaman → Admin Kredit (Review) 
    → Ketua Umum (Approval) → Admin Transfer (Pencairan)
    → Generate Cicilan → Generate Potongan → Pelunasan
```

### User Roles

1. **Anggota (anggot)**: Mengajukan pinjaman, melihat histori, melakukan pelunasan manual
2. **Ketua Admin (kadmin)**: Manajemen master data dan overview sistem
3. **Admin Kredit (akredt)**: Review dan approve/reject pengajuan pinjaman (level 1)
4. **Ketua Umum (ketuum)**: Final approval pengajuan pinjaman (level 2)
5. **Admin Transfer (atrans)**: Pencairan dana dan upload bukti transfer

***

## Tech Stack

### Backend

* **Framework**: Laravel 12 (PHP 8.2+)
* **Custom Framework**: MSJ Framework v1.1+
* **Database**: MySQL 5.7+ / PostgreSQL 10+
* **Authentication**: Laravel Sanctum
* **Cache**: Redis (optional)
* **Queue**: Redis (optional)
* **Server**: Laravel Octane with RoadRunner (optional)

### Frontend

* **Template**: Argon Dashboard
* **CSS Framework**: Bootstrap 5
* **JavaScript**: jQuery, DataTables
* **Charts**: Chart.js
* **Icons**: Font Awesome, Nucleo Icons
* **Forms**: Select2, SweetAlert2

### Development Tools

* **Package Manager**: Composer, NPM
* **Build Tool**: Vite
* **Testing**: PHPUnit
* **Code Quality**: Laravel Pint
* **API Testing**: Laravel Boost (optional)

### Additional Libraries

* **PDF Generation**: mPDF
* **Excel**: PhpSpreadsheet
* **QR Code**: SimpleSoftwareIO Simple QRCode
* **Image Processing**: Intervention Image

***

## Arsitektur Sistem

### Base Controller

**MSJBaseController** - Controller dasar yang menyediakan:

* Manajemen authorization dan authentication
* Database transaction handling
* Pagination utilities
* Logging system
* Error handling
* Export functionality

### Design Patterns

* **Helper Pattern**: Logika bisnis dipisahkan ke helper classes
* **Repository Pattern**: Data access melalui model relationships
* **Service Layer**: Business logic encapsulation
* **Factory Pattern**: ID generation dan data creation
* **Observer Pattern**: Event logging dan audit trail

***

## Controllers

### 1. AnggotaController

**Path**: `app/Http/Controllers/AnggotaController.php`

**Fungsi Utama**:

* Manajemen data anggota koperasi
* Integrasi dengan sistem user management
* Upload dan manajemen foto KTP
* Auto-generate akses login untuk anggota

**Methods**:

* `index()` - List anggota dengan pagination dan search
* `add()` - Form tambah anggota baru
* `store()` - Simpan data anggota baru dengan validasi
* `show()` - Detail anggota dengan histori pinjaman dan potongan
* `edit()` - Form edit data anggota
* `update()` - Update data anggota dengan manajemen akses login
* `destroy()` - Toggle status aktif/non-aktif anggota
* `getKaryawanData()` - API endpoint untuk auto-fill data dari master karyawan
* `getExportData()` - Data untuk export Excel/PDF

**Fitur Khusus**:

* Auto-fill data dari master karyawan berdasarkan NIK
* Manajemen akses login otomatis (create/activate/deactivate)
* Upload foto KTP dengan validasi
* Integrasi dengan sistem authorization MSJ Framework

### 2. DashboardController

**Path**: `app/Http/Controllers/DashboardController.php`

**Fungsi Utama**:

* Dashboard multi-role dengan data spesifik per role
* Statistik real-time dan chart data
* AJAX endpoints untuk dynamic charts

**Role-based Dashboards**:

* **Anggota (`anggot`)**: Pinjaman berjalan, histori, SHU personal
* **Ketua Admin (`kadmin`)**: Overview keuangan, master data, chart pinjaman
* **Admin Kredit (`akredt`)**: Pengajuan review, approval statistics, SHU total
* **Ketua Umum (`ketuum`)**: Final approval, laporan keuangan, trend analysis
* **Admin Transfer (`atrans`)**: Transfer pending, performance metrics

**AJAX Methods**:

* `getChartData()` - Dynamic chart data dengan filter periode
* `getLaporanKeuangan()` - Data keuangan untuk ketua umum
* `getPinjamanPerDepartemen()` - Statistik pinjaman per departemen

### 3. DebitkreditController

**Path**: `app/Http/Controllers/DebitkreditController.php`

**Fungsi Utama**:

* Manajemen transaksi debit dan kredit
* Auto-update stock paket berdasarkan transaksi
* Upload bukti transaksi

**Methods**:

* `index()` - List transaksi dengan filter bulan
* `add()` - Form tambah transaksi
* `store()` - Simpan transaksi dengan auto-update paket stock
* `show()` - Detail transaksi
* `edit()` - Form edit transaksi
* `update()` - Update transaksi dengan recalculate paket stock
* `destroy()` - Soft delete transaksi dengan adjust paket stock

**Business Logic**:

* Auto-generate ID dengan prefix DEB/KRE
* Konversi balance ke stock paket otomatis
* Validasi dan manajemen file upload

### 4. PelunasanController

**Path**: `app/Http/Controllers/PelunasanController.php`

**Fungsi Utama**:

* Manajemen pengajuan pelunasan pinjaman
* Approval workflow untuk pelunasan
* Auto-update status cicilan saat approved

**Methods**:

* `index()` - List pelunasan dengan statistik
* `add()` - Form pengajuan pelunasan
* `store()` - Simpan pengajuan pelunasan
* `show()` - Detail pelunasan dengan perhitungan
* `approval()` - Proses approval/reject pelunasan

**Business Logic**:

* Validasi pinjaman yang eligible untuk pelunasan
* Perhitungan otomatis sisa cicilan
* Auto-update semua cicilan belum bayar menjadi lunas saat approved
* Integrasi dengan sistem potongan (optional)

### 5. PelunasanManualController

**Path**: `app/Http/Controllers/PelunasanManualController.php`

**Fungsi Utama**:

* Pelunasan manual oleh anggota
* Upload bukti pelunasan
* Validasi nominal pelunasan

**Methods**:

* `index()` - List pinjaman yang bisa dilunasi manual
* `show()` - Detail perhitungan pelunasan
* `store()` - Submit pengajuan pelunasan manual

**Business Logic**:

* Hanya anggota yang bisa akses pinjaman sendiri
* Validasi nominal dengan tolerance 5%
* Upload bukti pelunasan mandatory
* Status pending menunggu approval admin

### 6. PengajuanPinjamanController

**Path**: `app/Http/Controllers/PengajuanPinjamanController.php`

**Fungsi Utama**:

* Manajemen pengajuan pinjaman (baru dan top-up)
* Multi-level approval workflow
* Transfer dana dan bukti transfer
* Perhitungan cicilan otomatis

**Methods**:

* `index()` - List pengajuan dengan filter role-based
* `add()` - Form pengajuan dengan validasi paket
* `store()` - Simpan pengajuan dengan auto-detect jenis
* `show()` - Detail pengajuan dengan approval history
* `edit()` - Form edit pengajuan
* `update()` - Update pengajuan
* `destroy()` - Hapus pengajuan
* `approval()` - Multi-level approval process
* `processTransfer()` - Transfer dana dengan bukti
* `calculate()` - AJAX calculation untuk preview cicilan
* `checkJenisPengajuan()` - Auto-detect jenis pengajuan (baru/top-up)

**Business Logic**:

* Auto-detect pinjaman baru vs top-up berdasarkan sisa cicilan
* Multi-level approval: Admin Kredit → Ketua Umum → Transfer
* Auto-generate cicilan schedule saat final approval
* Validasi paket availability untuk admin
* Top-up otomatis lunasi sisa cicilan lama

### 7. PeriodeController

**Path**: `app/Http/Controllers/PeriodeController.php`

**Fungsi Utama**:

* Manajemen master periode pencairan
* Auto-generate 12 periode per tahun
* Pagination berdasarkan tahun

**Methods**:

* `index()` - List periode dengan grouping per tahun
* `add()` - Form tambah periode
* `store()` - Generate 12 periode untuk tahun tertentu
* `show()` - Detail periode
* `edit()` - Form edit periode
* `update()` - Update periode
* `destroy()` - Toggle status aktif periode

**Business Logic**:

* Format periode: MMYYYY (contoh: 012025 untuk Januari 2025)
* Auto-generate ID menggunakan IdGenerator
* Pagination custom per tahun (12 bulan per halaman)

### 8. PotonganController

**Path**: `app/Http/Controllers/PotonganController.php`

**Fungsi Utama**:

* Generate potongan gaji bulanan
* Manajemen data potongan per anggota
* Auto-close master periode setelah generate

**Methods**:

* `index()` - List potongan dengan session-based display
* `add()` - Form tambah potongan manual
* `store()` - Simpan potongan atau trigger generate
* `show()` - Detail potongan anggota
* `edit()` - Form edit potongan
* `update()` - Update potongan dengan recalculate total
* `destroy()` - Toggle status potongan
* `generatePotongan()` - Generate dari master periode
* `generatePotonganByPeriode()` - Generate berdasarkan input bulan/tahun

**Business Logic**:

* Generate otomatis dari cicilan yang jatuh tempo
* Auto-close master periode setelah generate
* Session-based data display (hanya tampil setelah generate)
* Support regenerate untuk include pinjaman baru
* Cache last generated periode

### 9. ReportrekapController

**Path**: `app/Http/Controllers/ReportrekapController.php`

**Fungsi Utama**:

* Dashboard laporan dengan multiple report types
* Generate laporan dengan filter dinamis
* Export ke Excel/PDF

**Report Types**:

* **Laporan Pinjaman**: Data pinjaman dengan filter status
* **Laporan SHU**: Data SHU dengan filter nominal
* **Laporan Potongan**: Data potongan dengan filter jenis
* **Laporan Debit & Kredit**: Data transaksi dengan filter type

**Methods**:

* `index()` - Dashboard laporan
* `show()` - Tampil laporan dengan pagination
* `store()` - Generate laporan via AJAX
* `getExportData()` - Data untuk export dengan totals

**Business Logic**:

* Session-based report storage
* Dynamic filtering per report type
* Pagination untuk large datasets
* Calculate totals untuk export

### 10. ShuController

**Path**: `app/Http/Controllers/ShuController.php`

**Fungsi Utama**:

* Manajemen SHU (Sisa Hasil Usaha)
* Generate SHU bulk untuk semua anggota
* Perhitungan berdasarkan simpanan dan bunga

**Methods**:

* `index()` - List SHU dengan statistik
* `add()` - Form tambah SHU manual
* `store()` - Simpan SHU atau trigger generate bulk
* `show()` - Detail SHU anggota
* `edit()` - Form edit SHU
* `update()` - Update SHU dengan recalculate
* `destroy()` - Soft delete SHU
* `generateShu()` - Generate SHU untuk semua anggota per tahun

**Business Logic**:

* Perhitungan: (Simpanan × % Simpanan) + (Bunga × % Bunga)
* Data simpanan dari trs\_potongan per tahun
* Data bunga dari trs\_cicilan per tahun
* Composite key: periode|nik

***

## Helpers

### Core Helpers

#### 1. ValidationHelper

**Path**: `app/Helpers/Koperasi/ValidationHelper.php`

**Fungsi**:

* Centralized validation menggunakan sys\_table configuration
* Dynamic validation rules dari database
* Support untuk create/update validation dengan unique handling

**Methods**:

* `getValidationFromDatabase()` - Ambil rules dari sys\_table
* `validateAnggotaStore/Update()` - Validasi data anggota
* `validatePengajuanPinjamanStore/Update()` - Validasi pengajuan dengan custom rules
* `validate()` - Core validation method

#### 2. ResponseHelper

**Path**: `app/Helpers/Koperasi/ResponseHelper.php`

**Fungsi**:

* Standardized response format untuk AJAX/API
* Consistent error handling

**Methods**:

* `response()` - Build response array
* `json()` - JSON response untuk AJAX endpoints

#### 3. PaketHelper

**Path**: `app/Helpers/Koperasi/PaketHelper.php`

**Fungsi**:

* Single gate untuk manajemen stock paket
* Perhitungan balance dan availability
* Statistik untuk dashboard

**Methods**:

* `get()` - Current stock paket
* `update()` - Update stock dengan operation type
* `validate()` - Validasi availability
* `calculate()` - Berbagai perhitungan paket
* `getStatistics()` - Data untuk dashboard

#### 4. ApprovalHistoryHelper

**Path**: `app/Helpers/Koperasi/ApprovalHistoryHelper.php`

**Fungsi**:

* Format approval history logs untuk display
* Extract informasi dari log descriptions

**Methods**:

* `format()` - Format collection logs dengan user info dan color coding

### Generator Helpers

#### 1. IdGenerator

**Path**: `app/Helpers/Koperasi/Generator/IdGenerator.php`

**Fungsi**:

* Polymorphic ID generation berdasarkan sys\_id configuration
* Support berbagai format ID dengan prefix dan counter

**Methods**:

* `generate()` - Main method dengan polymorphic behavior
* `standard()` - Standard ID generation
* `withPrefix()` - ID dengan prefix (DEB/KRE)
* `forPeriode()` - ID untuk periode (MMYYYY)

**Usage**:

```php
IdGenerator::generate('pinjaman')           // PIN240001
IdGenerator::generate('debitKredit', type: 'debit')  // DEB240001
IdGenerator::generate('periode', bulan: 1, tahun: 2025)  // 012025
```

#### 2. CicilanGenerator

**Path**: `app/Helpers/Koperasi/Generator/CicilanGenerator.php`

**Fungsi**:

* Generate jadwal cicilan berdasarkan pinjaman
* Perhitungan bunga dan angsuran
* Save ke database trs\_cicilan

**Methods**:

* `generate()` - Generate dan save cicilan schedule
* `calculate()` - Perhitungan preview tanpa save

#### 3. PotonganGenerator

**Path**: `app/Helpers/Koperasi/Generator/PotonganGenerator.php`

**Fungsi**:

* Generate potongan gaji bulanan dari cicilan jatuh tempo
* Handle regenerate untuk include pinjaman baru
* Skip cicilan yang sudah lunas via pelunasan

**Methods**:

* `generate()` - Generate dari master periode
* `generateWithPeriodeValidation()` - Generate dengan validasi periode
* `regenerate()` - Re-generate existing periode

### Business Logic Helpers

#### 1. AnggotaHelper

**Path**: `app/Helpers/Koperasi/Anggota/AnggotaHelper.php`

**Fungsi**:

* CRUD operations untuk anggota
* Manajemen akses login
* Integration dengan user management

**Methods**:

* `create/get/update/delete()` - Basic CRUD
* `createLogin/removeLogin/reactivateLogin()` - Login management
* `hasLogin()` - Check login status
* `getDepartemenOptions/getJabatanOptions()` - Form options

#### 2. PengajuanPinjamanHelper

**Path**: `app/Helpers/Koperasi/Pengajuan/PengajuanPinjamanHelper.php`

**Fungsi**:

* Business logic untuk pengajuan pinjaman
* Auto-detect jenis pengajuan (baru/top-up)
* Data retrieval dengan role-based filtering

#### 3. PengajuanPinjamanApprovalHelper

**Path**: `app/Helpers/Koperasi/Pengajuan/PengajuanPinjamanApprovalHelper.php`

**Fungsi**:

* Multi-level approval workflow
* Status management dan level progression
* Approval history logging

#### 4. PengajuanPinjamanWorkflowHelper

**Path**: `app/Helpers/Koperasi/Pengajuan/PengajuanPinjamanWorkflowHelper.php`

**Fungsi**:

* Workflow state management
* Transfer process handling
* Top-up cicilan auto-payment

### Report Helpers

#### 1. ShuReport

**Path**: `app/Helpers/Koperasi/Report/ShuReport.php`

**Fungsi**:

* Generate laporan SHU dengan filtering
* Summary calculations
* Data transformation untuk export

#### 2. PinjamanReport, PotonganReport, DebitKreditReport

**Paths**: `app/Helpers/Koperasi/Report/`

**Fungsi**:

* Generate laporan spesifik per module
* Consistent filtering dan summary
* Export-ready data format

### Constants

#### KoperasiConstants

**Path**: `app/Helpers/Koperasi/Constants/KoperasiConstants.php`

**Fungsi**:

* Business logic constants
* Role definitions dengan level mapping
* Workflow steps configuration
* Upload directories dan enum IDs

**Key Constants**:

```php
// Roles dengan level
const ADMIN_ROLES = [
    'kadmin' => ['level' => 1, 'description' => 'Ketua Admin'],
    'akredt' => ['level' => 2, 'description' => 'Admin Kredit'],
    'ketuum' => ['level' => 3, 'description' => 'Ketua Umum'],
    'atrans' => ['level' => 4, 'description' => 'Admin Transfer'],
];

// Status
const STATUS_PENDING = 'pending';
const STATUS_APPROVED = 'approve';
const STATUS_REJECTED = 'rejected';

// Jenis Pengajuan
const JENIS_PENGAJUAN_BARU = 'baru';
const JENIS_PENGAJUAN_TOP_UP = 'top_up';
```

***

## API Endpoints

### AJAX Endpoints

#### Dashboard

* `GET /dashboard/getChartData` - Dynamic chart data
  * Parameters: `dataType`, `month`, `year`
  * Response: Chart labels dan data

#### Pengajuan Pinjaman

* `POST /pengajuan-pinjaman/calculate` - Preview perhitungan cicilan
  * Parameters: `nik`, `nominal_pinjaman`, `tenor_pinjaman`
  * Response: Jadwal cicilan dan summary
* `POST /pengajuan-pinjaman/checkJenisPengajuan` - Auto-detect jenis pengajuan
  * Parameters: `nik`
  * Response: Jenis pengajuan dan eligibility data

#### Anggota

* `GET /anggota/getKaryawanData/{nik}` - Auto-fill data karyawan
  * Response: Data karyawan untuk form anggota

#### Report

* `POST /reportrekap/store/{type}` - Generate laporan
  * Parameters: Filter sesuai jenis laporan
  * Response: Success status dan redirect URL

### Export Endpoints

* `GET /export/{module}/{type}` - Export data
  * Modules: `anggota`, `pengajuan-pinjaman`, `potongan`, `shu`, `debitkredit`, `reportrekap`
  * Types: `excel`, `pdf`, `print`

***

## Database Schema

### Tabel Utama

#### mst\_anggota

**Path**: `app/Models/MstAnggota.php`

* **Primary Key**: `nik` (string, non-incrementing)
* **Table**: `mst_anggota`

**Fields**:

```php
// Personal Info
FIELD_NIK = 'nik'                           // Primary Key
FIELD_USER_ID = 'user_id'                   // Foreign Key to users table
FIELD_NAMA_LENGKAP = 'nama_lengkap'
FIELD_JENIS_KELAMIN = 'jenis_kelamin'
FIELD_TANGGAL_LAHIR = 'tanggal_lahir'      // datetime cast
FIELD_NO_TELP = 'no_telp'
FIELD_ALAMAT = 'alamat'

// Work Info
FIELD_DEPARTEMEN = 'departemen'
FIELD_JABATAN = 'jabatan'
FIELD_BAGIAN = 'bagian'
FIELD_TANGGAL_BERGABUNG = 'tanggal_bergabung'  // datetime cast

// Bank Info
FIELD_NO_REKENING = 'no_rekening'
FIELD_NAMA_BANK = 'nama_bank'
FIELD_NAMA_PEMILIK_REKENING = 'nama_pemilik_rekening'
FIELD_NO_KTP = 'no_ktp'
FIELD_FOTO_KTP = 'foto_ktp'                // File path

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(User::class)` - User account
* `hasMany(TrsPinjaman::class)` - Pinjaman anggota
* `hasMany(TrsCicilan::class)` - Cicilan anggota
* `hasMany(TrsPotongan::class)` - Potongan gaji
* `hasMany(TrsShu::class)` - SHU anggota

#### mst\_karyawan

**Path**: `app/Models/MstKaryawan.php`

* **Primary Key**: `nik` (string, non-incrementing)
* **Table**: `mst_karyawan`
* **Purpose**: Master data karyawan untuk auto-fill form anggota

**Fields**: Similar to MstAnggota (tanpa user\_id dan fields koperasi)

#### mst\_periode

**Path**: `app/Models/MstPeriode.php`

* **Primary Key**: `id` (string, non-incrementing)
* **Table**: `mst_periode`

**Fields**:

```php
FIELD_ID = 'id'                             // Generated ID
FIELD_PERIODE_PENCAIRAN = 'periode_pencairan'  // Format: MMYYYY (012025)
FIELD_ISACTIVE = 'isactive'
// System fields...
```

**Attributes**:

* `formatted_periode` - "Januari 2025"
* `tahun` - Extract tahun from periode
* `bulan` - Extract bulan from periode

#### trs\_pinjaman

**Path**: `app/Models/TrsPinjaman.php`

* **Primary Key**: `nomor_pinjaman` (string, non-incrementing)
* **Table**: `trs_pinjaman`

**Fields**:

```php
// Basic Info
FIELD_NOMOR_PINJAMAN = 'nomor_pinjaman'     // Primary Key
FIELD_NIK = 'nik'                           // Foreign Key
FIELD_TENOR_PINJAMAN = 'tenor_pinjaman'     // "12 Bulan", "24 Bulan"
FIELD_JUMLAH_PAKET_DIPILIH = 'jumlah_paket_dipilih'  // int cast
FIELD_NOMINAL_PINJAMAN = 'nominal_pinjaman' // decimal:2 cast
FIELD_BUNGA_PINJAMAN = 'bunga_pinjaman'     // decimal:2 cast
FIELD_TOTAL_PINJAMAN = 'total_pinjaman'     // decimal:2 cast
FIELD_TUJUAN_PINJAMAN = 'tujuan_pinjaman'
FIELD_JENIS_PENGAJUAN = 'jenis_pengajuan'   // 'baru' | 'top_up'

// Approval Workflow
FIELD_STATUS_APPROVAL = 'status_approval'   // 'pending' | 'approve' | 'rejected'
FIELD_LEVEL_APPROVAL = 'level_approval'     // '0', '1', '2', '3'
FIELD_CATATAN_APPROVAL = 'catatan_approval'
FIELD_TANGGAL_PENGAJUAN = 'tanggal_pengajuan'  // datetime cast
FIELD_TANGGAL_APPROVAL = 'tanggal_approval'    // datetime cast

// Transfer Info
FIELD_PERIODE = 'periode_pencairan'         // MMYYYY format
FIELD_NOMINAL_TRANSFER = 'nominal_transfer' // decimal:2 cast
FIELD_BUKTI_TRANSFER = 'bukti_transfer'     // File path
FIELD_TANGGAL_TRANSFER = 'tanggal_transfer' // datetime cast
FIELD_CATATAN_TRANSFER = 'catatan_transfer'

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(MstAnggota::class)` - Anggota peminjam
* `hasMany(TrsCicilan::class)` - Jadwal cicilan
* `hasMany(TrsPelunasan::class)` - Pelunasan pinjaman

#### trs\_cicilan

**Path**: `app/Models/TrsCicilan.php`

* **Composite Key**: `[nomor_pinjaman, nik, periode, angsuran_ke]`
* **Table**: `trs_cicilan`

**Fields**:

```php
// Composite Primary Key
FIELD_NOMOR_PINJAMAN = 'nomor_pinjaman'
FIELD_NIK = 'nik'
FIELD_PERIODE = 'periode'                   // MMYYYY format
FIELD_ANGSURAN_KE = 'angsuran_ke'           // int cast

// Cicilan Details
FIELD_TANGGAL_JATUH_TEMPO = 'tanggal_jatuh_tempo'  // date cast
FIELD_NOMINAL_POKOK = 'nominal_pokok'       // float cast
FIELD_BUNGA_RP = 'bunga_rp'                 // float cast
FIELD_TOTAL_ANGSURAN = 'total_angsuran'     // float cast

// Payment Status
FIELD_TANGGAL_BAYAR = 'tanggal_bayar'       // datetime cast
FIELD_ISBAYAR = 'isbayar'                   // '0' = unpaid, '1' = paid
FIELD_TOTAL_BAYAR = 'total_bayar'           // float cast

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(MstAnggota::class)` - Anggota
* `belongsTo(TrsPinjaman::class)` - Pinjaman induk

**Special Methods**:

* `getKey()` - Handle composite primary key
* `setKeysForSaveQuery()` - Query builder untuk composite key

#### trs\_potongan

**Path**: `app/Models/TrsPotongan.php`

* **Composite Key**: `[periode, nik]`
* **Table**: `trs_potongan`

**Fields**:

```php
// Composite Primary Key
FIELD_PERIODE = 'periode'                   // MMYYYY format
FIELD_NIK = 'nik'

// Potongan Details
FIELD_ANGSURAN_KE = 'angsuran_ke'           // integer cast
FIELD_SIMPANAN = 'simpanan'                 // decimal:2 cast
FIELD_CICILAN_PINJAMAN = 'cicilan_pinjaman' // decimal:2 cast
FIELD_TOTAL_POTONGAN = 'total_potongan'     // decimal:2 cast
FIELD_KETERANGAN = 'keterangan'

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(MstAnggota::class)` - Anggota

**Special Methods**:

* `getKey()` - Handle composite primary key
* `setKeysForSaveQuery()` - Query builder untuk composite key

#### trs\_shu

**Path**: `app/Models/TrsShu.php`

* **Primary Key**: `id` (auto-increment)
* **Unique Key**: `[periode, nik]`
* **Table**: `trs_shu`

**Fields**:

```php
FIELD_ID = 'id'                             // Auto-increment primary key
FIELD_PERIODE = 'periode'                   // YYYY format (2025)
FIELD_NIK = 'nik'

// SHU Calculation
FIELD_SIMPANAN_TOTAL = 'simpanan_total'     // float cast
FIELD_BUNGA_TOTAL = 'bunga_total'           // float cast
FIELD_HASIL_PERSEN_SIMPANAN = 'hasil_persen_simpanan'  // float cast
FIELD_HASIL_PERSEN_BUNGA = 'hasil_persen_bunga'        // float cast
FIELD_TOTAL_SHU = 'total_shu'               // float cast

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(MstAnggota::class)` - Anggota penerima SHU

#### trs\_debitkredit

**Path**: `app/Models/TrsDebitKredit.php`

* **Primary Key**: `id_transaksi` (string, non-incrementing)
* **Table**: `trs_debitkredit`

**Fields**:

```php
FIELD_ID_TRANSAKSI = 'id_transaksi'         // Generated ID (DEB/KRE prefix)
FIELD_TANGGAL = 'tanggal'                   // date cast
FIELD_TYPE = 'type'                         // 'debit' | 'kredit'
FIELD_NOMINAL = 'nominal'                   // float cast
FIELD_KETERANGAN = 'keterangan'
FIELD_BUKTI_FOTO = 'bukti_foto'             // File path

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Business Logic**: Auto-update paket stock saat create/update/delete

#### trs\_pelunasan

**Path**: `app/Models/TrsPelunasan.php`

* **Primary Key**: `id_transaksi` (string, non-incrementing)
* **Table**: `trs_pelunasan`

**Fields**:

```php
FIELD_ID_TRANSAKSI = 'id_transaksi'         // Generated ID (LNS prefix)
FIELD_NOMOR_PINJAMAN = 'nomor_pinjaman'     // Foreign Key
FIELD_NIK = 'nik'                           // Foreign Key
FIELD_PERIODE = 'periode'                   // MMYYYY format
FIELD_NOMINAL = 'nominal'                   // decimal:2 cast
FIELD_BUKTI = 'bukti'                       // File path
FIELD_STS = 'sts'                           // 'pending' | 'approve' | 'rejected'

// System Fields
FIELD_ISACTIVE = 'isactive'
FIELD_CREATED_AT = 'created_at'
FIELD_UPDATED_AT = 'updated_at'
FIELD_USER_CREATE = 'user_create'
FIELD_USER_UPDATE = 'user_update'
```

**Relations**:

* `belongsTo(MstAnggota::class)` - Anggota
* `getCicilanAttribute()` - Get specific cicilan record

### Tabel Master MSJ Framework

#### sys\_table

* Configuration untuk form fields dan validation rules
* Digunakan oleh ValidationHelper untuk dynamic validation

#### sys\_id

* Configuration untuk ID generation
* Digunakan oleh IdGenerator untuk auto-numbering

#### sys\_enum

* Master data untuk dropdown dan constants
* Digunakan oleh EnumValues helper

#### sys\_counter

* Counter untuk ID generation
* Auto-increment per lookup pattern

***

## Models & Relationships

### Model Overview

Aplikasi ini menggunakan 10 model utama dengan berbagai relationship:

```
User (Authentication)
  └── hasOne → MstAnggota

MstKaryawan (Master Data)
  └── (Reference only - tidak ada FK)

MstAnggota (Master)
  ├── hasMany → TrsPinjaman
  ├── hasMany → TrsCicilan
  ├── hasMany → TrsPotongan
  ├── hasMany → TrsShu
  └── hasMany → TrsPelunasan

TrsPinjaman (Transactions)
  ├── belongsTo → MstAnggota
  ├── hasMany → TrsCicilan
  └── hasMany → TrsPelunasan

TrsCicilan (Transactions)
  ├── belongsTo → MstAnggota
  └── belongsTo → TrsPinjaman

TrsPotongan (Transactions)
  └── belongsTo → MstAnggota

TrsShu (Transactions)
  └── belongsTo → MstAnggota

TrsDebitKredit (Transactions)
  └── (Standalone)

TrsPelunasan (Transactions)
  ├── belongsTo → MstAnggota
  └── belongsTo → TrsPinjaman
```

### Key Relationships

```php
// Eager loading untuk performa
$anggota = MstAnggota::with(['trs_pinjamans', 'trs_cicilans', 'user'])->find($nik);

// Get pinjaman dengan cicilan
$pinjaman = TrsPinjaman::with('trs_cicilans')->find($nomorPinjaman);

// Get cicilan belum bayar
$unpaidCicilan = TrsCicilan::where('nomor_pinjaman', $nomorPinjaman)
    ->where('isbayar', '0')
    ->orderBy('periode')
    ->get();
```

***

## Security & Authorization

### Authentication

Aplikasi menggunakan Laravel's built-in authentication dengan session-based login:

```php
// Login process
Auth::attempt(['username' => $username, 'password' => $password])

// Check authentication
if (Auth::check()) {
    // User is authenticated
}

// Get current user
$user = Auth::user();
```

### Authorization

Authorization menggunakan MSJ Framework's role-based system:

```php
// Check user role
if ($user->role === KoperasiConstants::ROLE_ADMIN_KREDIT) {
    // Admin kredit specific actions
}

// MSJBaseController provides helper methods
$this->getUsername();  // Get current username
$this->getUserRole();  // Get current user role
$this->isAdmin();      // Check if user is admin
```

### Data Access Control

```php
// Role-based data filtering
if ($userRole === KoperasiConstants::ROLE_ANGGOTA) {
    // Anggota hanya bisa lihat data sendiri
    $query->where('nik', $userNik);
} elseif (in_array($userRole, [KoperasiConstants::ROLE_ADMIN_KREDIT, ...])) {
    // Admin bisa lihat semua data
}
```

### File Upload Security

```php
// Validasi file upload
$rules = [
    'foto_ktp' => 'required|image|mimes:jpeg,png,jpg|max:2048',
    'bukti_transfer' => 'required|file|mimes:jpeg,png,jpg,pdf|max:5120'
];

// Secure file storage
$path = $request->file('foto_ktp')->store(KoperasiConstants::UPLOAD_DIR_ANGGOTA);
```

### CSRF Protection

Semua form dan AJAX request dilindungi dengan CSRF token:

```blade
<!-- Blade form -->
@csrf

<!-- JavaScript AJAX -->
<script>
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
</script>
```

***

## File Structure

### Application Structure

```
MSJ-Koperasi/
├── app/
│   ├── Console/
│   │   └── Kernel.php
│   ├── Exceptions/
│   │   └── Handler.php
│   ├── Helpers/
│   │   ├── Format_Helper.php
│   │   ├── Function_Helper.php
│   │   └── Koperasi/              # 40+ helper files
│   │       ├── ValidationHelper.php
│   │       ├── ResponseHelper.php
│   │       ├── PaketHelper.php
│   │       ├── ApprovalHistoryHelper.php
│   │       ├── ErrorHelper.php
│   │       ├── Anggota/
│   │       │   ├── AnggotaHelper.php
│   │       │   ├── SimpananHelper.php
│   │       │   └── AnggotaEligibilityHelper.php
│   │       ├── Constants/
│   │       │   ├── KoperasiConstants.php
│   │       │   └── EnumValues.php
│   │       ├── Dashboard/
│   │       │   ├── StatsHelper.php
│   │       │   ├── ChartHelper.php
│   │       │   └── CalculationHelper.php
│   │       ├── Generator/
│   │       │   ├── IdGenerator.php
│   │       │   ├── CicilanGenerator.php
│   │       │   └── PotonganGenerator.php
│   │       ├── Pengajuan/
│   │       │   ├── PinjamanRepositories.php
│   │       │   ├── ApprovalHelper.php
│   │       │   ├── TransferHelper.php
│   │       │   └── ValidationHelper.php
│   │       ├── Pelunasan/
│   │       │   └── PelunasanHelper.php
│   │       ├── Periode/
│   │       ├── Potongan/
│   │       │   └── PotonganHelper.php
│   │       ├── Report/
│   │       │   ├── ShuReport.php
│   │       │   ├── PinjamanReport.php
│   │       │   ├── PotonganReport.php
│   │       │   └── DebitKreditReport.php
│   │       └── View/
│   │           └── FormOptionsHelper.php
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Controller.php
│   │   │   ├── MSJBaseController.php
│   │   │   ├── AnggotaController.php
│   │   │   ├── DashboardController.php
│   │   │   ├── DebitkreditController.php
│   │   │   ├── LoginController.php
│   │   │   ├── PageController.php
│   │   │   ├── PelunasanController.php
│   │   │   ├── PelunasanmanualController.php
│   │   │   ├── PengajuanPinjamanController.php
│   │   │   ├── PeriodeController.php
│   │   │   ├── PotonganController.php
│   │   │   ├── ReportrekapController.php
│   │   │   ├── ShuController.php
│   │   │   └── Api/
│   │   │       └── AccessController.php
│   │   └── Middleware/
│   │       ├── Authenticate.php
│   │       └── VerifyCsrfToken.php
│   ├── Models/
│   │   ├── User.php
│   │   ├── MstAnggota.php
│   │   ├── MstKaryawan.php
│   │   ├── MstPeriode.php
│   │   ├── TrsCicilan.php
│   │   ├── TrsDebitKredit.php
│   │   ├── TrsPelunasan.php
│   │   ├── TrsPinjaman.php
│   │   ├── TrsPotongan.php
│   │   └── TrsShu.php
│   ├── Rules/
│   │   ├── MemberEligibilityRule.php
│   │   ├── NoPendingApplicationRule.php
│   │   └── TopUpEligibilityRule.php
│   └── View/
│       └── Components/
│           └── Alert.php
├── config/
│   ├── app.php
│   ├── database.php
│   ├── auth.php
│   └── ...
├── database/
│   ├── factories/               # 10 factory files
│   ├── migrations/              # 35+ migration files
│   └── seeders/                 # 25+ seeder files
│       ├── DatabaseSeeder.php
│       ├── KoperasiMenuSeeder.php
│       ├── KoperasiEnumSeeder.php
│       ├── KoperasiTableSeeder.php
│       ├── KoperasiDataSeeder.php
│       └── ...
├── public/
│   ├── assets/
│   │   ├── css/
│   │   ├── js/
│   │   └── fonts/
│   └── img/
├── resources/
│   ├── css/
│   ├── js/
│   │   ├── app.js
│   │   └── custom.js
│   ├── scss/
│   └── views/
│       ├── auth/
│       ├── components/
│       ├── js/                  # JavaScript per module
│       ├── KOP001/, KOP002/, KOP004/, KOP006/
│       ├── layouts/
│       ├── master/, standr/, sublnk/, system/, transc/
│       └── pages/
├── routes/
│   ├── web.php
│   ├── api.php
│   ├── channels.php
│   └── console.php
├── storage/
│   ├── app/
│   │   └── public/
│   │       └── uploads/         # File uploads
│   ├── framework/
│   └── logs/
├── tests/
│   ├── Feature/
│   │   └── Controllers/         # 7 controller tests
│   └── Unit/
│       ├── Helpers/
│       ├── Models/              # 10 model tests
│       ├── Rules/               # 3 rule tests
│       └── Services/
├── .env.example
├── artisan
├── composer.json
├── package.json
├── phpunit.xml
├── vite.config.js
├── README.md
├── documentation.md
└── how.md
```

### Key Directories

* **app/Helpers/Koperasi**: 40+ helper classes untuk business logic
* **app/Http/Controllers**: 20+ controllers untuk berbagai modules
* **app/Models**: 10 Eloquent models dengan relationships
* **app/Rules**: 3 custom validation rules
* **database/seeders**: 25+ seeders untuk initial data
* **resources/views**: 100+ Blade templates
* **tests**: 45+ test files untuk quality assurance

***

## Cara Penggunaan

Untuk panduan lengkap cara menggunakan semua komponen dalam aplikasi Laravel Koperasi, silakan lihat file [**HOW.md**](how.md).

File HOW.md berisi:

* **Validation Rules** - Custom rules untuk business logic (MemberEligibilityRule, TopUpEligibilityRule, NoPendingApplicationRule)
* **Helper Classes** - Utility classes untuk berbagai fungsi (ValidationHelper, ResponseHelper, PaketHelper, dll)
* **Generator Classes** - Auto-generate data dan ID (IdGenerator, CicilanGenerator, PotonganGenerator)
* **Business Logic Helpers** - Logic khusus koperasi (AnggotaHelper, PengajuanPinjamanHelper, dll)
* **Report Helpers** - Generate berbagai laporan (ShuReport, PinjamanReport, dll)
* **Controller Examples** - Contoh penggunaan dalam controller dengan best practices
* **Frontend Integration** - AJAX calls dan JavaScript integration
* **Constants Usage** - Penggunaan konstanta sistem (KoperasiConstants)
* **Model Relationships** - Cara menggunakan relasi model dengan Eloquent
* **Testing** - Cara menulis dan menjalankan tests (45+ test files)
* **Best Practices** - Code organization, error handling, validation, dan database queries
* **Troubleshooting** - Common issues dan debugging tips
* **Deployment** - Pre-deployment checklist dan environment configuration

***

## Changelog

### Version 1.0 (2025)

**Initial Release**:
- ✅ Manajemen Anggota dengan integrasi master karyawan
- ✅ Pengajuan Pinjaman dengan multi-level approval
- ✅ Auto-generate Cicilan dengan perhitungan bunga
- ✅ Pelunasan manual dengan approval workflow
- ✅ Generate Potongan Gaji otomatis per periode
- ✅ Perhitungan dan distribusi SHU
- ✅ Manajemen Debit Kredit dengan stock paket
- ✅ Dashboard multi-role dengan charts
- ✅ Laporan dengan filter dan export Excel/PDF
- ✅ 45+ Test files untuk quality assurance
- ✅ Comprehensive documentation dalam Bahasa Indonesia

**Technical Highlights**:
- Laravel 12 dengan PHP 8.2+
- MSJ Framework v1.1+ integration
- 40+ Helper classes untuk business logic
- 10 Eloquent models dengan relationships
- 3 Custom validation rules
- 25+ Database seeders
- 100+ Blade templates
- RESTful API endpoints
- AJAX-powered interactions

***

## Kontribusi

### Development Team

- **Lead Developer**: Reynald Silva (@reysilvaa)
- **Core Developer**: Faiq Ramzy (@FaiqRN)

### Code Standards

- Follow Laravel best practices
- Use PSR-12 coding standards
- Write unit tests untuk new features
- Update documentation untuk changes
- Use Laravel Pint untuk code formatting

### Contribution Workflow

```bash
# 1. Fork dan clone repository
git clone https://github.com/your-username/MSJ-Koperasi.git

# 2. Create feature branch
git checkout -b feature/your-feature-name

# 3. Make changes dan test
php artisan test

# 4. Format code
./vendor/bin/pint

# 5. Commit dan push
git commit -m "Add: your feature description"
git push origin feature/your-feature-name

# 6. Create pull request
```

***

## Support & Contact

Untuk pertanyaan, issue, atau feature request:

- **GitHub**: Repository issues (jika tersedia)
- **Email**: Development team email
- **Documentation**: Lihat [HOW.md](how.md) untuk usage guide

***

**Last Updated**: 2025  
**Version**: 1.0  
**Framework**: Laravel 12 + MSJ Framework v1.1+  
**License**: MIT (atau sesuai license proyek)  
**Maintained by**: MSJ Development Team
