migrate to gtea from bistbucket
This commit is contained in:
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user