Merge branch 'main' of https://git.tempo.co.mz/nala/Investidor-V2
tests / ci (push) Waiting to run

This commit is contained in:
2026-11-13 14:43:34 +02:00
42 changed files with 4400 additions and 10 deletions
@@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers;
use App\Services\DemographicEvidence;
use App\Services\DemographicImport;
use App\Services\DemographicInstallation;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Inertia\Inertia;
use Inertia\Response;
final class DemographyController extends Controller
{
public function index(Request $request, DemographicEvidence $service): Response|JsonResponse
{
$data = $request->validate(['territories' => 'nullable|array|max:4', 'territories.*' => 'required|uuid|distinct',
'start_year' => 'nullable|integer|between:1900,2100', 'end_year' => 'nullable|integer|between:1900,2100|gte:start_year',
'sector' => 'nullable|in:'.implode(',', array_keys(DemographicEvidence::sectors())), 'edition' => 'nullable|uuid']);
$start = (int) ($data['start_year'] ?? date('Y'));
$end = (int) ($data['end_year'] ?? $start);
abort_unless($end >= $start && $end - $start <= 50, 422, 'Escolha um horizonte até 50 anos.');
$evidence = $service->analyse($data['territories'] ?? [], $start, $end, $data['sector'] ?? 'general', $data['edition'] ?? null);
if ($request->expectsJson()) {
return response()->json($evidence);
}
$territories = $service->territories()->orderBy('name')->get(['id', 'name', 'parent_id', 'location_type']);
return Inertia::render('investment/demography', ['evidence' => $evidence, 'filters' => $data, 'territories' => $territories, 'sectors' => DemographicEvidence::sectors()]);
}
public function management(Request $request, DemographicImport $service): Response|RedirectResponse
{
if (! Schema::hasTable('demographic_imports')) {
return redirect('/management/demography/install');
}
$service->authorize($request->user());
$data = $request->validate(['batch' => 'nullable|uuid']);
return Inertia::render('management/demography', ['qa' => ! app(DemographicInstallation::class)->activeTarget(), 'batches' => DB::table('demographic_imports')->orderByDesc('created_at')->get(['id', 'file_name', 'publication_version', 'status', 'created_at']),
'preview' => isset($data['batch']) ? $service->preview($request->user(), $data['batch']) : null]);
}
public function installation(Request $request, DemographicInstallation $service): Response
{
return Inertia::render('management/demography-install', ['plan' => $service->preview($request->user())]);
}
public function install(Request $request, DemographicInstallation $service): JsonResponse
{
return response()->json($service->apply($request->user(), $request->all()));
}
public function prepare(Request $request, DemographicImport $service): JsonResponse
{
$data = $request->validate(['file' => 'required|file|mimes:xlsx|max:19531', 'publication_version' => 'required|string|max:255', 'baseline_year' => 'nullable|integer|between:1900,2100']);
$file = $request->file('file');
return response()->json($service->prepare($request->user(), $file->getRealPath(), $file->getClientOriginalName(), $data['publication_version'], isset($data['baseline_year']) ? (int) $data['baseline_year'] : null));
}
public function confirm(Request $request, string $id, DemographicImport $service): JsonResponse
{
$data = $request->validate(['sha256' => 'required|string|size:64', 'mapping' => 'present|array', 'mapping.*' => 'required|uuid', 'reason' => 'required|string|min:10|max:2000']);
return response()->json($service->confirm($request->user(), $id, $data['sha256'], $data['mapping'], $data['reason']));
}
public function transition(Request $request, string $id, DemographicImport $service): JsonResponse
{
$data = $request->validate(['action' => 'required|in:approved,disabled', 'reason' => 'required|string|min:10|max:2000']);
$service->transition($request->user(), $id, $data['action'], $data['reason']);
return response()->json(['id' => $id, 'status' => $data['action']]);
}
}
@@ -20,6 +20,16 @@ use Inertia\Response;
class InvestorPathController extends Controller
{
public function fiscalReport(Request $request, string $id, string $reportId, \App\Services\SimulationFormDrafts $drafts): JsonResponse
{
abort_unless(app(InvestorPath::class)->available(), 404);
$request->validate(['opportunity' => 'nullable|string|max:150']);
$data = $drafts->dossierReport($request->user(), $id, $reportId, $request->query('opportunity'));
return response()->json($data)->header('Content-Disposition', 'attachment; filename="relatorio-fiscal-'.$reportId.'.json"')
->header('X-Content-Type-Options', 'nosniff');
}
public function index(Request $request, InvestorPath $path): JsonResponse|Response
{
abort_unless($path->available(), 404);