|
|
@@ -17,6 +17,7 @@ use App\Models\ScheduleProposal;
|
|
|
use App\Models\Speciality;
|
|
|
use App\Rules\ScheduleBusinessRules;
|
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
|
|
+use Illuminate\Support\Collection;
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
@@ -72,63 +73,55 @@ class DashboardService
|
|
|
$nextSchedules = Schedule::with([
|
|
|
'address:district,address,source_id,source,id,address_type',
|
|
|
])
|
|
|
- ->where('schedules.client_id', $cliente->id)
|
|
|
- ->whereIn('schedules.status', ['accepted', 'paid'])
|
|
|
- ->whereDate('schedules.date', '>=', now()->toDateString())
|
|
|
- ->where('schedules.date', '>=', now()->toDateString())
|
|
|
- ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
- ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
- ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
- ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'schedules.provider_id',
|
|
|
- 'provider_user.name as provider_name',
|
|
|
- 'providers.gender',
|
|
|
- 'schedules.date',
|
|
|
- 'schedules.start_time',
|
|
|
- 'schedules.end_time',
|
|
|
- 'schedules.total_amount',
|
|
|
- 'schedules.period_type',
|
|
|
- 'schedules.schedule_type',
|
|
|
- 'schedules.address_id',
|
|
|
- 'custom_schedules.address_type as custom_address_type',
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
+ ->where('schedules.client_id', $cliente->id)
|
|
|
+ ->whereIn('schedules.status', ['accepted', 'paid'])
|
|
|
+ ->whereDate('schedules.date', '>=', now()->toDateString())
|
|
|
+ ->where('schedules.date', '>=', now()->toDateString())
|
|
|
+ ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
+ ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
+ ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'schedules.provider_id',
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
+ 'providers.gender',
|
|
|
+ 'schedules.date',
|
|
|
+ 'schedules.start_time',
|
|
|
+ 'schedules.end_time',
|
|
|
+ 'schedules.total_amount',
|
|
|
+ 'schedules.period_type',
|
|
|
+ 'schedules.schedule_type',
|
|
|
+ 'schedules.address_id',
|
|
|
+ 'custom_schedules.address_type as custom_address_type',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT spi.service_package_id
|
|
|
+ FROM service_package_items spi
|
|
|
+ WHERE spi.schedule_id = schedules.id
|
|
|
+ LIMIT 1
|
|
|
+ ) AS service_package_id
|
|
|
+ "),
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT COUNT(*)
|
|
|
+ FROM service_package_items spi_count
|
|
|
+ WHERE spi_count.service_package_id = (
|
|
|
SELECT spi.service_package_id
|
|
|
FROM service_package_items spi
|
|
|
WHERE spi.schedule_id = schedules.id
|
|
|
LIMIT 1
|
|
|
- ) AS service_package_id
|
|
|
- "),
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
- SELECT COUNT(*)
|
|
|
- FROM service_package_items spi_count
|
|
|
- WHERE spi_count.service_package_id = (
|
|
|
- SELECT spi.service_package_id
|
|
|
- FROM service_package_items spi
|
|
|
- WHERE spi.schedule_id = schedules.id
|
|
|
- LIMIT 1
|
|
|
- )
|
|
|
- ) AS service_package_items_count
|
|
|
- "),
|
|
|
- )
|
|
|
- ->orderBy('schedules.date', 'asc')
|
|
|
- ->limit(5)
|
|
|
- ->get();
|
|
|
+ )
|
|
|
+ ) AS service_package_items_count
|
|
|
+ "),
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.date', 'asc')
|
|
|
+ ->limit(5)
|
|
|
+ ->get();
|
|
|
|
|
|
$nextSchedules->each(function ($item) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
-
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
- unset($item->provider_photo_path);
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
});
|
|
|
|
|
|
$latestPerProvider = Schedule::where('client_id', $cliente->id)
|
|
|
@@ -139,36 +132,28 @@ class DashboardService
|
|
|
$lastDoneSchedules = Schedule::joinSub($latestPerProvider, 'latest', function ($join) {
|
|
|
$join->on('schedules.id', '=', 'latest.max_id');
|
|
|
})
|
|
|
- ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
- ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
- ->leftJoinSub(
|
|
|
- Address::preferredForProvider(),
|
|
|
- 'provider_address',
|
|
|
- fn($join) =>
|
|
|
- $join->on('provider_address.source_id', '=', 'providers.id')
|
|
|
- ->where('provider_address.rn', 1)
|
|
|
- )
|
|
|
- ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'schedules.provider_id',
|
|
|
- 'provider_user.name as provider_name',
|
|
|
- 'providers.gender',
|
|
|
- 'provider_address.district as provider_district',
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
- )
|
|
|
- ->orderBy('schedules.date', 'desc')
|
|
|
- ->limit(5)
|
|
|
- ->get();
|
|
|
+ ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
+ ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
+ ->leftJoinSub(
|
|
|
+ Address::preferredForProvider(),
|
|
|
+ 'provider_address',
|
|
|
+ fn($join) =>
|
|
|
+ $join->on('provider_address.source_id', '=', 'providers.id')
|
|
|
+ ->where('provider_address.rn', 1)
|
|
|
+ )
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'schedules.provider_id',
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
+ 'providers.gender',
|
|
|
+ 'provider_address.district as provider_district',
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.date', 'desc')
|
|
|
+ ->limit(5)
|
|
|
+ ->get();
|
|
|
|
|
|
$lastDoneSchedules->each(function ($item) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
-
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
- unset($item->provider_photo_path);
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
});
|
|
|
|
|
|
$favoriteProviders = ClientFavoriteProvider::where('client_favorite_providers.client_id', $cliente->id)
|
|
|
@@ -184,27 +169,19 @@ class DashboardService
|
|
|
$join->on('provider_address.source_id', '=', 'providers.id')
|
|
|
->where('provider_address.rn', 1)
|
|
|
)
|
|
|
- ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
|
|
|
->select(
|
|
|
'providers.id as provider_id',
|
|
|
'provider_user.name as provider_name',
|
|
|
'providers.gender',
|
|
|
'providers.average_rating',
|
|
|
'provider_address.district as provider_district',
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
)
|
|
|
->orderBy('client_favorite_providers.created_at', 'desc')
|
|
|
->limit(5)
|
|
|
->get();
|
|
|
|
|
|
$favoriteProviders->each(function ($item) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
-
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
- unset($item->provider_photo_path);
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
});
|
|
|
|
|
|
$blockedProviderIds = ScheduleBusinessRules::getBlockedProviderIdsForClient($cliente->id);
|
|
|
@@ -229,20 +206,21 @@ class DashboardService
|
|
|
data_get($clientCoordinates, 'longitude'),
|
|
|
);
|
|
|
|
|
|
- $providerAddressLatestSubquery = DB::raw("
|
|
|
- (
|
|
|
- SELECT DISTINCT ON (source_id)
|
|
|
- *
|
|
|
- FROM addresses
|
|
|
- WHERE source = 'provider'
|
|
|
- AND deleted_at IS NULL
|
|
|
- ORDER BY
|
|
|
- source_id,
|
|
|
- (latitude IS NOT NULL AND longitude IS NOT NULL) DESC,
|
|
|
- is_primary DESC,
|
|
|
- id DESC
|
|
|
- ) AS provider_address
|
|
|
- ");
|
|
|
+ $providerAddressLatestSubquery = DB::raw("
|
|
|
+ (
|
|
|
+ SELECT DISTINCT ON (source_id)
|
|
|
+ *
|
|
|
+ FROM addresses
|
|
|
+ WHERE
|
|
|
+ source = 'provider'
|
|
|
+ AND deleted_at IS NULL
|
|
|
+ ORDER BY
|
|
|
+ source_id,
|
|
|
+ (latitude IS NOT NULL AND longitude IS NOT NULL) DESC,
|
|
|
+ is_primary DESC,
|
|
|
+ id DESC
|
|
|
+ ) AS provider_address
|
|
|
+ ");
|
|
|
|
|
|
$providersCloseDebugQuery = Provider::leftJoin(
|
|
|
'users as provider_user',
|
|
|
@@ -250,14 +228,14 @@ class DashboardService
|
|
|
'=',
|
|
|
'providers.user_id'
|
|
|
)
|
|
|
- ->visibleToCustomers()
|
|
|
- ->leftJoin(
|
|
|
- $providerAddressLatestSubquery,
|
|
|
- 'provider_address.source_id',
|
|
|
- '=',
|
|
|
- 'providers.id'
|
|
|
- )
|
|
|
- ->whereNull('providers.deleted_at');
|
|
|
+ ->visibleToCustomers()
|
|
|
+ ->leftJoin(
|
|
|
+ $providerAddressLatestSubquery,
|
|
|
+ 'provider_address.source_id',
|
|
|
+ '=',
|
|
|
+ 'providers.id'
|
|
|
+ )
|
|
|
+ ->whereNull('providers.deleted_at');
|
|
|
|
|
|
Log::info('Contexto de prestadores próximos no dashboard', [
|
|
|
'client_id' => $cliente->id,
|
|
|
@@ -319,60 +297,52 @@ class DashboardService
|
|
|
'=',
|
|
|
'providers.user_id'
|
|
|
)
|
|
|
- ->visibleToCustomers()
|
|
|
- ->leftJoin(
|
|
|
- $providerAddressLatestSubquery,
|
|
|
- 'provider_address.source_id',
|
|
|
- '=',
|
|
|
- 'providers.id'
|
|
|
- )
|
|
|
- ->leftJoin(
|
|
|
- 'media as provider_media',
|
|
|
- 'provider_media.id',
|
|
|
- '=',
|
|
|
- 'providers.profile_media_id'
|
|
|
- )
|
|
|
- ->whereNotNull('provider_address.id')
|
|
|
- ->when(
|
|
|
- $clientPrimaryAddress?->city_id,
|
|
|
- fn ($query, int $cityId) => $query->where('provider_address.city_id', $cityId)
|
|
|
- )
|
|
|
- ->whereNotIn('providers.id', $blockedProviderIds)
|
|
|
- ->whereIn('providers.id', $providersWithWorkingDays)
|
|
|
- ->whereNull('providers.deleted_at')
|
|
|
- ->select(
|
|
|
- 'providers.id as provider_id',
|
|
|
- 'provider_user.name as provider_name',
|
|
|
- 'providers.gender',
|
|
|
- 'provider_address.id as address_id',
|
|
|
- 'provider_address.zip_code as provider_zip_code',
|
|
|
- 'provider_address.district',
|
|
|
- 'provider_address.latitude as provider_latitude',
|
|
|
- 'provider_address.longitude as provider_longitude',
|
|
|
- 'providers.average_rating',
|
|
|
- 'providers.total_services',
|
|
|
- 'providers.daily_price_8h',
|
|
|
- 'providers.daily_price_6h',
|
|
|
- 'providers.daily_price_4h',
|
|
|
- 'providers.daily_price_2h',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
- SELECT COUNT(*)
|
|
|
- FROM reviews
|
|
|
- LEFT JOIN schedules
|
|
|
- ON schedules.id = reviews.schedule_id
|
|
|
- WHERE reviews.origin = 'provider'
|
|
|
- AND schedules.provider_id = providers.id
|
|
|
- ) AS total_reviews
|
|
|
- "),
|
|
|
-
|
|
|
- $providersCloseDistanceSelect,
|
|
|
-
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
- )
|
|
|
- ->orderByRaw('distance_km ASC NULLS LAST')
|
|
|
- ->get();
|
|
|
+ ->visibleToCustomers()
|
|
|
+ ->leftJoin(
|
|
|
+ $providerAddressLatestSubquery,
|
|
|
+ 'provider_address.source_id',
|
|
|
+ '=',
|
|
|
+ 'providers.id'
|
|
|
+ )
|
|
|
+ ->whereNotNull('provider_address.id')
|
|
|
+ ->when(
|
|
|
+ $clientPrimaryAddress?->city_id,
|
|
|
+ fn ($query, int $cityId) => $query->where('provider_address.city_id', $cityId)
|
|
|
+ )
|
|
|
+ ->whereNotIn('providers.id', $blockedProviderIds)
|
|
|
+ ->whereIn('providers.id', $providersWithWorkingDays)
|
|
|
+ ->whereNull('providers.deleted_at')
|
|
|
+ ->select(
|
|
|
+ 'providers.id as provider_id',
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
+ 'providers.gender',
|
|
|
+ 'provider_address.id as address_id',
|
|
|
+ 'provider_address.zip_code as provider_zip_code',
|
|
|
+ 'provider_address.district',
|
|
|
+ 'provider_address.latitude as provider_latitude',
|
|
|
+ 'provider_address.longitude as provider_longitude',
|
|
|
+ 'providers.average_rating',
|
|
|
+ 'providers.total_services',
|
|
|
+ 'providers.daily_price_8h',
|
|
|
+ 'providers.daily_price_6h',
|
|
|
+ 'providers.daily_price_4h',
|
|
|
+ 'providers.daily_price_2h',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT COUNT(*)
|
|
|
+ FROM reviews
|
|
|
+ LEFT JOIN schedules
|
|
|
+ ON schedules.id = reviews.schedule_id
|
|
|
+ WHERE reviews.origin = 'provider'
|
|
|
+ AND schedules.provider_id = providers.id
|
|
|
+ ) AS total_reviews
|
|
|
+ "),
|
|
|
+
|
|
|
+ $providersCloseDistanceSelect,
|
|
|
+ )
|
|
|
+ ->orderByRaw('distance_km ASC NULLS LAST')
|
|
|
+ ->get();
|
|
|
|
|
|
Log::info('Resultado da consulta de prestadores próximos no dashboard', [
|
|
|
'count' => $providersClose->count(),
|
|
|
@@ -401,7 +371,7 @@ class DashboardService
|
|
|
);
|
|
|
|
|
|
$providersClose->each(function ($item) use ($clientDistanceAddress) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
|
|
|
if ($item->distance_km === null) {
|
|
|
$item->distance_km = $this->zipCodeCoordinatesService->calculateDistance(
|
|
|
@@ -414,11 +384,7 @@ class DashboardService
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
- unset($item->provider_photo_path, $item->provider_zip_code);
|
|
|
+ unset($item->provider_zip_code);
|
|
|
|
|
|
$item->daily_price_8h_base = $item->daily_price_8h;
|
|
|
$item->daily_price_6h_base = $item->daily_price_6h;
|
|
|
@@ -448,79 +414,70 @@ class DashboardService
|
|
|
$pendingSchedules = Schedule::with([
|
|
|
'address:district,address,number,source_id,source,id,address_type',
|
|
|
])
|
|
|
- ->where('schedules.client_id', $cliente->id)
|
|
|
- ->whereIn('schedules.status', ['pending', 'accepted'])
|
|
|
- ->where('schedules.schedule_type', 'default')
|
|
|
- ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
- ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
- ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'schedules.provider_id',
|
|
|
- 'provider_user.name as provider_name',
|
|
|
- 'providers.gender',
|
|
|
- 'schedules.date',
|
|
|
- 'schedules.address_id',
|
|
|
- 'schedules.status',
|
|
|
- 'schedules.total_amount',
|
|
|
- 'schedules.start_time',
|
|
|
- 'schedules.end_time',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- CASE
|
|
|
- WHEN (NOW() - schedules.created_at) < INTERVAL '1 hour' THEN
|
|
|
- CONCAT(
|
|
|
- ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 60),
|
|
|
- 'min'
|
|
|
- )
|
|
|
- WHEN (NOW() - schedules.created_at) < INTERVAL '1 day' THEN
|
|
|
- CONCAT(
|
|
|
- ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 3600),
|
|
|
- 'h'
|
|
|
- )
|
|
|
- ELSE
|
|
|
- CONCAT(
|
|
|
- ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 86400),
|
|
|
- 'd'
|
|
|
- )
|
|
|
- END AS time_since_request
|
|
|
- "),
|
|
|
-
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
+ ->where('schedules.client_id', $cliente->id)
|
|
|
+ ->whereIn('schedules.status', ['pending', 'accepted'])
|
|
|
+ ->where('schedules.schedule_type', 'default')
|
|
|
+ ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
+ ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'schedules.provider_id',
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
+ 'providers.gender',
|
|
|
+ 'schedules.date',
|
|
|
+ 'schedules.address_id',
|
|
|
+ 'schedules.status',
|
|
|
+ 'schedules.total_amount',
|
|
|
+ 'schedules.start_time',
|
|
|
+ 'schedules.end_time',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ CASE
|
|
|
+ WHEN (NOW() - schedules.created_at) < INTERVAL '1 hour' THEN
|
|
|
+ CONCAT(
|
|
|
+ ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 60),
|
|
|
+ 'min'
|
|
|
+ )
|
|
|
+ WHEN (NOW() - schedules.created_at) < INTERVAL '1 day' THEN
|
|
|
+ CONCAT(
|
|
|
+ ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 3600),
|
|
|
+ 'h'
|
|
|
+ )
|
|
|
+ ELSE
|
|
|
+ CONCAT(
|
|
|
+ ROUND(EXTRACT(EPOCH FROM (NOW() - schedules.created_at)) / 86400),
|
|
|
+ 'd'
|
|
|
+ )
|
|
|
+ END AS time_since_request
|
|
|
+ "),
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT spi.service_package_id
|
|
|
+ FROM service_package_items spi
|
|
|
+ WHERE spi.schedule_id = schedules.id
|
|
|
+ LIMIT 1
|
|
|
+ ) AS service_package_id
|
|
|
+ "),
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT COUNT(*)
|
|
|
+ FROM service_package_items spi_count
|
|
|
+ WHERE spi_count.service_package_id = (
|
|
|
SELECT spi.service_package_id
|
|
|
FROM service_package_items spi
|
|
|
WHERE spi.schedule_id = schedules.id
|
|
|
LIMIT 1
|
|
|
- ) AS service_package_id
|
|
|
- "),
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
- SELECT COUNT(*)
|
|
|
- FROM service_package_items spi_count
|
|
|
- WHERE spi_count.service_package_id = (
|
|
|
- SELECT spi.service_package_id
|
|
|
- FROM service_package_items spi
|
|
|
- WHERE spi.schedule_id = schedules.id
|
|
|
- LIMIT 1
|
|
|
- )
|
|
|
- ) AS service_package_items_count
|
|
|
- "),
|
|
|
- )
|
|
|
- ->orderBy('schedules.date', 'asc')
|
|
|
- ->get();
|
|
|
+ )
|
|
|
+ ) AS service_package_items_count
|
|
|
+ "),
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.date', 'asc')
|
|
|
+ ->get();
|
|
|
|
|
|
$pendingSchedules->each(function ($item) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
-
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
- unset($item->provider_photo_path);
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
});
|
|
|
|
|
|
$proposalsDistanceSelect = DistanceService::sqlExpression(
|
|
|
@@ -560,12 +517,6 @@ class DashboardService
|
|
|
'=',
|
|
|
'providers.id'
|
|
|
)
|
|
|
- ->leftJoin(
|
|
|
- 'media as provider_media',
|
|
|
- 'provider_media.id',
|
|
|
- '=',
|
|
|
- 'providers.profile_media_id'
|
|
|
- )
|
|
|
->where('schedules.client_id', $cliente->id)
|
|
|
->where('schedules.schedule_type', 'custom')
|
|
|
->where('schedules.status', 'pending')
|
|
|
@@ -598,8 +549,6 @@ class DashboardService
|
|
|
'provider_address.zip_code as provider_zip_code',
|
|
|
|
|
|
$proposalsDistanceSelect,
|
|
|
-
|
|
|
- 'provider_media.path as provider_photo_path',
|
|
|
])
|
|
|
->get();
|
|
|
|
|
|
@@ -615,7 +564,7 @@ class DashboardService
|
|
|
->get();
|
|
|
|
|
|
$schedulesProposals->each(function ($item) use ($clientDistanceAddress) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
|
|
|
if ($item->distance_km === null) {
|
|
|
$item->distance_km = $this->zipCodeCoordinatesService->calculateDistance(
|
|
|
@@ -628,12 +577,7 @@ class DashboardService
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- $item->provider_photo = $item->provider_photo_path
|
|
|
- ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
|
|
|
- : null;
|
|
|
-
|
|
|
unset(
|
|
|
- $item->provider_photo_path,
|
|
|
$item->provider_latitude,
|
|
|
$item->provider_longitude,
|
|
|
$item->provider_zip_code,
|
|
|
@@ -643,76 +587,89 @@ class DashboardService
|
|
|
$todaySchedules = Schedule::with([
|
|
|
'address:district,address,number,source_id,source,id,address_type',
|
|
|
])
|
|
|
- ->where('schedules.client_id', $cliente->id)
|
|
|
- ->whereIn('schedules.status', ['accepted', 'paid', 'started', 'finished'])
|
|
|
- ->whereDate('schedules.date', now()->toDateString())
|
|
|
- ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
- ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
- ->leftJoin('media', 'media.id', '=', 'providers.profile_media_id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'schedules.provider_id',
|
|
|
- 'provider_user.name as provider_name',
|
|
|
- 'providers.gender',
|
|
|
- 'schedules.date',
|
|
|
- 'schedules.start_time',
|
|
|
- 'schedules.end_time',
|
|
|
- 'schedules.total_amount',
|
|
|
- 'schedules.period_type',
|
|
|
- 'schedules.schedule_type',
|
|
|
- 'schedules.address_id',
|
|
|
- 'schedules.status',
|
|
|
- 'schedules.code_verified',
|
|
|
- 'schedules.code',
|
|
|
- 'media.path as provider_photo',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
+ ->where('schedules.client_id', $cliente->id)
|
|
|
+ ->whereIn('schedules.status', ['accepted', 'paid', 'started', 'finished'])
|
|
|
+ ->whereDate('schedules.date', now()->toDateString())
|
|
|
+ ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
+ ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'schedules.provider_id',
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
+ 'providers.gender',
|
|
|
+ 'schedules.date',
|
|
|
+ 'schedules.start_time',
|
|
|
+ 'schedules.end_time',
|
|
|
+ 'schedules.total_amount',
|
|
|
+ 'schedules.period_type',
|
|
|
+ 'schedules.schedule_type',
|
|
|
+ 'schedules.address_id',
|
|
|
+ 'schedules.status',
|
|
|
+ 'schedules.code_verified',
|
|
|
+ 'schedules.code',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT spi.service_package_id
|
|
|
+ FROM service_package_items spi
|
|
|
+ WHERE spi.schedule_id = schedules.id
|
|
|
+ LIMIT 1
|
|
|
+ ) AS service_package_id
|
|
|
+ "),
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ (
|
|
|
+ SELECT COUNT(*)
|
|
|
+ FROM service_package_items spi_count
|
|
|
+ WHERE spi_count.service_package_id = (
|
|
|
SELECT spi.service_package_id
|
|
|
FROM service_package_items spi
|
|
|
WHERE spi.schedule_id = schedules.id
|
|
|
LIMIT 1
|
|
|
- ) AS service_package_id
|
|
|
- "),
|
|
|
+ )
|
|
|
+ ) AS service_package_items_count
|
|
|
+ "),
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ EXISTS (
|
|
|
+ SELECT 1
|
|
|
+ FROM reviews
|
|
|
+ WHERE reviews.schedule_id = schedules.id
|
|
|
+ AND reviews.origin = 'client'
|
|
|
+ AND reviews.origin_id = {$cliente->id}
|
|
|
+ AND reviews.deleted_at IS NULL
|
|
|
+ ) AS client_reviewed
|
|
|
+ "),
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.start_time', 'asc')
|
|
|
+ ->get()
|
|
|
+ ->map(function ($item) {
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
|
|
|
- DB::raw("
|
|
|
- (
|
|
|
- SELECT COUNT(*)
|
|
|
- FROM service_package_items spi_count
|
|
|
- WHERE spi_count.service_package_id = (
|
|
|
- SELECT spi.service_package_id
|
|
|
- FROM service_package_items spi
|
|
|
- WHERE spi.schedule_id = schedules.id
|
|
|
- LIMIT 1
|
|
|
- )
|
|
|
- ) AS service_package_items_count
|
|
|
- "),
|
|
|
+ return $item;
|
|
|
+ });
|
|
|
|
|
|
- DB::raw("
|
|
|
- EXISTS (
|
|
|
- SELECT 1
|
|
|
- FROM reviews
|
|
|
- WHERE reviews.schedule_id = schedules.id
|
|
|
- AND reviews.origin = 'client'
|
|
|
- AND reviews.origin_id = {$cliente->id}
|
|
|
- AND reviews.deleted_at IS NULL
|
|
|
- ) AS client_reviewed
|
|
|
- "),
|
|
|
- )
|
|
|
- ->orderBy('schedules.start_time', 'asc')
|
|
|
- ->get()
|
|
|
- ->map(function ($item) {
|
|
|
- $item->gender_label = $item->gender ? GenderEnum::tryFrom($item->gender)?->label() : null;
|
|
|
+ $providerCollections = collect([
|
|
|
+ $nextSchedules,
|
|
|
+ $lastDoneSchedules,
|
|
|
+ $favoriteProviders,
|
|
|
+ $providersClose,
|
|
|
+ $pendingSchedules,
|
|
|
+ $schedulesProposals,
|
|
|
+ $todaySchedules,
|
|
|
+ ]);
|
|
|
|
|
|
- $item->provider_photo = $item->provider_photo
|
|
|
- ? Storage::temporaryUrl(
|
|
|
- $item->provider_photo,
|
|
|
- now()->addMinutes(60)
|
|
|
- )
|
|
|
- : null;
|
|
|
+ $providerPhotoUrls = $this->providerPhotoUrls(
|
|
|
+ $providerCollections->flatMap(
|
|
|
+ fn (Collection $items) => $items->pluck('provider_id'),
|
|
|
+ ),
|
|
|
+ );
|
|
|
|
|
|
- return $item;
|
|
|
+ $providerCollections->each(function (Collection $items) use ($providerPhotoUrls) {
|
|
|
+ $items->each(function ($item) use ($providerPhotoUrls) {
|
|
|
+ $item->provider_photo = $providerPhotoUrls->get($item->provider_id);
|
|
|
});
|
|
|
+ });
|
|
|
|
|
|
$notifications = Notification::where('user_id', $user->id)
|
|
|
->orderBy('read', 'asc')
|
|
|
@@ -791,57 +748,57 @@ class DashboardService
|
|
|
$solicitations = Schedule::with([
|
|
|
'address:district,source_id,source,id,zip_code,latitude,longitude',
|
|
|
])
|
|
|
- ->where('schedules.provider_id', $provider->id)
|
|
|
- ->where('schedules.status', 'pending')
|
|
|
- ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
|
|
|
- ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
|
|
|
- ->leftJoin('media as client_media', 'client_media.id', '=', 'clients.profile_media_id')
|
|
|
- ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'client_user.name as client_name',
|
|
|
- 'clients.average_rating',
|
|
|
- 'schedules.date',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- TO_CHAR(schedules.date, 'DD/MM/YYYY') AS formatted_date
|
|
|
- "),
|
|
|
-
|
|
|
- 'schedules.start_time',
|
|
|
- 'schedules.end_time',
|
|
|
- 'schedules.total_amount',
|
|
|
- 'schedules.period_type',
|
|
|
- 'schedules.schedule_type',
|
|
|
- 'schedules.address_id',
|
|
|
- 'schedules.status',
|
|
|
- 'custom_schedules.offers_meal',
|
|
|
- 'client_media.path as customer_photo_path',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- CASE
|
|
|
- WHEN (NOW() - schedules.created_at) < INTERVAL '1 day' THEN
|
|
|
- CONCAT(
|
|
|
- ROUND(
|
|
|
- EXTRACT(
|
|
|
- EPOCH FROM (NOW() - schedules.created_at)
|
|
|
- ) / 3600
|
|
|
- ),
|
|
|
- ' hours ago'
|
|
|
- )
|
|
|
- ELSE
|
|
|
- CONCAT(
|
|
|
- ROUND(
|
|
|
- EXTRACT(
|
|
|
- EPOCH FROM (NOW() - schedules.created_at)
|
|
|
- ) / 86400
|
|
|
- ),
|
|
|
- ' days ago'
|
|
|
- )
|
|
|
- END AS time_since_request
|
|
|
- "),
|
|
|
- )
|
|
|
- ->orderBy('schedules.date', 'asc')
|
|
|
- ->get();
|
|
|
+ ->where('schedules.provider_id', $provider->id)
|
|
|
+ ->where('schedules.status', 'pending')
|
|
|
+ ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
|
|
|
+ ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
|
|
|
+ ->leftJoin('media as client_media', 'client_media.id', '=', 'clients.profile_media_id')
|
|
|
+ ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'client_user.name as client_name',
|
|
|
+ 'clients.average_rating',
|
|
|
+ 'schedules.date',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ TO_CHAR(schedules.date, 'DD/MM/YYYY') AS formatted_date
|
|
|
+ "),
|
|
|
+
|
|
|
+ 'schedules.start_time',
|
|
|
+ 'schedules.end_time',
|
|
|
+ 'schedules.total_amount',
|
|
|
+ 'schedules.period_type',
|
|
|
+ 'schedules.schedule_type',
|
|
|
+ 'schedules.address_id',
|
|
|
+ 'schedules.status',
|
|
|
+ 'custom_schedules.offers_meal',
|
|
|
+ 'client_media.path as customer_photo_path',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ CASE
|
|
|
+ WHEN (NOW() - schedules.created_at) < INTERVAL '1 day' THEN
|
|
|
+ CONCAT(
|
|
|
+ ROUND(
|
|
|
+ EXTRACT(
|
|
|
+ EPOCH FROM (NOW() - schedules.created_at)
|
|
|
+ ) / 3600
|
|
|
+ ),
|
|
|
+ ' hours ago'
|
|
|
+ )
|
|
|
+ ELSE
|
|
|
+ CONCAT(
|
|
|
+ ROUND(
|
|
|
+ EXTRACT(
|
|
|
+ EPOCH FROM (NOW() - schedules.created_at)
|
|
|
+ ) / 86400
|
|
|
+ ),
|
|
|
+ ' days ago'
|
|
|
+ )
|
|
|
+ END AS time_since_request
|
|
|
+ "),
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.date', 'asc')
|
|
|
+ ->get();
|
|
|
|
|
|
$solicitations->each(function ($solicitation) use ($address) {
|
|
|
$solicitation->customer_photo = $solicitation->customer_photo_path
|
|
|
@@ -863,43 +820,43 @@ class DashboardService
|
|
|
$todayServices = Schedule::with([
|
|
|
'address:district,address,number,source_id,source,id',
|
|
|
])
|
|
|
- ->where('schedules.provider_id', $provider->id)
|
|
|
- ->whereIn('schedules.status', ['accepted', 'paid', 'started', 'finished'])
|
|
|
- ->whereDate('schedules.date', now()->toDateString())
|
|
|
- ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
|
|
|
- ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
|
|
|
- ->leftJoin('media as client_media', 'client_media.id', '=', 'clients.profile_media_id')
|
|
|
- ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
- ->select(
|
|
|
- 'schedules.id',
|
|
|
- 'schedules.client_id',
|
|
|
- 'client_user.name as client_name',
|
|
|
- 'schedules.date',
|
|
|
- 'schedules.start_time',
|
|
|
- 'schedules.end_time',
|
|
|
- 'schedules.total_amount',
|
|
|
- 'schedules.period_type',
|
|
|
- 'schedules.address_id',
|
|
|
- 'schedules.schedule_type',
|
|
|
- 'schedules.status',
|
|
|
- 'schedules.code_verified',
|
|
|
- 'schedules.code',
|
|
|
- 'custom_schedules.offers_meal',
|
|
|
- 'client_media.path as customer_photo_path',
|
|
|
-
|
|
|
- DB::raw("
|
|
|
- EXISTS (
|
|
|
- SELECT 1
|
|
|
- FROM reviews
|
|
|
- WHERE reviews.schedule_id = schedules.id
|
|
|
- AND reviews.origin = 'provider'
|
|
|
- AND reviews.origin_id = {$provider->id}
|
|
|
- AND reviews.deleted_at IS NULL
|
|
|
- ) AS provider_reviewed
|
|
|
- "),
|
|
|
- )
|
|
|
- ->orderBy('schedules.start_time', 'asc')
|
|
|
- ->get();
|
|
|
+ ->where('schedules.provider_id', $provider->id)
|
|
|
+ ->whereIn('schedules.status', ['accepted', 'paid', 'started', 'finished'])
|
|
|
+ ->whereDate('schedules.date', now()->toDateString())
|
|
|
+ ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
|
|
|
+ ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
|
|
|
+ ->leftJoin('media as client_media', 'client_media.id', '=', 'clients.profile_media_id')
|
|
|
+ ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
+ ->select(
|
|
|
+ 'schedules.id',
|
|
|
+ 'schedules.client_id',
|
|
|
+ 'client_user.name as client_name',
|
|
|
+ 'schedules.date',
|
|
|
+ 'schedules.start_time',
|
|
|
+ 'schedules.end_time',
|
|
|
+ 'schedules.total_amount',
|
|
|
+ 'schedules.period_type',
|
|
|
+ 'schedules.address_id',
|
|
|
+ 'schedules.schedule_type',
|
|
|
+ 'schedules.status',
|
|
|
+ 'schedules.code_verified',
|
|
|
+ 'schedules.code',
|
|
|
+ 'custom_schedules.offers_meal',
|
|
|
+ 'client_media.path as customer_photo_path',
|
|
|
+
|
|
|
+ DB::raw("
|
|
|
+ EXISTS (
|
|
|
+ SELECT 1
|
|
|
+ FROM reviews
|
|
|
+ WHERE reviews.schedule_id = schedules.id
|
|
|
+ AND reviews.origin = 'provider'
|
|
|
+ AND reviews.origin_id = {$provider->id}
|
|
|
+ AND reviews.deleted_at IS NULL
|
|
|
+ ) AS provider_reviewed
|
|
|
+ "),
|
|
|
+ )
|
|
|
+ ->orderBy('schedules.start_time', 'asc')
|
|
|
+ ->get();
|
|
|
|
|
|
$todayServices->each(function ($s) {
|
|
|
$s->customer_photo = $s->customer_photo_path
|
|
|
@@ -998,17 +955,18 @@ class DashboardService
|
|
|
->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
|
|
|
- ->leftJoin('media', 'media.id', '=', 'providers.profile_media_id')
|
|
|
->select(
|
|
|
'schedules.provider_id',
|
|
|
'provider_user.name as provider_name',
|
|
|
'providers.birth_date as provider_birth_date',
|
|
|
'providers.gender',
|
|
|
- 'media.path as provider_photo',
|
|
|
'custom_schedules.offers_meal',
|
|
|
)
|
|
|
->firstOrFail();
|
|
|
|
|
|
+ $providerPhoto = $this->providerPhotoUrls([$schedule->provider_id])
|
|
|
+ ->get($schedule->provider_id);
|
|
|
+
|
|
|
$allSpecialities = Speciality::where('active', true)
|
|
|
->select('id', 'description')
|
|
|
->orderBy('description')
|
|
|
@@ -1028,16 +986,32 @@ class DashboardService
|
|
|
'provider_name' => $schedule->provider_name,
|
|
|
'provider_birth_date' => $schedule->provider_birth_date,
|
|
|
'gender' => $schedule->gender,
|
|
|
- 'gender_label' => $schedule->gender ? GenderEnum::tryFrom($schedule->gender)?->label() : null,
|
|
|
+ 'gender_label' => GenderEnum::labelFor($schedule->gender),
|
|
|
'offers_meal' => $schedule->offers_meal,
|
|
|
'specialities' => $specialities,
|
|
|
|
|
|
- 'provider_photo' => $schedule->provider_photo
|
|
|
- ? Storage::temporaryUrl($schedule->provider_photo, now()->addMinutes(60))
|
|
|
- : null,
|
|
|
+ 'provider_photo' => $providerPhoto,
|
|
|
];
|
|
|
}
|
|
|
|
|
|
+ // gera urls apenas para fotos verificadas ou visiveis ao proprio prestador.
|
|
|
+
|
|
|
+ private function providerPhotoUrls(iterable $providerIds): Collection
|
|
|
+ {
|
|
|
+ return Provider::query()
|
|
|
+ ->select('id', 'profile_media_id')
|
|
|
+ ->with('profileMedia')
|
|
|
+ ->whereIn('id', collect($providerIds)->filter()->unique())
|
|
|
+ ->get()
|
|
|
+ ->mapWithKeys(function (Provider $provider) {
|
|
|
+ $path = $provider->profileMedia?->path;
|
|
|
+
|
|
|
+ return [
|
|
|
+ $provider->id => $path ? Storage::temporaryUrl($path, now()->addMinutes(60)) : null,
|
|
|
+ ];
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
//
|
|
|
|
|
|
private function applyCreditCardFee(?float $price): ?float
|