0,404); $ctx=app(CompanyContext::class);$s=$ctx->identifiers();$unit=$ctx->unitId();$actor=$ctx->userId();$host=DB::connection();$generation=hash('sha256',json_encode([$s,$unit,request()->session()->get('company_context.module_id'),request()->session()->get('company_context.token')],JSON_THROW_ON_ERROR)); return $host->transaction(function()use($kind,$id,$edit,$work,$ctx,$s,$unit,$actor,$host,$generation){ $host->table('companies')->where('id',$s['company_id'])->where('tenant_id',$s['tenant_id'])->lockForUpdate()->firstOrFail();$host->table('users')->where('id',$actor)->lockForUpdate()->firstOrFail(); abort_unless($host->table('company_memberships')->where($s)->where('user_id',$actor)->lockForUpdate()->first(),403); $require=function(string $right,?int $u=null)use($host,$s,$actor){abort_unless($host->table('permission_grants')->where($s)->where(['user_id'=>$actor,'permission'=>$right,'unit_id'=>$u])->lockForUpdate()->first(),403);}; $require('company.view');if($unit!==null)$require('unit.view',$unit); $base=$s+['unit_key'=>0,'module_key'=>'general','kind'=>$kind,'entity_id'=>$id,'provider'=>'sgf']; if($kind==='supplier'){ abort_unless($unit!==null,403);$base['unit_key']=$unit;$base['module_key']='purchasing'; return app(ReceiptRuntime::class)->run($edit?'purchasing_suppliers.prepare':'purchasing_suppliers.view',function($native,$binding,$fingerprint,$origin)use($id,$edit,$work,$base,$host,$actor,$generation){ abort_unless($native->hasFunctions($edit?['procurement']:['admin','procurement','finance','department_head']),403); $supplier=SupplierAccess::query($binding,$origin['sgf_context_key'])->lockForUpdate()->findOrFail($id); if($edit)abort_unless(app(\Tempo\Purchasing\Embedded\Services\SupplierParticipation::class)->canPrepare($native),403); $scope=$base;$scope['provider']=hash('sha256',DB::connection()->getDatabaseName());$entity=['id'=>$id,'name'=>$supplier->name,'version'=>(int)$supplier->version,'editable'=>$host->table('permission_grants')->where(['tenant_id'=>$base['tenant_id'],'company_id'=>$base['company_id'],'unit_id'=>$base['unit_key'],'user_id'=>$actor,'permission'=>'purchasing_suppliers.prepare'])->exists()&&app(\Tempo\Purchasing\Embedded\Services\SupplierParticipation::class)->canPrepare($native)]; return $work($host,$scope,$entity,$actor,hash('sha256',$fingerprint.$generation)); }); } if($kind==='company'){abort_unless($id===$s['company_id'],403);$require($edit?'company.edit':'company.view');$entity=$host->table('companies')->where('tenant_id',$s['tenant_id'])->where('id',$id)->lockForUpdate()->first();} elseif($kind==='unit'){abort_unless($id===$unit,403);$require($edit?'unit.edit':'unit.view',$id);$base['unit_key']=$id;$entity=$host->table('units')->where($s)->where('id',$id)->lockForUpdate()->first();} else{$require('clients.view');if($edit)$require('clients.edit');abort_unless(ModuleRecords::active()==='commercial',403);$base['module_key']='commercial';$entity=ModuleRecords::query('a_clients')->where($s)->whereNull('unit_id')->where('id',$id)->lockForUpdate()->first();} abort_unless($entity,403,'Registo fora do âmbito autorizado.');return $work($host,$base,['id'=>$id,'name'=>$entity->name,'version'=>(int)($entity->version??0),'updated_at'=>$entity->updated_at??null,'editable'=>$host->table('permission_grants')->where($s)->where(['unit_id'=>$kind==='unit'?$id:null,'user_id'=>$actor,'permission'=>match($kind){'company'=>'company.edit','unit'=>'unit.edit','client'=>'clients.edit'}])->exists()],$actor,$generation); }); } public static function current($db,array $scope):?array { $r=$db->table('geo_locations')->where($scope)->first();return $r?['revision'=>(int)$r->revision,'selection'=>$r->selection===null?null:json_decode($r->selection,true),'actor_id'=>(int)$r->actor_id,'reason'=>$r->reason,'updated_at'=>$r->updated_at]:null; } public static function hash(mixed $v):string{return hash('sha256',json_encode($v,JSON_THROW_ON_ERROR));} public static function useHost($host,\Closure $work):mixed { $old=DB::getDefaultConnection();DB::setDefaultConnection($host->getName());try{return $work();}finally{DB::setDefaultConnection($old);} } }