diff --git a/database/migrations/2026_05_27_160000_extend_purchases_for_partial_receipt.php b/database/migrations/2026_05_27_160000_extend_purchases_for_partial_receipt.php index 47d62ea..00807e8 100644 --- a/database/migrations/2026_05_27_160000_extend_purchases_for_partial_receipt.php +++ b/database/migrations/2026_05_27_160000_extend_purchases_for_partial_receipt.php @@ -9,32 +9,41 @@ return new class extends Migration { public function up(): void { - Schema::table('purchases', function (Blueprint $t) { - $t->foreignId('warehouse_id')->nullable()->after('supplier_id') - ->constrained('warehouses')->nullOnDelete(); - }); + // Idempotent: MariaDB has no transactional DDL, so a half-applied prior + // run can leave columns/tables behind without recording the migration. + // Guard each step so a re-run completes instead of erroring on duplicates. + if (! Schema::hasColumn('purchases', 'warehouse_id')) { + Schema::table('purchases', function (Blueprint $t) { + $t->foreignId('warehouse_id')->nullable()->after('supplier_id') + ->constrained('warehouses')->nullOnDelete(); + }); + } - Schema::table('purchase_items', function (Blueprint $t) { - $t->decimal('qty_received', 10, 2)->default(0)->after('qty'); - }); + if (! Schema::hasColumn('purchase_items', 'qty_received')) { + Schema::table('purchase_items', function (Blueprint $t) { + $t->decimal('qty_received', 10, 2)->default(0)->after('qty'); + }); + } // Backfill: items previously marked `received=true` were fully received. DB::statement('UPDATE purchase_items SET qty_received = qty WHERE received = 1'); - Schema::create('supplier_part_prices', function (Blueprint $t) { - $t->id(); - $t->foreignId('company_id')->constrained()->cascadeOnDelete(); - $t->foreignId('supplier_id')->constrained()->cascadeOnDelete(); - $t->foreignId('part_id')->constrained()->cascadeOnDelete(); - $t->foreignId('purchase_id')->nullable()->constrained()->nullOnDelete(); - $t->decimal('price', 12, 2); - $t->string('currency', 6)->default('MDL'); - $t->dateTime('observed_at'); - $t->timestamps(); + if (! Schema::hasTable('supplier_part_prices')) { + Schema::create('supplier_part_prices', function (Blueprint $t) { + $t->id(); + $t->foreignId('company_id')->constrained()->cascadeOnDelete(); + $t->foreignId('supplier_id')->constrained()->cascadeOnDelete(); + $t->foreignId('part_id')->constrained()->cascadeOnDelete(); + $t->foreignId('purchase_id')->nullable()->constrained()->nullOnDelete(); + $t->decimal('price', 12, 2); + $t->string('currency', 6)->default('MDL'); + $t->dateTime('observed_at'); + $t->timestamps(); - $t->index(['company_id', 'supplier_id', 'part_id', 'observed_at']); - $t->index(['company_id', 'part_id', 'observed_at']); - }); + $t->index(['company_id', 'supplier_id', 'part_id', 'observed_at']); + $t->index(['company_id', 'part_id', 'observed_at']); + }); + } } public function down(): void