# Blueprint Refactoring: Modul Pembelian (Create.php)

Dokumen ini adalah *blueprint* dan *checklist* strategis untuk mengurai (*decouple*) logika bisnis dari *Controller* `Create.php` menuju lapisan *Service/Library* dan *Helper*. Mengikuti prinsip **Thin Controller - Fat Service** (AGENTS.md §4), **Single Responsibility Principle** (SOLID/SRP), dan standar pemeliharaan kode **ISO/IEC 25010** (Maintainability: Modularity, Reusability, Analysability, Modifiability).

## Profil File Saat Ini

| Metrik | Nilai |
|--------|-------|
| **Total Baris Awal** | ~9.480 |
| **Total Baris Sekarang** | ~7.000 (setelah save() diekstrak) |
| **Total Method** | 11 (semua public) |
| **Lokasi** | `application/modules/pembelian/controllers/Create.php` |

## Peta Seluruh Method

| # | Nama Method | ± Ukuran | Domain Fungsional | Target Pemindahan |
|---|-------------|----------|--------------------|--------------------|
| 1 | `__construct()` | 38 | Inisialisasi | **TETAP** di Controller |
| 2 | `index()` | 511 | UI / Form | Bagian UI → Helper |
| 3 | `preview()` | 532 | Simpan (Preview) | `LibPembelianCreateSave` |
| 4 | `save()` | ✅ Sudah | Simpan (Eksekusi) | `LibPembelianCreateSave` ✅ |
| 5 | `viewIncompleteStepAntarCabang()` | 175 | Laporan | Evaluasi (< 200 baris) |
| 6 | `recordColumn()` | 80 | Utilitas | **TETAP** di Controller |
| 7 | `editPreview()` | 302 | Edit (Preview) | `LibPembelianCreateEdit` |
| 8 | `doEdit()` | 2.445 | Edit (Eksekusi) | `LibPembelianCreateEdit` |
| 9 | `preCancelPackingPreview()` | 273 | Batal (Preview) | `LibPembelianCreateCancel` |
| 10 | `doPreCancelPacking()` | 2.387 | Batal (Eksekusi) | `LibPembelianCreateCancel` |
| 11 | `swapFrom()` | 162 | Utilitas | **TETAP** di Controller |

## Arsitektur Target

```
application/modules/pembelian/
├── controllers/
│   └── Create.php                        (~400 baris, murni delegasi)
├── helpers/
│   └── he_pembelian_ui_helper.php        (✅ sudah dibuat, UI builder)
└── libraries/
    ├── LibPembelianCreateSave.php         (save + preview)
    ├── LibPembelianCreateEdit.php         (doEdit + editPreview)
    └── LibPembelianCreateCancel.php       (doPreCancelPacking + preCancelPackingPreview)
```

### Prinsip Pengelompokan Library (SRP)
Setiap file Library menampung **satu domain fungsional** yang terdiri dari pasangan:
- **Method Eksekusi** (`save`, `doEdit`, `doPreCancelPacking`) — logika bisnis berat.
- **Method Preview** (`preview`, `editPreview`, `preCancelPackingPreview`) — komputasi & rendering pra-eksekusi.

Pasangan ini **selalu diubah bersama-sama** saat ada perubahan logika bisnis (misal: penambahan field variant), sehingga menempatkannya dalam satu file meminimalkan jumlah file yang harus disentuh (*change locality*).

---

## 📋 Checklist Eksekusi Bertahap

### Fase 0: Persiapan — Rename Library yang Sudah Ada ✅→🔄
Library `LibPembelianCreate.php` (hasil Fase 1 lama) perlu di-rename agar konsisten dengan penamaan baru.
- [ ] Rename `LibPembelianCreate.php` → `LibPembelianCreateSave.php`
- [ ] Sesuaikan nama class di dalamnya: `class LibPembelianCreateSave`
- [ ] Update pemanggilan di `Create.php`: `$this->load->library("LibPembelianCreateSave")`
- [ ] Tambahkan DocBlock pada class

### Fase 1: Domain Save — Tambah `preview()` ke `LibPembelianCreateSave`
- [ ] Pindahkan isi `preview()` (±532 baris) ke `LibPembelianCreateSave->processPreview($c)`
- [ ] Konversi `$this->` → `$c->`
- [ ] Delegasi di `Create.php`
- [ ] Tambahkan DocBlock

### Fase 2: Domain Edit — Buat `LibPembelianCreateEdit.php` 🔴
- [ ] Buat file `LibPembelianCreateEdit.php`
- [ ] Pindahkan isi `doEdit()` (±2.445 baris) ke `processDoEdit($c)`
- [ ] Pindahkan isi `editPreview()` (±302 baris) ke `processEditPreview($c)`
- [ ] Konversi `$this->` → `$c->`
- [ ] Delegasi di `Create.php`
- [ ] Uji coba edit transaksi

### Fase 3: Domain Cancel — Buat `LibPembelianCreateCancel.php` 🔴
- [ ] Buat file `LibPembelianCreateCancel.php`
- [ ] Pindahkan isi `doPreCancelPacking()` (±2.387 baris) ke `processDoPreCancelPacking($c)`
- [ ] Pindahkan isi `preCancelPackingPreview()` (±273 baris) ke `processPreCancelPackingPreview($c)`
- [ ] Konversi `$this->` → `$c->`
- [ ] Delegasi di `Create.php`
- [ ] Uji coba pembatalan

### Fase 4: Evaluasi & Pembersihan 🟢
- [ ] Evaluasi `index()` (511 baris) — apakah masih ada blok UI yang bisa dipindah ke `he_pembelian_ui_helper.php`
- [ ] Evaluasi `viewIncompleteStepAntarCabang()` (175 baris) — tetap atau pindah
- [ ] `recordColumn()` (80 baris) dan `swapFrom()` (162 baris) → **tetap di controller**
- [ ] `__construct()` → **tetap di controller**

---

## Proyeksi Hasil Akhir

| File | Sebelum | Sesudah |
|------|---------|---------|
| `Create.php` | ~9.480 baris | **~400 baris** |
| `LibPembelianCreateSave.php` | - | ~3.000 baris |
| `LibPembelianCreateEdit.php` | - | ~2.750 baris |
| `LibPembelianCreateCancel.php` | - | ~2.660 baris |
| `he_pembelian_ui_helper.php` | ✅ | ~200 baris |

---

## 🛠 Panduan Teknis

### Metodologi Pemindahan (Safe Refactoring)
1. **Pemotongan (Cut):** Salin seluruh *body* dari fungsi di Controller. Jangan hapus deklarasi `public function`.
2. **Penempelan (Paste):** Buat *public function* baru di Library dengan parameter `$c`. Letakkan *body* di dalamnya.
3. **Regex Terukur (Replace):** Ganti semua `$this->` → `$c->` HANYA di dalam blok fungsi yang baru dipindah. Hati-hati dengan string literal di dalam query.
4. **Sambungkan (Wire-up):** Pada Controller, isi method yang kosong:
   ```php
   $this->load->library("LibPembelianCreateSave");
   $this->libpembeliancreatesave->processSave($this);
   ```
5. **Dokumentasi:** DocBlock wajib di Library + Tombstone comment di Controller.

### Aturan Batasan Pemecahan File
| Aturan | Batas |
|--------|-------|
| Maks baris per file Library | ~5.000 - 8.000 baris |
| Min baris untuk dipecah | < 1.000 baris → gabung ke domain terdekat |
| Kriteria pengelompokan | Domain fungsional (Save/Edit/Cancel) |
| Penamaan | `Lib[Modul][Controller][Domain].php` |
| Method < 200 baris | Tetap di Controller (tidak perlu diekstrak) |
