浏览代码

ajuste aba pedidos

Gustavo Zanatta 2 周之前
父节点
当前提交
74fd7e4e38
共有 1 个文件被更改,包括 212 次插入107 次删除
  1. 212 107
      app/Services/DashboardService.php

+ 212 - 107
app/Services/DashboardService.php

@@ -341,7 +341,78 @@ class DashboardService
                 ->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(
             $providersCloseLatitude,
@@ -574,7 +645,16 @@ class DashboardService
 
         $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 [
             '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(
             $schedulesProposals->pluck('provider_id')
-                ->merge($pendingSchedules->pluck('provider_id')),
+                ->merge($pendingSchedules->pluck('provider_id'))
+                ->merge($pendingServicePackages->pluck('provider_id')),
         );
 
         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 [
             'schedulesProposals'         => $schedulesProposals,
             'customSchedulesNoProposals' => $customSchedulesNoProposals,
             '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.
 
-    /**
-     * 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
     {
         return Provider::query()