(string)Str::uuid(),'revision'=>$id?$r['data']['revision']:$r['data']['new_revision'],'action'=>$action,'data'=>$data]);if($p['status']!==200)throw new RuntimeException('Source request preview');$r=$call($role,$base.'/'.$id.'/confirm',['preview'=>$p['data']['preview']]);if($r['status']!==201)throw new RuntimeException('Source request confirmation');return $r['data'];}; $r=$requestCommand('requester',0,'save',['cost_center_id'=>$n['centre'],'priority'=>'normal','needed_by'=>date('Y-m-d',strtotime('+30 days')),'justification'=>'Fixture aberta para o selector inicial de fornecedores.','items'=>[['description'=>'Consulta inicial QA','category'=>'Outro','purchase_type'=>'consumable','quantity'=>'1.000','unit'=>'UN','unit_price'=>'1.00','tax_rate'=>'0']]]);$id=$r['request_id'];$requestCommand('requester',$id,'submit',[]);$requestCommand('approver',$id,'decide',['decision'=>'approved','comment'=>'Conferencia distinta da fixture aberta de1MZN.']);$url='/api/purchasing-sourcing/requests/'.$id.'/suppliers';$a=$call('actor',$url.'?page=1');$b=$call('actor',$url.'?page=1&search=');$ok($a['status']===200&&$b['status']===200&&$a['data']['data']===$b['data']['data']&&$a['data']['total']===$b['data']['total']&&$b['data']['total']===3,'supplier empty initial search equals omitted search and returns native paginated eligible directory');$r=$call('actor',$url.'?page=1&search=%20%20');$ok($r['status']===200&&$r['data']['data']===$a['data']['data'],'trimmed blank supplier search keeps unfiltered initial-page semantics');$ok($call('actor',$url.'?search[]=x')['status']===422&&$call('actor',$url.'?per_page=30')['status']===422,'nullable empty filter still rejects array search and unsupported page size');$ok($call('validator',$url.'?search=')['status']===403,'empty search does not bypass sourcing preparation right');$source=json_decode(file_get_contents($s['root'].'/receipt-ui-source.json'),true);$ok($call('actor','/api/purchasing-sourcing/requests/'.$source['request_id'].'/suppliers?search=')['status']===403,'empty search does not reopen proposals closed by actual award');$catalogue='/api/purchasing-receipts/orders/'.$source['order']['id'].'/lines/'.$source['order']['items'][0]['id'].'/catalogue';$a=$call('validator',$catalogue.'?page=1');$b=$call('validator',$catalogue.'?search=&page=1');$ok($a['status']===200&&$b['status']===200&&$a['data']['data']===$b['data']['data'],'empty article filter equals omitted filter in actual receipt catalogue');$ok($call('validator',$catalogue.'?search[]=x')['status']===422&&$call('validator',$catalogue.'?unknown=1')['status']===422,'article catalogue keeps strict parameter types and allowlist');$ok($db->table('goods_receipts')->count()===1&&$db->table('stock_movements')->count()===1&&(int)$db->table('stock_movements')->sum('quantity_milli')===1000&&$db->table('invoices')->count()===0&&$db->table('pa_obligations')->count()===0&&$db->table('external_payments')->count()===0,'catalogue checks preserve one UI receipt and physical movement without invoice debt or payment');file_put_contents($out,json_encode(['passed'=>true,'checks'=>$checks,'open_request_fixture_minor'=>100,'supplier_rows'=>3,'new_right_names'=>[],'visual_review'=>false],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo count($checks)." continuity boundary checks passed.\n";