57 lines
6.5 KiB
PHP
57 lines
6.5 KiB
PHP
<?php
|
|
// Called only after a fresh, restricted QA database has been provisioned.
|
|
$mode=$argv[1]??'';$root=$mode==='compras'?'C:/laragon/www/compras':'C:/laragon/www/sgf-tempo';
|
|
require $root.'/vendor/autoload.php';$app=require $root.'/bootstrap/app.php';$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
$db=DB::connection();$name=$db->getDatabaseName();
|
|
if(!preg_match('/^(compras_receipts_test_|payable_sgf_)[a-f0-9]{12}$/D',$name)||$db->selectOne('select current_database() as d')->d!==$name||Schema::hasTable('users'))throw new LogicException('Fresh QA only.');
|
|
$file=getenv('PAYABLE_ACCESS_FILE');$bundle=getenv('PAYABLE_BUNDLE');
|
|
if($mode==='compras'){
|
|
\Illuminate\Support\Facades\Artisan::call('migrate',['--force'=>true]);
|
|
require __DIR__.'/../qa-schema.php';require __DIR__.'/ReceiptFixture.php';
|
|
$f=payableReceiptFixture();
|
|
app(\App\Services\ReceiptWorkflow::class)->confirm($f['receiver'],$f['order'],payableReceiptPayload($f,'1.000'));
|
|
$p=\App\Models\User::factory()->create(['tenant_id'=>$f['tenant']->id,'department_id'=>$f['department']->id,'purchasing_role'=>'finance']);
|
|
$v=\App\Models\User::factory()->create(['tenant_id'=>$f['tenant']->id,'department_id'=>$f['department']->id,'purchasing_role'=>'finance']);
|
|
$q=\App\Models\User::factory()->create(['tenant_id'=>$f['tenant']->id,'department_id'=>$f['department']->id,'purchasing_role'=>'admin']);
|
|
auth()->guard()->setUser($p);
|
|
\App\Models\Budget::query()->create(['tenant_id'=>$f['tenant']->id,'cost_center_id'=>$f['r']->cost_center_id,'year'=>now()->year,'amount_minor'=>2000000,'includes_tax'=>true,'approved_by'=>$v->id,'created_by'=>$p->id,'reason'=>'Only synthetic source preparation']);
|
|
DB::transaction(function()use($p,$f){app(\App\Services\BudgetWorkflow::class)->record($p,$f['r'],'reserve',1160000,1000000);app(\App\Services\BudgetWorkflow::class)->record($p,$f['r'],'commit',1160000,1000000);});
|
|
$invoice=app(\App\Services\InvoiceWorkflow::class)->register($p,$f['order'],['number'=>'FT-SIM-11600','issued_on'=>now()->format('Y-m-d'),'subtotal'=>'10000.00','tax'=>'1600.00','total'=>'11600.00','items'=>[['purchase_order_item_id'=>$f['line']->id,'quantity'=>'1.000','unit'=>'cx','unit_price'=>'10000.00','tax_rate'=>'16']]]);
|
|
auth()->guard()->setUser($v);app(\App\Services\InvoiceWorkflow::class)->validate($v,$invoice);
|
|
$scope=['tenant_id'=>$f['tenant']->id,'company_id'=>0,'unit_id'=>0];
|
|
auth()->guard()->setUser($p);$source=app(\App\Services\SupplierPayables::class)->document($p,$invoice->id);
|
|
if($source['total_minor']!==1160000||$source['tax_minor']!==160000||$source['status']!=='validated'||!$source['validation_audit_id'])throw new RuntimeException('Source scenario mismatch.');
|
|
file_put_contents($bundle,\Tempo\Finance\Payables\Payables::canonical($source),LOCK_EX);
|
|
$sourceId=$invoice->id;
|
|
}else{
|
|
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 $m)(require $root.'/database/migrations/'.$m)->up();
|
|
require __DIR__.'/../qa-schema.php';
|
|
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','supplier_payables.view') AND unit_id IS NOT NULL))");
|
|
$now=now();$tenant=DB::table('tenants')->insertGetId(['name'=>'Tenant sintético','created_at'=>$now,'updated_at'=>$now]);
|
|
DB::table('companies')->insert(['tenant_id'=>$tenant,'name'=>'Empresa não autorizada','created_at'=>$now,'updated_at'=>$now]);
|
|
$company=DB::table('companies')->insertGetId(['tenant_id'=>$tenant,'name'=>'Horizonte Sintética — Obrigações','created_at'=>$now,'updated_at'=>$now]);
|
|
DB::table('units')->insert(['tenant_id'=>$tenant,'company_id'=>$company,'name'=>'Unidade reservada','created_at'=>$now,'updated_at'=>$now]);
|
|
$unit=DB::table('units')->insertGetId(['tenant_id'=>$tenant,'company_id'=>$company,'name'=>'Unidade de obrigações','created_at'=>$now,'updated_at'=>$now]);
|
|
$scope=['tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$unit];
|
|
$p=\App\Models\User::create(['name'=>'Preparador','email'=>'seed-p@example.test','password'=>bin2hex(random_bytes(20))]);
|
|
$v=\App\Models\User::create(['name'=>'Validador','email'=>'seed-v@example.test','password'=>bin2hex(random_bytes(20))]);
|
|
$q=\App\Models\User::create(['name'=>'Consulta','email'=>'seed-q@example.test','password'=>bin2hex(random_bytes(20))]);
|
|
foreach([$p,$v,$q] as $u){DB::table('company_memberships')->insert(['user_id'=>$u->id,'tenant_id'=>$tenant,'company_id'=>$company]);foreach(['company.view'=>null,'unit.view'=>$unit,'supplier_payables.view'=>$unit] as $right=>$which)DB::table('permission_grants')->insert(['tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$which,'user_id'=>$u->id,'permission'=>$right,'created_at'=>$now,'updated_at'=>$now]);}
|
|
Schema::create('pa_imported_sources',function(Blueprint $t){$t->id();foreach(['tenant_id','company_id','unit_id'] as $k)$t->unsignedBigInteger($k);$t->jsonb('payload');$t->string('receipt_hash',64);});
|
|
$source=json_decode(file_get_contents($bundle),true,64,JSON_THROW_ON_ERROR);
|
|
if(\Tempo\Finance\Payables\Payables::missing($source)!==[])throw new RuntimeException('Conferred Compras source required.');
|
|
$sourceId=DB::table('pa_imported_sources')->insertGetId($scope+['payload'=>\Tempo\Finance\Payables\Payables::canonical($source),'receipt_hash'=>hash('sha256',\Tempo\Finance\Payables\Payables::canonical($source))]);
|
|
}
|
|
$accounts=[];
|
|
foreach(['preparacao'=>[$p,['view','prepare']],'validacao'=>[$v,['view','validate']],'consulta'=>[$q,['view']]] as $role=>[$user,$rights]){
|
|
$password=bin2hex(random_bytes(20));$user->forceFill(['name'=>'Obrigações — '.$role,'email'=>$role.'-obrigacoes@example.test','password'=>$password]);$user->save();
|
|
foreach($rights as $right)DB::table('pa_access')->insert($scope+['user_id'=>$user->id,'person'=>'synthetic-person-'.$role,'action'=>$right]);
|
|
$accounts[$role]=['id'=>$user->id,'email'=>$user->email,'password'=>$password];
|
|
}
|
|
file_put_contents($file,json_encode(['mode'=>$mode,'scope'=>$scope,'source_id'=>$sourceId,'accounts'=>$accounts],JSON_THROW_ON_ERROR),LOCK_EX);
|
|
echo "Synthetic conferred-source scenario prepared; obligations remain unrecognised for team testing.\n";
|