Explorar o código

refactor: add informacao de quais schedules pertencem a um cart

Gustavo Mantovani hai 4 días
pai
achega
8b24b8b694
Modificáronse 2 ficheiros con 162 adicións e 80 borrados
  1. 25 14
      app/Http/Resources/ScheduleResource.php
  2. 137 66
      app/Services/DashboardService.php

+ 25 - 14
app/Http/Resources/ScheduleResource.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Resources;
 
+use App\Models\CartItem;
 use Illuminate\Http\Request;
 use Illuminate\Http\Resources\Json\JsonResource;
 
@@ -9,6 +10,14 @@ class ScheduleResource extends JsonResource
 {
     public function toArray(Request $request): array
     {
+        $cartId = $this->cart_id ?? CartItem::query()
+            ->where('schedule_id', $this->id)
+            ->value('cart_id');
+
+        $cartItemsCount = $this->cart_items_count ?? (
+            $cartId ? CartItem::query()->where('cart_id', $cartId)->count() : 0
+        );
+
         return [
             'id'            => $this->id,
             'client_id'     => $this->client_id,
@@ -24,20 +33,22 @@ class ScheduleResource extends JsonResource
                 $this->address->city ? "{$this->address->city->name}/{$this->address->state?->code}" : null,
             ])) : null,
 
-            'address'       => new AddressResource($this->whenLoaded('address')),
-            'date'          => $this->date?->format('Y-m-d'),
-            'period_type'   => $this->period_type,
-            'schedule_type' => $this->schedule_type,
-            'start_time'    => $this->start_time,
-            'end_time'      => $this->end_time,
-            'offers_meal'   => $this->offers_meal,
-            'status'        => $this->status,
-            'total_amount'  => $this->total_amount,
-            'code'          => $this->code,
-            'code_verified' => $this->code_verified,
-            'created_at'    => $this->created_at?->toISOString(),
-            'updated_at'    => $this->updated_at?->toISOString(),
-            'deleted_at'    => $this->deleted_at?->toISOString(),
+            'address'          => new AddressResource($this->whenLoaded('address')),
+            'date'             => $this->date?->format('Y-m-d'),
+            'period_type'      => $this->period_type,
+            'schedule_type'    => $this->schedule_type,
+            'start_time'       => $this->start_time,
+            'end_time'         => $this->end_time,
+            'offers_meal'      => $this->offers_meal,
+            'status'           => $this->status,
+            'total_amount'     => $this->total_amount,
+            'code'             => $this->code,
+            'code_verified'    => $this->code_verified,
+            'cart_id'          => $cartId,
+            'cart_items_count' => $cartItemsCount,
+            'created_at'       => $this->created_at?->toISOString(),
+            'updated_at'       => $this->updated_at?->toISOString(),
+            'deleted_at'       => $this->deleted_at?->toISOString(),
         ];
     }
 }

+ 137 - 66
app/Services/DashboardService.php

@@ -37,12 +37,13 @@ class DashboardService
         $cliente = Client::with('profileMedia')->where('user_id', $user->id)->first();
 
         $headerBar = [
-            'rating'        => $cliente->average_rating,
+            'rating'         => $cliente->average_rating,
+            'total_services' => $cliente->total_services,
+
             'total_ratings' => Review::where('reviews.origin', 'provider')
                 ->leftJoin('schedules', 'schedules.id', '=', 'reviews.schedule_id')
                 ->where('schedules.client_id', $cliente->id)
                 ->count(),
-            'total_services' => $cliente->total_services,
         ];
 
         $address = Address::where('source', 'client')
@@ -52,11 +53,13 @@ class DashboardService
             ->first();
 
         $summaryInfos = [
-            'name'          => $user->name,
+            'name'    => $user->name,
+            'address' => $address,
+
             'profile_photo' => $cliente->profileMedia?->path
                 ? Storage::temporaryUrl($cliente->profileMedia->path, now()->addMinutes(60))
                 : null,
-            'address'          => $address,
+
             'pending_services' => Schedule::where('client_id', $cliente->id)
                 ->whereIn('status', ['pending', 'paid', 'accepted'])
                 ->whereDate('date', '>=', now()->toDateString())
@@ -85,6 +88,18 @@ class DashboardService
                 'schedules.address_id',
                 'custom_schedules.address_type as custom_address_type',
                 'provider_media.path as provider_photo_path',
+
+                DB::raw("(SELECT ci.cart_id FROM cart_items ci WHERE ci.schedule_id = schedules.id LIMIT 1) as cart_id"),
+
+                DB::raw(
+                    "(SELECT COUNT(*) FROM cart_items ci_count
+                        WHERE ci_count.cart_id = (
+                            SELECT ci.cart_id FROM cart_items ci
+                                WHERE ci.schedule_id = schedules.id
+                                    LIMIT 1
+                        )
+                    ) as cart_items_count"
+                ),
             )
             ->orderBy('schedules.date', 'asc')
             ->limit(5)
@@ -94,6 +109,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);
         });
 
@@ -109,7 +125,7 @@ class DashboardService
             ->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)
+                    ->where('provider_address.rn', 1)
             )
             ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
             ->select(
@@ -127,6 +143,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);
         });
 
@@ -135,7 +152,7 @@ class DashboardService
             ->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)
+                    ->where('provider_address.rn', 1)
             )
             ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
             ->select(
@@ -153,10 +170,11 @@ class DashboardService
             $item->provider_photo = $item->provider_photo_path
                 ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
                 : null;
+
             unset($item->provider_photo_path);
         });
 
-        $blockedProviderIds = ScheduleBusinessRules::getBlockedProviderIdsForClient($cliente->id);
+        $blockedProviderIds       = ScheduleBusinessRules::getBlockedProviderIdsForClient($cliente->id);
         $providersWithWorkingDays = ScheduleBusinessRules::getProviderIdsWithWorkingDays();
 
         $clientPrimaryAddress = Address::where('source', 'client')
@@ -165,21 +183,18 @@ class DashboardService
             ->first();
 
         $providersCloseDistanceSelect = $this->distanceSelect(
-            $clientPrimaryAddress?->latitude !== null ? (float) $clientPrimaryAddress->latitude : null,
+            $clientPrimaryAddress?->latitude  !== null ? (float) $clientPrimaryAddress->latitude  : null,
             $clientPrimaryAddress?->longitude !== null ? (float) $clientPrimaryAddress->longitude : null,
         );
 
         $providersClose = Provider::leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
-            ->leftJoin(DB::raw("
-        (
-          SELECT DISTINCT ON (source_id)
-            *
-          FROM addresses
-          WHERE source = 'provider'
-          AND deleted_at IS NULL
-          ORDER BY source_id, is_primary DESC
-        ) as provider_address
-      "), 'provider_address.source_id', '=', 'providers.id')
+            ->leftJoin(DB::raw(
+                "(SELECT DISTINCT ON (source_id) * FROM addresses
+                    WHERE source = 'provider'
+                        AND deleted_at IS NULL
+                            ORDER BY source_id, is_primary DESC
+                ) as provider_address"), 'provider_address.source_id', '=', 'providers.id'
+            )
             ->leftJoin('media as provider_media', 'provider_media.id', '=', 'providers.profile_media_id')
             ->whereNotNull('provider_address.id')
             ->where('provider_address.city_id', $clientPrimaryAddress?->city_id)
@@ -199,14 +214,17 @@ class DashboardService
                 '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"),
+
+                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',
             )
             ->get();
@@ -215,6 +233,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);
         });
 
@@ -235,12 +254,28 @@ class DashboardService
                 '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(
+                    "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("(SELECT ci.cart_id FROM cart_items ci WHERE ci.schedule_id = schedules.id LIMIT 1) as cart_id"),
+
+                DB::raw(
+                    "(SELECT COUNT(*) FROM cart_items ci_count
+                        WHERE ci_count.cart_id = (
+                            SELECT ci.cart_id FROM cart_items ci
+                                WHERE ci.schedule_id = schedules.id
+                                    LIMIT 1
+                        )
+                    ) as cart_items_count"
+                ),
             )
             ->orderBy('schedules.date', 'asc')
             ->get();
@@ -249,11 +284,12 @@ class DashboardService
             $item->provider_photo = $item->provider_photo_path
                 ? Storage::temporaryUrl($item->provider_photo_path, now()->addMinutes(60))
                 : null;
+
             unset($item->provider_photo_path);
         });
 
         $proposalsDistanceSelect = DistanceService::sqlExpression(
-            $clientPrimaryAddress?->latitude !== null ? (float) $clientPrimaryAddress->latitude : null,
+            $clientPrimaryAddress?->latitude  !== null ? (float) $clientPrimaryAddress->latitude  : null,
             $clientPrimaryAddress?->longitude !== null ? (float) $clientPrimaryAddress->longitude : null,
         );
 
@@ -261,14 +297,15 @@ class DashboardService
             ->leftJoin('schedules', 'schedule_proposals.schedule_id', '=', 'schedules.id')
             ->leftJoin('providers', 'schedule_proposals.provider_id', '=', 'providers.id')
             ->leftJoin('users', 'providers.user_id', '=', 'users.id')
-            ->leftJoin(DB::raw("(
-                SELECT DISTINCT ON (source_id)
-                    *
-                FROM addresses
-                WHERE source = 'provider'
-                AND deleted_at IS NULL
-                ORDER BY source_id, is_primary DESC
-            ) as provider_address"), 'provider_address.source_id', '=', 'providers.id')
+            ->leftJoin(
+                DB::raw(
+                    "(SELECT DISTINCT ON (source_id) * FROM addresses
+                        WHERE source = 'provider'
+                            AND deleted_at IS NULL
+                                ORDER BY source_id, is_primary DESC
+                    ) as provider_address"
+                ), 'provider_address.source_id', '=', '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')
@@ -280,6 +317,7 @@ class DashboardService
                 'schedule_proposals.id',
 
                 DB::raw("DATE_PART('year', AGE(providers.birth_date)) as idade"),
+
                 'providers.id as provider_id',
                 'schedules.id as schedule_id',
                 'schedules.date',
@@ -292,7 +330,9 @@ class DashboardService
                 'providers.total_services',
 
                 'users.name as provider_name',
+
                 $proposalsDistanceSelect,
+
                 'provider_media.path as provider_photo_path',
             ])
             ->get();
@@ -301,6 +341,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);
         });
 
@@ -326,13 +367,28 @@ class DashboardService
                 'schedules.code_verified',
                 'schedules.code',
                 'media.path as provider_photo',
-                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"),
+
+                DB::raw("(SELECT ci.cart_id FROM cart_items ci WHERE ci.schedule_id = schedules.id LIMIT 1) as cart_id"),
+
+                DB::raw(
+                    "(SELECT COUNT(*) FROM cart_items ci_count
+                        WHERE ci_count.cart_id = (
+                            SELECT ci.cart_id FROM cart_items ci
+                                WHERE ci.schedule_id = schedules.id
+                                    LIMIT 1
+                        )
+                    ) as cart_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()
@@ -416,11 +472,12 @@ class DashboardService
         return [
             'provider_name'       => $schedule->provider_name,
             'provider_birth_date' => $schedule->provider_birth_date,
-            'provider_photo'      => $schedule->provider_photo
+            'offers_meal'         => $schedule->offers_meal,
+            'specialities'        => $specialities,
+
+            'provider_photo' => $schedule->provider_photo
                 ? Storage::temporaryUrl($schedule->provider_photo, now()->addMinutes(60))
                 : null,
-            'offers_meal'  => $schedule->offers_meal,
-            'specialities' => $specialities,
         ];
     }
 
@@ -443,12 +500,13 @@ class DashboardService
         $address = Address::where('source', 'provider')->where('source_id', $provider->id)->with(['city', 'state'])->first();
 
         $summaryInfos = [
-            'name'          => $user->name,
+            'name'             => $user->name,
+            'address'          => $address,
+            'pending_services' => Schedule::where('provider_id', $provider->id)->where('status', 'pending')->count(),
+
             'profile_photo' => $provider->profileMedia?->path
                 ? Storage::temporaryUrl($provider->profileMedia->path, now()->addMinutes(60))
                 : null,
-            'address'          => $address,
-            'pending_services' => Schedule::where('provider_id', $provider->id)->where('status', 'pending')->count(),
         ];
 
         $priceSuggestedAvg = Provider::where('user_id', '!=', $user->id)
@@ -475,7 +533,9 @@ class DashboardService
                 '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',
@@ -485,26 +545,31 @@ class DashboardService
                 '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"),
+
+                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();
 
-        $providerLat = $address?->latitude !== null ? (float) $address->latitude : null;
+        $providerLat = $address?->latitude  !== null ? (float) $address->latitude  : null;
         $providerLng = $address?->longitude !== null ? (float) $address->longitude : null;
 
         $solicitations->each(function ($solicitation) use ($providerLat, $providerLng) {
             $solicitation->customer_photo = $solicitation->customer_photo_path
                 ? Storage::temporaryUrl($solicitation->customer_photo_path, now()->addMinutes(60))
                 : null;
+
             unset($solicitation->customer_photo_path);
+
             $solicitation->distance_km = DistanceService::calculate(
                 $providerLat,
                 $providerLng,
-                $solicitation->address?->latitude !== null ? (float) $solicitation->address->latitude : null,
+                $solicitation->address?->latitude  !== null ? (float) $solicitation->address->latitude  : null,
                 $solicitation->address?->longitude !== null ? (float) $solicitation->address->longitude : null,
             );
         });
@@ -533,13 +598,16 @@ class DashboardService
                 '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"),
+
+                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();
@@ -548,6 +616,7 @@ class DashboardService
             $s->customer_photo = $s->customer_photo_path
                 ? Storage::temporaryUrl($s->customer_photo_path, now()->addMinutes(60))
                 : null;
+
             unset($s->customer_photo_path);
         });
 
@@ -580,11 +649,13 @@ class DashboardService
             $schedule->customer_photo = $schedule->customer_photo_path
                 ? Storage::temporaryUrl($schedule->customer_photo_path, now()->addMinutes(60))
                 : null;
+
             unset($schedule->customer_photo_path);
+
             $schedule->distance_km = DistanceService::calculate(
                 $providerLat,
                 $providerLng,
-                $schedule->address?->latitude !== null ? (float) $schedule->address->latitude : null,
+                $schedule->address?->latitude  !== null ? (float) $schedule->address->latitude  : null,
                 $schedule->address?->longitude !== null ? (float) $schedule->address->longitude : null,
             );
         });