87 lines
5.5 KiB
PHP
87 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\InterestRequest;
|
|
use App\Models\Investor;
|
|
use App\Models\InvestorJourney;
|
|
use App\Services\InterestSubmission;
|
|
use App\Services\PortalAudit;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class InvestorWorkspaceController extends Controller
|
|
{
|
|
public function index(Request $request): Response
|
|
{
|
|
$journeys = InvestorJourney::where('user_id', $request->user()->id)->latest()->get()->map(function ($journey) {
|
|
$dossier = InvestmentPortfolioController::visible()->find($journey->dossier_id);
|
|
$interest = $journey->interest_request_id ? InterestRequest::find($journey->interest_request_id) : null;
|
|
|
|
return ['id' => $journey->id, 'dossier_id' => $dossier?->id, 'title' => $dossier->title ?? 'Ficha temporariamente indisponível',
|
|
'status' => $journey->status, 'reference' => $interest?->reference, 'request_status' => $interest?->status];
|
|
});
|
|
|
|
return Inertia::render('portfolio/workspace', ['journeys' => $journeys]);
|
|
}
|
|
|
|
public function start(Request $request, string $id): RedirectResponse
|
|
{
|
|
$dossier = InvestmentPortfolioController::visible()->findOrFail($id);
|
|
$data = $request->validate(['origin_id' => ['nullable', 'uuid']]);
|
|
$origin = ! empty($data['origin_id']) ? InvestmentPortfolioController::visible()->whereKey($data['origin_id'])->firstOrFail() : null;
|
|
abort_if($origin && ! InvestmentPortfolioController::related($dossier, $origin), 422);
|
|
DB::transaction(function () use ($request, $dossier, $origin) {
|
|
DB::table('users')->where('id', $request->user()->id)->lockForUpdate()->first();
|
|
$account = DB::table('investor_accounts')->where('user_id', $request->user()->id)->first();
|
|
$investorId = $account?->investor_id;
|
|
if (! $account) {
|
|
$investor = Investor::create(['legal_name' => $request->user()->name, 'investor_type' => 'individual',
|
|
'status' => 'prospect', 'source_system' => 'portal-account', 'data_classification' => 'confidential']);
|
|
DB::table('investor_accounts')->insert(['user_id' => $request->user()->id, 'investor_id' => $investor->id, 'created_at' => now(), 'updated_at' => now()]);
|
|
$investorId = $investor->id;
|
|
}
|
|
$journey = InvestorJourney::firstOrNew(['user_id' => $request->user()->id, 'dossier_id' => $dossier->id]);
|
|
if (! $journey->exists) {
|
|
PortalAudit::save($journey, ['investor_id' => $investorId, 'status' => 'started', 'origin_dossier_id' => $origin?->id,
|
|
'source_system' => 'portal-account', 'data_classification' => 'confidential'], $request->user()->id);
|
|
}
|
|
});
|
|
|
|
return redirect('/investidor')->with('success', 'Guardado no seu painel.');
|
|
}
|
|
|
|
public function submit(Request $request, string $id, InterestSubmission $submission): RedirectResponse
|
|
{
|
|
$data = $request->validate(['message' => ['required', 'string', 'min:20', 'max:5000'], 'country' => ['required', 'string', 'max:100'],
|
|
'privacy_consent' => ['accepted'], 'role' => ['required', 'in:investir,financiar,fornecer,operar,parceria'],
|
|
'horizon' => ['required', 'string', 'max:100']]);
|
|
DB::transaction(function () use ($request, $id, $data, $submission) {
|
|
$journey = InvestorJourney::where('user_id', $request->user()->id)->whereKey($id)->lockForUpdate()->firstOrFail();
|
|
if ($journey->interest_request_id) {
|
|
return; // One expression per saved journey; retry returns its original protocol.
|
|
}
|
|
$dossier = InvestmentPortfolioController::visible()->whereKey($journey->dossier_id)->lockForUpdate()->firstOrFail();
|
|
$origin = $journey->origin_dossier_id ? InvestmentPortfolioController::visible()->find($journey->origin_dossier_id) : null;
|
|
$interest = $submission->receive(['email' => $request->user()->email, 'fullName' => $request->user()->name, 'message' => $data['message']], null,
|
|
fn () => InterestRequest::create([
|
|
'reference' => 'IR-'.now()->year.'-'.Str::ulid(), 'full_name' => $request->user()->name,
|
|
'email' => $request->user()->email, 'investor_type' => 'individual', 'country' => $data['country'],
|
|
'sector_interest' => Str::limit($dossier->content['sector'] ?? $dossier->title, 150, ''), 'message' => $data['message'],
|
|
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/carteira/'.$dossier->id,
|
|
'metadata' => ['journey_id' => $journey->id, 'dossier_id' => $dossier->id, 'origin_dossier_id' => $journey->origin_dossier_id,
|
|
'project_id' => $dossier->project_id ?? $origin?->project_id,
|
|
'cluster_id' => $dossier->cluster_id ?? $origin?->cluster_id, 'corridor_id' => $dossier->corridor_id ?? $origin?->corridor_id,
|
|
'role' => $data['role'], 'horizon' => $data['horizon'], 'purpose' => 'Acompanhamento da manifestação de interesse'],
|
|
]));
|
|
PortalAudit::save($journey, ['interest_request_id' => $interest->id, 'status' => 'active'], $request->user()->id);
|
|
});
|
|
|
|
return back()->with('success', 'Manifestação recebida. Consulte o protocolo no painel.');
|
|
}
|
|
}
|