181 lines
9.7 KiB
PHP
181 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Services\CompanyComparison;
|
|
use App\Services\FintechInvestment;
|
|
use App\Services\InvestmentGuides;
|
|
use App\Services\InvestmentZonePathContext;
|
|
use App\Services\InvestorPath;
|
|
use App\Services\LegacyContent;
|
|
use App\Services\SectorResourceReferences;
|
|
use App\Services\SectorInvestment;
|
|
use App\Services\VirtualDesk;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class InvestorPathController extends Controller
|
|
{
|
|
public function index(Request $request, InvestorPath $path): JsonResponse|Response
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
$data = ['contexts' => $path->contexts($request->user()),
|
|
'companyComparisonAnswers' => $request->has('company_comparison') ? app(CompanyComparison::class)->answers(['answers' => $request->input('company_comparison')]) : null,
|
|
'guideSelection' => $request->has('investment_guide') ? app(InvestmentGuides::class)->selection($request->array('investment_guide')) : null];
|
|
|
|
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)];
|
|
if (isset(SectorResourceReferences::SOURCES[$sectorSlug]) && $request->filled('resource_area')) {
|
|
$data['resourceSource'] = app(SectorResourceReferences::class)->selection($sectorSlug, ['area_id' => $request->query('resource_area'), 'location_label' => $request->query('resource_location'), 'group_id' => $request->query('resource_group'), 'source_sha256' => $request->query('resource_source')]);
|
|
}
|
|
|
|
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 zoneStart(Request $request, string $zoneId, InvestorPath $path): JsonResponse|Response
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
$data = $request->validate(['consulted_public_version' => 'required|integer|min:1']);
|
|
$data = ['contexts' => $path->contexts($request->user()), 'zoneSource' => app(InvestmentZonePathContext::class)->context($zoneId, (int) $data['consulted_public_version'])];
|
|
|
|
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/index', $data);
|
|
}
|
|
|
|
public function zoneAttach(Request $request, string $id): JsonResponse|RedirectResponse
|
|
{
|
|
app(InvestmentZonePathContext::class)->attach($request->user(), $id, $request->all());
|
|
|
|
return $request->expectsJson() ? response()->json(['ok' => true]) : redirect('/investimentos/'.$id)->with('success', 'Referência do parque guardada; não constitui reserva ou autorização.');
|
|
}
|
|
|
|
public function create(Request $request, InvestorPath $path): JsonResponse|RedirectResponse
|
|
{
|
|
$comparison = $request->has('company_comparison') ? app(CompanyComparison::class)->answers(['answers' => $request->input('company_comparison')]) : null;
|
|
$guide = $request->has('investment_guide') ? app(InvestmentGuides::class)->selection($request->array('investment_guide')) : null;
|
|
abort_if($comparison !== null && $guide !== null, 422, 'Escolha o contexto de preparação que pretende continuar.');
|
|
$zone = $request->has('zone_id') ? app(InvestmentZonePathContext::class)->input($request->all()) : null;
|
|
if ($zone) {
|
|
$request->validate(['confirm' => 'required|accepted']);
|
|
app(InvestmentZonePathContext::class)->context($zone['zone_id'], (int) $zone['consulted_public_version']);
|
|
}
|
|
$sector = $request->validate(['sector_slug' => 'nullable|string|max:150'])['sector_slug'] ?? null;
|
|
if ($sector !== null) {
|
|
app(SectorInvestment::class)->context($sector);
|
|
}
|
|
$reference = $request->input('sector_reference');
|
|
if ($reference !== null) {
|
|
abort_unless(isset(SectorResourceReferences::SOURCES[$sector]) && is_array($reference), 422);
|
|
app(SectorResourceReferences::class)->selection($sector, $reference);
|
|
}
|
|
$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, $sector, $zone, $reference): string {
|
|
if ($reference !== null) {
|
|
DB::table('users')->where('id', $request->user()->id)->lockForUpdate()->first();
|
|
}
|
|
$existingReferenceCase = $reference !== null ? DB::table('desk_cases')->where('user_id', $request->user()->id)->where('client_key', $request->input('client_key'))->first() : null;
|
|
$id = $path->create($request->user(), $request->all());
|
|
if ($existingReferenceCase) {
|
|
$selection = app(SectorResourceReferences::class)->selection($sector, $reference);
|
|
$oldPayload = app(VirtualDesk::class)->decode($existingReferenceCase->payload);
|
|
abort_unless(array_any($oldPayload['investor_path']['sector_references'] ?? [], fn ($row) => $row['key'] === $selection['key']), 409, 'A chave de criação já foi usada com outra referência sectorial; recupere o dossier existente.');
|
|
}
|
|
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, 'sector_reference' => $reference]);
|
|
}
|
|
|
|
if ($zone) {
|
|
$case = $path->view($request->user(), $id)['case'];
|
|
app(InvestmentZonePathContext::class)->attach($request->user(), $id, [...$zone, 'version' => $case['version'], 'confirm' => true]);
|
|
}
|
|
|
|
return $id;
|
|
});
|
|
|
|
$href = $comparison === null ? '/investimentos/'.$id : '/investimentos/'.$id.'/forma-juridica?'.http_build_query(['answers' => $comparison]);
|
|
if ($guide !== null) {
|
|
$href = '/investimentos/'.$id.'/guias/'.$guide['slug'].'?'.http_build_query(['current' => 1, 'selection' => 1, 'sha256' => $guide['sha256'], 'instruments' => $guide['instruments']]);
|
|
}
|
|
|
|
return $request->expectsJson() ? response()->json(['id' => $id, ...($comparison !== null ? ['comparison_href' => $href] : []), ...($guide !== null ? ['guide_href' => $href] : [])], 201) : redirect($href)->with('success', 'Investimento guardado no seu dossier.');
|
|
}
|
|
|
|
public function show(Request $request, string $id, InvestorPath $path): JsonResponse|Response
|
|
{
|
|
$choice = $request->validate(['opportunity' => 'nullable|string|max:100'])['opportunity'] ?? null;
|
|
$data = $path->view($request->user(), $id, $choice);
|
|
|
|
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/show', $data);
|
|
}
|
|
|
|
public function facts(Request $request, string $id, InvestorPath $path): JsonResponse|RedirectResponse
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
$path->facts($request->user(), $id, $request->all());
|
|
|
|
return $this->saved($request, 'Aplicabilidade registada; o histórico foi preservado.');
|
|
}
|
|
|
|
public function stage(Request $request, string $id, string $code, InvestorPath $path): JsonResponse|RedirectResponse
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
$path->stage($request->user(), $id, $code, $request->all());
|
|
|
|
return $this->saved($request, 'Etapa e fundamento registados.');
|
|
}
|
|
|
|
public function tool(Request $request, string $id, InvestorPath $path): JsonResponse
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
|
|
return response()->json(['result' => $path->returnTool($request, $id, $request->all())]);
|
|
}
|
|
|
|
public function task(Request $request, string $id, InvestorPath $path): JsonResponse|RedirectResponse
|
|
{
|
|
abort_unless($path->available(), 404);
|
|
$task = $path->task($request->user(), $id, $request->all());
|
|
|
|
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);
|
|
}
|
|
}
|