Przeglądaj źródła

feat: :sparkles: feat (dependentes do associado) adicionada aprovacao de dependentes + correcao no status

foi adicionada a aprovacao de dependentes cadastrados pelos associados. O adm precisa aprovar na dashboard. Alem disso, foi corrigido para que o associado nao consiga preencher campo status do dependente

fase:dev | origin:escopo
Gustavo Zanatta 1 dzień temu
rodzic
commit
084a5be212

+ 33 - 0
app/Http/Controllers/UserDependentController.php

@@ -6,6 +6,7 @@ use App\Http\Requests\UserDependentRequest;
 use App\Http\Resources\UserDependentResource;
 use App\Services\UserDependentService;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 
 class UserDependentController extends Controller
 {
@@ -17,6 +18,20 @@ class UserDependentController extends Controller
         return $this->successResponse(payload: UserDependentResource::collection($items));
     }
 
+    public function indexPaginated(Request $request): JsonResponse
+    {
+        $filters = $request->only(['status', 'search']);
+        $perPage = min((int) $request->get('per_page', 10), 100);
+        $paginator = $this->service->getAllPaginated($filters, $perPage);
+
+        return $this->successResponse(payload: [
+            'data'  => UserDependentResource::collection($paginator->items()),
+            'total' => $paginator->total(),
+            'from'  => $paginator->firstItem() ?? 0,
+            'to'    => $paginator->lastItem() ?? 0,
+        ]);
+    }
+
     public function store(UserDependentRequest $request): JsonResponse
     {
         $item = $this->service->create($request->validated());
@@ -47,4 +62,22 @@ class UserDependentController extends Controller
         $this->service->delete($id);
         return $this->successResponse(message: __('messages.deleted'), code: 204);
     }
+
+    public function approve(int $id): JsonResponse
+    {
+        $item = $this->service->approve($id);
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        return $this->successResponse(payload: new UserDependentResource($item), message: __('messages.updated'));
+    }
+
+    public function refuse(int $id): JsonResponse
+    {
+        $item = $this->service->refuse($id);
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        return $this->successResponse(payload: new UserDependentResource($item), message: __('messages.updated'));
+    }
 }

+ 10 - 0
app/Http/Resources/UserDependentResource.php

@@ -16,6 +16,16 @@ class UserDependentResource extends JsonResource
             'name'                => $this->name,
             'kinship'             => $this->kinship,
             'status'              => $this->status,
+            'responsible_user'    => $this->whenLoaded('responsibleUser', fn() => [
+                'id'       => $this->responsibleUser->id,
+                'name'     => $this->responsibleUser->name,
+                'position' => $this->responsibleUser->relationLoaded('position')
+                    ? $this->responsibleUser->position?->name
+                    : null,
+                'sector'   => $this->responsibleUser->relationLoaded('sector')
+                    ? $this->responsibleUser->sector?->name
+                    : null,
+            ]),
             'created_at'          => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
             'updated_at'          => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
         ];

+ 3 - 0
app/Services/DashboardService.php

@@ -2,11 +2,13 @@
 
 namespace App\Services;
 
+use App\Enums\UserDependentStatusEnum;
 use App\Enums\UserStatusEnum;
 use App\Enums\UserTypeEnum;
 use App\Models\PartnerAgreement;
 use App\Models\User;
 use App\Models\UserAccessLog;
+use App\Models\UserDependent;
 use App\Models\Appointment;
 use Illuminate\Support\Facades\Auth;
 
@@ -23,6 +25,7 @@ class DashboardService
         ->count(),
       'novos_mes'           => PartnerAgreement::whereMonth('created_at', now()->month)->whereYear('created_at', now()->year)->count(),
       'associados_pendentes' => User::where('type', UserTypeEnum::ASSOCIADO)->where('status', UserStatusEnum::PENDING)->count(),
+      'dependentes_pendentes' => UserDependent::where('status', UserDependentStatusEnum::PENDING)->count(),
       'ultimos_acessos'     => UserAccessLog::distinct('user_id')->count('user_id'),
       'associados_com_acesso_app' => UserAccessLog::whereHas('user', fn ($q) => $q->where('type', UserTypeEnum::ASSOCIADO))
         ->distinct('user_id')

+ 50 - 0
app/Services/UserDependentService.php

@@ -2,8 +2,10 @@
 
 namespace App\Services;
 
+use App\Enums\UserDependentStatusEnum;
 use App\Models\UserDependent;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Pagination\LengthAwarePaginator;
 
 class UserDependentService
 {
@@ -14,6 +16,28 @@ class UserDependentService
             ->get();
     }
 
+    public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
+    {
+        $query = UserDependent::with(['responsibleUser.position', 'responsibleUser.sector'])
+            ->orderBy('created_at', 'asc');
+
+        if (!empty($filters['status'])) {
+            $query->where('status', $filters['status']);
+        }
+
+        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]);
+                  });
+            });
+        }
+
+        return $query->paginate($perPage);
+    }
+
     public function findById(int $id): ?UserDependent
     {
         return UserDependent::find($id);
@@ -21,9 +45,35 @@ class UserDependentService
 
     public function create(array $data): UserDependent
     {
+        $data['status'] = UserDependentStatusEnum::PENDING->value;
+
         return UserDependent::create($data);
     }
 
+    public function approve(int $id): ?UserDependent
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        $model->update(['status' => UserDependentStatusEnum::APPROVED]);
+        return $model->fresh();
+    }
+
+    public function refuse(int $id): ?UserDependent
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        $model->update(['status' => UserDependentStatusEnum::REFUSED]);
+        return $model->fresh();
+    }
+
     public function update(int $id, array $data): ?UserDependent
     {
         $model = $this->findById($id);

+ 6 - 0
database/seeders/PermissionSeeder.php

@@ -173,6 +173,12 @@ class PermissionSeeder extends Seeder
                         "bits" => Permission::CRUD,
                         "children" => [],
                     ],
+                    [
+                        "scope" => "associado.dependente_aprovacao",
+                        "description" => "Aprovação de Dependentes (Admin)",
+                        "bits" => Permission::VIEW | Permission::EDIT,
+                        "children" => [],
+                    ],
                     [
                        "scope" => "associado.loja",
                         "description" => "Loja do Associado",

+ 6 - 0
routes/authRoutes/user_dependent.php

@@ -6,11 +6,17 @@ use Illuminate\Support\Facades\Route;
 Route::controller(UserDependentController::class)->prefix('user-dependent')->group(function () {
     Route::get('/user/{userId}', 'indexByUser')->middleware('permission:associado.dependente,view');
 
+    Route::get('/paginated', 'indexPaginated')->middleware('permission:associado.dependente_aprovacao,view');
+
     Route::post('/', 'store')->middleware('permission:associado.dependente,add');
 
     Route::get('/{id}', 'show')->middleware('permission:associado.dependente,view');
 
     Route::put('/{id}', 'update')->middleware('permission:associado.dependente,edit');
 
+    Route::put('/{id}/approve', 'approve')->middleware('permission:associado.dependente_aprovacao,edit');
+
+    Route::put('/{id}/refuse', 'refuse')->middleware('permission:associado.dependente_aprovacao,edit');
+
     Route::delete('/{id}', 'destroy')->middleware('permission:associado.dependente,delete');
 });