Files
SGF/scripts/invoice-demo-smoke.php
2026-11-04 09:37:20 +02:00

6 lines
3.4 KiB
PHP

<?php
use Illuminate\Support\Facades\DB;
$s=json_decode(file_get_contents(getenv('RECEIPT_COMPOSITION_STATE')),true);$out=$s['root'].'/invoice-demo-smoke.json';if(is_file($out))throw new LogicException('Proof preserved');require $s['app'].'/vendor/autoload.php';$app=require $s['app'].'/bootstrap/app.php';$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();$n=json_decode(file_get_contents($s['root'].'/native-fixture.json'),true);config(['database.connections.invoice_demo_verify'=>$s['nativeConnection']]);$db=DB::connection('invoice_demo_verify');$checks=[];$ok=function($v,$name)use(&$checks){if(!$v)throw new RuntimeException($name);$checks[]=$name;};$fp=fn()=>hash('sha256',json_encode([$db->table('purchase_orders')->orderBy('id')->get(),$db->table('goods_receipts')->orderBy('id')->get(),$db->table('invoices')->orderBy('id')->get(),$db->table('budget_entries')->orderBy('id')->get(),$db->table('budget_consumptions')->get(),$db->table('audit_logs')->orderBy('id')->get()]));$before=$fp();$ok($db->table('purchase_orders')->where('tenant_id',$n['tenant'])->count()===0&&$db->table('goods_receipts')->count()===0&&$db->table('invoices')->count()===0&&$db->table('budget_consumptions')->count()===0,'main demo starts before order receipt invoice or consumption');$client=new GuzzleHttp\Client(['base_uri'=>'http://127.0.0.1:8070','http_errors'=>false,'timeout'=>25]);
foreach(['issuer','reviewer','auditor','actor','validator']as$role){$jar=new GuzzleHttp\Cookie\CookieJar;$r=$client->get('/qa/enter/'.$role,['cookies'=>$jar]);$v=json_decode((string)$r->getBody(),true);$o=['cookies'=>$jar,'headers'=>['Accept'=>'application/json','X-SGF-Context'=>$v['context']]];$r=$client->get('/api/purchasing-invoices',$o);$d=json_decode((string)$r->getBody(),true);$ok(in_array($role,['actor','validator'],true)?$r->getStatusCode()===403:($r->getStatusCode()===200&&$d['data']===[]),'invoice access and empty order list match '.$role);if($role==='issuer'){$r=$client->get('/purchasing/invoices',$o);$ok($r->getStatusCode()===200&&str_contains((string)$r->getBody(),'supplier-invoice-workspace.mjs'),'invoice workspace is live');$r=$client->get('/api/session',$o);$d=json_decode((string)$r->getBody(),true);$ok($r->getStatusCode()===200&&$d['context']['purchasing']['supplier_invoices']===true,'session exposes explicit invoice composition capability');$r=$client->get('/api/purchasing-invoices/orders/'.$n['foreign_order'],$o);$ok($r->getStatusCode()===403,'foreign order stays hidden in live demo');}if($role==='actor'){$r=$client->get('/api/purchasing-orders',$o);$d=json_decode((string)$r->getBody(),true);$ok($r->getStatusCode()===200&&count($d['data'])===1,'buyer starts with one approved award and no issued main order');}if($role==='validator'){$r=$client->get('/api/purchasing-receipts',$o);$d=json_decode((string)$r->getBody(),true);$ok($r->getStatusCode()===200&&$d['data']===[],'warehouse waits for actual main order');}}
$r=$client->get('/supplier-invoice-workspace.mjs');$ok($r->getStatusCode()===200&&hash('sha256',(string)$r->getBody())===hash_file('sha256',$s['app'].'/public/supplier-invoice-workspace.mjs'),'served invoice script matches delivery');$ok($fp()===$before,'demo smoke leaves business and budget evidence unchanged');file_put_contents($out,json_encode(['passed'=>true,'checks'=>$checks,'before'=>$before,'after'=>$fp(),'main_orders'=>0,'invoices'=>0,'consumptions'=>0,'visual_review'=>false],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo count($checks)." invoice demo checks passed.\n";