21-11-2025

This commit is contained in:
Kevin Adametz 2025-11-21 18:21:23 +01:00
parent fa2ebd457d
commit 07959c0ba2
113 changed files with 4730 additions and 898 deletions

View file

@ -0,0 +1,136 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$teams = config('permission.teams');
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
$pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
$pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
throw_if(empty($tableNames), new Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.'));
throw_if($teams && empty($columnNames['team_foreign_key'] ?? null), new Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.'));
Schema::create($tableNames['permissions'], static function (Blueprint $table) {
// $table->engine('InnoDB');
$table->bigIncrements('id'); // permission id
$table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format)
$table->string('guard_name'); // For MyISAM use string('guard_name', 25);
$table->timestamps();
$table->unique(['name', 'guard_name']);
});
Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) {
// $table->engine('InnoDB');
$table->bigIncrements('id'); // role id
if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
$table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
}
$table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format)
$table->string('guard_name'); // For MyISAM use string('guard_name', 25);
$table->timestamps();
if ($teams || config('permission.testing')) {
$table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
} else {
$table->unique(['name', 'guard_name']);
}
});
Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) {
$table->unsignedBigInteger($pivotPermission);
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
$table->foreign($pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary');
} else {
$table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary');
}
});
Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) {
$table->unsignedBigInteger($pivotRole);
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
$table->foreign($pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary');
} else {
$table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary');
}
});
Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) {
$table->unsignedBigInteger($pivotPermission);
$table->unsignedBigInteger($pivotRole);
$table->foreign($pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign($pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['model_has_roles']);
Schema::drop($tableNames['model_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
};

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('hubs', function (Blueprint $table) {
$table->id();
$table->string('name'); // z.B. "OWL" oder "Rhein-Main"
$table->string('slug')->unique(); // Für saubere URLs, z.B. "owl"
$table->string('keyvisual_url')->nullable(); // Keyvisual-Bild des Hubs
$table->string('emblem_url')->nullable(); // Wappen-URL des Hubs
$table->boolean('is_active')->default(false);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('hubs');
}
};

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('hub_locations', function (Blueprint $table) {
$table->id();
// Beziehung zum Hub
$table->foreignId('hub_id')->constrained()->onDelete('cascade');
$table->string('city_name')->nullable(); // z.B. "Bielefeld"
$table->string('zip_code'); // z.B. "33602"
// Index für schnelle PLZ-Suche
$table->index('zip_code');
// Verhindert doppelte PLZ-Einträge pro Hub
$table->unique(['hub_id', 'zip_code']);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('hub_locations');
}
};

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('partners', function (Blueprint $table) {
$table->id();
$table->string('company_name');
$table->string('slug')->unique();
// Partner-Typ (gemäß Wissensbasis)
$table->string('type'); // 'Retailer', 'Manufacturer', 'Estate-Agent'
// Hub-Zugehörigkeit (kann NULL sein für "globale" Hersteller)
$table->foreignId('hub_id')->nullable()->constrained()->onDelete('set null');
$table->text('description')->nullable();
$table->string('logo_url')->nullable();
$table->boolean('is_active')->default(false);
// Spezifische Felder für 'Retailer' (Händler)
$table->integer('delivery_radius_km')->nullable();
$table->integer('assembly_radius_km')->nullable();
// Flexible Provisions-Engine (pro Partner)
// Speichert den Wert in Cents, um Rundungsfehler zu vermeiden
$table->integer('provision_fixed_amount')->nullable();
// Speichert als 10.5 für 10.5%
$table->decimal('provision_rate_percentage', 5, 2)->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('partners');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->string('color', 50)->default('zinc')->after('guard_name');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->dropColumn('color');
});
}
};

View file

@ -0,0 +1,40 @@
<?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::table('users', function (Blueprint $table) {
// Verknüpft einen User mit einer Partner-Firma
// 'after' ist optional, aber gut für die DB-Lesbarkeit
$table->foreignId('partner_id')
->nullable()
->after('id')
->constrained('partners')
->onDelete('set null'); // Wenn Partner gelöscht wird, bleibt User bestehen
});
}
public function down(): void
{
// Entferne Foreign Key zuerst
try {
Schema::table('users', function (Blueprint $table) {
$table->dropForeign(['partner_id']);
});
} catch (\Exception $e) {
// Foreign Key existiert nicht oder hat anderen Namen - weitermachen
}
// Entferne Spalte
if (Schema::hasColumn('users', 'partner_id')) {
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('partner_id');
});
}
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('attributes', function (Blueprint $table) {
$table->id();
$table->string('name'); // z.B. "Farbe", "Größe", "Material"
$table->string('slug')->unique();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('attributes');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('attribute_values', function (Blueprint $table) {
$table->id();
$table->foreignId('attribute_id')->constrained('attributes')->onDelete('cascade');
$table->string('value'); // z.B. "Anthrazit", "3-Sitzer", "Eiche"
$table->string('slug')->unique();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('attribute_values');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('media', function (Blueprint $table) {
$table->id();
$table->string('model_type'); // "App\Models\Product" ODER "App\Models\ProductVariant"
$table->unsignedBigInteger('model_id');
$table->string('file_path');
$table->string('type')->default('image'); // 'image', 'video', 'pdf', '3d_model'
$table->string('alt_text')->nullable();
$table->integer('order_column')->default(0);
$table->timestamps();
$table->index(['model_type', 'model_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('media');
}
};

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
{
/**
* Run the migrations.
*/
// database/migrations/xxxx_create_brands_table.php
public function up(): void
{
Schema::create('brands', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->string('logo_url')->nullable();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('brands');
}
};

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
{
/**
* Run the migrations.
*/
// database/migrations/xxxx_create_collections_table.php
public function up(): void
{
Schema::create('collections', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('collections');
}
};

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
{
/**
* Run the migrations.
*/
// database/migrations/xxxx_create_categories_table.php
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
// Für Baumstruktur (z.B. "Sofas" gehört zu "Wohnzimmer")
$table->foreignId('parent_id')
->nullable()
->constrained('categories')
->onDelete('set null');
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tax_rates', function (Blueprint $table) {
$table->id();
$table->string('name'); // z.B. "Regelsatz", "Ermäßigt"
$table->decimal('rate_percentage', 5, 2); // z.B. 19.00, 7.00
$table->boolean('is_default')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tax_rates');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('shipping_classes', function (Blueprint $table) {
$table->id();
$table->string('name'); // z.B. "Paketversand", "Spedition (2-Mann)"
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('shipping_classes');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tags');
}
};

View file

@ -0,0 +1,61 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
// database/migrations/xxxx_create_products_table.php
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->foreignId('partner_id')->constrained('partners')->onDelete('cascade');
// NEU: Verknüpfung zu Marke/Hersteller
$table->foreignId('brand_id')->nullable()->constrained('brands')->onDelete('set null');
// NEU: Verknüpfung zu Kollektion/Serie
$table->foreignId('collection_id')->nullable()->constrained('collections')->onDelete('set null');
$table->string('name'); // z.B. "3-Sitzer Sofa 'Stockholm'"
$table->string('slug')->unique();
$table->string('status')->default('draft'); // draft, active, archived
$table->text('description_short')->nullable();
$table->text('description_long')->nullable();
$table->text('care_instructions')->nullable();
// Basis-Maße (können von Varianten überschrieben werden, wenn nötig)
$table->integer('width_cm')->nullable();
$table->integer('height_cm')->nullable();
$table->integer('depth_cm')->nullable();
// PERFEKTER ANWENDUNGSFALL FÜR JSON:
// Spezifische Maße, nach denen nie gefiltert wird.
$table->json('dimensions_specific')->nullable();
// Bsp: {"seat_height_cm": 45, "seat_depth_cm": 60}
// Logistik-Basis
$table->string('assembly_status')->nullable(); // z.B. 'flat_pack', 'partially_assembled', 'fully_assembled'
// SEO
$table->string('meta_title')->nullable();
$table->text('meta_description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('products');
}
};

View file

@ -0,0 +1,62 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
// database/migrations/xxxx_create_product_variants_table.php
public function up(): void
{
Schema::create('product_variants', function (Blueprint $table) {
$table->id();
// Jede Variante gehört zu einem "Parent"-Produkt
$table->foreignId('product_id')->constrained('products')->onDelete('cascade');
$table->string('name_suffix')->nullable(); // z.B. "Anthrazit / 3-Sitzer"
$table->boolean('is_master_variant')->default(false); // Die "Standard"-Variante
// Eindeutige IDs
$table->string('sku')->unique(); // Interne SKU
$table->string('han_mpn')->nullable()->index(); // Hersteller-Nr.
$table->string('ean_gtin')->nullable()->index(); // Barcode
// Preis-Logik (in Cents)
$table->integer('selling_price'); // VK
$table->integer('msrp')->nullable(); // UVP (Streichpreis)
$table->integer('purchase_price')->nullable(); // EK
$table->foreignId('tax_rate_id')->constrained('tax_rates');
// Lager-Logik
$table->integer('stock_quantity')->default(0);
$table->integer('stock_min_threshold')->nullable(); // Meldebestand
$table->string('availability_status')->nullable(); // z.B. 'in_stock', 'out_of_stock'
$table->string('delivery_time_text')->nullable(); // z.B. "6-8 Wochen" (ersetzt altes Feld)
// WICHTIG: Re-Integration des Mietmodells aus dem Initial-Briefing
$table->boolean('is_rentable')->default(false);
$table->json('rental_duration_options')->nullable(); // [6, 12, 24]
$table->string('rental_rate_formula')->nullable();
$table->decimal('residual_value_percentage', 5, 2)->nullable();
// Variante-spezifische Maße & Gewicht (falls abweichend vom Parent)
$table->integer('variant_weight_g')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('product_variants');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
// ... create_product_variant_attributes_table.php
Schema::create('product_variant_attributes', function (Blueprint $table) {
// Composite Primary Key
$table->foreignId('product_variant_id')->constrained('product_variants')->onDelete('cascade');
$table->foreignId('attribute_value_id')->constrained('attribute_values')->onDelete('cascade');
$table->primary(['product_variant_id', 'attribute_value_id'], 'variant_attribute_primary');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('product_variant_attributes');
}
};

View file

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('partner_invitations', function (Blueprint $table) {
$table->id();
$table->string('company_name');
$table->enum('partner_type', ['Retailer', 'Manufacturer', 'Estate-Agent', 'Customer'])->default('Retailer');
$table->string('email');
$table->string('token', 64)->unique();
$table->enum('status', ['pending', 'accepted', 'expired', 'cancelled'])->default('pending');
$table->timestamp('expires_at');
$table->foreignId('invited_by')->constrained('users')->onDelete('cascade');
$table->foreignId('partner_id')->nullable()->constrained('partners')->onDelete('set null');
$table->timestamp('accepted_at')->nullable();
$table->timestamps();
$table->index(['token', 'status']);
$table->index(['email', 'status']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Foreign Keys werden automatisch mit der Tabelle gelöscht
Schema::dropIfExists('partner_invitations');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('category_product', function (Blueprint $table) {
$table->foreignId('category_id')->constrained()->onDelete('cascade');
$table->foreignId('product_id')->constrained()->onDelete('cascade');
// Primärschlüssel aus beiden IDs
$table->primary(['category_id', 'product_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('category_product');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('product_tag', function (Blueprint $table) {
$table->foreignId('product_id')->constrained()->onDelete('cascade');
$table->foreignId('tag_id')->constrained()->onDelete('cascade');
// Primärschlüssel aus beiden IDs
$table->primary(['product_id', 'tag_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('product_tag');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('related_products', function (Blueprint $table) {
// Das "Basis"-Produkt
$table->foreignId('product_id')->constrained('products')->onDelete('cascade');
// Das "verknüpfte" Produkt
$table->foreignId('related_product_id')->constrained('products')->onDelete('cascade');
$table->primary(['product_id', 'related_product_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('related_products');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('product_logistics', function (Blueprint $table) {
$table->id();
// 1-zu-1 Beziehung zur Variante
$table->foreignId('product_variant_id')->constrained('product_variants')->onDelete('cascade');
$table->foreignId('shipping_class_id')->nullable()->constrained('shipping_classes');
// Verpackungsmaße
$table->integer('package_width_cm')->nullable();
$table->integer('package_height_cm')->nullable();
$table->integer('package_depth_cm')->nullable();
$table->integer('package_weight_g')->nullable(); // Bruttogewicht
$table->integer('package_count')->default(1); // Anzahl Packstücke
$table->string('location_bin')->nullable(); // Lagerort
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('product_logistics');
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->string('display_name')->nullable()->after('name');
$table->string('icon')->nullable()->after('display_name');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->dropColumn(['display_name', 'icon']);
});
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('partner_invitations', function (Blueprint $table) {
$table->string('contact_first_name')->nullable()->after('company_name');
$table->string('contact_last_name')->nullable()->after('contact_first_name');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('partner_invitations', function (Blueprint $table) {
$table->dropColumn(['contact_first_name', 'contact_last_name']);
});
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->boolean('can_be_invited')->default(false)->after('icon');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('roles', function (Blueprint $table) {
$table->dropColumn('can_be_invited');
});
}
};

View file

@ -0,0 +1,101 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Füge zuerst role_id als nullable hinzu (falls nicht existiert)
if (!Schema::hasColumn('partner_invitations', 'role_id')) {
Schema::table('partner_invitations', function (Blueprint $table) {
$table->unsignedBigInteger('role_id')->nullable()->after('contact_last_name');
});
}
// Migriere bestehende Daten: partner_type -> role_id
if (Schema::hasColumn('partner_invitations', 'partner_type')) {
DB::table('partner_invitations')->get()->each(function ($invitation) {
$roleName = $invitation->partner_type;
$role = DB::table('roles')->where('name', $roleName)->first();
if ($role) {
DB::table('partner_invitations')
->where('id', $invitation->id)
->update(['role_id' => $role->id]);
}
});
// Jetzt partner_type entfernen und role_id als required machen
Schema::table('partner_invitations', function (Blueprint $table) {
$table->dropColumn('partner_type');
});
}
// Mache role_id required und füge Foreign Key hinzu
try {
Schema::table('partner_invitations', function (Blueprint $table) {
$table->unsignedBigInteger('role_id')->nullable(false)->change();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
});
} catch (\Exception $e) {
// Foreign Key existiert bereits, nur die Spalte ändern
Schema::table('partner_invitations', function (Blueprint $table) {
$table->unsignedBigInteger('role_id')->nullable(false)->change();
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Füge partner_type wieder hinzu (als nullable, da wir Daten migrieren)
if (!Schema::hasColumn('partner_invitations', 'partner_type')) {
Schema::table('partner_invitations', function (Blueprint $table) {
$table->enum('partner_type', ['Retailer', 'Manufacturer', 'Estate-Agent', 'Customer'])->nullable()->after('email');
});
}
// Migriere Daten zurück: role_id -> partner_type
if (Schema::hasColumn('partner_invitations', 'role_id')) {
DB::table('partner_invitations')->get()->each(function ($invitation) {
if ($invitation->role_id) {
$role = DB::table('roles')->where('id', $invitation->role_id)->first();
if ($role) {
DB::table('partner_invitations')
->where('id', $invitation->id)
->update(['partner_type' => $role->name]);
}
}
});
}
// Entferne role_id Foreign Key und Spalte
try {
Schema::table('partner_invitations', function (Blueprint $table) {
$table->dropForeign(['role_id']);
});
} catch (\Exception $e) {
// Foreign Key existiert nicht oder hat anderen Namen - weitermachen
}
if (Schema::hasColumn('partner_invitations', 'role_id')) {
Schema::table('partner_invitations', function (Blueprint $table) {
$table->dropColumn('role_id');
});
}
// Mache partner_type wieder required mit default
Schema::table('partner_invitations', function (Blueprint $table) {
$table->enum('partner_type', ['Retailer', 'Manufacturer', 'Estate-Agent', 'Customer'])->default('Retailer')->change();
});
}
};

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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('partners', function (Blueprint $table) {
$table->boolean('setup_completed')->default(false)->after('is_active');
$table->timestamp('setup_completed_at')->nullable()->after('setup_completed');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('partners', function (Blueprint $table) {
$table->dropColumn(['setup_completed', 'setup_completed_at']);
});
}
};