Files
Investidor-V2/app/Services/PublicBusinessLocations.php
T

58 lines
2.7 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
/** Disclosure is decided by the stored public flag and declared precision, never inferred from an address. */
final class PublicBusinessLocations
{
/** @return literal-string */
public function sourceProjection(): string
{
return app(BusinessPointPublication::class)->available()
? 'l.public_source_reference AS location_source_reference, l.source_date AS location_source_date'
: 'NULL::text AS location_source_reference, NULL::date AS location_source_date';
}
public function disclosed(): Builder
{
$query = DB::table('existing_business_locations as l')->where('l.is_public', true);
foreach (['province_id' => ['province', 'district', 'admin_post', 'locality', 'exact'],
'district_id' => ['district', 'admin_post', 'locality', 'exact'],
'admin_post_id' => ['admin_post', 'locality', 'exact'], 'locality_id' => ['locality', 'exact']] as $field => $precisions) {
$query->where(fn (Builder $scope) => $scope->whereNotIn('l.precision_level', $precisions)->orWhereNull('l.'.$field)
->orWhereIn('l.'.$field, app(InvestmentGeography::class)->publicReferences()->select('id')));
}
return $query;
}
public function primary(): Builder
{
return $this->disclosed()->where('l.is_primary', true);
}
public function points(): Builder
{
// Nested CASE is intentional: ST_X/ST_Y must never receive a polygon or collection.
return $this->primary()->where('l.precision_level', 'exact')
->select('l.existing_business_id', 'l.updated_at as location_recorded_at')
->selectRaw($this->sourceProjection())
->selectRaw("CASE WHEN GeometryType(l.geom)='POINT' AND ST_IsValid(l.geom) AND NOT ST_IsEmpty(l.geom) AND ST_SRID(l.geom)=4326
THEN CASE WHEN ST_X(l.geom) BETWEEN -180 AND 180 AND ST_Y(l.geom) BETWEEN -90 AND 90 THEN l.geom END END AS point");
}
/** @param list<string> $ids */
public function matchingArea(array $ids): Builder
{
return $this->disclosed()->where(function (Builder $query) use ($ids): void {
$query->whereIn('l.province_id', $ids)
->orWhere(fn (Builder $level) => $level->whereIn('l.precision_level', ['district', 'admin_post', 'locality', 'exact'])->whereIn('l.district_id', $ids))
->orWhere(fn (Builder $level) => $level->whereIn('l.precision_level', ['admin_post', 'locality', 'exact'])->whereIn('l.admin_post_id', $ids))
->orWhere(fn (Builder $level) => $level->whereIn('l.precision_level', ['locality', 'exact'])->whereIn('l.locality_id', $ids));
});
}
}