# Finalisasi Modul Persediaan Dokumen ini menjadi catatan implementasi development dan panduan penerapan ke production. Perubahan tidak menghapus jurnal, barcode, stock log, ledger, maupun histori transaksi lama. ## Fondasi yang digunakan - `inventory_ledger` adalah sumber saldo dan nilai persediaan. - `items.stok` hanya cache dan disinkronkan dari ledger setelah transaksi stok. - `stock_logs` adalah jejak operasional/audit, bukan sumber saldo utama. - Barcode menyimpan ketersediaan fisik per unit/kelompok. Stok yang `pending`, `installed`, `closed`, `returned`, atau `sold_out` tidak dapat dipilih sebagai stok operasional. - Perpindahan barang ke teknisi tidak mengurangi nilai persediaan perusahaan. Barcode berstatus `installed` agar tidak dapat dialokasikan atau dikeluarkan dua kali; pengembalian mengaktifkannya kembali pada gudang asal. - Dokumen posted tidak diedit atau dihapus. Koreksi dilakukan dengan dokumen reversal. - Endpoint hapus master Gudang dan Jenis/Kode Barang dinonaktifkan secara permanen; perubahan ketersediaan master dilakukan melalui status aktif/nonaktif. ## Migration baru 1. `20260906000100_finalize_professional_inventory.php` - melengkapi header/detail dokumen stok, sumber dokumen, approval, reversal, dan audit status; - melengkapi company, status aktif, gudang, rak/bin, batch, reservasi, dan rekonsiliasi; - membuat tabel histori dokumen serta reservasi; - menambahkan indeks pencarian, status, tanggal, sumber, barcode, dan lampiran; - melakukan backfill company secara konservatif. 2. `20260906000200_reconcile_inventory_company_and_cost.php` - mengisi `company_id` yang masih kosong; - mengisi biaya stock log dari ledger atau harga beli bila jejak lama memungkinkan; - membuat snapshot histori status dokumen lama; - tidak mengubah qty, saldo ledger, barcode, atau jurnal. 3. `20260906000300_harden_technician_inventory_custody.php` - menambahkan `company_id` dan indeks pada penguasaan barang teknisi; - menyelaraskan barcode assignment aktif lama dari `available` menjadi `installed` hanya bila tidak sedang direservasi; - tidak mengubah qty persediaan atau membuat jurnal. Status database development setelah migrasi: `20260906000300`. Pemeriksaan menunjukkan tidak ada item tanpa company dan tidak ada stock log tanpa unit cost. ## Alur operasional final - Barang pembelian tetap masuk melalui Purchase Workflow dan penerimaan gudang. - Barang berserial atau belum mempunyai harga jual masuk Barang Pending. - Aktivasi berserial dapat dilakukan bertahap; unit yang belum lengkap tetap berada di Barang Pending. - Barang aktif hanya dapat dilihat, ditelusuri stock card-nya, dan dicetak barcode. Pengeluaran menggunakan dokumen Operasional Stok. - Operasional Stok mendukung multi-baris, draft, pengajuan, approval sesuai jenis, posting, reversal, sumber dokumen, lampiran, detail, PDF, dan audit status. - Adjustment, selisih opname, rusak, dan hilang wajib approval. Mutasi biasa dan transfer mengikuti permission posting. - Reservasi mendukung release sebagian/seluruhnya, consume, cancel, dan expired otomatis. - Retur supplier tetap dikerjakan dari submenu Retur & Refund; penerimaan pembelian tidak diduplikasi sebagai input manual. - Penjualan, penerimaan pembelian, retur supplier, aset, dan peralatan teknisi sudah menggunakan ledger atau adapter transaksi yang mempertahankan jejak dokumen. ## Hasil pemeriksaan development, 6 September 2026 Pemeriksaan integritas lulus: - duplicate barcode: 0; - duplicate ledger idempotency: 0; - stok ledger negatif: 0; - selisih qty ledger dengan stock log: 0; - selisih cache `items.stok`: 0; - reservasi barcode melebihi saldo: 0; - release reservasi berlebih: 0; - dokumen posted tanpa ledger: 0; - trigger pencegahan stok negatif: aktif. - assignment teknisi aktif dengan status barcode selain `installed`: 0 (satu metadata legacy telah diselaraskan tanpa mengubah qty/jurnal). Rekonsiliasi nilai lama belum balance dan sengaja tidak dikoreksi otomatis: - nilai inventory ledger: Rp268.920.950,00; - nilai stock log: Rp275.369.950,00; - nilai akun persediaan GL: Rp243.151.515,00; - selisih ledger terhadap GL: Rp25.769.435,00. Sumber selisih nilai ledger terhadap stock log yang teridentifikasi: - `ONT-200526 - ONT TF525G`, Gudang Cikembar: ledger Rp57.836.670,00; stock log Rp64.305.670,00; selisih Rp-6.469.000,00; - `ADP-260905120758-20 - Adpator 12 Volt`, Gudang Cikembar: ledger Rp180.000,00; stock log Rp160.000,00; selisih Rp20.000,00. Terdapat tujuh posisi barcode legacy yang berbeda dari ledger: - `FO1-010426`: +463 pada ledger; - `ISK-140426`: -18 pada ledger; - `KLB-120426`: -13 pada ledger; - `JB24-010426`: +6 pada ledger; - `ONT-260626`: -5 pada ledger; - `PTC-270626`: -1 pada ledger; - `F42-260903004514`: +1 pada ledger. Angka tersebut tersedia pada Laporan Persediaan → Rekonsiliasi dan perintah `php index.php inventorycheck professional`. Koreksi hanya boleh dilakukan setelah dokumen sumber, stock opname fisik, dan saldo awal GL disepakati. Gunakan adjustment/opname beralasan dan approval; jangan mengedit tabel langsung. ## Hasil automated test - PHP lint: 32 file inti Persediaan, integrasi Pembelian/Penjualan/Aset/Teknisi, migration, view, dan test lolos. - PHPUnit: 24 test, 243 assertion, seluruhnya lulus. - `stage17check`: seluruh kontrol accounting berstatus pass; terdapat warning 12 invoice legacy tanpa jurnal yang sudah dicatat untuk cut-over. - `stage15check`: shell desktop/mobile, kesamaan sumber menu, breakpoint 360/390/768/1366, modal, local asset fallback, dan double-submit guard lulus. - `stage16check`: tabel skalabilitas, cache, queue idempotent, dan database session lulus. - `purchaseadjustmentcheck integrity/runtime`: seluruh invariant retur/refund serta query laporan lulus. - Rekonsiliasi inventory terhadap GL sengaja menghasilkan exit code 1 karena selisih legacy Rp25.769.435,00 masih terbuka dan harus ditindaklanjuti, bukan ditutupi. ## Langkah wajib production 1. Backup database penuh dan folder `uploads/accounting` lalu uji restore-nya. 2. Terapkan pada staging yang merupakan salinan production; hentikan posting stok saat cut-over. 3. Deploy kode, lalu jalankan `php index.php migrate latest` dan pastikan `php index.php migrate status` menunjukkan `20260906000300` atau versi lebih baru. 4. Jalankan pemeriksaan berikut sebelum membuka transaksi: ```text php index.php inventorycheck integrity php index.php inventorycheck reconciliation php index.php inventorycheck trigger_test php index.php inventorycheck professional php index.php inventorycheck anomalies php index.php stage17check php index.php purchaseadjustmentcheck integrity php index.php purchaseadjustmentcheck runtime ``` 5. Ekspor hasil rekonsiliasi, cocokkan dengan saldo awal, pembelian/penjualan legacy, dan lakukan stock opname untuk item yang berbeda. 6. Jangan menjalankan repair GL atau membuat jurnal penutup selisih sebelum penyebab dan otorisasinya terdokumentasi. 7. Uji permission Maker/Approver/Poster per perusahaan dan pastikan pengguna hanya melihat company aktif. 8. Uji smoke test pada laptop 1366×768, Full HD, Android kecil/besar, serta Safari iPhone: buat dokumen multi-item, preview PDF, scan barcode, reservasi, approval, posting, dan reversal. 9. Pantau query lambat, deadlock, ukuran ledger/log, dan job export setelah go-live. Rollback migration finalisasi hanya melalui pemulihan backup karena menurunkan skema dapat menghilangkan metadata audit baru.