Bagian 4 dari seri

Membuat CRUD Master Data Sistem Kasir Laravel

Diterbitkan 15 September 2026

Buat controller resource:

php artisan make:controller CategoryController --resource --model=Category
php artisan make:controller UnitController --resource --model=Unit
php artisan make:controller ProductController --resource --model=Product
php artisan make:controller CustomerController --resource --model=Customer
php artisan make:controller SupplierController --resource --model=Supplier

Daftarkan route:

Route::middleware('auth')->group(function () {
    Route::resources([
        'categories' => CategoryController::class,
        'units' => UnitController::class,
        'products' => ProductController::class,
        'customers' => CustomerController::class,
        'suppliers' => SupplierController::class,
    ]);
});

Controller produk

public function index(Request $request)
{
    $products = Product::with(['category', 'unit'])
        ->when($request->filled('q'), fn ($query) => $query
            ->where(fn ($search) => $search->where('name', 'like', '%'.$request->q.'%')
                ->orWhere('sku', 'like', '%'.$request->q.'%')))
        ->orderBy('name')->paginate(20)->withQueryString();

    return view('products.index', compact('products'));
}

public function store(Request $request)
{
    Product::create($this->validated($request));
    return redirect()->route('products.index')->with('success', 'Produk berhasil ditambahkan.');
}

private function validated(Request $request, ?Product $product = null): array
{
    return $request->validate([
        'category_id' => ['nullable', 'exists:categories,id'],
        'unit_id' => ['nullable', 'exists:units,id'],
        'sku' => ['required', 'max:50', Rule::unique('products')->ignore($product)],
        'name' => ['required', 'max:255'],
        'purchase_price' => ['required', 'numeric', 'min:0'],
        'selling_price' => ['required', 'numeric', 'min:0'],
        'stock' => ['required', 'integer', 'min:0'],
        'minimum_stock' => ['nullable', 'integer', 'min:0'],
        'is_active' => ['nullable', 'boolean'],
    ]);
}

Form produk harus berisi @csrf, menampilkan @error, dan memakai @method('PUT') untuk update. Tombol hapus harus memakai form DELETE, bukan tautan GET.

Contoh tabel daftar produk:

@foreach($products as $product)
<tr>
    <td>{{ $product->sku }}</td>
    <td>{{ $product->name }}</td>
    <td>{{ $product->category?->name }}</td>
    <td>Rp{{ number_format($product->selling_price, 0, ',', '.') }}</td>
    <td>{{ $product->stock }} {{ $product->unit?->symbol }}</td>
</tr>
@endforeach

Terapkan pola validasi, redirect, pesan sukses, pencarian, dan pagination yang sama pada master lain.

Lanjut: Transaksi Penjualan