from pathlib import Path import json R=Path(__file__).resolve().parent.parent;P=R/'storage/app/private/investmoz-v2/portal-audit' plan=json.loads((P/'internal-designation-plan.json').read_text());S=Path(plan['source']) assert S.parent==P and plan['target']['port']==55441 def edit(file,old,new): p=S/file;t=p.read_text(encoding='utf-8');assert t.count(old)==1,(file,old[:70]);p.write_text(t.replace(old,new),encoding='utf-8') # Source-specific internal designation: no external request/documents or corporate membership. edit('app/Services/PortalProfileAdministration.php', " $this->administrative($actor);\n $data = Validator::make($input, ['user_id'", " $this->administrative($actor);\n if (($input['internal_designation'] ?? false) === true) {\n return app(PortalInternalDesignation::class)->grant($actor, $input);\n }\n $data = Validator::make($input, ['user_id'") edit('app/Services/PortalProfileAccess.php', " public function scoped(User $actor, string $role, ?string $organization, string $type): bool", ''' public function internalAssignment(User $actor, string $type): ?\\stdClass { foreach ($this->grants($actor, 'promoter') as $grant) { if ($grant->source === 'internal-portal-designation' && in_array($type, json_decode($grant->opportunity_types, true), true) && app(PortalInternalDesignation::class)->organization($grant->organization_id) !== null) { return $grant; } } return null; } public function promoterRecordScope(User $actor, Opportunity $record): bool { foreach ($this->grants($actor, 'promoter') as $grant) { if (! in_array($record->opportunity_category, json_decode($grant->opportunity_types, true), true)) continue; if ($grant->source === 'internal-portal-designation') { if (app(PortalInternalDesignation::class)->organization($grant->organization_id) !== null && ($record->workflow_context['operator_organization_id'] ?? null) === $grant->organization_id && ((int)$record->owner_user_id === $actor->id || in_array($actor->id,$record->workflow_context['contributors'] ?? [],true))) return true; } elseif ($grant->organization_id === $record->organization_id && $this->represents($actor,$record->organization_id) && ($record->organization_id !== null || (int)$record->owner_user_id === $actor->id)) return true; } return false; } public function scoped(User $actor, string $role, ?string $organization, string $type): bool''') edit('app/Services/PortalProfileAccess.php', " foreach ($this->grants($actor, $role) as $grant) {", " if ($role === 'promoter' && $organization !== null && $this->internalAssignment($actor,$type) !== null\n && DB::table('organizations')->where('id',$organization)->whereNull('deleted_at')->exists()) return true;\n foreach ($this->grants($actor, $role) as $grant) {") edit('app/Services/PortalProfileAccess.php', "($personal && $this->scoped($actor, 'promoter', $record->organization_id, $record->opportunity_category))", "$this->promoterRecordScope($actor, $record)") edit('app/Services/PortalProfileAccess.php', " if ($grant->role === 'promoter' && ! $this->represents($actor, $grant->organization_id)) {", " if ($grant->role === 'promoter' && $grant->source !== 'internal-portal-designation' && ! $this->represents($actor, $grant->organization_id)) {") edit('app/Services/PortalProfileAccess.php', " if ($grant->organization_id !== null) {", " if ($grant->role === 'promoter' && $grant->source === 'internal-portal-designation') {\n $allowed->where('owner_user_id',$actor->id)->where('workflow_context->operator_organization_id',$grant->organization_id);\n } elseif ($grant->organization_id !== null) {") edit('app/Services/PortalProfileAccess.php', " foreach ($this->grants($actor, 'promoter') as $grant) {\n if (! $this->represents($actor, $grant->organization_id)) {", " foreach ($this->grants($actor, 'promoter') as $grant) {\n if ($grant->source === 'internal-portal-designation' && app(PortalInternalDesignation::class)->organization($grant->organization_id) !== null) {\n foreach (DB::table('organizations')->whereNull('deleted_at')->get(['id','name']) as $realPromoter) {\n foreach (json_decode($grant->opportunity_types,true) as $type) {\n $key=$realPromoter->id.'|'.$type;\n if (!isset($seen[$key]) && $this->canCreate($actor,$realPromoter->id,$type)) {\n $contexts[]=['organization_id'=>$realPromoter->id,'type'=>$type];$seen[$key]=true;\n }\n }\n }\n continue;\n }\n if (! $this->represents($actor, $grant->organization_id)) {") edit('app/Services/OpportunityManagement.php', "$record->workflow_context = ['policy_version' => PortalProfileAccess::VERSION, 'contributors' => [$actor->id]];", "$record->workflow_context = ['policy_version' => PortalProfileAccess::VERSION, 'contributors' => [$actor->id]];\n if (($internal=$access->internalAssignment($actor,$data['opportunity_category'] ?? '')) !== null) {\n $record->workflow_context=[...$record->workflow_context,'operator_organization_id'=>$internal->organization_id,'internal_assignment_id'=>$internal->id];\n }") edit('app/Http/Controllers/PortalProfileController.php', " 'actorId' => $request->user()->id, 'types'", " 'operatorOrganizations' => app(\\App\\Services\\PortalInternalDesignation::class)->organizations(),\n 'actorId' => $request->user()->id, 'types'") edit('app/Http/Controllers/PortalProfileController.php', " public function grant(Request $request, PortalProfileAdministration $service): JsonResponse", ''' public function registerOperatorOrganization(Request $request, \\App\\Services\\PortalInternalDesignation $service): JsonResponse { return response()->json($service->registerOrganization($request->user(),$request->all()),201); } public function grant(Request $request, PortalProfileAdministration $service): JsonResponse''') edit('routes/web.php', " Route::post('/perfis/atribuicoes', [$profiles, 'grant']);", " Route::post('/perfis/organizacao-operadora', [$profiles, 'registerOperatorOrganization']);\n Route::post('/perfis/atribuicoes', [$profiles, 'grant']);") edit('app/Services/PortalProfileAccess.php', "return [__FILE__, app_path('Models/User.php')", "return [__FILE__, app_path('Services/PortalInternalDesignation.php'), app_path('Models/User.php')") print(json.dumps({'result':'QA_internal_designation_extension_prepared','active_application_changes':0,'active_database_writes':0}))