@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\ExistingBusinessClassification;
|
||||
use App\Services\Mne\BusinessRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class ExistingBusinessClassificationController extends Controller
|
||||
{
|
||||
public function show(Request $request, string $id, ExistingBusinessClassification $service): Response|JsonResponse
|
||||
{
|
||||
$props = ['supplement' => $service->privateView($request->user(), app(BusinessRepository::class)->find($id))];
|
||||
|
||||
return $request->expectsJson() ? response()->json($props) : Inertia::render('investment/business-classification', $props);
|
||||
}
|
||||
|
||||
public function act(Request $request, string $id, ExistingBusinessClassification $service): JsonResponse
|
||||
{
|
||||
$business = $service->act($request->user(), $id, $request->all());
|
||||
|
||||
return response()->json(['supplement' => $service->privateView($request->user(), $business)]);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ class InvestmentDiscoveryController extends Controller
|
||||
if (! empty($filters['geo_location_id'])) {
|
||||
app(InvestmentGeography::class)->constrainDossiersToTerritories($query, app(InvestmentGeography::class)->descendants($filters['geo_location_id']));
|
||||
}
|
||||
foreach (['zee_id', 'zfi_id', 'park_id', 'education', 'facets', 'sector', 'province', 'district', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level'] as $field) {
|
||||
foreach (['association_type', 'association_target', 'association_state', 'association_purpose', 'authority_id', 'chain_id', 'subsector_id', 'category', 'publication_state', 'zee_id', 'zfi_id', 'park_id', 'education', 'facets', 'sector', 'province', 'district', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level'] as $field) {
|
||||
if (isset($filters[$field]) && $filters[$field] !== '' && $filters[$field] !== false && $filters[$field] !== []) {
|
||||
return $query->whereRaw('false')->get();
|
||||
}
|
||||
@@ -131,7 +131,7 @@ class InvestmentDiscoveryController extends Controller
|
||||
{
|
||||
$filters = $catalogue->filters($request);
|
||||
$context = $this->territorial($filters)->map(fn ($d) => ['id' => 'dossier:'.$d->id, 'title' => $d->title, 'kind' => $d->cluster_id ? 'Cluster' : ($d->corridor_id ? 'Corredor' : 'Projeto âncora'), 'url' => '/carteira/'.$d->id]);
|
||||
$opportunityOnlyFilters = array_filter(Arr::only($filters, ['education', 'sector', 'facets', 'project_id', 'cluster_id', 'corridor_id', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level']), fn ($value) => $value !== null && $value !== '' && $value !== false && $value !== []);
|
||||
$opportunityOnlyFilters = array_filter(Arr::only($filters, ['association_type', 'association_target', 'association_state', 'association_purpose', 'authority_id', 'chain_id', 'subsector_id', 'category', 'publication_state', 'education', 'sector', 'facets', 'project_id', 'cluster_id', 'corridor_id', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level']), fn ($value) => $value !== null && $value !== '' && $value !== false && $value !== []);
|
||||
if ($opportunityOnlyFilters === [] && ! in_array($filters['dimension'] ?? null, ['cluster', 'corridor'], true)) {
|
||||
$zoneFilters = $filters;
|
||||
if (in_array($filters['dimension'] ?? null, ['zee', 'zfi'], true)) {
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\FintechInvestment;
|
||||
use App\Services\InvestorPath;
|
||||
use App\Services\LegacyContent;
|
||||
use App\Services\SectorInvestment;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -21,21 +23,45 @@ class InvestorPathController extends Controller
|
||||
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/index', $data);
|
||||
}
|
||||
|
||||
public function sectorStart(Request $request, string $sectorSlug, InvestorPath $path): JsonResponse|Response
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
$data = ['contexts' => $path->contexts($request->user()), 'sectorSource' => app(SectorInvestment::class)->context($sectorSlug)];
|
||||
|
||||
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/index', $data);
|
||||
}
|
||||
|
||||
public function sectorAttach(Request $request, string $id): JsonResponse|RedirectResponse
|
||||
{
|
||||
app(SectorInvestment::class)->attach($request->user(), $id, $request->all());
|
||||
|
||||
return $request->expectsJson() ? response()->json(['ok' => true]) : redirect('/investimentos/'.$id)->with('success', 'Setor associado ao mesmo dossier.');
|
||||
}
|
||||
|
||||
public function create(Request $request, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
$sector = $request->validate(['sector_slug' => 'nullable|string|max:150'])['sector_slug'] ?? null;
|
||||
if ($sector !== null) {
|
||||
app(SectorInvestment::class)->context($sector);
|
||||
}
|
||||
$source = $request->input('content_resource_id');
|
||||
if ($source !== null) {
|
||||
$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 = DB::transaction(function () use ($path, $request, $source, $sector): string {
|
||||
$id = $path->create($request->user(), $request->all());
|
||||
if ($source !== null) {
|
||||
$case = $path->view($request->user(), $id)['case'];
|
||||
app(LegacyContent::class)->attach($request->user(), $id, ['version' => $case['version'], 'resource_id' => (int) $source]);
|
||||
}
|
||||
|
||||
if ($sector !== null) {
|
||||
$case = $path->view($request->user(), $id)['case'];
|
||||
app(SectorInvestment::class)->attach($request->user(), $id, ['version' => $case['version'], 'sector_slug' => $sector]);
|
||||
}
|
||||
|
||||
return $id;
|
||||
});
|
||||
|
||||
@@ -80,6 +106,14 @@ class InvestorPathController extends Controller
|
||||
return $request->expectsJson() ? response()->json(['id' => $task], 201) : back()->with('success', 'Tarefa assumida no acompanhamento interno.');
|
||||
}
|
||||
|
||||
public function fintech(Request $request, string $id, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
app(FintechInvestment::class)->save($request->user(), $id, $request->all());
|
||||
|
||||
return $this->saved($request, 'Caracterização Fintech guardada no mesmo dossier; pendências e histórico preservados.');
|
||||
}
|
||||
|
||||
private function saved(Request $request, string $message): JsonResponse|RedirectResponse
|
||||
{
|
||||
return $request->expectsJson() ? response()->json(['message' => $message]) : back()->with('success', $message);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Opportunity;
|
||||
use App\Services\OpportunityClassification;
|
||||
use App\Services\OpportunityManagement;
|
||||
use App\Services\PortalProfileAccess;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class OpportunityClassificationController extends Controller
|
||||
{
|
||||
public function index(Request $request, int $id, OpportunityClassification $service): JsonResponse
|
||||
{
|
||||
$record = Opportunity::findOrFail($id);
|
||||
app(PortalProfileAccess::class)->authorize($request->user(), 'view', $record);
|
||||
|
||||
return response()->json(['version' => $service::VERSION, 'etag' => app(OpportunityManagement::class)->etag($record), 'rows' => $service->listing($request->user(), $record), 'duplicates' => $service->duplicates($request->user(), $record)])->header('Cache-Control', 'private, no-store');
|
||||
}
|
||||
|
||||
public function review(Request $request, int $id, OpportunityClassification $service): JsonResponse
|
||||
{
|
||||
$record = $service->review($request->user(), Opportunity::findOrFail($id), $request->all());
|
||||
|
||||
return response()->json(['etag' => app(OpportunityManagement::class)->etag($record), 'rows' => $service->listing($request->user(), $record)])->header('Cache-Control', 'private, no-store');
|
||||
}
|
||||
}
|
||||
@@ -136,6 +136,11 @@ class OpportunityManagementController extends Controller
|
||||
'profileMode' => $record ? $record->owner_user_id !== null : str_starts_with($request->path(), 'minhas-oportunidades'),
|
||||
'profileActions' => $record && $record->owner_user_id !== null ? app(OpportunityProfileWorkflow::class)->actions($request->user(), $record) : [], 'profileContext' => $record?->workflow_context, 'profileOrganization' => $record?->organization_id]);
|
||||
$values = $record ? $service->values($record) : [];
|
||||
if (! $record && $request->filled('sector_id')) {
|
||||
$selection = $request->validate(['sector_id' => ['required', 'integer', Rule::exists('sectors', 'id')->where('is_active', true)->whereNull('deleted_at')]]);
|
||||
$values['sector_id'] = (int) $selection['sector_id'];
|
||||
$values['canonical']['sector_id'] = (int) $selection['sector_id'];
|
||||
}
|
||||
Inertia::share('publicationPreview', app(OpportunityCanonicalContract::class)->publicProjection($values['canonical'] ?? []));
|
||||
$classification = $id ? DB::table('audit_events')->where('source_system', 'opportunity-origin-review')->where('after_data->opportunity_id', $id)->orderByDesc('occurred_at')->orderByDesc('id')->value('after_data') : null;
|
||||
|
||||
|
||||
@@ -123,12 +123,21 @@ class PortalProfileController extends Controller
|
||||
return app(OpportunityManagementController::class)->index($request, app(OpportunityManagement::class));
|
||||
}
|
||||
|
||||
public function edit(Request $request, PortalProfileAccess $access, ?int $id = null): Response
|
||||
public function edit(Request $request, PortalProfileAccess $access, ?int $id = null): Response|\Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
if ($id) {
|
||||
$access->authorize($request->user(), str_ends_with($request->path(), '/view') ? 'view' : 'edit', Opportunity::withTrashed()->findOrFail($id));
|
||||
} else {
|
||||
abort_unless($access->navigation($request->user())['contexts'] ?? [], 403);
|
||||
if (! ($access->navigation($request->user())['contexts'] ?? [])) {
|
||||
$reason = $access->has($request->user(), 'auditor')
|
||||
? 'O papel de Auditor permite consulta e impede a criação de oportunidades.'
|
||||
: 'Esta conta não dispõe de um contexto ativo de Promotor para uma organização e modalidade autorizadas. Confirme a vigência, o âmbito e os tipos atribuídos na gestão de perfis. A elevação excecional de Superutilizador não substitui a autorização de Promotor.';
|
||||
if ($request->expectsJson()) {
|
||||
abort(403, $reason);
|
||||
}
|
||||
|
||||
return response()->view('profiles.creation-unavailable', ['reason' => $reason], 403);
|
||||
}
|
||||
}
|
||||
|
||||
return app(OpportunityManagementController::class)->edit($request, app(OpportunityManagement::class), $id);
|
||||
|
||||
@@ -6,6 +6,8 @@ use App\Http\Resources\PublicBusinessOpportunityResource;
|
||||
use App\Models\ExistingBusiness;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\ExistingBusinessDrafts;
|
||||
use App\Services\ExistingBusinessClassification;
|
||||
use App\Services\OpportunityClassification;
|
||||
use App\Services\InvestmentGeography;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -19,16 +21,10 @@ class PublicBusinessOpportunityController extends Controller
|
||||
{
|
||||
public function index(Request $request): Response|JsonResponse
|
||||
{
|
||||
$filters = $request->validate([
|
||||
'q' => ['nullable', 'string', 'max:120'],
|
||||
'modality' => ['nullable', Rule::in(ExistingBusinessDrafts::MODALITIES)],
|
||||
'sector' => ['nullable', 'integer', 'min:1'],
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:50'],
|
||||
'province_id' => ['nullable', 'uuid'], 'district_id' => ['nullable', 'uuid'],
|
||||
'admin_post_id' => ['nullable', 'uuid'], 'locality_id' => ['nullable', 'uuid'],
|
||||
]);
|
||||
$filters = $this->filters($request);
|
||||
|
||||
$query = $this->publishedQuery();
|
||||
app(ExistingBusinessClassification::class)->constrain($query, $filters);
|
||||
$path = app(InvestmentGeography::class)->selection($filters);
|
||||
if ($path !== []) {
|
||||
$territoryIds = app(InvestmentGeography::class)->descendants($path[array_key_last($path)]->id);
|
||||
@@ -53,12 +49,27 @@ class PublicBusinessOpportunityController extends Controller
|
||||
$query->where('existing_businesses.modality', $filters['modality']);
|
||||
}
|
||||
|
||||
$results = PublicBusinessOpportunityResource::collection($query->paginate($filters['per_page'] ?? 12)->withQueryString());
|
||||
$results = PublicBusinessOpportunityResource::collection($query->paginate($filters['per_page'] ?? 12)->appends($filters));
|
||||
if ($request->expectsJson()) {
|
||||
return $results->response();
|
||||
}
|
||||
|
||||
return Inertia::render('investment/business-marketplace', ['results' => $results, 'filters' => $filters, 'territorySelection' => $path]);
|
||||
return Inertia::render('investment/business-marketplace', ['results' => $results, 'filters' => $filters, 'territorySelection' => $path,
|
||||
'classificationOptions' => app(OpportunityClassification::class)->options(),
|
||||
'authorities' => DB::table('authorities')->where('status', 'published')->orderBy('label_pt_mz')->get(['id', 'label_pt_mz'])]);
|
||||
}
|
||||
|
||||
private function filters(Request $request): array
|
||||
{
|
||||
return $request->validate([
|
||||
'q' => ['nullable', 'string', 'max:120'],
|
||||
'modality' => ['nullable', Rule::in(ExistingBusinessDrafts::MODALITIES)],
|
||||
'sector' => ['nullable', 'integer', 'min:1'],
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:50'],
|
||||
'province_id' => ['nullable', 'uuid'], 'district_id' => ['nullable', 'uuid'],
|
||||
'admin_post_id' => ['nullable', 'uuid'], 'locality_id' => ['nullable', 'uuid'],
|
||||
...app(ExistingBusinessClassification::class)->filterRules(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Request $request, string $slug): Response|JsonResponse
|
||||
@@ -69,7 +80,7 @@ class PublicBusinessOpportunityController extends Controller
|
||||
return $resource->response();
|
||||
}
|
||||
|
||||
$returnFilters = $request->query();
|
||||
$returnFilters = $this->filters($request);
|
||||
|
||||
return Inertia::render('investment/business-opportunity', ['record' => $resource->resolve($request),
|
||||
'returnUrl' => $returnFilters === [] ? '/negocios' : '/negocios?'.http_build_query($returnFilters),
|
||||
@@ -80,7 +91,7 @@ class PublicBusinessOpportunityController extends Controller
|
||||
{
|
||||
$record = $this->publishedQuery()->where('existing_businesses.public_slug', $slug)->firstOrFail();
|
||||
|
||||
$returnFilters = $request->query();
|
||||
$returnFilters = $this->filters($request);
|
||||
|
||||
return Inertia::render('investment/business-interest', [
|
||||
'record' => (new PublicBusinessOpportunityResource($record))->resolve($request),
|
||||
@@ -109,6 +120,7 @@ class PublicBusinessOpportunityController extends Controller
|
||||
'existing_businesses.activity_code', 'existing_businesses.stage', 'existing_businesses.objective',
|
||||
'existing_businesses.currency', 'existing_businesses.amount_min', 'existing_businesses.amount_max',
|
||||
'existing_businesses.available_percentage', 'existing_businesses.published_at', 'existing_businesses.sector_id',
|
||||
'existing_businesses.owner_user_id', 'existing_businesses.organization_id', 'existing_businesses.version_no', 'existing_businesses.expires_at', 'existing_businesses.status', 'existing_businesses.modality',
|
||||
'public_location.province', 'public_location.district', 'public_location.locality']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Opportunity;
|
||||
use App\Models\Sector;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\SectorInvestment;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
@@ -23,6 +24,7 @@ class PublicPortalController extends Controller
|
||||
$sector = Sector::where('slug', $slug)->where('is_active', true)->firstOrFail();
|
||||
|
||||
return Inertia::render('portal/services', ['section' => 'sector', 'sector' => $sector->only(['name', 'slug', 'description', 'short_description']),
|
||||
'sectorEntry' => array_key_exists($sector->slug, SectorInvestment::CONTENT) ? app(SectorInvestment::class)->publicView($sector) : null,
|
||||
'opportunities' => $sector->opportunities()->published()->latest('published_at')->limit(12)->get(['title', 'slug', 'province', 'summary'])]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user