id(); $table->string('name'); $table->string('currency', 3)->default('MZN'); $table->unsignedBigInteger('first_limit_minor')->default(2500000); $table->unsignedBigInteger('second_limit_minor')->default(15000000); $table->boolean('approval_includes_tax')->default(true); $table->boolean('rules_provisional')->default(true); $table->timestamps(); }); Schema::create('departments', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->string('name'); $table->timestamps(); $table->unique(['tenant_id', 'name']); }); Schema::create('cost_centers', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->foreignId('department_id')->constrained()->restrictOnDelete(); $table->string('code'); $table->string('name'); $table->timestamps(); $table->unique(['tenant_id', 'code']); }); Schema::table('users', function (Blueprint $table) { $table->foreignId('tenant_id')->nullable()->constrained()->restrictOnDelete(); $table->foreignId('department_id')->nullable()->constrained()->restrictOnDelete(); $table->string('purchasing_role')->default('requester'); }); Schema::create('requisitions', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->string('number')->nullable()->unique(); $table->foreignId('requester_id')->constrained('users')->restrictOnDelete(); $table->foreignId('department_id')->constrained()->restrictOnDelete(); $table->foreignId('cost_center_id')->constrained()->restrictOnDelete(); $table->string('priority'); $table->date('needed_by'); $table->text('justification'); $table->string('status')->default('draft'); $table->string('currency', 3)->default('MZN'); $table->unsignedBigInteger('subtotal_minor'); $table->unsignedBigInteger('tax_minor'); $table->unsignedBigInteger('total_minor'); $table->json('approval_snapshot')->nullable(); $table->timestamp('submitted_at')->nullable(); $table->timestamps(); $table->index(['tenant_id', 'status']); }); Schema::create('requisition_items', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->foreignId('requisition_id')->constrained()->cascadeOnDelete(); $table->string('description'); $table->string('category'); $table->string('purchase_type'); $table->decimal('quantity', 12, 3); $table->string('unit', 30); $table->unsignedBigInteger('unit_price_minor'); $table->decimal('tax_rate', 5, 2); $table->unsignedBigInteger('subtotal_minor'); $table->unsignedBigInteger('tax_minor'); $table->unsignedBigInteger('total_minor'); }); Schema::create('approval_steps', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->foreignId('requisition_id')->constrained()->restrictOnDelete(); $table->unsignedSmallInteger('position'); $table->string('role'); $table->string('decision')->default('pending'); $table->foreignId('approver_id')->nullable()->constrained('users')->restrictOnDelete(); $table->text('comment')->nullable(); $table->timestamp('decided_at')->nullable(); $table->unique(['requisition_id', 'position']); }); Schema::create('audit_logs', function (Blueprint $table) { $table->id(); $table->foreignId('tenant_id')->constrained()->restrictOnDelete(); $table->foreignId('user_id')->constrained()->restrictOnDelete(); $table->string('action'); $table->foreignId('requisition_id')->nullable()->constrained()->restrictOnDelete(); $table->string('ip_address', 45)->nullable(); $table->json('before')->nullable(); $table->json('after'); $table->timestamp('created_at')->useCurrent(); }); } public function down(): void { Schema::dropIfExists('audit_logs'); Schema::dropIfExists('approval_steps'); Schema::dropIfExists('requisition_items'); Schema::dropIfExists('requisitions'); Schema::table('users', function (Blueprint $table) { $table->dropConstrainedForeignId('department_id'); $table->dropConstrainedForeignId('tenant_id'); $table->dropColumn('purchasing_role'); }); Schema::dropIfExists('cost_centers'); Schema::dropIfExists('departments'); Schema::dropIfExists('tenants'); } };