Files
SGF/scripts/catalogue-accounting-access.php
T
nala f8d57b52aa Preserva classificacao contabilistica aceite e bases locais
Regista aceitacao funcional do primeiro incremento PGC-NIRF e preserva as dependencias documentais e tecnicas existentes. A validacao do calculo fiscal continua separada e pendente. Sem credenciais, bases operacionais ou publicacao.
2026-10-26 13:47:11 +02:00

30 lines
3.1 KiB
PHP

<?php
require __DIR__.'/../vendor/autoload.php';
$app=require __DIR__.'/../bootstrap/app.php'; $app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
if (!\App\Modules\Identity\Services\LocalDatabaseGuard::allows()) { throw new RuntimeException('Own local development database required.'); }
$args=array_values(array_filter(array_slice($argv,1),fn($v)=>$v!=='--apply'));
if(count($args)!==3 || array_filter($args,fn($v)=>!ctype_digit($v)))throw new RuntimeException('Usage: catalogue-accounting-access.php proposer_id validator_id company_id [--apply]; exact prior confirmation required.');
[$proposer,$validator,$companyId]=array_map('intval',$args);if($proposer===$validator)throw new RuntimeException('The agreed workflow uses distinct preparer and validator accounts.');
$db=\Illuminate\Support\Facades\DB::class;
$company=$db::table('companies')->where('id',$companyId)->first(['id','tenant_id','name']);
$accounts=$db::table('users')->whereIn('id',[$proposer,$validator])->orderBy('id')->get(['id','name','email']);
$operations=[];
foreach ($accounts as $account) {
if (!$company || !$db::table('company_memberships')->where('user_id',$account->id)->where('company_id',$company->id)->where('tenant_id',$company->tenant_id)->exists()) { throw new RuntimeException('Existing membership missing. No association inferred.'); }
foreach (['catalogue_accounting.view',$account->id===$proposer ? 'catalogue_accounting.propose' : 'catalogue_accounting.approve'] as $permission) { $operations[]=['user_id'=>$account->id,'tenant_id'=>$company->tenant_id,'company_id'=>$company->id,'unit_id'=>null,'permission'=>$permission]; }
}
if ($accounts->count()!==2) { throw new RuntimeException('Two existing accounts required.'); }
if (!in_array('--apply',$argv,true)) { echo json_encode(['accounts'=>$accounts,'company'=>$company,'proposed_grants'=>$operations,'applied'=>false],JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE).PHP_EOL; exit; }
$inserted=$db::transaction(function()use($db,$company,$operations){
$db::table('companies')->where('id',$company->id)->where('tenant_id',$company->tenant_id)->lockForUpdate()->firstOrFail();$count=0;
foreach($operations as $operation){
foreach(['company.view','services.view'] as $right)app(\App\Modules\Identity\Services\Permissions::class)->require($operation['user_id'],$company->tenant_id,$company->id,$right);
if(!$db::table('company_memberships')->where('user_id',$operation['user_id'])->where('tenant_id',$company->tenant_id)->where('company_id',$company->id)->exists())throw new RuntimeException('Membership changed. No grant applied.');
if($db::table('permission_grants')->insertOrIgnore($operation+['created_at'=>now(),'updated_at'=>now()])){
$count++;\App\Modules\Identity\Services\Audit::record('catalogue_accounting.access.initial_grant',null,$company->tenant_id,$company->id,subject:$operation['user_id'],details:['permission'=>$operation['permission'],'reason'=>'Exact initial classification grants specifically confirmed by the user; no fiscal or posting powers.']);
}
}
return $count;
});
echo "Applied $inserted specifically confirmed classification grants. Existing rights preserved.\n";