mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 05:21:57 +00:00
Mesin Stok FIFO
Utilitas FIFO bersifat reusable dan dibagi menjadi dua lapis:
- Registry (
internal/utils/fifo) – mendeklarasikan tabel mana yang bersifatStockable(sumber stok) atauUsable(pemakai stok). Setiap modul cukup menyebutkan nama tabel dan kolom wajib:- Stockable:
id,product_warehouse_id,total_qty,total_used_qty,created_at - Usable:
id,product_warehouse_id,usage_qty,pending_qty,created_at
- Stockable:
- Service (
internal/common/service/common.fifo.service.go) – memakai registry tersebut untuk:- Menambah stok baru (
Replenish). - Menyinkronkan total pemakaian (
Consume). Method ini idempotent: panggil dengan total kuantitas yang diinginkan (mis. saat create/update/delete). Service menghitung selisih terhadapusage_qty + pending_qty, kemudian otomatis mengalokasikan tambahan atau melepaskan selisihnya. - Membatalkan pemakaian (
ReleaseUsage) yang mengembalikan stok lalu memicu alokasi ulang ke antrian pending. - Baik
Replenishmaupun pelepasan stok akan menjalankanresolvePendingForWarehouse, sehingga pending tertua langsung terisi ketika stok tersedia.
- Menambah stok baru (
Registrasi tabel
import (
commonservice "gitlab.com/mbugroup/lti-api.git/internal/common/service"
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
)
func init() {
fifoSvc := commonservice.NewFifoService(db, stockAllocRepo, productWarehouseRepo, utils.Log)
fifoSvc.RegisterStockable(fifo.StockableConfig{
Key: fifo.StockableKey("PURCHASE_DETAIL"),
Table: "purchase_details",
Columns: fifo.StockableColumns{
ID: "id",
ProductWarehouseID: "product_warehouse_id",
TotalQuantity: "total_qty",
TotalUsedQuantity: "total_used_qty",
CreatedAt: "created_at",
},
})
fifoSvc.RegisterUsable(fifo.UsableConfig{
Key: fifo.UsableKey("RECORDING_STOCK"),
Table: "recording_stocks",
Columns: fifo.UsableColumns{
ID: "id",
ProductWarehouseID: "product_warehouse_id",
UsageQuantity: "usage_qty",
PendingQuantity: "pending_qty",
CreatedAt: "created_at",
},
})
}
Each registration optionally accepts an order clause or base scope (e.g. to exclude drafts).
Setiap registrasi bisa diberi klausa urutan atau scope dasar (mis. untuk mengecualikan draft).
Menggunakan service di modul
- Saat stok masuk (mis. purchase selesai): panggil
fifoSvc.Replenish(...)dengan key stockable, id record, id product warehouse, dan kuantitas yang baru tersedia. Service akan:- Menambah
total_qtypada tabel stockable, - Menambah
product_warehouses.quantity, - Mencoba membersihkan
pending_qtydari semua usable yang terdaftar (sesuai urutan FIFO).
- Menambah
- Saat modul memakai stok (recording, marketing, dsb.) panggil
fifoSvc.Consume(...)dengan total qty terbaru.- Jika qty baru lebih besar, service mengambil stok FIFO dan menambah
usage_qty; kekurangan dicatat sebagaipending_qty. - Jika qty baru lebih kecil, service otomatis menurunkan
pending_qtylebih dulu, lalu melepaskan alokasi aktif (stok kembali ke gudang) dan langsung dipakai untuk mengisi pending milik entitas lain. - Hapus data? panggil
Consumedengan qty 0 atau gunakanReleaseUsage.
- Jika qty baru lebih besar, service mengambil stok FIFO dan menambah
- Jika dibatalkan penuh:
fifoSvc.ReleaseUsage(...)mengosongkanusage_qty/pending_qtydan menandai baris pivot sebagaiRELEASED.
Tabel pivot (stock_allocations) menyimpan asal pemakaian secara presisi, sehingga audit trail dan rollback stok menjadi deterministik.