migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name'); // Category Name
$table->string('slug')->nullable();
$table->string('image')->nullable(); // Image path
$table->foreignId('parent_id')->nullable()->constrained('food_categories')->onDelete('cascade'); // Parent category
$table->boolean('is_offer')->default(false); // Offer toggle
$table->date('start_date')->nullable(); // Offer start
$table->date('end_date')->nullable(); // Offer end
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('food_categories');
}
};

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('menu_types', function (Blueprint $table) {
$table->id();
// Multi-restaurant support
$table->unsignedBigInteger('restaurant_id')->index()->nullable();
// Menu type details
$table->string('name')->index()->comment('e.g., Lunch, Dinner, Breakfast, Happy Hour');
$table->string('slug')->nullable()->unique()->comment('Unique slug for URLs and API');
$table->string('icon')->nullable()->comment('Optional icon or image for menu type');
$table->text('description')->nullable()->comment('Optional description of this menu type');
$table->integer('display_order')->default(0)->comment('Ordering in menu display');
// Status & flags
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->boolean('is_default')->default(false)->comment('Default menu type for new items');
$table->timestamps();
$table->softDeletes();
// Indexes
$table->index(['restaurant_id', 'status']);
$table->index(['restaurant_id', 'name']);
// Foreign key
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('menu_types');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('addons', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index();
$table->string('name')->index();
$table->decimal('price', 12, 2);
$table->decimal('vat', 5, 2)->default(0);
$table->decimal('pst', 5, 2)->default(0);
$table->tinyInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('addons');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('menu_categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name');
$table->string('slug')->nullable();
$table->string('icon')->nullable();
$table->text('description')->nullable();
$table->integer('priority')->default(0)->comment('Display order');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
// Unique constraint: restaurant_id + name (nullable restaurant_id supported)
$table->unique(['restaurant_id', 'name'], 'restaurant_name_unique');
});
}
public function down(): void
{
Schema::dropIfExists('menu_categories');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('menu_sections', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->foreignId('menu_category_id')->constrained('menu_categories')->onDelete('cascade');
$table->string('name');
$table->string('slug')->nullable();
$table->text('description')->nullable();
$table->integer('priority')->default(0)->comment('Display order');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
// Unique constraint: restaurant_id + name
$table->unique(['restaurant_id', 'name'], 'restaurant_section_name_unique');
});
}
public function down(): void
{
Schema::dropIfExists('menu_sections');
}
};

View File

@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index();
$table->unsignedBigInteger('category_id')->index();
$table->unsignedBigInteger('menu_category_id')->nullable();
$table->unsignedBigInteger('menu_section_id')->nullable();
$table->string('name')->index();
$table->string('slug')->nullable();
$table->text('description')->nullable();
$table->enum('food_type', ['Veg', 'Non-Veg']);
$table->integer('points')->default(0); // points for this item
$table->tinyInteger('is_featured')->default(0);
$table->tinyInteger('is_party')->default(0);
$table->tinyInteger('is_dinner')->default(0);
$table->tinyInteger('is_lunch')->default(0);
$table->tinyInteger('is_popular_item')->default(0)->index();
$table->tinyInteger('is_chef_special')->default(0)->index();
$table->string('image')->nullable();
$table->time('prep_time')->nullable();
$table->time('cooking_time')->nullable();
$table->decimal('vat', 5, 2)->default(0);
$table->decimal('pst', 5, 2)->default(0);
$table->decimal('ingredients_cost', 12, 2)->default(0);
$table->string('allergens')->nullable();
$table->text('notes')->nullable();
$table->tinyInteger('status')->default(1)->index();
$table->timestamps();
$table->softDeletes();
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->foreign('category_id')->references('id')->on('food_categories')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('food_items');
}
};

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('addon_food', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index();
$table->unsignedBigInteger('food_item_id')->index();
$table->unsignedBigInteger('addon_id')->index();
$table->tinyInteger('status')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('food_item_id')->references('id')->on('food_items')->onDelete('cascade');
$table->foreign('addon_id')->references('id')->on('addons')->onDelete('cascade');
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->unique(['food_item_id', 'addon_id']); // avoid duplicate assignments
});
}
public function down(): void
{
Schema::dropIfExists('addon_food');
}
};

View File

@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('units', function (Blueprint $table) {
$table->id();
// Multi-tenant support
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('user_id')->nullable();
// Full international naming
$table->string('name'); // e.g., Gram
$table->string('short_name'); // e.g., g
$table->string('type')->nullable(); // weight, volume, length, count
// Relation to base unit within same category
$table->foreignId('base_unit_id')->nullable()->constrained('units')->nullOnDelete();
// Conversion logic
$table->enum('operator', ['*', '/'])->default('*');
$table->float('operator_value')->default(1); // e.g., 1000 for (kg → g)
// Config
$table->smallInteger('priority')->default(1);
$table->smallInteger('version')->default(1);
$table->boolean('is_default')->default(false);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
// Indexes
$table->index(['type']);
$table->index(['name']);
});
}
public function down(): void
{
Schema::dropIfExists('units');
}
};

View File

@@ -0,0 +1,49 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_variants', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index();
$table->unsignedBigInteger('food_item_id')->index();
$table->string('name');
$table->string('sku')->unique();
$table->string('barcode')->nullable();
$table->decimal('price', 12, 2);
$table->decimal('offer_price', 12, 2)->nullable();
$table->integer('discount')->default(0);
$table->foreignId('unit_id')->constrained('units')->cascadeOnDelete();
$table->string('image')->nullable();
$table->text('description')->nullable();
$table->tinyInteger('is_default')->default(0);
$table->tinyInteger('stock_tracking')->default(0);
$table->decimal('ingredients_cost', 12, 2)->default(0);
$table->decimal('profit_margin', 12, 2)->default(0);
$table->decimal('alert_stock_quantity', 10, 2)->nullable();
$table->enum('combo_type', ['single', 'combo', 'add-on'])->default('single');
$table->tinyInteger('is_active_offer')->default(0);
$table->timestamp('offer_start_at')->nullable();
$table->timestamp('offer_end_at')->nullable();
$table->tinyInteger('status')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('food_item_id')->references('id')->on('food_items')->onDelete('cascade');
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('food_variants');
}
};

View File

@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_availabilities', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained()->onDelete('cascade');
$table->foreignId('food_item_id')->constrained()->onDelete('cascade');
$table->enum('day', [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
]);
$table->boolean('is_available')->default(true);
$table->timestamps();
$table->softDeletes();
$table->unique(['food_item_id', 'day']);
});
}
public function down(): void
{
Schema::dropIfExists('food_availabilities');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_availability_times', function (Blueprint $table) {
$table->id();
$table->foreignId('food_availability_id')
->constrained('food_availabilities')
->onDelete('cascade');
$table->time('open_time');
$table->time('close_time');
$table->timestamps();
$table->softDeletes();
$table->unique(
['food_availability_id', 'open_time', 'close_time'],
'unique_food_time_slot'
);
});
}
public function down(): void
{
Schema::dropIfExists('food_availability_times');
}
};

View File

@@ -0,0 +1,50 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('tables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index();
$table->string('name'); // T01, T02 …
$table->string('location')->nullable(); // floor / zone / hall
$table->string('section')->nullable();
$table->string('serial')->nullable(); // optional serial for sorting
// Table type
$table->enum('table_type', ['regular', 'vip', 'outdoor', 'booth'])
->default('regular');
$table->integer('capacity')->default(2);
$table->boolean('is_bookable')->default(true);
$table->string('qr_code')->nullable();
$table->string('image')->nullable(); // icon for UI
// ⭐ Position Fields for Drag & Drop Layout
$table->float('position_x')->default(0);
$table->float('position_y')->default(0);
$table->float('rotation')->default(0); // rotate table icon
$table->integer('z_index')->default(1); // layer ordering
$table->tinyInteger('status')->default(1)->comment('1 = Active, 2 = Inactive');
$table->timestamps();
$table->softDeletes();
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('tables');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('payment_methods', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->index()->nullable(); // multi-restaurant support
$table->string('name'); // e.g., "Stripe", "PayPal", "Cash"
$table->string('type')->nullable()->comment('gateway, cash, card, wallet');
$table->json('credentials')->nullable()->comment('store API keys, tokens, or config as JSON');
$table->boolean('is_default')->default(false); // default payment method
$table->tinyInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->unique(['restaurant_id', 'name']); // avoid duplicate payment methods per restaurant
});
}
public function down(): void
{
Schema::dropIfExists('payment_methods');
}
};

View File

@@ -0,0 +1,59 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable()->index();
$table->string('customer_code')->nullable(); // auto-generated code (QR/loyalty)
$table->string('name')->default('Walk-in');
$table->string('username')->nullable();
$table->string('email')->nullable();
$table->string('phone', 50)->nullable();
$table->string('password')->nullable();
$table->integer('otp_code')->nullable();
$table->boolean('isVerified')->default(false);
$table->timestamp('email_verified_at')->nullable();
$table->string('avatar')->nullable();
$table->string('address')->nullable();
$table->tinyInteger('role_id')->default(9)->comment('9=Customer');
$table->enum('gender', ['male', 'female', 'other'])->nullable();
$table->date('date_of_birth')->nullable();
$table->string('nid')->nullable();
$table->enum('platform', ['APP', 'WEB'])->default('APP');
$table->longText('device_info')->nullable();
$table->timestamp('last_active_time')->nullable();
$table->json('meta')->nullable(); // loyalty, preferences
$table->tinyInteger('status')->default(1)->comment('1 = Active, 2 = Inactive');
$table->timestamps();
$table->softDeletes();
// 🧩 Multi-restaurant scoped uniqueness
$table->unique(['restaurant_id', 'email']);
$table->unique(['restaurant_id', 'phone']);
// Foreign key
$table->foreign('restaurant_id')
->references('id')
->on('restaurants')
->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('customers');
}
};

View File

@@ -0,0 +1,85 @@
<?php
use App\Enum\OrderStatus;
use App\Enum\OrderType;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
// ====== Foreign Keys ======
$table->foreignId('restaurant_id')->constrained()->cascadeOnDelete();
$table->foreignId('table_id')->nullable()->constrained()->nullOnDelete();
$table->foreignId('waiter_id')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('driver_id')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('customer_id')->nullable()->constrained('customers')->nullOnDelete();
$table->foreignId('payment_method_id')->nullable()->constrained('payment_methods')->nullOnDelete();
// ====== Order Identifiers ======
$table->string('order_number')->unique()->comment('Unique order number for search');
$table->string('reference')->nullable();
// ====== Order Attributes ======
$table->enum('order_type', OrderType::values())->default(OrderType::DINE_IN)->index();
$table->enum('status', OrderStatus::values())->default(OrderStatus::PENDING)->index();
// ====== Amounts ======
$table->decimal('subtotal', 12, 2)->default(0.00)->comment('Sum of item totals before discount and tax');
$table->decimal('discount', 12, 2)->default(0.00)->comment('Discount applied to order');
$table->decimal('tax', 12, 2)->default(0.00)->comment('Tax applied on subtotal or after discount');
$table->decimal('service_charge', 12, 2)->default(0.00);
$table->decimal('tip_amount', 12, 2)->default(0.00);
$table->decimal('grand_total', 12, 2)->default(0.00)->comment('Total amount to be paid');
// ====== Payment Tracking ======
$table->boolean('payment_status')->default(false)->index();
$table->string('payment_reference')->nullable();
$table->timestamp('paid_at')->nullable();
// ====== Date & Time Tracking ======
$table->timestamp('order_date')->useCurrent()->index();
$table->time('preparation_time')->nullable()->comment('Estimated preparation duration (HH:MM:SS)');
$table->timestamp('ready_at')->nullable()->comment('Time when order ready');
$table->timestamp('handed_over_at')->nullable()->comment('Time when handed over to customer');
$table->timestamp('delivered_at')->nullable()->comment('Time delivered for delivery orders');
$table->timestamp('estimated_ready_time')->nullable();
// ====== Other Attributes ======
$table->text('delivery_address')->nullable();
$table->enum('order_source', ['POS', 'Web', 'MobileApp', 'ThirdParty'])->default('POS')->index();
$table->json('meta')->nullable()->comment('Flexible storage for extra info: loyalty, coupon, special instructions');
// Order Cancel
$table->timestamp('cancelled_at')->nullable();
$table->text('cancel_reason')->nullable();
$table->unsignedBigInteger('cancelled_by')->nullable();
// ====== Audit ======
$table->foreignId('added_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
// ====== Composite Indexes for Reports ======
$table->index(['restaurant_id', 'status', 'order_date'], 'idx_restaurant_status_date');
$table->index(['restaurant_id', 'order_date'], 'idx_restaurant_date');
$table->index(['customer_id', 'order_date'], 'idx_customer_date');
$table->index(['waiter_id', 'order_date'], 'idx_waiter_date');
$table->index(['order_type', 'order_date'], 'idx_order_type_date');
$table->index(['payment_status', 'order_date'], 'idx_payment_status_date');
$table->index(['order_source', 'order_date'], 'idx_order_source_date');
});
}
public function down(): void
{
Schema::dropIfExists('orders');
}
};

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('order_items', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')->constrained('orders')->cascadeOnDelete();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->foreignId('food_item_id')->constrained('food_items')->restrictOnDelete();
$table->foreignId('food_variant_id')->nullable()->constrained('food_variants')->restrictOnDelete();
$table->integer('quantity')->default(1);
$table->decimal('price', 12, 2)->default(0.00)->comment('Unit price of item/variant');
$table->decimal('discount', 12, 2)->default(0.00)->comment('Discount on this item');
$table->decimal('tax', 12, 2)->default(0.00)->comment('Tax for this item');
$table->decimal('total', 12, 2)->default(0.00)->comment('Total after quantity, discount, tax');
$table->json('addons')->nullable()->comment('List of addons with price, quantity');
$table->json('meta')->nullable()->comment('Extra info: special instructions, combo info, etc');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Cancelled');
$table->timestamps();
$table->softDeletes();
// ====== Indexes for reporting ======
$table->index(['order_id', 'food_item_id'], 'idx_order_food');
$table->index(['restaurant_id', 'food_item_id'], 'idx_restaurant_food');
});
}
public function down(): void
{
Schema::dropIfExists('order_items');
}
};

View File

@@ -0,0 +1,71 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('suppliers', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
// Basic Info
$table->string('name');
$table->string('phone');
$table->string('company_name')->nullable();
$table->string('contact_person')->nullable();
$table->string('alternate_phone')->nullable();
$table->string('email')->nullable();
$table->string('website')->nullable();
$table->string('image')->nullable(); // profile picture
// Address Info
$table->text('address')->nullable();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('country')->nullable();
$table->string('postal_code')->nullable();
// Financial / Business Info
$table->string('tax_number')->nullable()->comment('VAT/GST/Tax ID');
$table->string('bank_name')->nullable();
$table->string('bank_account_name')->nullable();
$table->string('bank_account_number')->nullable();
$table->string('ifsc_code')->nullable()->comment('For local bank transactions');
$table->decimal('opening_balance', 15, 2)->default(0);
$table->date('opening_balance_date')->nullable();
$table->decimal('due', 15, 2)->default(0);
$table->decimal('balance', 15, 2)->default(0);
// Relationship Info
$table->string('supply_type')->nullable()->comment('e.g. Food, Beverage, Cleaning, Equipment');
$table->string('payment_terms')->nullable()->comment('e.g. Net 7, Net 30, COD');
$table->decimal('credit_limit', 15, 2)->nullable();
// Ratings & Notes
$table->decimal('rating', 3, 2)->nullable()->comment('Average rating from 1-5');
$table->text('notes')->nullable();
// Documents
$table->string('contract_file')->nullable()->comment('Stored contract document path');
$table->string('trade_license')->nullable();
$table->string('nid_number')->nullable();
// Status and Timestamps
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Foreign key (optional if restaurants table exists)
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('suppliers');
}
};

View File

@@ -0,0 +1,58 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('ingredients', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name')->index();
// Unit Manage
$table->foreignId('unit_id')->constrained('units')->cascadeOnDelete();
$table->foreignId('unit_sale_id')->nullable()->constrained('units');
$table->foreignId('unit_purchase_id')->nullable()->constrained('units');
$table->decimal('stock_quantity', 10, 2)->default(0);
$table->decimal('cost_per_unit', 10, 2)->default(0);
$table->decimal('low_stock_alert', 10, 2)->default(0);
$table->string('image')->nullable(); // profile picture
// Supplier & Purchase Info
$table->unsignedBigInteger('supplier_id')->nullable()->comment('Link to main supplier');
$table->decimal('last_purchase_price', 10, 2)->nullable();
$table->date('last_purchase_date')->nullable();
// Units & conversions
$table->decimal('conversion_factor', 10, 2)->default(1)->comment('For unit conversions if needed');
// Stock & inventory tracking
$table->decimal('reserved_quantity', 10, 2)->default(0)->comment('Quantity reserved for pending orders/recipes');
$table->decimal('wastage_quantity', 10, 2)->default(0)->comment('Total wastage recorded');
// Optional categorization
$table->string('category')->nullable()->comment('e.g. Vegetable, Meat, Dairy, Beverage');
// Operational Notes
$table->text('notes')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
// Foreign keys
// $table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('ingredients');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_variant_ingredients', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('food_variant_id')->index();
$table->unsignedBigInteger('ingredient_id')->index();
$table->decimal('quantity', 10, 2)->default(0);
$table->decimal('wastage_percentage', 5, 2)->default(0);
$table->decimal('unit_conversion_factor', 10, 2)->default(1);
$table->string('optional', 1)->default('N');
$table->text('notes')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
$table->foreign('food_variant_id')->references('id')->on('food_variants')->onDelete('cascade');
$table->foreign('ingredient_id')->references('id')->on('ingredients')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('food_variant_ingredients');
}
};

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('purchases', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('supplier_id')->nullable()->index();
$table->string('invoice_no')->nullable()->unique();
$table->date('purchase_date')->default(now());
// Financial fields
$table->decimal('sub_total', 12, 2)->default(0);
$table->decimal('discount_amount', 12, 2)->default(0);
$table->decimal('tax_amount', 12, 2)->default(0);
$table->decimal('total_amount', 12, 2)->default(0);
$table->string('payment_status')->default('unpaid')->comment('paid, unpaid, partial');
$table->string('payment_method')->nullable()->comment('cash, bank, credit');
$table->string('purchase_type')->default('ingredient')->comment('ingredient, equipment, others');
$table->unsignedBigInteger('created_by')->nullable()->comment('User ID who created the purchase');
$table->text('notes')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Foreign keys
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('set null');
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
});
}
public function down(): void
{
Schema::dropIfExists('purchases');
}
};

View File

@@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('purchase_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('purchase_id')->index();
$table->unsignedBigInteger('ingredient_id')->index();
$table->unsignedBigInteger('food_variant_id')->nullable();
$table->decimal('quantity', 10, 2);
$table->decimal('unit_price', 12, 2);
$table->decimal('total_cost', 12, 2);
$table->decimal('tax_amount', 12, 2)->default(0);
$table->decimal('discount_amount', 12, 2)->default(0);
$table->string('batch_no')->nullable();
$table->date('expiry_date')->nullable();
$table->decimal('received_quantity', 10, 2)->nullable();
$table->decimal('wastage_quantity', 10, 2)->default(0);
$table->decimal('returned_quantity', 10, 2)->default(0);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
$table->foreign('purchase_id')->references('id')->on('purchases')->onDelete('cascade');
$table->foreign('ingredient_id')->references('id')->on('ingredients')->onDelete('cascade');
$table->foreign('food_variant_id')->references('id')->on('food_variants')->onDelete('set null');
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('purchase_items');
}
};

View File

@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('stocks', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->foreignId('ingredient_id')->constrained()->onDelete('cascade');
// Type of stock movement
$table->enum('type', ['purchase', 'usage', 'return', 'damage', 'transfer_in', 'transfer_out'])->index();
$table->decimal('quantity', 10, 2);
// Cost tracking
$table->decimal('unit_cost', 12, 2)->nullable()->comment('Cost per unit at time of stock movement');
$table->decimal('total_cost', 12, 2)->nullable()->comment('quantity * unit_cost');
// Reference linking
$table->string('reference_type')->nullable()->comment('e.g., Purchase, FoodVariant, Transfer');
$table->unsignedBigInteger('purchase_id')->nullable();
// Optional batch and expiry tracking
$table->string('batch_no')->nullable();
$table->date('expiry_date')->nullable();
// Accountability
$table->unsignedBigInteger('added_by')->nullable()->comment('User ID who added/modified stock');
$table->text('remarks')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Foreign keys
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->foreign('added_by')->references('id')->on('users')->onDelete('set null');
});
}
public function down(): void
{
Schema::dropIfExists('stocks');
}
};

View File

@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('ingredient_damages', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
// Link directly to the ingredient
$table->unsignedBigInteger('ingredient_id')->index();
// Optional: link to purchase batch for perishable tracking
$table->string('batch_no')->nullable();
$table->decimal('quantity', 10, 2);
// Cost tracking
$table->decimal('unit_cost', 12, 2)->nullable()->comment('Cost per unit at time of damage');
$table->decimal('total_cost', 12, 2)->nullable()->comment('quantity * unit_cost');
$table->string('reason')->nullable()->comment('Reason for damage: spoilage, breakage, etc.');
$table->date('damage_date')->default(now());
// Accountability
$table->unsignedBigInteger('reported_by')->nullable()->comment('User ID who reported the damage');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Foreign keys
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->foreign('ingredient_id')->references('id')->on('ingredients')->onDelete('cascade');
$table->foreign('reported_by')->references('id')->on('users')->onDelete('set null');
});
}
public function down(): void
{
Schema::dropIfExists('ingredient_damages');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_wastes', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->foreignId('food_item_id')->constrained('food_items')->restrictOnDelete();
$table->foreignId('food_variant_id')->nullable()->constrained('food_variants')->restrictOnDelete();
$table->decimal('quantity', 10, 2)->default(0);
$table->decimal('unit_cost', 16, 2)->nullable();
$table->string('reason')->nullable();
$table->text('notes')->nullable();
$table->unsignedBigInteger('wasted_by')->nullable();
$table->unsignedBigInteger('approved_by')->nullable();
$table->dateTime('wasted_at')->nullable();
$table->enum('status', ['pending', 'approved', 'rejected'])->default('pending');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('food_wastes');
}
};

View File

@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('purchase_returns', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
// Link to the original purchase and item
$table->unsignedBigInteger('purchase_id')->index();
$table->unsignedBigInteger('purchase_item_id')->index();
$table->unsignedBigInteger('ingredient_id')->index();
// Optional: link to purchase batch for tracking
$table->string('batch_no')->nullable();
// Return quantity and cost
$table->decimal('quantity', 10, 2);
$table->decimal('unit_cost', 12, 2)->nullable()->comment('Unit cost at time of purchase');
$table->decimal('total_cost', 12, 2)->nullable()->comment('quantity * unit_cost');
$table->string('reason')->nullable()->comment('Reason for return: damaged, expired, supplier return, etc.');
$table->date('return_date')->default(now());
// Accountability
$table->unsignedBigInteger('processed_by')->nullable()->comment('User ID who processed the return');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Foreign keys
$table->foreign('restaurant_id')->references('id')->on('restaurants')->onDelete('cascade');
$table->foreign('purchase_id')->references('id')->on('purchases')->onDelete('cascade');
$table->foreign('purchase_item_id')->references('id')->on('purchase_items')->onDelete('cascade');
$table->foreign('ingredient_id')->references('id')->on('ingredients')->onDelete('cascade');
$table->foreign('processed_by')->references('id')->on('users')->onDelete('set null');
});
}
public function down(): void
{
Schema::dropIfExists('purchase_returns');
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('reservations', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('table_id')->nullable();
$table->unsignedBigInteger('customer_id')->nullable();
$table->date('reservation_date');
$table->time('start_time');
$table->time('end_time')->nullable();
$table->integer('people_count')->default(1);
$table->enum('status', ['booked', 'free', 'upcoming', 'cancelled'])->default('upcoming');
$table->text('note')->nullable();
$table->foreign('table_id')->references('id')->on('tables')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('reservations');
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('reservation_unavailables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('table_id')->nullable();
$table->date('date');
$table->time('start_time');
$table->time('end_time');
$table->string('reason')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('reservation_unavailables');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('delivery_charges', function (Blueprint $table) {
$table->id();
$table->foreignId('zone_id')->constrained('zones')->onDelete('cascade');
$table->foreignId('restaurant_id')->nullable()->constrained('restaurants')->onDelete('cascade');
$table->enum('type', ['flat', 'distance_based'])->default('flat');
$table->decimal('base_charge', 10, 2)->default(0.00);
$table->decimal('per_km_charge', 10, 2)->nullable();
$table->decimal('min_order_amount', 10, 2)->default(0.00);
$table->decimal('free_delivery_above', 10, 2)->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('delivery_charges');
}
};

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('customer_addresses', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
$table->string('label', 50)->default('Home');
$table->string('address_line_1');
$table->string('address_line_2')->nullable();
$table->string('city', 100)->nullable();
$table->string('postal_code', 20)->nullable();
$table->decimal('latitude', 10, 7)->nullable();
$table->decimal('longitude', 10, 7)->nullable();
$table->boolean('is_default')->default(false);
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('customer_addresses');
}
};

View File

@@ -0,0 +1,43 @@
<?php
use App\Enum\TrackingStatus;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('order_trackings', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')
->constrained('orders')
->onDelete('cascade');
$table->foreignId('delivery_boy_id')
->nullable()
->constrained('users')
->onDelete('set null');
// ✅ Use Enum instead of hard-coded strings
$table->enum('status', TrackingStatus::values())
->default(TrackingStatus::Placed->value);
$table->decimal('latitude', 10, 7)->nullable();
$table->decimal('longitude', 10, 7)->nullable();
$table->string('location_name')->nullable();
$table->text('note')->nullable();
$table->timestamp('tracked_at')->useCurrent();
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('order_trackings');
}
};

View File

@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('restaurant_schedules', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained()->onDelete('cascade');
$table->enum('day', [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
]);
// if restaurant is closed full day
$table->boolean('is_open')->default(true);
$table->timestamps();
$table->softDeletes();
$table->unique(['restaurant_id', 'day']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_schedules');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('restaurant_schedule_times', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_schedule_id')->constrained('restaurant_schedules')->onDelete('cascade');
$table->time('open_time');
$table->time('close_time');
$table->timestamps();
$table->softDeletes();
$table->unique(['restaurant_schedule_id', 'open_time', 'close_time'], 'unique_restaurant_time_slot');
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_schedule_times');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('loyalty_points', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('order_id')->nullable();
$table->unsignedBigInteger('food_item_id')->nullable();
$table->integer('points')->default(0);
$table->enum('type', ['earned', 'redeemed', 'manual'])->default('earned');
$table->string('reason')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('loyalty_points');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('loyalty_redemptions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('food_item_id')->nullable();
$table->integer('points_used')->default(0);
$table->decimal('price', 16, 2)->nullable(); // original price
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('loyalty_redemptions');
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('reservation_settings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->time('start_time');
$table->time('end_time');
$table->integer('max_reservation')->default(0);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('reservation_settings');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('loyalty_point_settings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name');
$table->decimal('from_amount', 12, 2)->nullable();
$table->decimal('to_amount', 12, 2)->nullable();
$table->decimal('amount', 12, 2)->nullable();
$table->integer('earn_point')->default(0);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('loyalty_point_settings');
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('tax_settings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
// Basic tax info
$table->string('name', 100); // e.g., VAT, GST
$table->string('reg_no', 100)->nullable(); // registration number
// Upgrade: Instead of string default_value, use proper decimal
$table->enum('type', ['percentage', 'fixed'])->default('percentage');
$table->decimal('value', 12, 2)->nullable(); // actual tax value
// Default tax flag
$table->boolean('is_default')->default(false);
// Status
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('tax_settings');
}
};

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('q_r_menu_settings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
// Menu settings
$table->string('name', 100);
$table->string('menu_title', 150)->nullable();
$table->string('logo')->nullable();
$table->string('menu_url')->nullable();
$table->string('primary_color', 20)->nullable();
$table->string('secondary_color', 20)->nullable();
$table->string('bg_color', 20)->nullable();
$table->string('template', 50)->default('default');
$table->text('description')->nullable();
$table->string('qr_code_url')->nullable();
// WiFi settings
$table->string('wifi_name')->nullable();
$table->string('wifi_ssid')->nullable();
$table->string('wifi_password')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('q_r_menu_settings');
}
};

View File

@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('kitchens', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name');
$table->integer('serial')->default(0);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('kitchens');
}
};

View File

@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('kitchen_assigns', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->foreignId('kitchen_id')->constrained('kitchens')->onDelete('cascade');
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('kitchen_assigns');
}
};

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_reviews', function (Blueprint $table) {
$table->id();
// SaaS Scope
$table->unsignedBigInteger('restaurant_id')->index();
$table->unsignedBigInteger('food_item_id')->index();
$table->unsignedBigInteger('customer_id')->nullable()->index();
// Review Data
$table->tinyInteger('rating')->comment('1-5');
$table->text('review')->nullable();
// Media
$table->json('images')->nullable(); // ["url1","url2"]
$table->string('video_url')->nullable();
$table->string('video_file')->nullable();
// Status & Control
$table->enum('status', ['pending', 'approved', 'rejected'])->default('pending');
$table->boolean('is_featured')->default(false);
$table->integer('position')->default(0);
// Meta
$table->integer('helpful_count')->default(0);
$table->text('reject_reason')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('food_reviews');
}
};

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('food_review_replies', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->unsignedBigInteger('review_id')->index();
$table->unsignedBigInteger('user_id')->nullable();
$table->unsignedBigInteger('customer_id')->nullable();
$table->enum('user_type', ['admin', 'customer']);
$table->text('message')->nullable();
$table->json('attachments')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 0=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('food_review_replies');
}
};

View File

@@ -0,0 +1,38 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Modules\Authentication\Models\Restaurant;
use Modules\Restaurant\Models\Addon;
use Modules\Restaurant\Models\FoodItem;
class AddonFoodSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$foodItems = FoodItem::all();
$addons = Addon::all();
$restaurantId = Restaurant::first()?->id; // optional
foreach ($foodItems as $food) {
// randomly assign 1-3 addons
$randomAddons = $addons->random(rand(1, 3));
foreach ($randomAddons as $addon) {
DB::table('addon_food')->insert([
'restaurant_id' => $restaurantId,
'food_item_id' => $food->id,
'addon_id' => $addon->id,
'status' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\Addon;
class AddonTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$addons = [
['name' => 'Cookie', 'price' => 2.50, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Chilli Sauce', 'price' => 1.20, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Sour Plum Powder', 'price' => 0.99, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Extra Meat', 'price' => 3.99, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'BBQ Sauce', 'price' => 1.50, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Fresh Milk', 'price' => 2.00, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Enoki Mushrooms', 'price' => 2.99, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Chilli Padi', 'price' => 0.80, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Cheese', 'price' => 2.50, 'vat' => 5, 'pst' => 0, 'status' => 1],
['name' => 'Soup of the Day', 'price' => 3.99, 'vat' => 5, 'pst' => 0, 'status' => 1],
];
foreach ($addons as $addon) {
Addon::updateOrCreate(['restaurant_id' => 1, 'name' => $addon['name']], $addon);
}
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\FoodAvailability;
use Modules\Restaurant\Models\FoodAvailabilityTime;
class FoodAvailabilityTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$restaurantId = 1; // demo
$foodItemId = 1; // demo
$days = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
];
$defaultTimeSlots = [
['open_time' => '09:00:00', 'close_time' => '12:00:00'],
['open_time' => '13:00:00', 'close_time' => '17:00:00'],
['open_time' => '18:00:00', 'close_time' => '22:00:00'],
];
foreach ($days as $day) {
// Create availability per day
$availability = FoodAvailability::create([
'restaurant_id' => $restaurantId,
'food_item_id' => $foodItemId,
'day' => $day,
'is_available' => true,
]);
// Create time slots
foreach ($defaultTimeSlots as $slot) {
FoodAvailabilityTime::create([
'food_availability_id' => $availability->id,
'open_time' => $slot['open_time'],
'close_time' => $slot['close_time'],
]);
}
}
}
}

View File

@@ -0,0 +1,103 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\FoodCategory;
class FoodCategoryTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Biryani & Rice',
'image' => 'biryani_rice.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => false,
'start_date' => '2023-01-01',
'end_date' => null,
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Tandoori Specials',
'image' => 'tandoori_specials.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => true,
'start_date' => '2023-11-01',
'end_date' => '2023-12-31',
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Naan & Breads',
'image' => 'naan_breads.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => false,
'start_date' => '2022-10-10',
'end_date' => null,
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'South Indian',
'image' => 'south_indian.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => false,
'start_date' => '2023-02-01',
'end_date' => null,
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Chinese Cuisine',
'image' => 'chinese.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => true,
'start_date' => '2024-05-01',
'end_date' => '2024-07-01',
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Snacks & Starters',
'image' => 'starters.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => false,
'start_date' => '2023-03-01',
'end_date' => null,
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Desserts',
'image' => 'desserts.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => true,
'start_date' => '2024-12-01',
'end_date' => '2025-01-10',
]);
FoodCategory::create([
'restaurant_id' => 1,
'name' => 'Beverages',
'image' => 'beverages.jpg',
'parent_id' => null,
'status' => 1,
'is_offer' => false,
'start_date' => '2022-10-10',
'end_date' => null,
]);
}
}

View File

@@ -0,0 +1,183 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\FoodItem;
class FoodItemTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Butter Chicken',
'description' => 'Rich and creamy tomato-based chicken curry',
'category_id' => 2, // e.g., Tandoori Specials
'food_type' => 'Non-Veg',
'is_party' => 1,
'is_dinner' => 1,
'is_lunch' => 1,
'is_chef_special' => 1,
'is_popular_item' => 1,
'image' => 'butter_chicken.jpg',
'cooking_time' => '00:25:00',
'notes' => 'Pairs well with naan or rice',
'vat' => 5,
'pst' => 2,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Vegetable Biryani',
'description' => 'Fragrant basmati rice with mixed vegetables and spices',
'category_id' => 1, // Biryani & Rice
'food_type' => 'Veg',
'is_party' => 1,
'is_dinner' => 1,
'is_lunch' => 1,
'is_chef_special' => 1,
'is_popular_item' => 1,
'image' => 'veg_biryani.jpg',
'cooking_time' => '00:30:00',
'notes' => 'Best served with raita',
'vat' => 5,
'pst' => 0,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Masala Dosa',
'description' => 'Crispy rice pancake filled with spiced potato masala',
'category_id' => 4, // South Indian
'food_type' => 'Veg',
'is_party' => 0,
'is_dinner' => 0,
'is_lunch' => 1,
'is_chef_special' => 0,
'is_popular_item' => 1,
'image' => 'masala_dosa.jpg',
'cooking_time' => '00:20:00',
'notes' => 'Serve with coconut chutney and sambar',
'vat' => 5,
'pst' => 0,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Spring Rolls',
'description' => 'Crispy fried rolls stuffed with mixed vegetables',
'category_id' => 5, // Chinese Cuisine
'food_type' => 'Veg',
'is_party' => 1,
'is_dinner' => 0,
'is_lunch' => 0,
'is_chef_special' => 1,
'is_popular_item' => 0,
'image' => 'spring_rolls.jpg',
'cooking_time' => '00:15:00',
'notes' => 'Good as a starter',
'vat' => 5,
'pst' => 1,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Chicken Manchurian',
'description' => 'Fried chicken balls tossed in spicy tangy sauce',
'category_id' => 5,
'food_type' => 'Non-Veg',
'is_party' => 1,
'is_dinner' => 1,
'is_lunch' => 1,
'is_chef_special' => 1,
'is_popular_item' => 0,
'image' => 'chicken_manchurian.jpg',
'cooking_time' => '00:25:00',
'notes' => 'Serve with fried rice or noodles',
'vat' => 5,
'pst' => 2,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Paneer Tikka',
'description' => 'Grilled cottage cheese cubes marinated in Indian spices',
'category_id' => 2,
'food_type' => 'Veg',
'is_party' => 1,
'is_dinner' => 1,
'is_lunch' => 0,
'is_chef_special' => 0,
'is_popular_item' => 1,
'image' => 'paneer_tikka.jpg',
'cooking_time' => '00:20:00',
'notes' => 'Serve with mint chutney',
'vat' => 5,
'pst' => 1,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Gulab Jamun',
'description' => 'Soft deep-fried dumplings soaked in sugar syrup',
'category_id' => 7, // Desserts
'food_type' => 'Veg',
'is_party' => 1,
'is_dinner' => 0,
'is_lunch' => 0,
'is_chef_special' => 0,
'is_popular_item' => 1,
'image' => 'gulab_jamun.jpg',
'cooking_time' => '00:10:00',
'notes' => 'Serve warm',
'vat' => 5,
'pst' => 0,
'status' => 1,
]);
FoodItem::create([
'restaurant_id' => 1,
'menu_category_id' => 1,
'menu_section_id' => 1,
'name' => 'Lassi',
'description' => 'Refreshing yogurt-based drink',
'category_id' => 8, // Beverages
'food_type' => 'Veg',
'is_party' => 0,
'is_dinner' => 0,
'is_lunch' => 1,
'is_chef_special' => 1,
'is_popular_item' => 0,
'image' => 'lassi.jpg',
'cooking_time' => '00:05:00',
'notes' => 'Serve chilled',
'vat' => 5,
'pst' => 0,
'status' => 1,
]);
}
}

View File

@@ -0,0 +1,197 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class FoodVariantIngredientSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$now = Carbon::now();
$data = [
// 🍔 Beef Burger (variant_id = 1)
[
'restaurant_id' => 1,
'food_variant_id' => 1,
'ingredient_id' => 1, // Beef Patty
'quantity' => 1,
'wastage_percentage' => 2,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => '150g patty',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 1,
'ingredient_id' => 2, // Burger Bun
'quantity' => 1,
'wastage_percentage' => 1,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Fresh baked bun',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 1,
'ingredient_id' => 3, // Cheese Slice
'quantity' => 1,
'wastage_percentage' => 0,
'unit_conversion_factor' => 1,
'optional' => 'Y',
'notes' => 'Optional cheese topping',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 1,
'ingredient_id' => 4, // Tomato
'quantity' => 0.05,
'wastage_percentage' => 5,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Fresh tomato slices',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 1,
'ingredient_id' => 5, // Lettuce
'quantity' => 0.03,
'wastage_percentage' => 5,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Crisp lettuce leaves',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
// 🍟 French Fries (variant_id = 2)
[
'restaurant_id' => 1,
'food_variant_id' => 2,
'ingredient_id' => 6, // Potato
'quantity' => 0.25,
'wastage_percentage' => 8,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Peeled & sliced',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 2,
'ingredient_id' => 7, // Salt
'quantity' => 0.005,
'wastage_percentage' => 0,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Seasoning',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 2,
'ingredient_id' => 8, // Oil
'quantity' => 0.05,
'wastage_percentage' => 10,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'For deep frying',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
// 🍕 Margherita Pizza (variant_id = 3)
[
'restaurant_id' => 1,
'food_variant_id' => 3,
'ingredient_id' => 9, // Pizza Dough
'quantity' => 0.25,
'wastage_percentage' => 3,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Prepared dough base',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 3,
'ingredient_id' => 10, // Tomato Sauce
'quantity' => 0.10,
'wastage_percentage' => 2,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Base sauce',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 3,
'ingredient_id' => 11, // Mozzarella Cheese
'quantity' => 0.15,
'wastage_percentage' => 2,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Fresh mozzarella',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 3,
'ingredient_id' => 12, // Basil
'quantity' => 0.005,
'wastage_percentage' => 5,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Fresh basil leaves',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
[
'restaurant_id' => 1,
'food_variant_id' => 3,
'ingredient_id' => 13, // Olive Oil
'quantity' => 0.02,
'wastage_percentage' => 0,
'unit_conversion_factor' => 1,
'optional' => 'N',
'notes' => 'Drizzle after baking',
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
],
];
DB::table('food_variant_ingredients')->insert($data);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Modules\Restaurant\Models\FoodVariant;
class FoodVariantTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$variants = [
// Garlic Naan (food_item_id = 1)
['food_item_id' => 1, 'name' => 'Single Piece', 'price' => 1.99, 'offer_price' => 1.79, 'discount' => 10, 'unit_id' => 1],
['food_item_id' => 1, 'name' => 'Double Piece', 'price' => 3.49, 'offer_price' => 2.99, 'discount' => 14, 'unit_id' => 1],
// Butter Chicken (food_item_id = 2)
['food_item_id' => 2, 'name' => 'Half Plate', 'price' => 6.99, 'offer_price' => 6.49, 'discount' => 7, 'unit_id' => 1],
['food_item_id' => 2, 'name' => 'Full Plate', 'price' => 11.99, 'offer_price' => 10.99, 'discount' => 8, 'unit_id' => 1],
// Vegetable Biryani (food_item_id = 3)
['food_item_id' => 3, 'name' => 'Regular', 'price' => 5.49, 'offer_price' => 4.99, 'discount' => 9, 'unit_id' => 1],
['food_item_id' => 3, 'name' => 'Family Pack', 'price' => 9.99, 'offer_price' => 8.99, 'discount' => 10, 'unit_id' => 1],
// Masala Dosa (food_item_id = 4)
['food_item_id' => 4, 'name' => 'Classic', 'price' => 4.99, 'offer_price' => 4.49, 'discount' => 10, 'unit_id' => 1],
['food_item_id' => 4, 'name' => 'Cheese Masala Dosa', 'price' => 6.49, 'offer_price' => 5.99, 'discount' => 8, 'unit_id' => 1],
// Spring Rolls (food_item_id = 5)
['food_item_id' => 5, 'name' => '4 pcs', 'price' => 3.99, 'offer_price' => 3.49, 'discount' => 12, 'unit_id' => 1],
['food_item_id' => 5, 'name' => '8 pcs', 'price' => 6.99, 'offer_price' => 6.49, 'discount' => 7, 'unit_id' => 1],
// Paneer Tikka (food_item_id = 6)
['food_item_id' => 6, 'name' => '6 pcs', 'price' => 5.49, 'offer_price' => 4.99, 'discount' => 9, 'unit_id' => 1],
['food_item_id' => 6, 'name' => '10 pcs', 'price' => 8.99, 'offer_price' => 7.99, 'discount' => 11, 'unit_id' => 1],
// Gulab Jamun (food_item_id = 7)
['food_item_id' => 7, 'name' => '2 pcs', 'price' => 2.49, 'offer_price' => 2.29, 'discount' => 8, 'unit_id' => 1],
['food_item_id' => 7, 'name' => '5 pcs', 'price' => 5.49, 'offer_price' => 4.99, 'discount' => 9, 'unit_id' => 1],
// Lassi (food_item_id = 8)
['food_item_id' => 8, 'name' => 'Regular Glass', 'price' => 2.99, 'offer_price' => 2.49, 'discount' => 17, 'unit_id' => 1],
['food_item_id' => 8, 'name' => 'Large Glass', 'price' => 3.99, 'offer_price' => 3.49, 'discount' => 12, 'unit_id' => 1],
];
$foodItemDefaultMap = []; // Track default per food item
foreach ($variants as $variant) {
$foodItemId = $variant['food_item_id'];
// Assign default only if not assigned before
$isDefault = isset($foodItemDefaultMap[$foodItemId]) ? false : true;
if ($isDefault) {
$foodItemDefaultMap[$foodItemId] = true;
}
FoodVariant::create([
'restaurant_id' => 1,
'food_item_id' => $foodItemId,
'name' => $variant['name'],
'sku' => 'FV-'.strtoupper(Str::random(8)),
'price' => $variant['price'],
'offer_price' => $variant['offer_price'],
'discount' => $variant['discount'],
'unit_id' => $variant['unit_id'],
'description' => $variant['name'].' variant for food ID '.$foodItemId,
'is_default' => $isDefault,
'status' => 1,
'offer_start_at' => Carbon::now(),
'offer_end_at' => Carbon::now()->addDays(rand(5, 30)),
]);
}
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\Ingredient;
use Modules\Restaurant\Models\IngredientDamage;
class IngredientDamageSeeder extends Seeder
{
public function run(): void
{
$ingredients = Ingredient::limit(5)->get();
foreach ($ingredients as $ingredient) {
IngredientDamage::create([
'restaurant_id' => $ingredient->restaurant_id,
'ingredient_id' => $ingredient->id,
'batch_no' => 'BATCH-'.rand(100, 999),
'quantity' => rand(1, 20),
'unit_cost' => rand(10, 500),
'total_cost' => rand(10, 500) * rand(1, 20),
'reason' => ['Spoilage', 'Breakage', 'Expired'][array_rand(['Spoilage', 'Breakage', 'Expired'])],
'damage_date' => now()->subDays(rand(0, 30)),
'reported_by' => 1, // Admin/User ID
'status' => 1,
]);
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Faker\Factory as Faker;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\Ingredient;
use Modules\Restaurant\Models\Supplier;
class IngredientSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$faker = Faker::create();
$restaurantId = 1; // Change or randomize if multi-restaurant setup
// Try to get existing supplier IDs
$supplierIds = Supplier::pluck('id')->toArray();
$units = [1, 2, 3, 4, 5];
$categories = ['Vegetable', 'Meat', 'Dairy', 'Beverage', 'Spices', 'Grains', 'Bakery', 'Seafood', 'Fruits', 'Others'];
$ingredients = [];
for ($i = 1; $i <= 50; $i++) {
$unit = $faker->randomElement($units);
$category = $faker->randomElement($categories);
$supplierId = ! empty($supplierIds) ? $faker->randomElement($supplierIds) : null;
$costPerUnit = $faker->randomFloat(2, 10, 500);
$stockQty = $faker->randomFloat(2, 5, 500);
$lowStock = $faker->randomFloat(2, 1, 10);
$ingredients[] = [
'restaurant_id' => $restaurantId,
'supplier_id' => $supplierId,
'name' => ucfirst($faker->word),
'unit_id' => $unit,
'stock_quantity' => $stockQty,
'cost_per_unit' => $costPerUnit,
'low_stock_alert' => $lowStock,
'last_purchase_price' => $faker->optional()->randomFloat(2, 10, 500),
'last_purchase_date' => $faker->optional()->date(),
'conversion_factor' => $faker->randomFloat(2, 0.5, 2),
'reserved_quantity' => $faker->randomFloat(2, 0, 20),
'wastage_quantity' => $faker->randomFloat(2, 0, 10),
'category' => $category,
'notes' => $faker->optional()->sentence(10),
'status' => $faker->randomElement([0, 1]),
'created_at' => now(),
'updated_at' => now(),
];
}
Ingredient::insert($ingredients);
$this->command->info('✅ Seeded 50 ingredients successfully.');
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Modules\Restaurant\Models\MenuCategory;
class MenuCategorySeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$categories = [
[
'restaurant_id' => 1,
'name' => 'Coffee',
'icon' => 'coffee.png',
'description' => 'Hot and cold coffee beverages made from premium beans.',
'priority' => 1,
'status' => true,
],
[
'restaurant_id' => 1,
'name' => 'Fast Food',
'icon' => 'burger.png',
'description' => 'Quick bites and delicious fast-food meals.',
'priority' => 2,
'status' => true,
],
[
'restaurant_id' => 1,
'name' => 'Pizza',
'icon' => 'pizza.png',
'description' => 'Freshly baked pizzas with various toppings.',
'priority' => 3,
'status' => true,
],
[
'restaurant_id' => 1,
'name' => 'Desi Menu',
'icon' => 'desi.png',
'description' => 'Authentic local dishes with a traditional touch.',
'priority' => 4,
'status' => true,
],
[
'restaurant_id' => 1,
'name' => 'Desserts',
'icon' => 'dessert.png',
'description' => 'Sweet treats to complete your meal.',
'priority' => 5,
'status' => true,
],
];
foreach ($categories as $cat) {
MenuCategory::updateOrCreate(
['slug' => Str::slug($cat['name'])],
array_merge($cat, ['slug' => Str::slug($cat['name'])])
);
}
}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Modules\Restaurant\Models\MenuCategory;
use Modules\Restaurant\Models\MenuSection;
class MenuSectionSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$sections = [
// Coffee
[
'menu_category' => 'Coffee',
'name' => 'Hot Coffee',
'description' => 'Classic and premium hot coffee menu.',
'priority' => 1,
'status' => true,
],
[
'menu_category' => 'Coffee',
'name' => 'Cold Coffee',
'description' => 'Iced and refreshing cold coffee menu.',
'priority' => 2,
'status' => true,
],
// Fast Food
[
'menu_category' => 'Fast Food',
'name' => 'Burgers',
'description' => 'Delicious burgers made fresh to order.',
'priority' => 1,
'status' => true,
],
[
'menu_category' => 'Fast Food',
'name' => 'Wraps',
'description' => 'Tasty wraps filled with fresh ingredients.',
'priority' => 2,
'status' => true,
],
// Pizza
[
'menu_category' => 'Pizza',
'name' => 'Regular Pizzas',
'description' => 'Classic pizzas with standard toppings.',
'priority' => 1,
'status' => true,
],
[
'menu_category' => 'Pizza',
'name' => 'Special Pizzas',
'description' => 'Signature pizzas with unique flavors.',
'priority' => 2,
'status' => true,
],
// Desi Menu
[
'menu_category' => 'Desi Menu',
'name' => 'Rice Items',
'description' => 'Traditional rice dishes served with curry.',
'priority' => 1,
'status' => true,
],
[
'menu_category' => 'Desi Menu',
'name' => 'Curry Items',
'description' => 'Spicy and flavorful local curries.',
'priority' => 2,
'status' => true,
],
// Desserts
[
'menu_category' => 'Desserts',
'name' => 'Cakes',
'description' => 'Freshly baked cakes for every occasion.',
'priority' => 1,
'status' => true,
],
[
'menu_category' => 'Desserts',
'name' => 'Ice Creams',
'description' => 'Cool and creamy ice cream delights.',
'priority' => 2,
'status' => true,
],
];
foreach ($sections as $sec) {
$category = MenuCategory::where('name', $sec['menu_category'])->first();
if ($category) {
MenuSection::updateOrCreate(
['slug' => Str::slug($sec['name'])],
[
'restaurant_id' => 1,
'menu_category_id' => $category->id,
'name' => $sec['name'],
'slug' => Str::slug($sec['name']),
'description' => $sec['description'],
'priority' => $sec['priority'],
'status' => $sec['status'],
]
);
}
}
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\MenuType;
class MenuTypeTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$menuTypes = [
['name' => 'Party', 'icon' => 'party.jpg', 'status' => 1],
['name' => 'Coffee', 'icon' => 'coffee.jpg', 'status' => 1],
['name' => 'Dinner', 'icon' => 'dinner.jpg', 'status' => 1],
['name' => 'Launch', 'icon' => 'launch.jpg', 'status' => 1],
];
foreach ($menuTypes as $type) {
MenuType::create([
'restaurant_id' => 1,
'name' => $type['name'],
'icon' => 'uploads/menu/'.$type['icon'],
'status' => $type['status'],
]);
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Modules\Authentication\Models\User;
use Modules\Restaurant\Models\Customer;
use Modules\Restaurant\Models\FoodItem;
use Modules\Restaurant\Models\Order;
use Modules\Restaurant\Models\OrderItem;
use Modules\Restaurant\Models\PaymentMethod;
use Modules\Restaurant\Models\Table;
class OrderSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$foods = FoodItem::all();
$tables = Table::all();
$customers = Customer::all();
$paymentMethods = PaymentMethod::all();
$waiter = User::first(); // assume 1st user is waiter
// Prevent running if no data available
if ($foods->isEmpty() || $tables->isEmpty() || $customers->isEmpty() || $paymentMethods->isEmpty()) {
$this->command->warn('⚠️ Missing related data (foods, tables, customers, or payment methods). Seeder skipped.');
return;
}
foreach (range(1, 100) as $i) {
// Pick a random order date within the last 30 days
$orderDate = Carbon::now()->subDays(rand(0, 29))->setTime(rand(10, 22), [0, 30][rand(0, 1)]);
// Create main order
$order = Order::create([
'restaurant_id' => 1,
'order_type' => collect(['dine_in', 'takeaway', 'delivery'])->random(),
'order_number' => 'ORD-'.$orderDate->format('Ymd').'-'.rand(1000, 99999),
'status' => collect(['pending', 'completed', 'cancelled'])->random(),
'order_date' => $orderDate,
'table_id' => $tables->random()->id,
'payment_method_id' => $paymentMethods->random()->id,
'payment_status' => collect([0, 1])->random(),
'waiter_id' => $waiter?->id,
'customer_id' => $customers->random()->id,
'grand_total' => 0,
]);
// Add random items
$total = 0;
foreach ($foods->random(rand(1, 3)) as $food) {
$qty = rand(1, 2);
$price = $food->price ?? 100;
$lineTotal = $qty * $price;
OrderItem::create([
'restaurant_id' => 1,
'order_id' => $order->id,
'food_item_id' => $food->id,
'quantity' => $qty,
'price' => $price,
'total' => $lineTotal,
]);
$total += $lineTotal;
}
$order->update(['grand_total' => $total]);
}
$this->command->info('✅ 100 random orders seeded successfully (within the last 30 days).');
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\PaymentMethod;
class PaymentMethodSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$methods = ['Cash', 'Card', 'Online'];
foreach ($methods as $method) {
PaymentMethod::create([
'restaurant_id' => 1,
'name' => $method,
]);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\PurchaseItem;
use Modules\Restaurant\Models\PurchaseReturn;
class PurchaseReturnSeeder extends Seeder
{
public function run(): void
{
$purchaseItems = PurchaseItem::limit(5)->get();
foreach ($purchaseItems as $item) {
$returnQty = rand(1, max(1, (int) ($item->received_quantity - $item->returned_quantity)));
PurchaseReturn::create([
'restaurant_id' => $item->restaurant_id,
'purchase_id' => $item->purchase_id,
'purchase_item_id' => $item->id,
'ingredient_id' => $item->ingredient_id,
'batch_no' => $item->batch_no,
'quantity' => $returnQty,
'unit_cost' => $item->unit_price,
'total_cost' => $item->unit_price * $returnQty,
'reason' => ['Damaged', 'Expired', 'Supplier Return'][array_rand(['Damaged', 'Expired', 'Supplier Return'])],
'return_date' => now()->subDays(rand(0, 10)),
'processed_by' => 1, // Admin/User ID
'status' => 1,
]);
}
}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Faker\Factory as Faker;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Modules\Authentication\Models\User;
use Modules\Restaurant\Models\Ingredient;
use Modules\Restaurant\Models\Purchase;
use Modules\Restaurant\Models\PurchaseItem;
use Modules\Restaurant\Models\Stock;
use Modules\Restaurant\Models\Supplier;
class PurchaseSeeder extends Seeder
{
public function run(): void
{
$faker = Faker::create();
$restaurantId = 1; // set dynamically later if needed
$supplierIds = Supplier::pluck('id')->toArray();
$ingredientIds = Ingredient::pluck('id')->toArray();
$userIds = User::pluck('id')->toArray();
if (empty($supplierIds) || empty($ingredientIds)) {
$this->command->warn('⚠️ Skipping PurchaseSeeder: No suppliers or ingredients found.');
return;
}
$purchaseCount = rand(10, 20);
for ($i = 1; $i <= $purchaseCount; $i++) {
$supplierId = $faker->randomElement($supplierIds);
$createdBy = ! empty($userIds) ? $faker->randomElement($userIds) : null;
$purchase = Purchase::create([
'restaurant_id' => $restaurantId,
'supplier_id' => $supplierId,
'invoice_no' => strtoupper(Str::random(8)),
'purchase_date' => $faker->dateTimeBetween('-3 months', 'now'),
'sub_total' => 0,
'discount_amount' => 0,
'tax_amount' => 0,
'total_amount' => 0,
'payment_status' => $faker->randomElement(['paid', 'unpaid', 'partial']),
'payment_method' => $faker->randomElement(['cash', 'bank', 'credit']),
'purchase_type' => $faker->randomElement(['ingredient', 'equipment', 'others']),
'created_by' => $createdBy,
'notes' => $faker->optional()->sentence(10),
'status' => 1,
]);
$itemCount = rand(2, 6);
$subTotal = $taxTotal = $discountTotal = 0;
for ($j = 1; $j <= $itemCount; $j++) {
$ingredientId = $faker->randomElement($ingredientIds);
$quantity = $faker->randomFloat(2, 1, 20);
$unitPrice = $faker->randomFloat(2, 10, 500);
$tax = $faker->randomFloat(2, 0, 10);
$discount = $faker->randomFloat(2, 0, 5);
$totalCost = ($unitPrice * $quantity) + $tax - $discount;
$item = PurchaseItem::create([
'restaurant_id' => $restaurantId,
'purchase_id' => $purchase->id,
'ingredient_id' => $ingredientId,
'quantity' => $quantity,
'unit_price' => $unitPrice,
'total_cost' => $totalCost,
'tax_amount' => $tax,
'discount_amount' => $discount,
'batch_no' => strtoupper(Str::random(6)),
'expiry_date' => $faker->optional()->dateTimeBetween('now', '+1 year'),
'received_quantity' => $quantity,
'wastage_quantity' => $faker->randomFloat(2, 0, 1),
'returned_quantity' => $faker->randomFloat(2, 0, 1),
'status' => 1,
]);
// ✅ Stock Adjustment
Stock::create([
'restaurant_id' => $restaurantId,
'ingredient_id' => $ingredientId,
'type' => 'purchase',
'quantity' => $quantity,
'unit_cost' => $unitPrice,
'total_cost' => $totalCost,
'reference_type' => 'Purchase',
'purchase_id' => $purchase->id,
'batch_no' => $item->batch_no,
'expiry_date' => $item->expiry_date,
'added_by' => $createdBy,
'remarks' => 'Auto stock-in from purchase #'.$purchase->invoice_no,
'status' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
$subTotal += ($unitPrice * $quantity);
$taxTotal += $tax;
$discountTotal += $discount;
}
$purchase->update([
'sub_total' => $subTotal,
'tax_amount' => $taxTotal,
'discount_amount' => $discountTotal,
'total_amount' => ($subTotal + $taxTotal - $discountTotal),
]);
}
$this->command->info("✅ Seeded {$purchaseCount} purchases with items and stock adjustments successfully.");
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\QRMenuSetting;
class QRMenuSettingTableSeeder extends Seeder
{
public function run(): void
{
QRMenuSetting::create([
'restaurant_id' => 1,
'name' => 'Default QR Menu',
'menu_title' => 'Our Menu',
'primary_color' => '#FF5722',
'secondary_color' => '#FFC107',
'bg_color' => '#FFFFFF',
'template' => 'template_1',
'description' => 'Welcome to our digital menu!',
'wifi_name' => 'Restaurant-WiFi',
'wifi_ssid' => 'RESTO1234',
'wifi_password' => '12345678',
'status' => 1, // active/inactive
'created_at' => now(),
'updated_at' => now(),
]);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class ReservationSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Sample restaurant and table IDs
$restaurantIds = [1];
$tableIds = [1, 2, 3, 4, 5];
$customerIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
// Clear old data
DB::table('reservations')->truncate();
DB::table('reservation_unavailables')->truncate();
// Seed reservations
foreach (range(1, 10) as $i) {
$restaurantId = $restaurantIds[array_rand($restaurantIds)];
$tableId = $tableIds[array_rand($tableIds)];
$customerId = $customerIds[array_rand($customerIds)];
$date = Carbon::now()->addDays(rand(0, 5))->toDateString();
$startTime = Carbon::createFromTime(rand(10, 20), [0, 30][rand(0, 1)]);
$endTime = (clone $startTime)->addHours(2);
DB::table('reservations')->insert([
'restaurant_id' => $restaurantId,
'table_id' => $tableId,
'customer_id' => $customerId,
'reservation_date' => $date,
'start_time' => $startTime->format('H:i:s'),
'end_time' => $endTime->format('H:i:s'),
'people_count' => rand(2, 8),
'status' => collect(['booked', 'free', 'upcoming', 'cancelled'])->random(),
'note' => fake()->sentence(),
'created_at' => now(),
'updated_at' => now(),
]);
}
// Seed unavailable times
foreach (range(1, 5) as $i) {
$restaurantId = $restaurantIds[array_rand($restaurantIds)];
$tableId = $tableIds[array_rand($tableIds)];
$date = Carbon::now()->addDays(rand(0, 5))->toDateString();
$startTime = Carbon::createFromTime(rand(10, 22), [0, 30][rand(0, 1)]);
$endTime = (clone $startTime)->addHours(rand(1, 3));
DB::table('reservation_unavailables')->insert([
'restaurant_id' => $restaurantId,
'table_id' => $tableId,
'date' => $date,
'start_time' => $startTime->format('H:i:s'),
'end_time' => $endTime->format('H:i:s'),
'reason' => fake()->sentence(),
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
class RestaurantDatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$this->call([
QRMenuSettingTableSeeder::class,
FoodCategoryTableSeeder::class,
MenuCategorySeeder::class,
MenuSectionSeeder::class,
MenuTypeTableSeeder::class,
AddonTableSeeder::class,
UnitSeeder::class,
FoodItemTableSeeder::class,
AddonFoodSeeder::class,
FoodVariantTableSeeder::class,
FoodAvailabilityTableSeeder::class,
RestaurantScheduleTableSeeder::class,
SupplierSeeder::class,
TableSeeder::class,
PaymentMethodSeeder::class,
IngredientSeeder::class,
// Food Variant Ingredient
FoodVariantIngredientSeeder::class,
// Purchase
PurchaseSeeder::class,
PurchaseReturnSeeder::class,
IngredientDamageSeeder::class,
ReservationSeeder::class,
// Order
OrderSeeder::class,
]);
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\RestaurantSchedule;
use Modules\Restaurant\Models\RestaurantScheduleTime;
class RestaurantScheduleTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$restaurantId = 1; // demo restaurant id
$days = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
];
// Default demo opening time slots
$defaultTimeSlots = [
['open_time' => '08:00:00', 'close_time' => '12:00:00'],
['open_time' => '13:00:00', 'close_time' => '17:00:00'],
['open_time' => '18:00:00', 'close_time' => '23:00:00'],
];
foreach ($days as $day) {
// Create day-wise schedule
$schedule = RestaurantSchedule::create([
'restaurant_id' => $restaurantId,
'day' => $day,
'is_open' => true, // default restaurant is open
]);
// Insert multiple time slots
foreach ($defaultTimeSlots as $slot) {
RestaurantScheduleTime::create([
'restaurant_schedule_id' => $schedule->id,
'open_time' => $slot['open_time'],
'close_time' => $slot['close_time'],
]);
}
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Carbon\Carbon;
use Faker\Factory as Faker;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class SupplierSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$faker = Faker::create();
$count = rand(10, 50);
for ($i = 0; $i < $count; $i++) {
DB::table('suppliers')->insert([
'restaurant_id' => 1,
'name' => $faker->name,
'phone' => $faker->phoneNumber,
'company_name' => $faker->company,
'contact_person' => $faker->name,
'alternate_phone' => $faker->optional()->phoneNumber,
'email' => $faker->optional()->safeEmail,
'website' => $faker->optional()->url,
'address' => $faker->address,
'city' => $faker->city,
'state' => $faker->state,
'country' => $faker->country,
'postal_code' => $faker->postcode,
'tax_number' => $faker->optional()->numerify('TAX#######'),
'bank_name' => $faker->optional()->company,
'bank_account_name' => $faker->optional()->name,
'bank_account_number' => $faker->optional()->numerify('##########'),
'ifsc_code' => $faker->optional()->bothify('BANK####'),
'opening_balance' => $faker->randomFloat(2, 0, 50000),
'opening_balance_date' => $faker->optional()->date(),
'due' => $faker->randomFloat(2, 0, 10000),
'balance' => $faker->randomFloat(2, 0, 10000),
'supply_type' => $faker->randomElement(['Food', 'Beverage', 'Cleaning', 'Equipment']),
'payment_terms' => $faker->randomElement(['Net 7', 'Net 15', 'Net 30', 'COD']),
'credit_limit' => $faker->optional()->randomFloat(2, 1000, 50000),
'rating' => $faker->randomFloat(2, 3, 5),
'notes' => $faker->optional()->sentence(10),
'contract_file' => null,
'trade_license' => $faker->optional()->numerify('TL-######'),
'nid_number' => $faker->optional()->numerify('NID##########'),
'status' => $faker->randomElement([1, 2]),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
$this->command->info("✅ Seeded {$count} suppliers successfully.");
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\Table;
class TableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$sections = ['Main Hall', 'VIP Area', 'Outdoor'];
$tableTypes = ['regular', 'vip', 'outdoor', 'booth'];
foreach (range(1, 10) as $num) {
Table::create([
'restaurant_id' => 1,
'name' => 'T'.str_pad($num, 2, '0', STR_PAD_LEFT),
'serial' => 'T'.str_pad($num, 2, '0', STR_PAD_LEFT),
'location' => 'Floor 1',
'section' => $sections[array_rand($sections)],
'table_type' => $tableTypes[array_rand($tableTypes)],
'capacity' => rand(2, 6),
'is_bookable' => true,
'qr_code' => 'QR'.str_pad($num, 2, '0', STR_PAD_LEFT),
'image' => null,
'position_x' => rand(50, 500),
'position_y' => rand(50, 500),
'rotation' => rand(0, 360),
'z_index' => rand(1, 10),
'status' => 1,
]);
}
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace Modules\Restaurant\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Restaurant\Models\Unit;
class UnitSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run()
{
$restaurantId = 1; // fixed restaurant_id
// === Weight Units ===
$gram = Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Gram',
'short_name' => 'g',
'type' => 'weight',
'is_default' => 1,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Kilogram',
'short_name' => 'kg',
'type' => 'weight',
'base_unit_id' => $gram->id,
'operator' => '*',
'operator_value' => 1000,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Milligram',
'short_name' => 'mg',
'type' => 'weight',
'base_unit_id' => $gram->id,
'operator' => '/',
'operator_value' => 1000,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Pound',
'short_name' => 'lb',
'type' => 'weight',
'base_unit_id' => $gram->id,
'operator' => '*',
'operator_value' => 453.592,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Ounce',
'short_name' => 'oz',
'type' => 'weight',
'base_unit_id' => $gram->id,
'operator' => '*',
'operator_value' => 28.3495,
]);
// === Volume Units ===
$ml = Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Milliliter',
'short_name' => 'ml',
'type' => 'volume',
'is_default' => 1,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Liter',
'short_name' => 'l',
'type' => 'volume',
'base_unit_id' => $ml->id,
'operator' => '*',
'operator_value' => 1000,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Teaspoon',
'short_name' => 'tsp',
'type' => 'volume',
'base_unit_id' => $ml->id,
'operator' => '*',
'operator_value' => 5,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Tablespoon',
'short_name' => 'tbsp',
'type' => 'volume',
'base_unit_id' => $ml->id,
'operator' => '*',
'operator_value' => 15,
]);
// === Count Units ===
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Piece',
'short_name' => 'pcs',
'type' => 'count',
'is_default' => 1,
]);
// === Length Units ===
$meter = Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Meter',
'short_name' => 'm',
'type' => 'length',
'is_default' => 1,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Centimeter',
'short_name' => 'cm',
'type' => 'length',
'base_unit_id' => $meter->id,
'operator' => '/',
'operator_value' => 100,
]);
Unit::create([
'restaurant_id' => $restaurantId,
'name' => 'Millimeter',
'short_name' => 'mm',
'type' => 'length',
'base_unit_id' => $meter->id,
'operator' => '/',
'operator_value' => 1000,
]);
}
}