# Master Plan Migrasi Produk Varian (Holding <-> Subsidiary)

## Versi Dokumen
1. Tanggal update: 2026-04-27
2. Workspace sumber: `W:\san_varian` (holding)
3. Workspace target pilot: `W:\san_sarana_8apr` (subsidiary)
4. Database holding: `san_13mar`
5. Database subsidiary pilot: `san_sarana_18feb`

## Tujuan Bisnis
1. Menjamin proses transaksi varian berjalan end-to-end untuk `pembelian`, `distribusi`, dan `penjualan`.
2. Menjaga integritas stok, accounting, approval, laporan, dan audit pada sistem ERP legacy.
3. Menyediakan paket migrasi yang bisa direplikasi ke subsidiari lain (`san_add`, `san_ppu`, `san_sdl`, `san_tsa`) dengan langkah konsisten.

## Guardrail Teknis
1. Kompatibilitas wajib: PHP 5.6, CodeIgniter 3, MariaDB 10, CentOS 7.
2. Tidak gunakan syntax PHP 7/8.
3. Tidak membaca/mengubah file controller berawalan `__`.
4. Tidak membaca/mengubah file `*_OLD.php`.
5. Tidak mengambil referensi dari folder `trash`.
6. Jalur non-varian harus tetap stabil.

## Baseline Kondisi Saat Ini
### Kode yang Sudah Ada di Subsidiary (`san_sarana_8apr`)
1. Shared layer varian sudah tersedia:
   - `application/models/Mdls/MdlProdukVarian.php`
   - `application/models/Mdls/MdlLockerStockVarian.php`
   - `application/models/Mdls/MdlLockerStockMutasiVarian.php`
   - `application/models/Mdls/MdlFifoProdukJadiVarian.php`
   - `application/models/Coms/ComLockerStockVarian.php`
   - `application/models/Coms/ComFifoProdukJadiVarian.php`
   - `application/models/Coms/ComRekeningPembantuProdukVarian.php`
2. `MdlProdukVarian` sudah memiliki:
   - `find_selector_row()`
   - `get_picker_rows()`
   - `search_selector_rows()`
3. Jalur model transaksi `Mdl{Modul}Transaksi` pada `pembelian/distribusi/penjualan` sudah memuat field `variant_*` dan `cart_key`.
4. `pembelian/CliTransaksi` sudah ada hardening untuk skenario CRM varian vs non-varian.

### Skema DB yang Sudah Ada di Subsidiary (`san_sarana_18feb`)
1. Tabel varian stok/accounting sudah ada:
   - `stock_locker_varian`
   - `stock_locker_mutasi_varian`
   - `_rek_pembantu_produk_varian`
   - `_rek_pembantu_produk_varian_cache`
   - `rek_cache_persediaan_produk_varian_fifo`
2. Kolom master produk varian sudah ada:
   - `produk.has_variants`
   - `produk.variant_price_mode`
3. Tabel detail transaksi utama sudah punya kolom `variant_*`:
   - `pembelian_transaksi_data`
   - `distribusi_transaksi_data`
   - `penjualan_transaksi_data_bridge`
   - `penjualan_transaksi_data_crm_bridge`

### Gap Kritis yang Masih Tersisa
1. Tabel bridge pembelian belum punya kolom varian:
   - `pembelian_transaksi_bridge`
   - `pembelian_transaksi_bridge_terima`
2. Endpoint API holding untuk bridge/packing list masih belum full membawa kontrak varian.
3. Gap perilaku UI/UX masih mungkin muncul pada:
   - selector varian vs non-varian
   - default radio PPN pada cart
   - input harga item varian saat mode harga tertentu
   - preview/history/printing yang harus sinkron dengan data detail
4. `price_per_supplier` masih berbasis `produk_id` saja, sehingga perlu kebijakan jelas untuk sumber harga varian di subsidiary.

## Dampak Lintas Modul
1. `pembelian` terdampak paling awal karena menjadi jalur masuk PO dari CRM/bridge.
2. `distribusi` terdampak pada alur pemindahan dan posting stok varian.
3. `penjualan` terdampak pada preview/followup/printing dan sinkron bridge CRM.
4. `API ModulConnect` holding-subsidiary terdampak pada kontrak payload dan dedupe line item.

## Rencana Eksekusi Fase-1 (Disetujui untuk Dijalankan)
## Fase 0 - Freeze Baseline
1. Ambil snapshot file konfigurasi dan endpoint untuk ketiga modul.
2. Ambil precheck schema sebelum patch.
3. Definisikan `version stamp` paket migrasi, contoh: `variant-f1-20260427`.

Output:
1. `application/sql/variant_migration/precheck_*.sql`
2. `application/sql/variant_migration/postcheck_*.sql`
3. Catatan hasil precheck per instance.

## Fase 1 - Kontrak API Holding <-> Subsidiary
Target file holding:
1. `W:\san_varian\application\modules\penjualan\controllers\API\ModulConnect.php`

Target file subsidiary:
1. `W:\san_sarana_8apr\application\modules\penjualan\controllers\API\ModulConnect.php`

Pekerjaan:
1. Samakan kontrak payload line item varian:
   - `variant_id`
   - `variant_sku`
   - `variant_label`
   - `variant_key`
   - `cart_key`
2. Pastikan endpoint packing list/bridge mengembalikan varian secara eksplisit.
3. Pastikan dedupe update bridge berbasis kombinasi aman:
   - minimal `produk_id + variant_id + cart_key` (bila tersedia).

Risiko jika dilewati:
1. Item beda varian bisa collapse menjadi satu baris.
2. Proses CLI pembelian bisa salah mapping harga/qty.

## Fase 2 - Migrasi DB Bridge Pembelian
DB target: `san_sarana_18feb`

Perubahan tabel:
1. `ALTER TABLE pembelian_transaksi_bridge ADD variant_id INT(11) NULL DEFAULT NULL;`
2. `ALTER TABLE pembelian_transaksi_bridge ADD variant_sku VARCHAR(255) NULL DEFAULT NULL;`
3. `ALTER TABLE pembelian_transaksi_bridge ADD variant_label VARCHAR(255) NULL DEFAULT NULL;`
4. `ALTER TABLE pembelian_transaksi_bridge ADD variant_key VARCHAR(255) NULL DEFAULT NULL;`
5. `ALTER TABLE pembelian_transaksi_bridge ADD cart_key VARCHAR(255) NULL DEFAULT NULL;`
6. `ALTER TABLE pembelian_transaksi_bridge_terima ADD variant_id INT(11) NULL DEFAULT NULL;`
7. `ALTER TABLE pembelian_transaksi_bridge_terima ADD variant_sku VARCHAR(255) NULL DEFAULT NULL;`
8. `ALTER TABLE pembelian_transaksi_bridge_terima ADD variant_label VARCHAR(255) NULL DEFAULT NULL;`
9. `ALTER TABLE pembelian_transaksi_bridge_terima ADD variant_key VARCHAR(255) NULL DEFAULT NULL;`
10. `ALTER TABLE pembelian_transaksi_bridge_terima ADD cart_key VARCHAR(255) NULL DEFAULT NULL;`
11. Tambah index operasional sesuai volume data:
   - `(produk_id, variant_id)`
   - `cart_key`

Alasan bisnis:
1. Tanpa kolom ini, bridge tidak bisa menyimpan identitas varian yang stabil.
2. Mencegah salah akumulasi qty saat satu produk memiliki multi varian.
3. Menjaga audit trail line item dari CRM hingga PO/GRN.

## Fase 3 - Modul Pembelian (Prioritas 1)
File target utama:
1. `application/modules/pembelian/config/coTransaksiUi.php`
2. `application/modules/pembelian/config/coTransaksiLayout.php`
3. `application/modules/pembelian/config/coTransaksiCore.php`
4. `application/modules/pembelian/config/coTransaksiValues.php`
5. `application/modules/pembelian/controllers/_selectorItem.php`
6. `application/modules/pembelian/controllers/_processSelectProduct.php`
7. `application/modules/pembelian/controllers/_processSelectProductPpn.php`
8. `application/modules/pembelian/controllers/_shoppingCart.php`
9. `application/modules/pembelian/controllers/FollowUp.php`
10. `application/modules/pembelian/controllers/Printing.php`
11. `application/modules/pembelian/controllers/CliTransaksi.php`
12. `application/modules/pembelian/models/MdlPembelianTransaksi.php`
13. `application/modules/pembelian/views/shoppingCart.php`
14. `application/modules/pembelian/views/variant_picker.php`

Fokus pekerjaan:
1. Selector A/B konsisten:
   - qty dari selector item
   - price dari selector process
2. Radio PPN default harus mengikuti session (`checked` akurat).
3. Item varian dengan mode harga non-editable harus:
   - field terkunci secara UI
   - tampil pesan jelas alasan lock
4. Nilai cart (`qty`, `harga`, `subtotal`, `ppn`) harus stabil saat reload cart.
5. Jalur CLI pembelian mendukung:
   - data CRM varian normal
   - data CRM lama (produk non-varian, tetapi produk sekarang varian) lewat mekanisme staging/hold.

## Fase 4 - Modul Distribusi (Prioritas 2)
File target utama:
1. `application/modules/distribusi/config/coTransaksiUi.php`
2. `application/modules/distribusi/config/coTransaksiLayout.php`
3. `application/modules/distribusi/config/coTransaksiCore.php`
4. `application/modules/distribusi/config/coTransaksiValues.php`
5. `application/modules/distribusi/controllers/_selectorItem.php`
6. `application/modules/distribusi/controllers/_processSelectProduct.php`
7. `application/modules/distribusi/controllers/_shoppingCart.php`
8. `application/modules/distribusi/controllers/FollowUp.php`
9. `application/modules/distribusi/controllers/Printing.php`
10. `application/modules/distribusi/models/MdlDistribusiTransaksi.php`
11. `application/modules/distribusi/views/variant_picker.php`

Fokus pekerjaan:
1. Parity alur varian terhadap referensi `san_varian/modules/distribusifg`.
2. Validasi endpoint pending/ongoing/history:
   - `Transaksi/viewUndoneItemsIndex`
   - `History/showData`
   - `Transaksi/viewKepoinItems`
3. Pastikan preview/followup tidak menampilkan baris varian nol palsu.

## Fase 5 - Modul Penjualan (Prioritas 3)
File target utama:
1. `application/modules/penjualan/config/coTransaksiUi.php`
2. `application/modules/penjualan/config/coTransaksiLayout.php`
3. `application/modules/penjualan/config/coTransaksiCore.php`
4. `application/modules/penjualan/config/coTransaksiValues.php`
5. `application/modules/penjualan/controllers/_selectorItem.php`
6. `application/modules/penjualan/controllers/_processSelectProduct.php`
7. `application/modules/penjualan/controllers/_shoppingCart.php`
8. `application/modules/penjualan/controllers/FollowUp.php`
9. `application/modules/penjualan/controllers/Printing.php`
10. `application/modules/penjualan/models/MdlPenjualanTransaksi.php`

Fokus pekerjaan:
1. Konsistensi preview sebelum approve:
   - qty
   - uom
   - subtotal
2. Stabilitas doFollowup agar tidak false-positive "sudah diotorisasi".
3. Perbaikan query printing/resume agar tidak menghasilkan SQL syntax error.
4. Hardening fallback untuk data lama yang belum punya field baru.

## Fase 6 - UAT dan Audit Data
Matriks uji minimal:
1. Non-varian create/save/followup/print untuk 3 modul.
2. Varian single line dan multi line produk sama.
3. Kasus CRM lama:
   - produk kini varian, payload CRM masih non-varian.
   - sistem harus menahan transaksi atau minta staging varian, bukan salah tulis DB.
4. Validasi database:
   - line item transaksi menyimpan `variant_*` dan `cart_key` benar.
   - stok locker/mutasi/rekening/fifo konsisten dengan qty transaksi.
5. Validasi UI:
   - selector
   - popup preview
   - history
   - printing
   - tombol/radio/input state.

## Fase 7 - Rollout Ke Subsidiary Lain
1. Pilot di `san_sarana_8apr`.
2. Freeze delta.
3. Replikasi ke `san_add`, `san_ppu`, `san_sdl`, `san_tsa` menggunakan paket migrasi yang sama.
4. Jalankan precheck/postcheck per instance sebelum live.

## Fase 8 - Paket Dummy Data UAT (Lintas 3 Aplikasi)
Output paket:
1. `application/sql/variant_migration_phase3_uat_dummy/00_precheck_uat_dummy.sql`
2. `application/sql/variant_migration_phase3_uat_dummy/10_seed_crm_uat.sql`
3. `application/sql/variant_migration_phase3_uat_dummy/20_seed_holding_uat.sql`
4. `application/sql/variant_migration_phase3_uat_dummy/30_seed_subsidiary_uat.sql`
5. `application/sql/variant_migration_phase3_uat_dummy/90_verify_uat_dummy.sql`
6. `application/sql/variant_migration_phase3_uat_dummy/99_cleanup_uat_dummy.sql`

Tujuan fase:
1. Menyediakan data uji berulang untuk kasus non-varian, varian multi-line, legacy non-varian, dan harga 0.
2. Mempercepat UAT regresi tanpa input manual berulang.
3. Menjaga audit UAT bersih karena semua data dummy bertag `UATV3_*` dan bisa dibersihkan otomatis.

## Risiko dan Mitigasi
1. Risiko collapse data item varian.
   - Mitigasi: kunci key item pada `cart_key` dan index bridge.
2. Risiko mismatch stok/accounting.
   - Mitigasi: wajib jalankan UAT audit stok-rekening-fifo.
3. Risiko regressi non-varian.
   - Mitigasi: regresi non-varian jadi gate release.
4. Risiko dependency holding belum siap.
   - Mitigasi: fase API dilakukan lebih dulu sebelum patch penuh di subsidiary.

## Kriteria Sukses
1. Tidak ada SQL error/notice/warning pada jalur transaksi varian.
2. Nota/preview/history selaras dengan data detail transaksi.
3. Sinkron holding-subsidiary konsisten untuk payload varian.
4. Paket migrasi bisa dijalankan ulang di workspace subsidiari lain dengan perubahan minimal.
