94 lines
6.4 KiB
PHP
94 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\InvestmentDossier;
|
|
use App\Models\InvestmentZone;
|
|
use App\Models\Opportunity;
|
|
use App\Services\InvestmentCatalogue;
|
|
use App\Services\InvestmentZoneAccess;
|
|
use App\Services\InvestmentZones;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class InvestmentZoneController extends Controller
|
|
{
|
|
public function show(Request $request, InvestmentZones $zones, string $id): Response|JsonResponse
|
|
{
|
|
$management = $request->is('management/*', 'api/v2/investment/admin/*');
|
|
$zone = ($management ? InvestmentZone::query() : $zones->visible())->findOrFail($id);
|
|
$publicFields = ['id', 'code', 'category', 'name', 'name_en', 'description', 'description_en', 'province', 'district', 'validation_status', 'updated_at'];
|
|
$source = DB::table('investment_legal_sources')->where('id', $zone->legal_source_id)->first(['title', 'url', 'diploma', 'article', 'competent_entity', 'valid_from', 'valid_until', 'version_no']);
|
|
$operator = DB::table('organizations')->where('id', $zone->operator_id)->whereNull('deleted_at')
|
|
->when(! $management, fn ($q) => $q->where('data_classification', 'public'))->value('name');
|
|
$field = ['zee' => 'zee_id', 'zfi' => 'zfi_id', 'industrial_park' => 'park_id'][$zone->category] ?? null;
|
|
$opportunities = $field && ! $management ? app(InvestmentCatalogue::class)->query([$field => $id])->paginate(12)->withQueryString() : null;
|
|
$related = collect();
|
|
foreach (['cluster_id', 'corridor_id', 'project_id'] as $foreign) {
|
|
$relations = $zones->links(true)->where('zl.zone_id', $id)->whereNotNull('zl.'.$foreign);
|
|
$related = $related->merge(InvestmentPortfolioController::visible()->whereIn($foreign, $relations->select('zl.'.$foreign))->get());
|
|
}
|
|
$props = ['record' => $management ? $zone : $zone->only($publicFields), 'source' => $source, 'operator' => $operator, 'management' => $management,
|
|
'related' => $related->unique('id')->values(),
|
|
'relations' => $management ? DB::table('investment_zone_relations')->where('zone_id', $id)->orderByDesc('created_at')->limit(100)->get() : [],
|
|
'geometries' => $management ? DB::table('investment_zone_geometries')->where('zone_id', $id)->orderByDesc('created_at')->limit(100)->get() : [],
|
|
'targets' => $management ? ['opportunities' => Opportunity::orderBy('title')->limit(200)->get(['id', 'title']),
|
|
'dossiers' => InvestmentDossier::orderBy('title')->limit(200)->get(['id', 'title', 'project_id', 'cluster_id', 'corridor_id'])] : null,
|
|
'opportunities' => $opportunities,
|
|
'legalSources' => $management ? DB::table('investment_legal_sources')->orderByDesc('created_at')->limit(100)->get() : [],
|
|
'operators' => $management ? DB::table('organizations')->whereNull('deleted_at')->orderBy('name')->limit(200)->get(['id', 'name']) : [],
|
|
'links' => $management ? DB::table('investment_zone_links')->where('zone_id', $id)->orderByDesc('created_at')->limit(100)->get() : [],
|
|
'revisions' => $management ? DB::table('investment_zone_revisions')->where('zone_id', $id)->orderByDesc('version_no')->limit(20)->get(['version_no', 'action', 'sha256', 'created_at']) : []];
|
|
|
|
return $request->is('api/*') ? response()->json($props) : Inertia::render('investment/zone', $props);
|
|
}
|
|
|
|
public function index(Request $request, InvestmentZones $zones): Response|JsonResponse
|
|
{
|
|
$filters = $request->validate(['category' => ['nullable', 'in:zee,zfi,industrial_park'], 'q' => ['nullable', 'string', 'max:120'], 'page' => ['nullable', 'integer', 'min:1']]);
|
|
$management = $request->is('management/*', 'api/v2/investment/admin/*');
|
|
$query = $management ? InvestmentZone::query() : $zones->visible();
|
|
$rows = $query->when($filters['category'] ?? null, fn ($q, $v) => $q->where('category', $v))
|
|
->when($filters['q'] ?? null, fn ($q, $v) => $q->where(fn ($q) => $q->where('name', 'ilike', '%'.$v.'%')->orWhere('code', 'ilike', '%'.$v.'%')))
|
|
->orderBy('name')->orderBy('id')->paginate(12, $management ? ['*'] : ['id', 'code', 'name', 'name_en', 'category', 'province', 'district', 'description', 'description_en', 'validation_status', 'updated_at'])->withQueryString();
|
|
$props = ['records' => $rows, 'filters' => $filters, 'management' => $management];
|
|
|
|
return $request->is('api/*') ? response()->json($props) : Inertia::render('investment/zones', $props);
|
|
}
|
|
|
|
public function save(Request $request, InvestmentZones $zones, ?string $id = null): JsonResponse
|
|
{
|
|
$data = $request->validate(['version_no' => [$id ? 'required' : 'nullable', 'integer', 'min:1'],
|
|
'code' => ['required', 'string', 'max:80', Rule::unique('investment_zones')->ignore($id)],
|
|
'category' => ['required', 'in:zee,zfi,industrial_park,pending'], 'name' => ['required', 'string', 'max:255'],
|
|
'name_en' => ['nullable', 'string', 'max:255'], 'description' => ['nullable', 'string', 'max:15000'],
|
|
'description_en' => ['nullable', 'string', 'max:15000'], 'province' => ['nullable', 'string', 'max:100'], 'district' => ['nullable', 'string', 'max:100'],
|
|
'operator_id' => ['nullable', 'uuid', Rule::exists('organizations', 'id')->whereNull('deleted_at')],
|
|
'legal_source_id' => ['nullable', 'uuid', 'exists:investment_legal_sources,id']]);
|
|
|
|
return response()->json($zones->save($id, $data, $request->user()->id), $id ? 200 : 201);
|
|
}
|
|
|
|
public function transition(Request $request, InvestmentZones $zones, string $id, string $action): JsonResponse
|
|
{
|
|
if ($action === 'publish') {
|
|
InvestmentZoneAccess::requireRole($request->user(), 'publishers');
|
|
}
|
|
$data = $request->validate(['version_no' => ['required', 'integer', 'min:1']]);
|
|
|
|
return response()->json($action === 'publish' ? $zones->publish($id, $data['version_no'], $request->user()->id)
|
|
: $zones->suspend($id, $data['version_no'], $request->user()->id));
|
|
}
|
|
|
|
public function revisions(string $id): JsonResponse
|
|
{
|
|
InvestmentZone::findOrFail($id);
|
|
|
|
return response()->json(DB::table('investment_zone_revisions')->where('zone_id', $id)->orderByDesc('version_no')->paginate(20, ['id', 'version_no', 'actor_id', 'action', 'sha256', 'created_at']));
|
|
}
|
|
}
|