Files

60 lines
4.0 KiB
PHP

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
// QA fixture schema only. Never registered as an application migration.
\App\Modules\Purchasing\BudgetAdapter::guard();
foreach (['0001_01_01_000000_create_users_table.php', '2026_10_25_000000_create_identity_foundation.php', '2026_10_25_010000_add_identity_workflow.php'] as $migration) {
(require base_path('database/migrations/'.$migration))->up();
}
DB::statement('ALTER TABLE permission_grants DROP CONSTRAINT permission_grants_scope_check');
DB::statement("ALTER TABLE permission_grants ADD CONSTRAINT permission_grants_scope_check CHECK ((permission IN ('company.view','company.edit','unit.create','access.manage') AND unit_id IS NULL) OR ((permission IN ('unit.view','unit.edit') OR permission IN ('purchasing_budget.create','purchasing_budget.approve','purchasing_budget.record','purchasing_budget.consume','purchasing_budget.view','purchasing_budget.reinforcement.propose','purchasing_budget.reinforcement.review')) AND unit_id IS NOT NULL))");
$scope = function (Blueprint $t): void {
$t->unsignedBigInteger('tenant_id');
$t->unsignedBigInteger('company_id');
$t->unsignedBigInteger('unit_id');
$t->foreign(['tenant_id','company_id','unit_id'])->references(['tenant_id','company_id','id'])->on('units')->restrictOnDelete();
};
Schema::create('cb_centres', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->string('code');
$t->unique(['tenant_id','company_id','unit_id','code']);
});
Schema::create('cb_origins', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('cost_center_id')->constrained('cb_centres');
$t->string('required_kind'); $t->string('reference')->unique();
});
Schema::create('cb_budgets', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('cost_center_id')->constrained('cb_centres');
$t->integer('year'); $t->string('kind')->default('operating'); $t->bigInteger('amount_minor');
$t->boolean('includes_tax'); $t->text('reason');
$t->foreignId('created_by')->constrained('users'); $t->foreignId('approved_by')->nullable()->constrained('users');
$t->timestamp('approved_at')->nullable(); $t->timestamps();
$t->unique(['tenant_id','company_id','unit_id','cost_center_id','year']);
});
Schema::create('cb_budget_entries', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('budget_id')->constrained('cb_budgets');
$t->foreignId('requisition_id')->constrained('cb_origins'); $t->foreignId('created_by')->constrained('users');
$t->string('kind'); $t->bigInteger('reserved_minor'); $t->bigInteger('committed_minor'); $t->timestamp('created_at');
$t->unique(['requisition_id','kind']);
});
Schema::create('cb_budget_consumptions', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('budget_id')->constrained('cb_budgets');
// Only a synthetic source identifier, not a payable or invoice implementation.
$t->unsignedBigInteger('invoice_id')->unique(); $t->foreignId('created_by')->constrained('users');
$t->bigInteger('amount_minor'); $t->timestamp('created_at');
});
Schema::create('cb_budget_reinforcements', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('budget_id')->constrained('cb_budgets');
$t->foreignId('created_by')->constrained('users'); $t->foreignId('reviewed_by')->nullable()->constrained('users');
$t->string('reference'); $t->string('payload_hash',64); $t->bigInteger('amount_minor'); $t->text('reason');
$t->string('status')->default('pending'); $t->text('review_reason')->nullable(); $t->timestamp('reviewed_at')->nullable(); $t->timestamps();
$t->unique(['tenant_id','company_id','unit_id','reference']);
});
Schema::create('cb_audit', function (Blueprint $t) use ($scope) {
$t->id(); $scope($t); $t->foreignId('actor_id')->constrained('users'); $t->string('action');
$t->unsignedBigInteger('origin_id')->nullable(); $t->jsonb('payload'); $t->timestamp('created_at');
});