Przeglądaj źródła

feat: ✨ feat (dashboard) novos filtros de pesquisa

foram adicionados filtros de pesquisa nos blocos da dashboard

fase:dev | origin:escopo
Gustavo Zanatta 8 godzin temu
rodzic
commit
1048f1f3f7

+ 9 - 3
app/Http/Controllers/PartnerAgreementController.php

@@ -58,16 +58,22 @@ class PartnerAgreementController extends Controller
 
     public function indexPaginated(Request $request): JsonResponse
     {
-        $filters = $request->only(['search', 'expires_in_days', 'created_month', 'type']);
+        $filters = $request->only(['search', 'status', 'expires_in_days', 'created_month', 'type']);
         $perPage = min((int) $request->get('per_page', 10), 100);
         $paginator = $this->service->getAllPaginated($filters, $perPage);
 
-        return $this->successResponse(payload: [
+        $payload = [
             'data'  => PartnerAgreementListResource::collection($paginator->items()),
             'total' => $paginator->total(),
             'from'  => $paginator->firstItem() ?? 0,
             'to'    => $paginator->lastItem() ?? 0,
-        ]);
+        ];
+
+        if ($request->boolean('with_status_options')) {
+            $payload['statuses'] = $this->service->getStatusOptions($filters);
+        }
+
+        return $this->successResponse(payload: $payload);
     }
 
     public function indexExpiring(Request $request): JsonResponse

+ 1 - 1
app/Http/Controllers/UserAccessLogController.php

@@ -13,7 +13,7 @@ class UserAccessLogController extends Controller
 
     public function index(Request $request): JsonResponse
     {
-        $filters = $request->only(['type', 'date_from', 'date_to', 'last_per_user']);
+        $filters = $request->only(['type', 'search', 'date_from', 'date_to', 'last_per_user']);
         $perPage = min((int) $request->get('per_page', 10), 100);
         $paginator = $this->service->getAllPaginated($filters, $perPage);
 

+ 8 - 2
app/Http/Controllers/UserController.php

@@ -72,12 +72,18 @@ class UserController extends Controller
         $perPage = min((int) $request->get('per_page', 10), 100);
         $paginator = $this->service->getAllPaginated($filters, $perPage);
 
-        return $this->successResponse(payload: [
+        $payload = [
             'data'  => UserResource::collection($paginator->items()),
             'total' => $paginator->total(),
             'from'  => $paginator->firstItem() ?? 0,
             'to'    => $paginator->lastItem() ?? 0,
-        ]);
+        ];
+
+        if ($request->boolean('with_status_options')) {
+            $payload['statuses'] = $this->service->getStatusOptions($filters);
+        }
+
+        return $this->successResponse(payload: $payload);
     }
 
     public function getUserTypes(): JsonResponse

+ 8 - 2
app/Http/Controllers/UserDependentController.php

@@ -36,12 +36,18 @@ class UserDependentController extends Controller
         $perPage = min((int) $request->get('per_page', 10), 100);
         $paginator = $this->service->getAllPaginated($filters, $perPage);
 
-        return $this->successResponse(payload: [
+        $payload = [
             'data'  => UserDependentResource::collection($paginator->items()),
             'total' => $paginator->total(),
             'from'  => $paginator->firstItem() ?? 0,
             'to'    => $paginator->lastItem() ?? 0,
-        ]);
+        ];
+
+        if ($request->boolean('with_status_options')) {
+            $payload['statuses'] = $this->service->getStatusOptions($filters);
+        }
+
+        return $this->successResponse(payload: $payload);
     }
 
     public function store(UserDependentRequest $request): JsonResponse

+ 1 - 0
app/Http/Resources/PartnerAgreementListResource.php

@@ -13,6 +13,7 @@ class PartnerAgreementListResource extends JsonResource
         return [
             'id'                  => $this->id,
             'company_name'        => $this->company_name,
+            'type'                => $this->type,
             'cnpj'                => $this->cnpj,
             'responsible'         => $this->responsible,
             'email'               => $this->email,

+ 42 - 8
app/Services/PartnerAgreementService.php

@@ -7,6 +7,7 @@ use App\Enums\UserStatusEnum;
 use App\Enums\UserTypeEnum;
 use App\Models\PartnerAgreement;
 use App\Models\User;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Illuminate\Support\Facades\DB;
@@ -28,19 +29,52 @@ class PartnerAgreementService
 
     public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
     {
-        $query = PartnerAgreement::with(['category', 'city', 'logo'])
-            ->orderBy('company_name');
+        $query = $this->baseQuery($filters)
+            ->with(['category', 'city', 'logo']);
+
+        if (!empty($filters['expires_in_days'])) {
+            $query->orderBy('contract_end');
+        } else {
+            $query->orderBy('company_name');
+        }
+
+        if (!empty($filters['status'])) {
+            $query->where('status', $filters['status']);
+        }
+
+        return $query->paginate($perPage);
+    }
+
+    /**
+     * Status existentes no conjunto filtrado, desconsiderando o próprio filtro de status.
+     *
+     * @return array<int, string>
+     */
+    public function getStatusOptions(array $filters = []): array
+    {
+        return $this->baseQuery($filters)
+            ->toBase()
+            ->distinct()
+            ->pluck('status')
+            ->filter()
+            ->values()
+            ->all();
+    }
+
+    private function baseQuery(array $filters): Builder
+    {
+        $query = PartnerAgreement::query();
 
         if (!empty($filters['type'])) {
             $query->where('type', $filters['type']);
         }
 
         if (!empty($filters['search'])) {
-            $search = $filters['search'];
-            $query->where(function ($q) use ($search) {
-                $q->where('company_name', 'like', "%{$search}%")
-                  ->orWhere('responsible', 'like', "%{$search}%")
-                  ->orWhere('cnpj', 'like', "%{$search}%");
+            $term = '%' . mb_strtolower($filters['search']) . '%';
+            $query->where(function ($q) use ($term) {
+                $q->whereRaw('UNACCENT(LOWER(company_name)) LIKE UNACCENT(?)', [$term])
+                  ->orWhereRaw('UNACCENT(LOWER(COALESCE(responsible, \'\'))) LIKE UNACCENT(?)', [$term])
+                  ->orWhereRaw('UNACCENT(LOWER(COALESCE(cnpj, \'\'))) LIKE UNACCENT(?)', [$term]);
             });
         }
 
@@ -54,7 +88,7 @@ class PartnerAgreementService
                   ->whereYear('created_at', now()->year);
         }
 
-        return $query->paginate($perPage);
+        return $query;
     }
 
     public function getExpiringPaginated(int $days = 30, int $perPage = 10): LengthAwarePaginator

+ 13 - 0
app/Services/UserAccessLogService.php

@@ -24,6 +24,19 @@ class UserAccessLogService
             $query->whereHas('user', fn($q) => $q->where('type', $filters['type']));
         }
 
+        if (!empty($filters['search'])) {
+            $term = '%' . mb_strtolower($filters['search']) . '%';
+            $query->where(function ($q) use ($term) {
+                $q->whereHas('user', function ($u) use ($term) {
+                    $u->whereRaw('UNACCENT(LOWER(users.name)) LIKE UNACCENT(?)', [$term])
+                      ->orWhereRaw('UNACCENT(LOWER(COALESCE(users.cpf, \'\'))) LIKE UNACCENT(?)', [$term])
+                      ->orWhereRaw('UNACCENT(LOWER(COALESCE(users.registration, \'\'))) LIKE UNACCENT(?)', [$term])
+                      ->orWhereRaw('LOWER(users.type) LIKE ?', [$term]);
+                })
+                ->orWhereRaw("TO_CHAR(users_access_logs.accessed_at, 'DD/MM/YYYY HH24:MI:SS') LIKE ?", [$term]);
+            });
+        }
+
         if (!empty($filters['date_from'])) {
             $query->whereDate('accessed_at', '>=', $filters['date_from']);
         }

+ 31 - 5
app/Services/UserDependentService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\Enums\UserDependentStatusEnum;
 use App\Models\UserDependent;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Http\UploadedFile;
 use Illuminate\Pagination\LengthAwarePaginator;
@@ -21,24 +22,49 @@ class UserDependentService
 
     public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
     {
-        $query = UserDependent::with(['responsibleUser.position', 'responsibleUser.sector'])
+        $query = $this->baseQuery($filters)
+            ->with(['responsibleUser.position', 'responsibleUser.sector'])
             ->orderBy('created_at', 'asc');
 
         if (!empty($filters['status'])) {
             $query->where('status', $filters['status']);
         }
 
+        return $query->paginate($perPage);
+    }
+
+    /**
+     * Status existentes no conjunto filtrado, desconsiderando o próprio filtro de status.
+     *
+     * @return array<int, string>
+     */
+    public function getStatusOptions(array $filters = []): array
+    {
+        return $this->baseQuery($filters)
+            ->toBase()
+            ->distinct()
+            ->pluck('status')
+            ->filter()
+            ->values()
+            ->all();
+    }
+
+    private function baseQuery(array $filters): Builder
+    {
+        $query = UserDependent::query();
+
         if (!empty($filters['search'])) {
             $term = '%' . mb_strtolower($filters['search']) . '%';
             $query->where(function ($q) use ($term) {
-                $q->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term])
-                  ->orWhereHas('responsibleUser', function ($q) use ($term) {
-                      $q->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
+                $q->whereRaw('UNACCENT(LOWER(user_dependents.name)) LIKE UNACCENT(?)', [$term])
+                  ->orWhereRaw("TO_CHAR(user_dependents.created_at, 'DD/MM/YYYY HH24:MI:SS') LIKE ?", [$term])
+                  ->orWhereHas('responsibleUser', function ($u) use ($term) {
+                      $u->whereRaw('UNACCENT(LOWER(users.name)) LIKE UNACCENT(?)', [$term]);
                   });
             });
         }
 
-        return $query->paginate($perPage);
+        return $query;
     }
 
     public function findById(int $id): ?UserDependent

+ 32 - 6
app/Services/UserService.php

@@ -24,16 +24,42 @@ class UserService
 
     public function getAllPaginated(array $filters = [], int $perPage = 10): \Illuminate\Pagination\LengthAwarePaginator
     {
-        $query = User::with(['position', 'sector'])->withMin('accessLogs', 'accessed_at')->orderBy('name', 'asc');
-
-        if (!empty($filters['type'])) {
-            $query->where('type', $filters['type']);
-        }
+        $query = $this->baseQuery($filters)
+            ->with(['position', 'sector'])
+            ->withMin('accessLogs', 'accessed_at')
+            ->orderBy('name', 'asc');
 
         if (!empty($filters['status'])) {
             $query->where('status', $filters['status']);
         }
 
+        return $query->paginate($perPage);
+    }
+
+    /**
+     * Status existentes no conjunto filtrado, desconsiderando o próprio filtro de status.
+     *
+     * @return array<int, string>
+     */
+    public function getStatusOptions(array $filters = []): array
+    {
+        return $this->baseQuery($filters)
+            ->toBase()
+            ->distinct()
+            ->pluck('status')
+            ->filter()
+            ->values()
+            ->all();
+    }
+
+    private function baseQuery(array $filters): \Illuminate\Database\Eloquent\Builder
+    {
+        $query = User::query();
+
+        if (!empty($filters['type'])) {
+            $query->where('type', $filters['type']);
+        }
+
         if (!empty($filters['position_id'])) {
             $query->where('position_id', $filters['position_id']);
         }
@@ -52,7 +78,7 @@ class UserService
             });
         }
 
-        return $query->paginate($perPage);
+        return $query;
     }
 
     public function findById(int $id): ?User

+ 22 - 0
database/migrations/2026_08_10_000003_add_user_id_id_index_to_users_access_logs_table.php

@@ -0,0 +1,22 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('users_access_logs', function (Blueprint $table) {
+            $table->index(['user_id', 'id'], 'users_access_logs_user_id_id_index');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('users_access_logs', function (Blueprint $table) {
+            $table->dropIndex('users_access_logs_user_id_id_index');
+        });
+    }
+};