Bagian 6 dari seri
Pembelian dan Manajemen Stok Sistem Kasir Laravel
Diterbitkan 15 September 2026
Alur pembelian hampir sama dengan penjualan, tetapi jumlah barang menambah stok.
$purchase = DB::transaction(function () use ($data) {
$purchase = Purchase::create([
'invoice_number' => $data['invoice_number'],
'supplier_id' => $data['supplier_id'] ?? null,
'user_id' => auth()->id(),
'purchase_date' => $data['purchase_date'],
'grand_total' => 0,
'status' => 'received',
]);
$total = 0;
foreach ($data['items'] as $item) {
$product = Product::lockForUpdate()->findOrFail($item['product_id']);
$subtotal = $item['price'] * $item['quantity'];
$purchase->details()->create([
'product_id' => $product->id, 'quantity' => $item['quantity'],
'price' => $item['price'], 'subtotal' => $subtotal,
]);
$product->increment('stock', $item['quantity']);
$product->update(['purchase_price' => $item['price']]);
$product->stockMovements()->create([
'type' => 'purchase', 'quantity_in' => $item['quantity'],
'reference_type' => Purchase::class, 'reference_id' => $purchase->id,
]);
$total += $subtotal;
}
$purchase->update(['grand_total' => $total]);
return $purchase;
});
Penyesuaian stok
Penyesuaian hanya boleh dilakukan admin. Simpan selisih stok dan alasannya:
DB::transaction(function () use ($product, $newStock, $reason) {
$product = Product::lockForUpdate()->findOrFail($product->id);
$difference = $newStock - $product->stock;
$product->update(['stock' => $newStock]);
$product->stockMovements()->create([
'type' => 'adjustment',
'quantity_in' => max(0, $difference),
'quantity_out' => max(0, -$difference),
'notes' => $reason,
]);
});
Tampilkan halaman kartu stok berisi tanggal, jenis transaksi, stok masuk, stok keluar, dan referensi. Produk dengan stock <= minimum_stock ditampilkan sebagai stok menipis.
Jangan menghapus transaksi pembelian atau penjualan yang sudah memengaruhi stok. Sediakan proses pembatalan yang membuat pergerakan stok kebalikan dan mengubah status transaksi.




