@@ -15,6 +15,7 @@ use App\Services\InvestmentZones;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@@ -51,6 +52,9 @@ class InvestmentSubmissionController extends Controller
|
||||
abort_unless($company !== null, 404);
|
||||
$companyData = json_decode(Crypt::decryptString($company->payload), true, 512, JSON_THROW_ON_ERROR);
|
||||
$payload = [...$payload, 'organisation' => $companyData['name'], 'representative_role' => $companyData['role'], 'incorporation_country_code' => $companyData['incorporation_country_code'] ?? null];
|
||||
if (isset($companyData['organization_country_snapshot'])) {
|
||||
$payload['organization_country_snapshot'] = $companyData['organization_country_snapshot'];
|
||||
}
|
||||
}
|
||||
unset($data['company_id']);
|
||||
if (! empty($data['opportunity_id'])) {
|
||||
@@ -145,7 +149,8 @@ class InvestmentSubmissionController extends Controller
|
||||
{
|
||||
$required = $submitting ? 'required' : 'nullable';
|
||||
$data = $request->validate(['version' => ['required', 'integer', 'min:1'],
|
||||
'payload' => ['required', 'array:full_name,email,phone,country,residence_country_code,incorporation_country_code,declared_origin_country_code,organisation,representative_role,experience,investment_capacity,profile_id,sector,objective,participation_id,partnership_id,estimated_amount,currency,horizon,location,cluster_ids,corridor_ids,project_ids,contact_consent,other_details'],
|
||||
'payload' => ['required', 'array:full_name,email,phone,country,residence_country_code,incorporation_country_code,organization_country_snapshot,declared_origin_country_code,organisation,representative_role,experience,investment_capacity,profile_id,sector,objective,participation_id,partnership_id,estimated_amount,currency,horizon,location,cluster_ids,corridor_ids,project_ids,contact_consent,other_details'],
|
||||
'payload.organization_country_snapshot' => ['sometimes', 'array', 'max:10'],
|
||||
'payload.residence_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.incorporation_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.declared_origin_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
@@ -217,7 +222,7 @@ class InvestmentSubmissionController extends Controller
|
||||
$version = DB::transaction(function () use ($request, $id, $data) {
|
||||
$row = $this->owned($request, $id, true, true);
|
||||
abort_unless($row->status === 'draft' && $row->version === (int) $data['version'], 409, 'Rascunho alterado. Recarregue antes de guardar.');
|
||||
$row->update(['payload' => $data['payload'], 'version' => $row->version + 1]);
|
||||
$row->update(['payload' => $this->preserveCountrySource($row, $data['payload']), 'version' => $row->version + 1]);
|
||||
InvestmentSpecificNeed::where('submission_id', $id)->delete();
|
||||
foreach ($data['needs'] ?? [] as $need) {
|
||||
InvestmentSpecificNeed::create([...$need, 'submission_id' => $id]);
|
||||
@@ -230,6 +235,23 @@ class InvestmentSubmissionController extends Controller
|
||||
return $request->expectsJson() ? response()->json(['version' => $version]) : back()->with('success', 'Rascunho guardado.');
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $payload
|
||||
* @return array<string, mixed> */
|
||||
private function preserveCountrySource(InvestmentSubmission $row, array $payload): array
|
||||
{
|
||||
$source = $row->payload['organization_country_snapshot'] ?? null;
|
||||
if (isset($payload['organization_country_snapshot']) && (! is_array($payload['organization_country_snapshot']) || ! is_array($source) ||
|
||||
Arr::sortRecursive($payload['organization_country_snapshot']) !== Arr::sortRecursive($source))) {
|
||||
throw ValidationException::withMessages(['payload.organization_country_snapshot' => 'A proveniência é recuperada no servidor; não pode ser substituída pelo formulário.']);
|
||||
}
|
||||
unset($payload['organization_country_snapshot']);
|
||||
if ($source && ($row->payload['incorporation_country_code'] ?? null) === ($payload['incorporation_country_code'] ?? null)) {
|
||||
$payload['organization_country_snapshot'] = $source;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
public function submit(Request $request, string $id, InterestSubmission $intake): RedirectResponse|JsonResponse
|
||||
{
|
||||
// Replaying a completed submission returns only the owner's existing receipt.
|
||||
@@ -248,7 +270,7 @@ class InvestmentSubmissionController extends Controller
|
||||
if ($row->dossier_id) {
|
||||
InvestmentPortfolioController::visible()->findOrFail($row->dossier_id);
|
||||
}
|
||||
$p = $data['payload'];
|
||||
$p = $this->preserveCountrySource($row, $data['payload']);
|
||||
$zoneOrigin = DB::table('investment_submission_zones')->where('submission_id', $id)->first(['zone_id', 'zone_version', 'intent']);
|
||||
if ($zoneOrigin) {
|
||||
$zone = app(InvestmentZones::class)->visible()->whereKey($zoneOrigin->zone_id)->lockForUpdate()->firstOrFail();
|
||||
@@ -268,6 +290,7 @@ class InvestmentSubmissionController extends Controller
|
||||
'declared_origin_country_code' => $p['declared_origin_country_code'] ?? null,
|
||||
'residence_country_code' => $p['residence_country_code'] ?? null,
|
||||
'incorporation_country_code' => $p['incorporation_country_code'] ?? null,
|
||||
...(isset($p['organization_country_snapshot']) ? ['organization_country_snapshot' => $p['organization_country_snapshot']] : []),
|
||||
...($zoneOrigin ? ['zone_origin' => (array) $zoneOrigin] : [])]]));
|
||||
$row->update(['payload' => $p, 'version' => $row->version + 1, 'interest_request_id' => $interest->id, 'status' => 'submitted']);
|
||||
InvestmentSpecificNeed::where('submission_id', $id)->delete();
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\InvestmentSubmission;
|
||||
use App\Models\User;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InvestmentWorkspace;
|
||||
use App\Services\OrganizationCountry;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -19,9 +20,10 @@ class InvestmentWorkspaceController extends Controller
|
||||
{
|
||||
public function profile(Request $request, InvestmentWorkspace $workspace): Response|JsonResponse
|
||||
{
|
||||
$data = ['countries' => app(CountryCatalogue::class)->all(), 'account' => $workspace->account($request->user()->id), 'companies' => DB::table('investment_company_declarations')
|
||||
$data = ['organizationCountryAvailable' => app(OrganizationCountry::class)->available(), 'organizations' => app(OrganizationCountry::class)->represented($request->user()), 'countries' => app(CountryCatalogue::class)->all(), 'account' => $workspace->account($request->user()->id), 'companies' => DB::table('investment_company_declarations')
|
||||
->where('user_id', $request->user()->id)->orderByDesc('created_at')->get(['id', 'version', 'payload'])->map(function ($company) {
|
||||
$company->payload = json_decode(Crypt::decryptString($company->payload), true, 512, JSON_THROW_ON_ERROR);
|
||||
$company->countrySource = $company->payload['organization_country_snapshot'] ?? null;
|
||||
|
||||
return $company;
|
||||
})];
|
||||
@@ -68,9 +70,15 @@ class InvestmentWorkspaceController extends Controller
|
||||
abort_if(! $id && DB::table('investment_company_declarations')->where('user_id', $request->user()->id)->count() >= 20, 422, 'Máximo de vinte empresas declaradas.');
|
||||
$id ??= (string) Str::uuid();
|
||||
$version = (int) $data['version'] + 1;
|
||||
$previous = $row ? json_decode(Crypt::decryptString($row->payload), true, 512, JSON_THROW_ON_ERROR) : [];
|
||||
$payload = [...$previous, ...$data['payload']];
|
||||
if (($previous['incorporation_country_code'] ?? null) !== ($payload['incorporation_country_code'] ?? null)) {
|
||||
unset($payload['organization_country_snapshot']);
|
||||
}
|
||||
$encrypted = Crypt::encryptString(json_encode($payload, JSON_THROW_ON_ERROR));
|
||||
DB::table('investment_company_declarations')->updateOrInsert(['id' => $id], ['user_id' => $request->user()->id, 'version' => $version,
|
||||
'payload' => Crypt::encryptString(json_encode($data['payload'], JSON_THROW_ON_ERROR)), 'created_at' => $row->created_at ?? now(), 'updated_at' => now()]);
|
||||
$this->audit($request, 'company_declared', 'investment_company_declarations', $id, ['version' => $version]);
|
||||
'payload' => $encrypted, 'created_at' => $row->created_at ?? now(), 'updated_at' => now()]);
|
||||
$this->audit($request, 'company_declared', 'investment_company_declarations', $id, ['version' => $version, 'before_payload' => $row?->payload, 'after_payload' => $encrypted]);
|
||||
|
||||
return ['id' => $id, 'version' => $version];
|
||||
});
|
||||
@@ -78,6 +86,36 @@ class InvestmentWorkspaceController extends Controller
|
||||
return $request->expectsJson() ? response()->json($result) : back()->with('success', 'Declaração de empresa guardada.');
|
||||
}
|
||||
|
||||
public function organizationCountry(Request $request, string $id, OrganizationCountry $service): RedirectResponse|JsonResponse
|
||||
{
|
||||
$result = $service->save($request->user(), $id, $request->all());
|
||||
|
||||
return $request->expectsJson() ? response()->json($result) : back()->with('success', 'País de constituição guardado no cadastro mestre; submissões anteriores preservadas.');
|
||||
}
|
||||
|
||||
public function reuseOrganizationCountry(Request $request, string $id, OrganizationCountry $service): RedirectResponse|JsonResponse
|
||||
{
|
||||
$data = $request->validate(['version' => 'required|integer|min:1', 'organization_id' => 'required|uuid', 'organization_version' => 'required|integer|min:1']);
|
||||
$result = DB::transaction(function () use ($request, $id, $data, $service) {
|
||||
$row = DB::table('investment_company_declarations')->where('id', $id)->where('user_id', $request->user()->id)->lockForUpdate()->first();
|
||||
abort_unless($row !== null, 404);
|
||||
abort_unless((int) $row->version === (int) $data['version'], 409, 'Declaração alterada. Recarregue.');
|
||||
$snapshot = $service->snapshot($request->user(), $data['organization_id']);
|
||||
abort_unless((int) $snapshot['organization_version'] === (int) $data['organization_version'], 409, 'País mestre alterado. Recarregue.');
|
||||
$payload = json_decode(Crypt::decryptString($row->payload), true, 512, JSON_THROW_ON_ERROR);
|
||||
$payload['incorporation_country_code'] = $snapshot['country'];
|
||||
$payload['organization_country_snapshot'] = $snapshot;
|
||||
$encrypted = Crypt::encryptString(json_encode($payload, JSON_THROW_ON_ERROR));
|
||||
DB::table('investment_company_declarations')->where('id', $id)->update(['payload' => $encrypted, 'version' => $row->version + 1, 'updated_at' => now()]);
|
||||
$this->audit($request, 'organization_country_reused', 'investment_company_declarations', $id, ['version' => $row->version + 1,
|
||||
'before_payload' => $row->payload, 'after_payload' => $encrypted, 'organization_id' => $data['organization_id'], 'organization_version' => $snapshot['organization_version']]);
|
||||
|
||||
return ['version' => $row->version + 1, 'country' => $snapshot['country']];
|
||||
});
|
||||
|
||||
return $request->expectsJson() ? response()->json($result) : back()->with('success', 'País mestre reutilizado nesta declaração; manifestações anteriores não alteradas.');
|
||||
}
|
||||
|
||||
public function notifications(Request $request): Response|JsonResponse
|
||||
{
|
||||
$query = DB::table('investment_notifications')->where('user_id', $request->user()->id);
|
||||
|
||||
@@ -25,8 +25,9 @@ class InvestorPathController extends Controller
|
||||
{
|
||||
$source = $request->input('content_resource_id');
|
||||
if ($source !== null) {
|
||||
abort_unless(filter_var($source, FILTER_VALIDATE_INT), 422);
|
||||
app(LegacyContent::class)->articleForResource((int) $source);
|
||||
$resourceId = filter_var($source, FILTER_VALIDATE_INT);
|
||||
abort_unless(is_int($resourceId) && $resourceId !== 0, 422);
|
||||
app(LegacyContent::class)->articleForResource($resourceId);
|
||||
}
|
||||
$id = DB::transaction(function () use ($path, $request, $source): string {
|
||||
$id = $path->create($request->user(), $request->all());
|
||||
|
||||
@@ -309,6 +309,8 @@ class LandAssistanceController extends Controller
|
||||
'case' => $case->only(['reference', 'version', 'payload', 'updated_at']),
|
||||
'disclaimer' => self::DISCLAIMER,
|
||||
'modelVersion' => 'land-assistance-v1',
|
||||
'country' => app(CountryCatalogue::class)->describe($case->payload['country'] ?? null),
|
||||
'declaredOrigin' => app(CountryCatalogue::class)->describe($case->payload['declared_origin_country_code'] ?? null),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Services\OpportunityImageProcessor;
|
||||
use App\Services\OpportunityManagement;
|
||||
use App\Services\OpportunityResourceInstallation;
|
||||
use App\Services\OpportunityResources;
|
||||
use App\Services\OrganizationCountryInstallation;
|
||||
use App\Services\PortalProfileAccess;
|
||||
use App\Services\VerifiedDocumentBinary;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -16,6 +17,7 @@ use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
@@ -38,6 +40,39 @@ class OpportunityResourceController extends Controller
|
||||
return back()->with('success', 'Recursos instalados; nenhum ficheiro publicado ou oportunidade submetida.');
|
||||
}
|
||||
|
||||
public function organizationCountryPreview(Request $request, OrganizationCountryInstallation $service): JsonResponse|Response
|
||||
{
|
||||
$plan = $service->preview($request->user());
|
||||
$scope = $this->countryOperationScope($request, $plan);
|
||||
$operation = $request->session()->get('portal.country_installation_operation');
|
||||
if (! is_array($operation) || ($operation['scope'] ?? null) !== $scope) {
|
||||
$operation = ['scope' => $scope, 'key' => (string) Str::uuid()];
|
||||
$request->session()->put('portal.country_installation_operation', $operation);
|
||||
}
|
||||
$plan = [...$plan, 'operationKey' => $operation['key'], 'actionUrl' => '/management/opportunity-resources-install/organization-country', 'extension' => true];
|
||||
|
||||
return $request->expectsJson() ? response()->json($plan) : Inertia::render('management/opportunity-install', $plan);
|
||||
}
|
||||
|
||||
public function organizationCountryApply(Request $request, OrganizationCountryInstallation $service): JsonResponse|RedirectResponse
|
||||
{
|
||||
// Preview authorizes the actor; the UUID remains stable until this scope changes or logout.
|
||||
$plan = $service->preview($request->user());
|
||||
$operation = $request->session()->get('portal.country_installation_operation');
|
||||
$data = $request->validate(['idempotency_key' => 'required|uuid']);
|
||||
abort_unless(is_array($operation) && ($operation['scope'] ?? null) === $this->countryOperationScope($request, $plan)
|
||||
&& hash_equals($operation['key'], $data['idempotency_key']), 409, 'A operação não corresponde a esta prévia. Atualize a página antes de tentar novamente.');
|
||||
$result = $service->apply($request->user(), $request->all());
|
||||
|
||||
return $request->expectsJson() ? response()->json($result) : back()->with('success', 'País mestre instalado; nenhuma submissão anterior alterada.');
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $plan */
|
||||
private function countryOperationScope(Request $request, array $plan): string
|
||||
{
|
||||
return hash('sha256', json_encode([$request->user()->getAuthIdentifier(), $plan['target'], $plan['migration'], $plan['code_hash']], JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
public function index(int $id, OpportunityResources $service): Response
|
||||
{
|
||||
$opportunity = Opportunity::withTrashed()->findOrFail($id);
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Services\InvestmentGeography;
|
||||
use App\Services\InvestmentWorkspace;
|
||||
use App\Services\OpportunityManagement;
|
||||
use App\Services\PortalAudit;
|
||||
use App\Services\PortalProfileAccess;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -126,7 +127,7 @@ class PortalManagementController extends Controller
|
||||
'id', 'reference', 'full_name', 'email', 'phone', 'investor_type', 'country',
|
||||
'sector_interest', 'opportunity_reference', 'investment_range', 'message',
|
||||
'privacy_consent', 'consented_at', 'status', 'created_at', 'reviewed_at', 'reviewed_by', 'metadata',
|
||||
'existing_business_id', 'modality', 'assigned_to', 'next_action', 'next_action_due_at',
|
||||
'existing_business_id', 'modality', 'assigned_to', 'next_action', 'next_action_due_at', 'source_page',
|
||||
]),
|
||||
'history' => $history,
|
||||
'consents' => $consents,
|
||||
@@ -231,7 +232,7 @@ class PortalManagementController extends Controller
|
||||
$query = $model::query();
|
||||
if ($resource === 'opportunities') {
|
||||
if (Schema::hasColumn('opportunities', 'owner_user_id')) {
|
||||
$query = app(\App\Services\PortalProfileAccess::class)->scope(Opportunity::query(), $request->user());
|
||||
$query = app(PortalProfileAccess::class)->scope(Opportunity::query(), $request->user());
|
||||
}
|
||||
$query->with('primaryTerritory:id,name,location_type,source_system,source_code');
|
||||
if (isset($filters['geography_scope'])) {
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Opportunity;
|
||||
use App\Services\OpportunityCanonicalContract;
|
||||
use App\Services\OpportunityContacts;
|
||||
use App\Services\OpportunityManagement;
|
||||
use App\Services\OpportunityProfileWorkflow;
|
||||
use App\Services\PortalInternalDesignation;
|
||||
use App\Services\PortalProfileAccess;
|
||||
use App\Services\PortalProfileAdministration;
|
||||
use App\Services\PortalSuperusers;
|
||||
@@ -47,6 +50,8 @@ class PortalProfileController extends Controller
|
||||
|
||||
return Inertia::render('profiles/administration', ['requests' => DB::table('portal_profile_requests')->latest()->get(),
|
||||
'assignments' => DB::table('portal_role_assignments')->get(), 'pair' => DB::table('portal_superuser_pair')->first(),
|
||||
'operatorOrganizations' => app(PortalInternalDesignation::class)->organizations(),
|
||||
'internalTypes' => OpportunityCanonicalContract::BASE_CATEGORIES,
|
||||
'actorId' => $request->user()->id, 'types' => OpportunityManagement::CATEGORIES,
|
||||
'organizations' => DB::table('organizations')->whereNull('deleted_at')->get(['id', 'name']),
|
||||
'securityRequests' => DB::table('portal_security_approvals')->latest()->limit(30)->get(),
|
||||
@@ -83,6 +88,11 @@ class PortalProfileController extends Controller
|
||||
return Inertia::render('profiles/audit', ['records' => $records, 'filters' => $filters]);
|
||||
}
|
||||
|
||||
public function registerOperatorOrganization(Request $request, PortalInternalDesignation $service): JsonResponse
|
||||
{
|
||||
return response()->json($service->registerOrganization($request->user(), $request->all()), 201);
|
||||
}
|
||||
|
||||
public function grant(Request $request, PortalProfileAdministration $service): JsonResponse
|
||||
{
|
||||
return response()->json(['id' => $service->grant($request->user(), $request->all())], 201);
|
||||
@@ -131,6 +141,11 @@ class PortalProfileController extends Controller
|
||||
return response()->json(['id' => $id, 'status' => app(PortalProfileAccess::class)->state($record), 'publication_status' => $record->status, 'etag' => app(OpportunityManagement::class)->etag($record), 'message' => 'Ação interna registada; não representa decisão externa.']);
|
||||
}
|
||||
|
||||
public function contact(Request $request, int $id, OpportunityContacts $service): JsonResponse
|
||||
{
|
||||
return response()->json($service->save($request->user(), $id, $request->all()));
|
||||
}
|
||||
|
||||
public function replacement(Request $request, PortalSuperusers $service): JsonResponse
|
||||
{
|
||||
$data = $request->validate(['old_user_id' => 'required|integer', 'new_user_id' => 'required|integer', 'reason' => 'required|string|min:20|max:1000']);
|
||||
|
||||
@@ -26,4 +26,15 @@ class PortalProfileInstallationController extends Controller
|
||||
{
|
||||
return response()->json($installation->bootstrap($request->user(), $request->all()));
|
||||
}
|
||||
|
||||
public function bootstrapPreview(Request $request, string $id, PortalProfileInstallation $installation): JsonResponse|Response
|
||||
{
|
||||
$plan = $installation->bootstrapPreview($request->user(), $id);
|
||||
return $request->expectsJson() ? response()->json($plan) : Inertia::render('profiles/bootstrap-confirmation', $plan);
|
||||
}
|
||||
|
||||
public function confirmBootstrap(Request $request, string $id, PortalProfileInstallation $installation): JsonResponse
|
||||
{
|
||||
return response()->json($installation->confirmBootstrap($request->user(), $id, $request->all()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,13 +236,22 @@ class PortalServicesController extends Controller
|
||||
abort_unless(DB::table('portal_partnerships')->where('id', $data['partnership_id'])->where('status', 'published')->exists(), 422);
|
||||
}
|
||||
$data['portal_user_id'] = $request->user()?->id;
|
||||
// Preserve the actual entry form, not only the shared POST endpoint. Never accept an external or administrative referrer as the entry page.
|
||||
$entry = parse_url($request->headers->get('referer', ''));
|
||||
$sourcePage = '/apoio';
|
||||
if (is_array($entry) && strtolower($entry['scheme'] ?? '') === $request->getScheme()
|
||||
&& strtolower($entry['host'] ?? '') === strtolower($request->getHost())
|
||||
&& (int) ($entry['port'] ?? (($entry['scheme'] ?? '') === 'https' ? 443 : 80)) === $request->getPort()
|
||||
&& in_array($entry['path'] ?? '', ['/apoio', '/formularios/investidor', '/formularios/empresa', '/parcerias', '/parcerias/painel'], true)) {
|
||||
$sourcePage = $entry['path'];
|
||||
}
|
||||
try {
|
||||
$interest = $submission->receive($data, $data['submission_key'], fn () => InterestRequest::create([
|
||||
'reference' => 'AP-'.now()->year.'-'.Str::ulid(), 'full_name' => $data['fullName'], 'email' => $data['email'],
|
||||
'phone' => $data['phone'] ?? null, 'country' => $data['country'],
|
||||
'investor_type' => $data['kind'] === 'company' ? 'empresa' : 'individual',
|
||||
'sector_interest' => $data['sectorInterest'], 'message' => $data['message'],
|
||||
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/apoio',
|
||||
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => $sourcePage,
|
||||
'metadata' => ['kind' => $data['kind'], 'company' => $data['company'] ?? null,
|
||||
'portal_user_id' => $data['portal_user_id'], 'partnership_id' => $data['partnership_id'] ?? null,
|
||||
'declared_origin_country_code' => $data['declared_origin_country_code'] ?? null],
|
||||
@@ -637,7 +646,7 @@ class PortalServicesController extends Controller
|
||||
'document_id' => ['required', 'uuid'], 'title' => ['required', 'string', 'max:200'],
|
||||
'description' => ['nullable', 'string', 'max:4000'], 'category' => ['required', 'string', 'max:80'],
|
||||
// QA legacy originals may have no theme (e.g. a shared image). Do not invent a sector to disclose an authorized original.
|
||||
'topic' => [app(\App\Services\LegacyContent::class)->available() ? 'nullable' : 'required', 'string', 'max:80'],
|
||||
'topic' => [app(LegacyContent::class)->available() ? 'nullable' : 'required', 'string', 'max:80'],
|
||||
'document_type' => ['required', 'in:legislation,procedure,official_form,digital_adaptation,guidance_template,guide,study,reference_data,unknown'],
|
||||
'issuer' => ['nullable', 'string', 'max:180'], 'document_number' => ['nullable', 'string', 'max:120'],
|
||||
'document_date' => ['nullable', 'date_format:Y-m-d'], 'source_url' => ['nullable', 'url:https', 'max:2000'],
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\TerritoryGeometryImport;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class TerritoryGeometryImportController extends Controller
|
||||
{
|
||||
public function preview(Request $request, TerritoryGeometryImport $service)
|
||||
public function preview(Request $request, TerritoryGeometryImport $service): JsonResponse|Response
|
||||
{
|
||||
$data = $request->validate(['level' => 'nullable|integer|in:1,2,3']);
|
||||
$plan = $service->preview($request->user(), (int) ($data['level'] ?? 1));
|
||||
@@ -16,12 +18,12 @@ class TerritoryGeometryImportController extends Controller
|
||||
return $request->expectsJson() ? response()->json($plan) : Inertia::render('management/territory-geometry-import', ['plan' => $plan]);
|
||||
}
|
||||
|
||||
public function apply(Request $request, TerritoryGeometryImport $service)
|
||||
public function apply(Request $request, TerritoryGeometryImport $service): JsonResponse
|
||||
{
|
||||
return response()->json($service->apply($request->user(), $request->all()));
|
||||
}
|
||||
|
||||
public function reverse(Request $request, string $batch, TerritoryGeometryImport $service)
|
||||
public function reverse(Request $request, string $batch, TerritoryGeometryImport $service): JsonResponse
|
||||
{
|
||||
return response()->json($service->reverse($request->user(), $batch, $request->all()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user