|
@@ -341,7 +341,78 @@ class DashboardService
|
|
|
->values();
|
|
->values();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $pendingSchedules = $this->clientPendingSchedules($cliente);
|
|
|
|
|
|
|
+ $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')
|
|
|
|
|
+ ->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.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
|
|
|
|
|
+ JOIN schedules s_count ON s_count.id = spi_count.schedule_id
|
|
|
|
|
+ AND s_count.status NOT IN ('cancelled', 'rejected')
|
|
|
|
|
+ AND s_count.schedule_type = 'default'
|
|
|
|
|
+ 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();
|
|
|
|
|
+
|
|
|
|
|
+ $pendingSchedules->each(function ($item) {
|
|
|
|
|
+ $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
$proposalsDistanceSelect = DistanceService::sqlExpression(
|
|
$proposalsDistanceSelect = DistanceService::sqlExpression(
|
|
|
$providersCloseLatitude,
|
|
$providersCloseLatitude,
|
|
@@ -574,7 +645,16 @@ class DashboardService
|
|
|
|
|
|
|
|
$hasPaymentMethods = ClientPaymentMethod::where('client_id', $cliente->id)->exists();
|
|
$hasPaymentMethods = ClientPaymentMethod::where('client_id', $cliente->id)->exists();
|
|
|
|
|
|
|
|
- $pendingServicePackages = $this->clientPendingServicePackages($cliente);
|
|
|
|
|
|
|
+ $pendingServicePackages = ServicePackage::query()
|
|
|
|
|
+ ->where('client_id', $cliente->id)
|
|
|
|
|
+ ->where('status', ServicePackageStatusEnum::OPEN->value)
|
|
|
|
|
+ ->whereHas('items.schedule', fn($q) => $q->where('status', 'accepted'))
|
|
|
|
|
+ ->whereDoesntHave('items.schedule', fn($q) => $q->where('status', 'pending'))
|
|
|
|
|
+ ->with(['items.schedule' => function ($query) {
|
|
|
|
|
+ $query->with(['provider.user', 'address']);
|
|
|
|
|
+ }])
|
|
|
|
|
+ ->with('provider.user')
|
|
|
|
|
+ ->get();
|
|
|
|
|
|
|
|
return [
|
|
return [
|
|
|
'headerBar' => $headerBar,
|
|
'headerBar' => $headerBar,
|
|
@@ -733,11 +813,99 @@ class DashboardService
|
|
|
);
|
|
);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- $pendingSchedules = $this->clientPendingSchedules($cliente);
|
|
|
|
|
|
|
+ $packageItemCounts = DB::table('service_package_items as spi_count')
|
|
|
|
|
+ ->join('schedules as s_count', function ($join) {
|
|
|
|
|
+ $join->on('s_count.id', '=', 'spi_count.schedule_id')
|
|
|
|
|
+ ->whereNotIn('s_count.status', ['cancelled', 'rejected'])
|
|
|
|
|
+ ->where('s_count.schedule_type', 'default');
|
|
|
|
|
+ })
|
|
|
|
|
+ ->groupBy('spi_count.service_package_id')
|
|
|
|
|
+ ->select('spi_count.service_package_id', DB::raw('COUNT(*) AS items_count'));
|
|
|
|
|
+
|
|
|
|
|
+ $pendingSchedules = Schedule::query()
|
|
|
|
|
+ ->where('schedules.client_id', $cliente->id)
|
|
|
|
|
+ ->where('schedules.schedule_type', 'default')
|
|
|
|
|
+ ->where('schedules.status', 'pending')
|
|
|
|
|
+ ->whereDate('schedules.date', '>=', now()->toDateString())
|
|
|
|
|
+ ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
|
|
|
|
|
+ ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
|
|
|
|
|
+ ->leftJoin('addresses as schedule_address', 'schedule_address.id', '=', 'schedules.address_id')
|
|
|
|
|
+ ->leftJoin('service_package_items as spi', 'spi.schedule_id', '=', 'schedules.id')
|
|
|
|
|
+ ->leftJoinSub(
|
|
|
|
|
+ $packageItemCounts,
|
|
|
|
|
+ 'package_counts',
|
|
|
|
|
+ 'package_counts.service_package_id',
|
|
|
|
|
+ '=',
|
|
|
|
|
+ 'spi.service_package_id',
|
|
|
|
|
+ )
|
|
|
|
|
+ ->orderBy('schedules.date', 'asc')
|
|
|
|
|
+ ->select([
|
|
|
|
|
+ 'schedules.id',
|
|
|
|
|
+ 'schedules.provider_id',
|
|
|
|
|
+ 'schedules.date',
|
|
|
|
|
+ 'schedules.start_time',
|
|
|
|
|
+ 'schedules.end_time',
|
|
|
|
|
+ 'schedules.status',
|
|
|
|
|
+ 'provider_user.name as provider_name',
|
|
|
|
|
+ 'spi.service_package_id',
|
|
|
|
|
+
|
|
|
|
|
+ DB::raw('COALESCE(package_counts.items_count, 1) AS service_package_items_count'),
|
|
|
|
|
+
|
|
|
|
|
+ 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
|
|
|
|
|
+ "),
|
|
|
|
|
+
|
|
|
|
|
+ 'schedule_address.address as address_address',
|
|
|
|
|
+ 'schedule_address.number as address_number',
|
|
|
|
|
+ 'schedule_address.district as address_district',
|
|
|
|
|
+ ])
|
|
|
|
|
+ ->get()
|
|
|
|
|
+ ->unique(fn ($schedule) => $schedule->service_package_id
|
|
|
|
|
+ ? 'package-'.$schedule->service_package_id
|
|
|
|
|
+ : 'schedule-'.$schedule->id)
|
|
|
|
|
+ ->values();
|
|
|
|
|
+
|
|
|
|
|
+ $pendingSchedules->each(function ($schedule) {
|
|
|
|
|
+ $schedule->address = [
|
|
|
|
|
+ 'address' => $schedule->address_address,
|
|
|
|
|
+ 'number' => $schedule->address_number,
|
|
|
|
|
+ 'district' => $schedule->address_district,
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ unset(
|
|
|
|
|
+ $schedule->address_address,
|
|
|
|
|
+ $schedule->address_number,
|
|
|
|
|
+ $schedule->address_district,
|
|
|
|
|
+ );
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ $pendingServicePackages = ServicePackage::query()
|
|
|
|
|
+ ->where('client_id', $cliente->id)
|
|
|
|
|
+ ->where('status', ServicePackageStatusEnum::OPEN->value)
|
|
|
|
|
+ ->whereHas('items.schedule', fn ($query) => $query->where('status', 'accepted'))
|
|
|
|
|
+ ->whereDoesntHave('items.schedule', fn ($query) => $query->where('status', 'pending'))
|
|
|
|
|
+ ->with([
|
|
|
|
|
+ 'provider:id,user_id',
|
|
|
|
|
+ 'provider.user:id,name',
|
|
|
|
|
+ 'items:id,service_package_id,schedule_id',
|
|
|
|
|
+
|
|
|
|
|
+ 'items.schedule' => fn ($query) => $query
|
|
|
|
|
+ ->select('id', 'date', 'start_time', 'end_time', 'status', 'total_amount', 'address_id')
|
|
|
|
|
+ ->with('address:id,address,number,district'),
|
|
|
|
|
+ ])
|
|
|
|
|
+ ->get();
|
|
|
|
|
|
|
|
$providerPhotoUrls = $this->providerPhotoUrls(
|
|
$providerPhotoUrls = $this->providerPhotoUrls(
|
|
|
$schedulesProposals->pluck('provider_id')
|
|
$schedulesProposals->pluck('provider_id')
|
|
|
- ->merge($pendingSchedules->pluck('provider_id')),
|
|
|
|
|
|
|
+ ->merge($pendingSchedules->pluck('provider_id'))
|
|
|
|
|
+ ->merge($pendingServicePackages->pluck('provider_id')),
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
collect([$schedulesProposals, $pendingSchedules])->each(
|
|
collect([$schedulesProposals, $pendingSchedules])->each(
|
|
@@ -746,11 +914,50 @@ class DashboardService
|
|
|
}),
|
|
}),
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
+ $pendingServicePackages = $pendingServicePackages->map(
|
|
|
|
|
+ function (ServicePackage $package) use ($providerPhotoUrls) {
|
|
|
|
|
+ $schedules = $package->items
|
|
|
|
|
+ ->pluck('schedule')
|
|
|
|
|
+ ->filter()
|
|
|
|
|
+ ->values();
|
|
|
|
|
+
|
|
|
|
|
+ $activeSchedules = $schedules->reject(
|
|
|
|
|
+ fn ($schedule) => in_array($schedule->status, ['cancelled', 'rejected'], true),
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'id' => $package->id,
|
|
|
|
|
+ 'provider_id' => $package->provider_id,
|
|
|
|
|
+ 'provider_name' => $package->provider?->user?->name,
|
|
|
|
|
+ 'provider_photo' => $providerPhotoUrls->get($package->provider_id),
|
|
|
|
|
+ 'total_amount' => (float) $activeSchedules->sum(
|
|
|
|
|
+ fn ($schedule) => (float) $schedule->total_amount,
|
|
|
|
|
+ ),
|
|
|
|
|
+ 'service_package_items_count' => $activeSchedules->count(),
|
|
|
|
|
+
|
|
|
|
|
+ 'schedules' => $schedules->map(fn ($schedule) => [
|
|
|
|
|
+ 'id' => $schedule->id,
|
|
|
|
|
+ 'status' => $schedule->status,
|
|
|
|
|
+ 'date' => $schedule->date?->format('Y-m-d'),
|
|
|
|
|
+ 'start_time' => $schedule->start_time,
|
|
|
|
|
+ 'end_time' => $schedule->end_time,
|
|
|
|
|
+ 'total_amount' => (float) $schedule->total_amount,
|
|
|
|
|
+
|
|
|
|
|
+ 'address' => [
|
|
|
|
|
+ 'address' => $schedule->address?->address,
|
|
|
|
|
+ 'number' => $schedule->address?->number,
|
|
|
|
|
+ 'district' => $schedule->address?->district,
|
|
|
|
|
+ ],
|
|
|
|
|
+ ])->values(),
|
|
|
|
|
+ ];
|
|
|
|
|
+ },
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
return [
|
|
return [
|
|
|
'schedulesProposals' => $schedulesProposals,
|
|
'schedulesProposals' => $schedulesProposals,
|
|
|
'customSchedulesNoProposals' => $customSchedulesNoProposals,
|
|
'customSchedulesNoProposals' => $customSchedulesNoProposals,
|
|
|
'pendingSchedules' => $pendingSchedules,
|
|
'pendingSchedules' => $pendingSchedules,
|
|
|
- 'pendingServicePackages' => $this->clientPendingServicePackages($cliente),
|
|
|
|
|
|
|
+ 'pendingServicePackages' => $pendingServicePackages,
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1141,108 +1348,6 @@ class DashboardService
|
|
|
|
|
|
|
|
// gera urls apenas para fotos verificadas ou visiveis ao proprio prestador.
|
|
// gera urls apenas para fotos verificadas ou visiveis ao proprio prestador.
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * Agendamentos padrão do cliente ainda pendentes ou já aceitos aguardando pagamento.
|
|
|
|
|
- * Compartilhado entre a dashboard e a tela de pedidos.
|
|
|
|
|
- */
|
|
|
|
|
- private function clientPendingSchedules(Client $cliente): Collection
|
|
|
|
|
- {
|
|
|
|
|
- $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')
|
|
|
|
|
- ->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.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
|
|
|
|
|
- JOIN schedules s_count ON s_count.id = spi_count.schedule_id
|
|
|
|
|
- AND s_count.status NOT IN ('cancelled', 'rejected')
|
|
|
|
|
- AND s_count.schedule_type = 'default'
|
|
|
|
|
- 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();
|
|
|
|
|
-
|
|
|
|
|
- $pendingSchedules->each(function ($item) {
|
|
|
|
|
- $item->gender_label = GenderEnum::labelFor($item->gender);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- return $pendingSchedules;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Pacotes abertos cujos agendamentos já foram todos aceitos — é o que
|
|
|
|
|
- * dispara o bloco "realize o pagamento para" no app do cliente.
|
|
|
|
|
- */
|
|
|
|
|
- private function clientPendingServicePackages(Client $cliente): Collection
|
|
|
|
|
- {
|
|
|
|
|
- $pendingServicePackages = ServicePackage::query()
|
|
|
|
|
- ->where('client_id', $cliente->id)
|
|
|
|
|
- ->where('status', ServicePackageStatusEnum::OPEN->value)
|
|
|
|
|
- ->whereHas('items.schedule', fn($q) => $q->where('status', 'accepted'))
|
|
|
|
|
- ->whereDoesntHave('items.schedule', fn($q) => $q->where('status', 'pending'))
|
|
|
|
|
- ->with(['items.schedule' => function ($query) {
|
|
|
|
|
- $query->with(['provider.user', 'address']);
|
|
|
|
|
- }])
|
|
|
|
|
- ->with('provider.user')
|
|
|
|
|
- ->get();
|
|
|
|
|
-
|
|
|
|
|
- return $pendingServicePackages;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private function providerPhotoUrls(iterable $providerIds): Collection
|
|
private function providerPhotoUrls(iterable $providerIds): Collection
|
|
|
{
|
|
{
|
|
|
return Provider::query()
|
|
return Provider::query()
|