Files
SGF/scripts/sgf-fiscal-obligations-proof.php
2026-11-11 09:00:17 +02:00

15 lines
7.5 KiB
PHP

<?php
require __DIR__.'/sgf-fiscal-obligations-proof-bootstrap.php';
$tables=['fx_versions','fx_commands','si_invoices','sd_outputs','cash_events','fr_calculations','permission_grants'];$before=[];foreach($tables as$t)$before[$t]=$host->table($t)->orderBy('id')->get()->toJson();$versions=$host->table('fo_versions')->count();$commands=$host->table('fo_commands')->count();$host->beginTransaction();try{
$key=(string)Illuminate\Support\Str::uuid();$input=$foInput($key,0,$foData);$cut=$foPreview(13,$input);$ok($cut['impact']['tax_payable']===null&&$cut['impact']['journals']===0&&!$cut['impact']['official_submission'],'preview no financial or official effect');$ok($host->table('fo_versions')->count()===$versions,'preview fully rolled back');[$v1,$p1,$opKey]=$foCommand(13,$input);$ok($v1['version']===1&&$v1['state']==='prepared','individual preparation stored');$again=$foConfirm(13,$p1['preview']);$ok($again['replayed']&&$again['id']===$v1['id']&&$host->table('fo_commands')->count()===$commands+1,'same key no duplicate');$review=$foInput($key,1,['decision'=>'approved'],'review');$reject(fn()=>$foPreview(13,$review),403,'own review refused');$reject(fn()=>$foPreview(14,$input),403,'reviewer cannot prepare');$reject(fn()=>$foPreview(17,$input),403,'reader cannot prepare');$reject(fn()=>$foPreview(13,$foInput((string)Illuminate\Support\Str::uuid(),0,$foData)),409,'same map pending duplicate refused');
$stale=$foPreview(14,$review);[$v2]=$foCommand(13,$foInput($key,1,$foData));$reject(fn()=>$foConfirm(14,$stale['preview']),409,'changed preparation invalidates old review');[$v3]=$foCommand(14,$foInput($key,2,['decision'=>'approved'],'review'));$ok($v3['version']===3&&$v3['impact']['after']['effective']['administrative_status']==='active','distinct review activates administrative record');$day=$foList(17,['record_key'=>$key]);$ok($day['records']['data'][0]['days_overdue']===0,'same due day no delay');$next=$foList(17,['record_key'=>$key,'reference_on'=>'2026-12-16']);$ok($next['records']['data'][0]['days_overdue']===1,'next day one day explicit reference');
$unknown=array_replace($foData,['operation'=>'amend','due_on'=>null,'evidence'=>'QA correcção explícita para prazo desconhecido.']);[$v4]=$foCommand(13,$foInput($key,3,$unknown));[$v5]=$foCommand(14,$foInput($key,4,['decision'=>'refused'],'review'));$ok($foList(17,['record_key'=>$key])['records']['data'][0]['effective']['due_on']==='2026-12-15','refusal preserves effective deadline');[$v6]=$foCommand(13,$foInput($key,5,$unknown));[$v7]=$foCommand(14,$foInput($key,6,['decision'=>'approved'],'review'));$uk=$foList(17,['record_key'=>$key]);$ok($uk['records']['data'][0]['days_overdue']===null&&$uk['records']['data'][0]['due_status']==='unknown','approved unknown has indeterminate delay');
$deliver=array_replace($unknown,['operation'=>'delivery','export_sha256'=>$foSource['export_sha256'],'evidence'=>'QA entrega APENAS simulada da exportação interna, sem recibo oficial.']);$reject(fn()=>$foPreview(13,$foInput($key,7,array_replace($deliver,['export_sha256'=>str_repeat('0',64)]))),409,'wrong export SHA refused');[$v8]=$foCommand(13,$foInput($key,7,$deliver));$ok($foList(17,['record_key'=>$key])['records']['data'][0]['effective']['administrative_status']==='active','delivery preparation not fulfilled');[$v9]=$foCommand(14,$foInput($key,8,['decision'=>'approved'],'review'));$result=$foList(17,['record_key'=>$key]);$ok($result['records']['data'][0]['effective']['administrative_status']==='delivery_simulated'&&!$result['official_submission'],'approved delivery explicitly simulated');$reject(fn()=>$foPreview(13,$foInput($key,9,$deliver)),409,'second delivery refused');
$cancel=array_replace($unknown,['operation'=>'cancel','evidence'=>'QA cancelamento administrativo, não retira envio a autoridade.']);[$v10]=$foCommand(13,$foInput($key,9,$cancel));[$v11]=$foCommand(14,$foInput($key,10,['decision'=>'approved'],'review'));$ok($foList(17,['record_key'=>$key])['records']['data'][0]['effective']['administrative_status']==='cancelled','reviewed cancellation retained');$reject(fn()=>$foPreview(13,$foInput($key,11,$unknown)),409,'cancelled record cannot be silently reopened');
$ownActor=$selectFiscal(13);$receipt=$fo->receipt($ownActor,$opKey);$ok($receipt['historical_receipt_only']&&!$receipt['operation_executed']&&$receipt['result']['id']===$v1['id'],'historical receipt no execution');$selectFiscal(14);$reject(fn()=>$fo->receipt(14,$opKey),404,'other actor receipt hidden');$reject(fn()=>$foList(17,['record_key'=>(string)Illuminate\Support\Str::uuid()]),403,'foreign history refused');$reject(fn()=>$foList(17,['tenant_id'=>2]),422,'tenant override refused');$reject(fn()=>$foList(17,['per_page'=>1000]),422,'unbounded page refused');$reject(fn()=>$foPreview(13,$foInput((string)Illuminate\Support\Str::uuid(),0,array_replace($foData,['responsible_id'=>10]))),403,'ineligible responsible refused');$reject(fn()=>$foPreview(13,$foInput((string)Illuminate\Support\Str::uuid(),0,array_replace($foData,['due_on'=>'2026-02-30']))),422,'impossible date refused');
// Current original map changed only as a reverted SQL history fixture.
$host->beginTransaction();try{$map=(array)$host->table('fx_versions')->where('id',$foSource['form_id'])->first();unset($map['id']);$map['version']++;$map['previous_id']=$foSource['form_id'];$map['action']='prepare';$map['state']='prepared';$map['actor_id']=13;$host->table('fx_versions')->insert($map);$reject(fn()=>$foPreview(13,$foInput((string)Illuminate\Support\Str::uuid(),0,$foData)),409,'source map no longer reviewed refuses command');$blocked=$foList();$ok($blocked['source']===null&&$blocked['blocked']!==null,'source blocked does not invent readiness');}finally{$host->rollBack();}
$failureKey=(string)Illuminate\Support\Str::uuid();$failure=$foPreview(13,$foInput($failureKey,0,$foData));$host->unprepared("CREATE FUNCTION fo_test_fail() RETURNS trigger LANGUAGE plpgsql AS \$\$ BEGIN RAISE EXCEPTION 'QA_TEST_FAILURE'; END; \$\$; CREATE TRIGGER fo_test_failure BEFORE INSERT ON fo_commands FOR EACH ROW EXECUTE FUNCTION fo_test_fail();");$failed=false;try{$foConfirm(13,$failure['preview']);}catch(Illuminate\Database\QueryException){$failed=true;}$ok($failed&&!$host->table('fo_versions')->where('record_key',$failureKey)->exists(),'receipt failure rolls back version and audit');$host->unprepared('DROP TRIGGER fo_test_failure ON fo_commands; DROP FUNCTION fo_test_fail();');$recovery=$foConfirm(13,$failure['preview']);$ok($recovery['version']===1&&$host->table('fo_versions')->where('record_key',$failureKey)->count()===1,'same confirmation recovers once');$future=$foPreview(14,$foInput($failureKey,1,['decision'=>'approved'],'review'));$reject(fn()=>$foConfirm(14,$future['preview'],'changed-generation'),409,'changed context invalidates confirmation');$host->table('permission_grants')->where(['tenant_id'=>1,'company_id'=>2,'unit_id'=>2,'user_id'=>14,'permission'=>'fiscal_obligations.review'])->delete();$reject(fn()=>$foConfirm(14,$future['preview']),403,'review right revoked is revalidated');
}finally{while($host->transactionLevel()>0)$host->rollBack();}
foreach($before as$t=>$json)$ok($host->table($t)->orderBy('id')->get()->toJson()===$json,'original '.$t.' unchanged');$ok($host->table('fo_versions')->count()===$versions&&$host->table('fo_commands')->count()===$commands,'all administrative fixtures rolled back');file_put_contents($work.'/fiscal-obligations-result.json',json_encode(['passed'=>true,'checks'=>$checks,'fixtures_rolled_back'=>true,'new_financial_effects'=>0,'new_demo'=>false],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'checks'=>count($checks),'proof'=>$work.'/fiscal-obligations-result.json']).PHP_EOL;