id(); // Какая запчасть зарезервирована $table->foreignId('spare_part_id') ->constrained('spare_parts') ->restrictOnDelete(); // Из какой партии (для FIFO учёта) $table->foreignId('spare_part_order_id') ->constrained('spare_part_orders') ->restrictOnDelete(); // Для какой рекламации $table->foreignId('reclamation_id') ->constrained('reclamations') ->cascadeOnDelete(); // Количество зарезервировано $table->unsignedInteger('reserved_qty'); // Признак документов $table->boolean('with_documents')->default(false); // Статус резерва $table->enum('status', [ 'active', // Активный резерв 'issued', // Списано (резерв реализован) 'cancelled', // Отменён ])->default('active'); // Связь с движением (для аудита) $table->foreignId('movement_id') ->nullable() ->constrained('inventory_movements') ->nullOnDelete(); $table->timestamps(); // Индексы $table->index(['spare_part_id', 'with_documents', 'status']); $table->index(['spare_part_order_id', 'status']); $table->index(['reclamation_id', 'status']); $table->index('status'); }); // CHECK constraint для положительного количества // MySQL 8.0.16+ поддерживает CHECK constraints DB::statement('ALTER TABLE reservations ADD CONSTRAINT chk_reserved_qty_positive CHECK (reserved_qty > 0)'); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('reservations'); } };