Files
2026-11-02 08:08:05 +02:00

98 lines
4.1 KiB
PHP

<?php
namespace Tempo\Purchasing\Delivery;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Schema\Blueprint;
/** Host schema preserving the existing SGF common-budget contract; no business motor or fixtures. */
final class BudgetSchema
{
public static function create(ConnectionInterface $db): void
{
$schema = $db->getSchemaBuilder();
$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');
});
}
}