115 lines
6.0 KiB
PHP
115 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Resources\PublicBusinessOpportunityResource;
|
|
use App\Models\ExistingBusiness;
|
|
use App\Services\CountryCatalogue;
|
|
use App\Services\ExistingBusinessDrafts;
|
|
use App\Services\InvestmentGeography;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
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'],
|
|
]);
|
|
|
|
$query = $this->publishedQuery();
|
|
$path = app(InvestmentGeography::class)->selection($filters);
|
|
if ($path !== []) {
|
|
$territoryIds = app(InvestmentGeography::class)->descendants($path[array_key_last($path)]->id);
|
|
$query->whereExists(fn ($locations) => $locations->selectRaw('1')->from('existing_business_locations as matching_location')
|
|
->whereColumn('matching_location.existing_business_id', 'existing_businesses.id')->where('matching_location.is_public', true)
|
|
->where(function ($match) use ($territoryIds): void {
|
|
foreach (['province_id', 'district_id', 'admin_post_id', 'locality_id'] as $field) {
|
|
$match->orWhereIn('matching_location.'.$field, $territoryIds);
|
|
}
|
|
}));
|
|
}
|
|
if (! empty($filters['q'])) {
|
|
$term = trim($filters['q']);
|
|
$query->where(fn (Builder $builder) => $builder->whereLike('existing_businesses.public_title', '%'.$term.'%')
|
|
->orWhereLike('existing_businesses.activity_code', '%'.$term.'%')
|
|
->orWhereLike('existing_businesses.objective', '%'.$term.'%'));
|
|
}
|
|
if (! empty($filters['sector'])) {
|
|
$query->where('existing_businesses.sector_id', $filters['sector']);
|
|
}
|
|
if (! empty($filters['modality'])) {
|
|
$query->where('existing_businesses.modality', $filters['modality']);
|
|
}
|
|
|
|
$results = PublicBusinessOpportunityResource::collection($query->paginate($filters['per_page'] ?? 12)->withQueryString());
|
|
if ($request->expectsJson()) {
|
|
return $results->response();
|
|
}
|
|
|
|
return Inertia::render('investment/business-marketplace', ['results' => $results, 'filters' => $filters, 'territorySelection' => $path]);
|
|
}
|
|
|
|
public function show(Request $request, string $slug): Response|JsonResponse
|
|
{
|
|
$record = $this->publishedQuery()->where('existing_businesses.public_slug', $slug)->firstOrFail();
|
|
$resource = new PublicBusinessOpportunityResource($record);
|
|
if ($request->expectsJson()) {
|
|
return $resource->response();
|
|
}
|
|
|
|
$returnFilters = $request->query();
|
|
|
|
return Inertia::render('investment/business-opportunity', ['record' => $resource->resolve($request),
|
|
'returnUrl' => $returnFilters === [] ? '/negocios' : '/negocios?'.http_build_query($returnFilters),
|
|
'interestUrl' => '/negocios/'.rawurlencode($slug).'/manifestar-interesse'.($returnFilters === [] ? '' : '?'.http_build_query($returnFilters))]);
|
|
}
|
|
|
|
public function interest(Request $request, string $slug): Response
|
|
{
|
|
$record = $this->publishedQuery()->where('existing_businesses.public_slug', $slug)->firstOrFail();
|
|
|
|
$returnFilters = $request->query();
|
|
|
|
return Inertia::render('investment/business-interest', [
|
|
'record' => (new PublicBusinessOpportunityResource($record))->resolve($request),
|
|
'modalities' => ExistingBusinessDrafts::MODALITIES,
|
|
'countries' => app(CountryCatalogue::class)->all(),
|
|
'returnUrl' => $returnFilters === [] ? '/negocios' : '/negocios?'.http_build_query($returnFilters),
|
|
]);
|
|
}
|
|
|
|
/** @return Builder<ExistingBusiness> */
|
|
private function publishedQuery(): Builder
|
|
{
|
|
$publicLocations = DB::table('existing_business_locations as locations')
|
|
->leftJoin('geo_locations as province', 'province.id', '=', 'locations.province_id')
|
|
->leftJoin('geo_locations as district', 'district.id', '=', 'locations.district_id')
|
|
->leftJoin('geo_locations as locality', 'locality.id', '=', 'locations.locality_id')
|
|
->where('locations.is_public', true)->where('locations.is_primary', true)
|
|
->whereNull('province.deleted_at')->whereNull('district.deleted_at')->whereNull('locality.deleted_at')
|
|
->select('locations.existing_business_id', 'province.name as province')
|
|
->selectRaw("CASE WHEN locations.precision_level IN ('district','admin_post','locality','exact') THEN district.name ELSE NULL END AS district")
|
|
->selectRaw('NULL::text AS locality');
|
|
|
|
return ExistingBusiness::query()->published()->with('sector:id,name,slug')
|
|
->leftJoinSub($publicLocations, 'public_location', 'public_location.existing_business_id', '=', 'existing_businesses.id')
|
|
->select(['existing_businesses.id', 'existing_businesses.public_slug', 'existing_businesses.public_title', 'existing_businesses.modality',
|
|
'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',
|
|
'public_location.province', 'public_location.district', 'public_location.locality']);
|
|
}
|
|
}
|