Bagian 2 dari seri
Membuat Struktur Database Sistem Kasir Laravel
Diterbitkan 15 September 2026
Bagian ini membuat seluruh tabel bisnis. Buat model beserta migration:
php artisan make:model Category -m
php artisan make:model Unit -m
php artisan make:model Product -m
php artisan make:model Customer -m
php artisan make:model Supplier -m
php artisan make:model Purchase -m
php artisan make:model PurchaseDetail -m
php artisan make:model Sale -m
php artisan make:model SaleDetail -m
php artisan make:model StockMovement -m
php artisan make:model Setting -m
Tabel master
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->timestamps();
});
Schema::create('units', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('symbol', 20);
$table->timestamps();
});
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->foreignId('category_id')->nullable()->constrained()->nullOnDelete();
$table->foreignId('unit_id')->nullable()->constrained()->nullOnDelete();
$table->string('sku', 50)->unique();
$table->string('name');
$table->decimal('purchase_price', 15, 2)->default(0);
$table->decimal('selling_price', 15, 2)->default(0);
$table->integer('stock')->default(0);
$table->integer('minimum_stock')->default(0);
$table->boolean('is_active')->default(true);
$table->timestamps();
});
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('phone', 30)->nullable();
$table->text('address')->nullable();
$table->timestamps();
});
Schema::create('suppliers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('phone', 30)->nullable();
$table->text('address')->nullable();
$table->timestamps();
});
Tabel transaksi
Schema::create('sales', function (Blueprint $table) {
$table->id();
$table->string('invoice_number')->unique();
$table->foreignId('user_id')->constrained()->restrictOnDelete();
$table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();
$table->timestamp('sale_date');
$table->decimal('subtotal', 15, 2);
$table->decimal('discount', 15, 2)->default(0);
$table->decimal('grand_total', 15, 2);
$table->decimal('paid_amount', 15, 2);
$table->decimal('change_amount', 15, 2);
$table->string('status', 20)->default('paid');
$table->text('notes')->nullable();
$table->timestamps();
});
Schema::create('sale_details', function (Blueprint $table) {
$table->id();
$table->foreignId('sale_id')->constrained()->cascadeOnDelete();
$table->foreignId('product_id')->constrained()->restrictOnDelete();
$table->integer('quantity');
$table->decimal('price', 15, 2);
$table->decimal('discount', 15, 2)->default(0);
$table->decimal('subtotal', 15, 2);
$table->timestamps();
});
Schema::create('purchases', function (Blueprint $table) {
$table->id();
$table->string('invoice_number')->unique();
$table->foreignId('supplier_id')->nullable()->constrained()->nullOnDelete();
$table->foreignId('user_id')->constrained()->restrictOnDelete();
$table->timestamp('purchase_date');
$table->decimal('grand_total', 15, 2);
$table->string('status', 20)->default('received');
$table->timestamps();
});
Schema::create('purchase_details', function (Blueprint $table) {
$table->id();
$table->foreignId('purchase_id')->constrained()->cascadeOnDelete();
$table->foreignId('product_id')->constrained()->restrictOnDelete();
$table->integer('quantity');
$table->decimal('price', 15, 2);
$table->decimal('subtotal', 15, 2);
$table->timestamps();
});
Riwayat stok dan pengaturan
Schema::create('stock_movements', function (Blueprint $table) {
$table->id();
$table->foreignId('product_id')->constrained()->restrictOnDelete();
$table->string('type', 20);
$table->integer('quantity_in')->default(0);
$table->integer('quantity_out')->default(0);
$table->string('reference_type')->nullable();
$table->unsignedBigInteger('reference_id')->nullable();
$table->text('notes')->nullable();
$table->timestamps();
});
Schema::create('settings', function (Blueprint $table) {
$table->id();
$table->string('key')->unique();
$table->text('value')->nullable();
$table->timestamps();
});
Pastikan urutan migration menempatkan tabel master sebelum tabel yang mempunyai foreign key. Kemudian jalankan:
php artisan migrate
php artisan migrate:status




