# Blueprint & Design Arsitektur: Penyetaraan Varian Supplies & Produksi Bervarian (Multi-Variant BOM)

**Tanggal:** 2026-07-27  
**Status:** Design Proposal & Implementation Blueprint  

---

## 📌 1. Penyetaraan Varian Supplies (Bahan Penolong) ke Modul-Modul Inventory

### 🎯 Tujuan
Menyelaraskan penanganan **Supplies Bervarian** (Bahan Penolong) agar memiliki standar arsitektur dan flow dual-write yang setara 100% dengan **Produk Utama Bervarian (Finished Goods)**.

### 🗂️ Modul Target & Rencana Penyetaraan

| No | Modul Target | Jenis Item | Handler & Model yang Ditingkatkan | Catatan Penyetaraan |
|:---:|:---|:---|:---|:---|
| 1 | `biaya` | Supplies / Biaya Penolong | `_processSelectSupplies.php` $\rightarrow$ `ComLockerStockSuppliesDualWrite` | Penambahan variant picker supplies & hold/active locker dual-write. |
| 2 | `distribusisupplies` | Supplies Transfer | `_processSelectSupplies.php` $\rightarrow$ `ComLockerStockSuppliesDualWrite` | Transfer stok varian supplies antar gudang/cabang. |
| 3 | `pembelian` | Purchase Order Supplies | `_processSelectSupplies.php` $\rightarrow$ `ComLockerStockSuppliesDualWrite` | Pembelian bahan penolong bervarian dari supplier. |
| 4 | `produksi` & `produksiproses` | Material & Supplies Consumed | `_processSelectSupplies.php` $\rightarrow$ `ComLockerStockSuppliesDualWrite` | Konsumsi supplies sebagai penolong proses manufaktur. |
| 5 | `opname` | Opname Supplies | `Opname.php` $\rightarrow$ `stock_locker_supplies_variant` | Penyesuaian fisik persediaan supplies bervarian. |

### 🔑 Format Session Cart Key Supplies
- **Bervarian:** `supplies:{supplies_id}:{variant_id}` (contoh: `supplies:405:8`).
- **Non-Varian:** `supplies_id` polos dengan fallback `variant_id = 1` (Sentinel Fix).

---

## 📌 2. Desain Arsitektur Produksi Bervarian (Multi-Variant BOM / Bill of Materials)

### ❓ Tantangan Bisnis
Saat pengguna memproduksi barang bervarian, terdapat 2 pola kebutuhan komposisi (BOM/Formula):
1. **Kasus A (Komposisi SAMA):** Varian Merah, Biru, Hijau menggunakan bahan baku dan jumlah yang sama persis (hanya warna bahan beda).
2. **Kasus B (Komposisi BERBEDA):** Varian Ukuran Small vs Jumbo / 2 Pintu vs 3 Pintu membutuhkan takaran bahan baku & penolong yang berbeda.

---

### 💡 Solusi Desain yang "Tidak Membingungkan": Pattern *Inherit-or-Override*

Untuk mencegah pengguna harus menginput formula berulang kali untuk 20 varian yang mayoritas komposisinya sama, kita menggunakan prinsip **Inherit-or-Override (Formula Induk + Mode Override Varian)**.

```
                   ┌─────────────────────────────────────────┐
                   │    FORMULA INDUK (GLOBAL BOM)           │
                   │    variant_id = 0                       │
                   │    (Default untuk semua varian)        │
                   └────────────────────┬────────────────────┘
                                        │
                         ┌──────────────┴──────────────┐
                         ▼                             ▼
         ┌───────────────────────────────┐  ┌───────────────────────────────┐
         │ VARIAN A (Merah-S)            │  │ VARIAN B (Jumbo-XL)           │
         │ [ ] Override Formula = FALSE  │  │ [x] Override Formula = TRUE   │
         │                               │  │                               │
         │ ➔ Menggunakan Formula Induk   │  │ ➔ Menggunakan Formula Khusus  │
         │   (Auto Inherit)              │  │   Varian B (Variant Override) │
         └───────────────────────────────┘  └───────────────────────────────┘
```

---

### 🗄️ Skema Tabel Database BOM Produksi Varian

#### 1. Tabel Master BOM (`produksi_bom`)
```sql
CREATE TABLE produksi_bom (
    id INT AUTO_INCREMENT PRIMARY KEY,
    produk_id INT NOT NULL,                     -- ID Produk Induk Finished Goods
    variant_id INT NOT NULL DEFAULT 0,          -- 0 = Formula Global/Induk, >0 = Formula Khusus Varian Spesifik
    nama_formula VARCHAR(255) NOT NULL,
    deskripsi TEXT,
    is_active TINYINT(1) DEFAULT 1,
    dtime DATETIME DEFAULT CURRENT_TIMESTAMP,
    oleh_id INT DEFAULT 0,
    INDEX idx_produk_variant (produk_id, variant_id)
);
```

#### 2. Tabel Rincian Bahan BOM (`produksi_bom_detail`)
```sql
CREATE TABLE produksi_bom_detail (
    id INT AUTO_INCREMENT PRIMARY KEY,
    bom_id INT NOT NULL,                        -- FK ke produksi_bom.id
    item_type ENUM('produk', 'supplies') NOT NULL DEFAULT 'produk',
    item_id INT NOT NULL,                       -- ID Produk (Bahan Baku) atau Supplies (Bahan Penolong)
    item_variant_id INT NOT NULL DEFAULT 1,     -- ID Varian Bahan (Default 1 jika non-varian)
    qty DECIMAL(24,10) NOT NULL DEFAULT 1.0,    -- Jumlah kebutuhan per 1 unit FG
    satuan VARCHAR(32) NOT NULL,
    keterangan VARCHAR(255),
    INDEX idx_bom (bom_id)
);
```

---

### ⚙️ Alur Kerja Sistem (Workflow Resolution) saat Membuat SPK Produksi:

1. User memilih Produk Induk & Varian yang hendak diproduksi (misal: Produksi 50 unit `ALPEN B28D - Ukuran XL`).
2. Sistem menjalankan query resolution resolution order:
   ```sql
   -- Langkah A: Cek Formula Khusus Varian
   SELECT * FROM produksi_bom 
   WHERE produk_id = 1625 AND variant_id = 14 AND is_active = 1 
   LIMIT 1;

   -- Langkah B: Jika Langkah A Kosong, Cek Formula Global Induk
   SELECT * FROM produksi_bom 
   WHERE produk_id = 1625 AND variant_id = 0 AND is_active = 1 
   LIMIT 1;
   ```
3. Rincian bahan baku & penolong dari BOM yang ditemukan langsung otomatis mengisi form SPK Produksi.
4. User **tidak perlu bingung** memilih formula secara manual; sistem otomatis memilih komposisi yang paling presisi!

---

### 🎨 Antarmuka UI Form BOM (User Acceptance Flow):

- Pada Menu Master Produk / Formula Produksi:
  - Terdapat tab **"Formula Produksi (BOM)"**.
  - Dropdown Pilihan Varian: `[ Global (Semua Varian) ]` | `[ Varian: Ukuran XL ]` | `[ Varian: Ukuran S ]`.
  - Jika user memilih varian spesifik, tombol **"Copy dari Formula Global"** tersedia agar user tidak perlu mengetik dari awal!
