Pesanan masuk dari marketplace, Anda mengemas barang, lalu sadar stoknya sudah terjual lewat website satu jam sebelumnya. Pelanggan kecewa, rating turun, dan Anda harus membatalkan pesanan. Di sisi lain, ada barang yang tampil "habis" padahal masih ada beberapa unit di rak karena lupa diperbarui.
Dua masalah itu, overselling dan stok hantu, adalah alasan utama toko online butuh aplikasi manajemen stok. Artikel ini membahas fitur yang benar-benar penting, cara menghitung kapan harus restock, rancangan database yang membuat angka stok bisa dipertanggungjawabkan, serta contoh implementasi di Laravel bagi Anda yang membangun sistem sendiri.
Kenapa Spreadsheet Tidak Lagi Cukup
Spreadsheet bekerja selama Anda berjualan di satu kanal dan pesanan masih bisa dihitung jari. Begitu ada website, dua marketplace, dan penjualan lewat chat, masalahnya berlipat:
- Stok di tiap kanal diperbarui manual dan tidak bersamaan, sehingga barang yang terjual di satu kanal masih tampil tersedia di kanal lain.
- Salah ketik satu angka tidak meninggalkan jejak. Anda tidak tahu kapan dan siapa yang mengubahnya.
- Sulit melihat barang mana yang laris dan mana yang mengendap berbulan-bulan.
- Saat lonjakan pesanan, misalnya promo tanggal kembar, update manual tidak bisa mengejar kecepatan penjualan.
Fitur yang Benar-Benar Penting
| Fitur | Masalah yang diselesaikan | Prioritas |
|---|---|---|
| Sinkronisasi stok multi-kanal | Overselling antar website dan marketplace | Wajib bila jual di 2+ kanal |
| Peringatan stok menipis | Kehabisan barang laris | Wajib |
| Laporan terlaris dan slow-moving | Modal mengendap di barang mati | Wajib |
| Varian (ukuran, warna) dan bundling | Stok per varian tidak akurat | Wajib untuk fashion dan aksesori |
| Stok per gudang atau lokasi | Tidak tahu barang ada di mana | Bila punya lebih dari satu lokasi |
| Pemindaian barcode | Salah ambil dan salah kirim | Saat volume pesanan tinggi |
| Riwayat mutasi stok | Selisih yang tidak bisa dijelaskan | Wajib |
Fitur terakhir sering diremehkan, padahal paling menentukan. Angka stok tanpa riwayat hanyalah angka yang harus dipercaya begitu saja. Dengan riwayat, setiap selisih bisa ditelusuri ke transaksi tertentu.
Jangan tergoda memilih aplikasi dengan fitur paling banyak. Toko dengan satu gudang dan puluhan produk tidak membutuhkan modul multi-gudang atau pemindaian barcode di bulan pertama. Mulailah dari fitur berlabel wajib, lalu tambahkan sisanya ketika volume pesanan dan jumlah lokasi memang menuntutnya. Fitur yang tidak dipakai hanya menambah menu yang membingungkan staf.
Integrasi dengan Marketplace
Aplikasi stok yang terhubung ke marketplace bekerja dengan dua arah: menerima pesanan baru dari marketplace, lalu mengirim angka stok terbaru ke semua kanal. Integrasi biasanya memakai API resmi marketplace atau layanan perantara. Hal yang perlu Anda pastikan:
- Seberapa cepat sinkronisasi terjadi. Jeda beberapa menit masih bisa menyebabkan overselling saat promo besar.
- Apa yang terjadi bila API marketplace sedang gangguan. Sistem yang baik mencoba ulang secara otomatis.
- Apakah SKU di semua kanal sudah sama. Sinkronisasi gagal bila kode produk berbeda-beda.
Strategi yang aman saat promo besar adalah menahan sebagian stok sebagai cadangan, misalnya tidak menampilkan dua unit terakhir di marketplace, sehingga jeda sinkronisasi tidak berujung pembatalan.
Menghitung Titik Restock
Peringatan stok menipis hanya berguna bila ambangnya benar. Rumus sederhana yang banyak dipakai:
Titik restock = rata-rata penjualan harian x lama pengiriman supplier (hari) + stok pengaman
Contoh: sebuah kaos terjual rata-rata 6 unit per hari, supplier butuh 5 hari untuk mengirim, dan Anda ingin cadangan 3 hari penjualan (18 unit). Titik restocknya 6 x 5 + 18 = 48 unit. Saat stok menyentuh 48, saatnya memesan. Angka ini hanya ilustrasi; hitung ulang tiap bulan karena pola penjualan berubah, terutama menjelang musim ramai.
Rancangan Database: Simpan Mutasi, Bukan Hanya Angka
Bagi developer, keputusan paling penting adalah menyimpan setiap perubahan stok sebagai baris mutasi. Kolom stock di tabel produk tetap ada untuk kecepatan baca, tetapi selalu bisa dicocokkan dengan jumlah mutasinya.
Schema::create('stock_movements', function (Blueprint $table) {
$table->id();
$table->foreignId('product_variant_id')->constrained();
$table->foreignId('warehouse_id')->constrained();
$table->integer('qty'); // + masuk, - keluar
$table->string('type', 20); // purchase, sale, return, adjustment
$table->string('reference')->nullable(); // no. order atau no. PO
$table->foreignId('user_id')->nullable()->constrained();
$table->timestamps();
$table->index(['product_variant_id', 'warehouse_id']);
});
Lalu, saat pesanan masuk, kurangi stok secara atomik agar dua pesanan bersamaan tidak sama-sama lolos:
use Illuminate\Support\Facades\DB;
DB::transaction(function () use ($variantId, $qty, $orderNo) {
$affected = DB::table('product_variants')
->where('id', $variantId)
->where('stock', '>=', $qty)
->decrement('stock', $qty);
if ($affected === 0) {
throw new \RuntimeException('Stok tidak cukup');
}
StockMovement::create([
'product_variant_id' => $variantId,
'warehouse_id' => 1,
'qty' => -$qty,
'type' => 'sale',
'reference' => $orderNo,
]);
});
Kenapa tidak membaca stok dulu lalu menyimpannya? Karena di antara baca dan simpan, request lain bisa masuk. Kondisi where('stock', '>=', $qty) di dalam satu perintah UPDATE membuat database sendiri yang menjamin stok tidak minus. Untuk peringatan stok menipis, jadwalkan command harian dengan scheduler Laravel dan kirim notifikasinya lewat queue, seperti dibahas di queue dan job di Laravel untuk tugas berat.
Gudang, Pemenuhan Pesanan, dan Retur
Saat toko mulai besar, masalah bergeser dari "berapa stoknya" menjadi "barangnya di rak mana dan sudah dikirim atau belum". Alur pemenuhan pesanan yang rapi biasanya terdiri dari tiga status: pesanan diambil dari rak (picking), dikemas (packing), lalu diserahkan ke kurir. Pemindaian barcode di tahap picking dan packing mencegah salah ambil ukuran atau warna, kesalahan yang sangat sering terjadi pada produk fashion.
Retur juga harus masuk sistem, bukan hanya ditumpuk di sudut gudang. Catat retur sebagai mutasi bertipe return, lalu periksa kondisinya. Barang yang layak jual dikembalikan ke stok, sedangkan barang rusak dicatat sebagai penyesuaian dengan alasan "rusak". Dengan begitu laporan kerugian barang rusak bisa dilihat per bulan, dan Anda tahu apakah masalahnya ada di pengemasan, kurir, atau supplier.
Stok dan Arus Kas
Stok adalah uang yang tertidur di rak. Barang slow-moving menahan modal yang seharusnya bisa dipakai untuk menambah barang laris. Biasakan meninjau laporan bulanan: barang yang tidak terjual dalam 60 sampai 90 hari layak dipertimbangkan untuk dibundel, didiskon, atau tidak dipesan ulang. Angka hari itu hanya patokan awal; sesuaikan dengan sifat produk Anda. Hubungan stok dengan laporan keuangan juga dibahas di otomatisasi laporan keuangan dengan spreadsheet dan AI.
Langkah Menerapkan Aplikasi Stok
- Seragamkan SKU di semua kanal penjualan sebelum menghubungkan apa pun.
- Lakukan stok opname fisik dan jadikan hasilnya stok awal.
- Atur titik restock untuk 20 sampai 30 produk terlaris lebih dulu.
- Hubungkan satu kanal, uji selama seminggu, lalu tambah kanal berikutnya.
- Tetapkan aturan: setiap koreksi stok wajib diberi alasan.
- Jadwalkan stok opname berkala, misalnya bulanan untuk barang bernilai tinggi.
Kesalahan yang Perlu Dihindari
- Tetap pakai spreadsheet saat sudah multi-kanal. Overselling hanya soal waktu.
- Tidak mengatur ambang stok minimum. Peringatan baru datang saat barang sudah habis.
- Mengoreksi stok tanpa catatan. Selisih berikutnya tidak bisa ditelusuri.
- Mengabaikan barang slow-moving. Modal tertahan diam-diam.
- Varian dicatat sebagai satu produk. Stok total benar, tetapi ukuran M ternyata sudah habis.
Checklist Memilih Aplikasi Stok
- Mendukung semua kanal yang Anda pakai sekarang.
- Stok per varian, bukan hanya per produk.
- Ada riwayat mutasi lengkap dengan pengguna dan alasan.
- Peringatan stok menipis yang ambangnya bisa diatur per produk.
- Laporan terlaris dan slow-moving bisa diekspor.
- Mendukung banyak gudang bila Anda berencana menambah lokasi.
Jika Anda developer yang ingin mempelajari struktur aplikasi inventory berbasis Laravel, katalog GudangCode bisa menjadi salah satu referensi untuk dibandingkan dengan checklist di atas.