16 lines
3.2 KiB
PHP
16 lines
3.2 KiB
PHP
<?php
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tempo\Finance\Payables\Payables;
|
|
$output=$s['root'].'/ledger-reports-isolation.json';if(file_exists($output)||!is_file($s['root'].'/ledger-reports-seed.json'))throw new LogicException('Fresh isolation proof in dedicated report database required');$before=$financialFingerprint();$range=['from_on'=>'2026-10-01','to_on'=>'2026-10-31'];$report=fn($options)=>$ledger->report($enter('read'),'trial-balance',$options);$base=$report($range);$checks=0;$ok=function($v,$m)use(&$checks){$checks++;if(!$v)throw new LogicException($m);};
|
|
DB::beginTransaction();try{
|
|
foreach(['tenant_id','company_id','unit_id'] as $key){
|
|
$foreign=$scope;$foreign[$key]+=990000;$j=(array)DB::table('gl_journals')->orderBy('id')->first();$p=(array)DB::table('gl_proposals')->where('id',$j['proposal_id'])->first();$r=(array)DB::table('gl_reviews')->where('id',$j['review_id'])->first();$snap=json_decode($j['snapshot'],true,64,JSON_THROW_ON_ERROR);$accounts=[];
|
|
foreach($snap['lines'] as $i=>$line){$a=(array)DB::table('gl_accounts')->where('id',$line['account_id'])->first();unset($a['id']);$a=array_replace($a,$foreign);$accounts[$i]=DB::table('gl_accounts')->insertGetId($a);$snap['lines'][$i]['account_id']=$accounts[$i];}
|
|
$snapshot=Payables::canonical($snap);$revision=hash('sha256',$snapshot);unset($p['id'],$r['id'],$j['id']);$p=array_replace($p,$foreign,['snapshot'=>$snapshot,'revision'=>$revision,'reason'=>'Rollback-only foreign report fixture.']);$pid=DB::table('gl_proposals')->insertGetId($p);$r=array_replace($r,$foreign,['proposal_id'=>$pid,'revision'=>$revision]);$rid=DB::table('gl_reviews')->insertGetId($r);$j=array_replace($j,$foreign,['proposal_id'=>$pid,'review_id'=>$rid,'snapshot'=>$snapshot]);$jid=DB::table('gl_journals')->insertGetId($j);foreach($snap['lines'] as $i=>$line)DB::table('gl_lines')->insert($foreign+['journal_id'=>$jid,'line_no'=>$i+1,'account_id'=>$line['account_id'],'debit_minor'=>$line['debit_minor'],'credit_minor'=>$line['credit_minor']]);DB::select('SELECT gl_assert_balanced(?)',[$jid]);
|
|
$current=$report($range);$ok($current['totals']===$base['totals']&&$current['rows']===$base['rows']&&$current['basis']===$base['basis'],'Foreign '.$key.' facts never enter report');$caught=false;try{$report($range+['account_id'=>$accounts[0]]);}catch(DomainException){$caught=true;}$ok($caught,'Foreign account explicitly refused even with otherwise valid dates');
|
|
}
|
|
DB::statement('ALTER TABLE gl_lines RENAME TO gl_lines_rollback_probe');$caught=false;try{$report($range);}catch(Symfony\Component\HttpKernel\Exception\HttpException $e){$caught=$e->getStatusCode()===503;}$ok($caught,'Missing source table is 503, never empty/zero');
|
|
}finally{while(DB::transactionLevel()>0)DB::rollBack();}
|
|
$ok($financialFingerprint()===$before&&$report($range)===$base,'Rollback restored scope/source/rights and identical report');
|
|
file_put_contents($output,json_encode(['passed'=>true,'checks'=>$checks,'foreign_tenant_company_unit_excluded'=>true,'foreign_accounts_refused'=>true,'missing_source_is_503'=>true,'rollback_only'=>true,'source_and_rights_unchanged'=>true],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo "Report isolation: $checks checks, foreign books excluded and missing source unavailable rather than zero.\n";
|