Просмотр исходного кода

Merge branch 'feature/GC-GAB-cadastro-colaboradores' of Softpar/sfp_api_laravel_ginastica_cerebro into development

Gabriel Alves 1 месяц назад
Родитель
Сommit
394ccfb107

+ 9 - 0
app/Http/Controllers/UserController.php

@@ -28,6 +28,15 @@ public function index(): JsonResponse
         );
     }
 
+    public function indexByUnit(): JsonResponse
+    {
+        $items = $this->service->getAllByUnit();
+
+        return $this->successResponse(
+            payload: UserResource::collection($items),
+        );
+    }
+
     public function store(UserRequest $request): JsonResponse
     {
         $item = $this->service->create($request->validated());

+ 52 - 0
app/Http/Controllers/UserTypeController.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\UserTypeService;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class UserTypeController extends Controller
+{
+    public function __construct(protected UserTypeService $service) {}
+
+    public function index(): JsonResponse
+    {
+        $items = $this->service->getAll();
+
+        return $this->successResponse(
+            payload: $items->map(fn($t) => [
+                'id'        => $t->id,
+                'slug'      => $t->slug,
+                'label'     => $t->label,
+                'is_system' => $t->is_system,
+            ])->values(),
+        );
+    }
+
+    public function store(Request $request): JsonResponse
+    {
+        $data = $request->validate([
+            'label' => 'required|string|max:100',
+        ]);
+
+        $item = $this->service->create($data);
+
+        return $this->successResponse(
+            payload: ['id' => $item->id, 'slug' => $item->slug, 'label' => $item->label, 'is_system' => $item->is_system],
+            message: __('messages.created'),
+            code:    201,
+        );
+    }
+
+    public function destroy(int $id): JsonResponse
+    {
+        $deleted = $this->service->delete($id);
+
+        if (!$deleted) {
+            return $this->errorResponse(message: 'Tipo de usuário não encontrado ou não pode ser removido.', code: 422);
+        }
+
+        return $this->successResponse(message: __('messages.deleted'), code: 204);
+    }
+}

+ 3 - 2
app/Http/Requests/UserRequest.php

@@ -17,9 +17,10 @@ public function rules(): array
             'avatar'    => 'sometimes|nullable|image|max:2048',
             'name'      => 'sometimes|string|nullable|max:255',
             'cpf'       => 'sometimes|nullable|string|max:14',
+            'phone'     => 'sometimes|nullable|string|max:20',
             'email'     => 'sometimes|email',
             'password'  => 'sometimes|string|nullable|min:8',
-            'user_type' => ['sometimes', Rule::enum(UserTypeEnum::class)],
+            'user_type' => 'sometimes|nullable|string|exists:user_types,slug',
             'language'  => ['sometimes', Rule::enum(LanguageEnum::class)],
             'state_id'  => 'sometimes|nullable|integer|exists:states,id',
             'unit_id'   => 'sometimes|nullable|integer|exists:units,id',
@@ -29,7 +30,7 @@ public function rules(): array
             $rules['name']      = 'required|string|max:255';
             $rules['email']     = 'required|email|unique:users,email';
             $rules['password']  = 'required|string|min:8';
-            $rules['user_type'] = ['required', Rule::enum(UserTypeEnum::class)];
+            $rules['user_type'] = 'required|string|exists:user_types,slug';
 
             if (!$this->has('language')) {
                 $this->merge(['language' => LanguageEnum::PORTUGUESE->value]);

+ 5 - 3
app/Http/Resources/UserResource.php

@@ -16,9 +16,11 @@ public function toArray(Request $request): array
             'id'            => $this->id,
             'name'          => $this->name,
             'cpf'           => $this->cpf,
+            'phone'         => $this->phone,
             'email'         => $this->email,
             'language'      => $this->language,
-            'user_type'     => $this->user_type,
+            'user_type'       => $this->user_type,
+            'user_type_label' => $this->whenLoaded('userType', fn() => $this->userType?->label),
             'status'        => $this->status,
             'state_id'      => $this->state_id,
             'unit_id'       => $this->whenLoaded('units', fn() => $this->units->first()?->id),
@@ -28,8 +30,8 @@ public function toArray(Request $request): array
             'last_login_at' => $this->last_login_at
                 ? Carbon::parse($this->last_login_at)->format('Y-m-d H:i:s')
                 : 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'),
+            'created_at'    => Carbon::parse($this->created_at)->format('Y-m-d'),
+            'updated_at'    => Carbon::parse($this->updated_at)->format('Y-m-d'),
 
             'state' => $this->whenLoaded('state', fn() => [
                 'id'   => $this->state->id,

+ 6 - 7
app/Http/Resources/UserTypeResource.php

@@ -1,9 +1,8 @@
 <?php
 
-
 namespace App\Http\Resources;
 
-use App\Enums\UserTypeEnum;
+use App\Models\UserType;
 use Illuminate\Http\Request;
 use Illuminate\Http\Resources\Json\JsonResource;
 
@@ -11,13 +10,13 @@ class UserTypeResource extends JsonResource
 {
     public function toArray(Request $request): array
     {
-        $allowedTypes = [UserTypeEnum::ADMIN, UserTypeEnum::ADMIN_FRANCHISEE];
+        $types = UserType::orderBy('label')->get();
 
-        $return = [];
-        foreach ($allowedTypes as $type) {
-            $return[$type->value] = $type->label();
+        $result = [];
+        foreach ($types as $type) {
+            $result[$type->slug] = $type->label;
         }
 
-        return $return;
+        return $result;
     }
 }

+ 7 - 2
app/Models/User.php

@@ -80,14 +80,19 @@ protected function casts(): array
             "email_verified_at" => "datetime",
             "last_login_at"     => "datetime",
             "password"          => "hashed",
-            "user_type"         => UserTypeEnum::class,
+
             "language"          => LanguageEnum::class,
         ];
     }
 
     public function isAdmin(): bool
     {
-        return $this->user_type === UserTypeEnum::ADMIN;
+        return $this->user_type === 'ADMIN';
+    }
+
+    public function userType(): \Illuminate\Database\Eloquent\Relations\BelongsTo
+    {
+        return $this->belongsTo(\App\Models\UserType::class, 'user_type', 'slug');
     }
 
     public function state(): \Illuminate\Database\Eloquent\Relations\BelongsTo

+ 16 - 0
app/Models/UserType.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+
+class UserType extends Model
+{
+    protected $guarded = ['id'];
+
+    public function users(): HasMany
+    {
+        return $this->hasMany(User::class, 'user_type', 'slug');
+    }
+}

+ 24 - 9
app/Services/UserService.php

@@ -2,8 +2,6 @@
 
 namespace App\Services;
 
-use App\Enums\UserTypeEnum;
-use App\Models\Unit;
 use App\Models\UnitUser;
 use App\Models\User;
 use Illuminate\Database\Eloquent\Collection;
@@ -20,17 +18,31 @@ public function authUser(): ?User
 
     public function getAll(): Collection
     {
-        return User::with(['state', 'units'])->orderBy('name')->get();
+        return User::with(['state', 'units', 'userType'])->orderBy('name')->get();
+    }
+
+    public function getAllByUnit(): Collection
+    {
+        $unitId = Auth::user()->units->first()?->id;
+
+        if (!$unitId) {
+            return User::with(['state', 'units', 'userType'])->whereNull('id')->get();
+        }
+
+        return User::with(['state', 'units', 'userType'])
+            ->whereHas('units', fn($q) => $q->where('units.id', $unitId))
+            ->orderBy('name')
+            ->get();
     }
 
     public function findById(int $id): ?User
     {
-        return User::with(['state', 'units'])->find($id);
+        return User::with(['state', 'units', 'userType'])->find($id);
     }
 
     public function create(array $data): User
     {
-        $unitId = $data['unit_id'] ?? null;
+        $unitId = $data['unit_id'] ?? Auth::user()->units->first()?->id;
         unset($data['unit_id']);
 
         $data = $this->handleAvatar($data);
@@ -54,13 +66,16 @@ public function update(int $id, array $data): ?User
             return null;
         }
 
-        $unitId = $data['unit_id'] ?? null;
+        $hasUnitId = array_key_exists('unit_id', $data);
+        $unitId    = $data['unit_id'] ?? null;
         unset($data['unit_id']);
 
         $data = $this->handleAvatar($data, $model->avatar_url);
         $model->update($data);
 
-        $model->units()->sync($unitId ? [$unitId] : []);
+        if ($hasUnitId) {
+            $model->units()->sync($unitId ? [$unitId] : []);
+        }
 
         return $model->fresh(['state', 'units']);
     }
@@ -80,9 +95,9 @@ public function delete(int $id): bool
         return $model->delete();
     }
 
-    public function getUserTypes(): array
+    public function getUserTypes(): \Illuminate\Database\Eloquent\Collection
     {
-        return UserTypeEnum::toArray();
+        return \App\Models\UserType::orderBy('label')->get();
     }
 
     private function handleAvatar(array $data, ?string $oldAvatarPath = null): array

+ 2 - 3
app/Services/UserTypePermissionService.php

@@ -2,7 +2,6 @@
 
 namespace App\Services;
 
-use App\Enums\UserTypeEnum;
 use Illuminate\Database\Eloquent\Collection;
 use App\Models\UserTypePermission;
 use Cache;
@@ -17,9 +16,9 @@ public function allGuestPermissions(): ?Collection
     }
 
     public function allPermissionsByUserType(
-        UserTypeEnum $userType,
+        string $userType,
     ): ?Collection {
-        return Cache::remember("permissions_role_{$userType->value}", 60 * 60 * 24, function () use ($userType) {
+        return Cache::remember("permissions_role_{$userType}", 60 * 60 * 24, function () use ($userType) {
             return UserTypePermission::with('permission')
                 ->where('user_type', $userType)
                 ->get();

+ 37 - 0
app/Services/UserTypeService.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\UserType;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Str;
+
+class UserTypeService
+{
+    public function getAll(): Collection
+    {
+        return UserType::orderBy('label')->get();
+    }
+
+    public function create(array $data): UserType
+    {
+        $slug = strtoupper(Str::slug($data['label'], '_'));
+
+        return UserType::create([
+            'slug'      => $slug,
+            'label'     => $data['label'],
+            'is_system' => false,
+        ]);
+    }
+
+    public function delete(int $id): bool
+    {
+        $model = UserType::find($id);
+
+        if (!$model || $model->is_system) {
+            return false;
+        }
+
+        return $model->delete();
+    }
+}

+ 22 - 0
database/migrations/2026_05_07_000001_add_phone_to_users_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', function (Blueprint $table) {
+            $table->string('phone', 20)->nullable()->after('cpf');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('phone');
+        });
+    }
+};

+ 24 - 0
database/migrations/2026_05_07_000003_create_user_types_table.php

@@ -0,0 +1,24 @@
+<?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::create('user_types', function (Blueprint $table) {
+            $table->id();
+            $table->string('slug')->unique();
+            $table->string('label');
+            $table->boolean('is_system')->default(false);
+            $table->timestamps();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('user_types');
+    }
+};

+ 1 - 0
database/seeders/DatabaseSeeder.php

@@ -9,6 +9,7 @@ class DatabaseSeeder extends Seeder
     public function run(): void
     {
         $this->call([
+            UserTypeSeeder::class,
             UserSeeder::class,
             PermissionSeeder::class,
             UserTypePermissionSeeder::class,

+ 22 - 0
database/seeders/UserTypeSeeder.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\UserType;
+use Illuminate\Database\Seeder;
+
+class UserTypeSeeder extends Seeder
+{
+    public function run(): void
+    {
+        $types = [
+            ['slug' => 'ADMIN',            'label' => 'Administrador (Franqueadora)', 'is_system' => true],
+            ['slug' => 'ADMIN_FRANCHISEE', 'label' => 'Administrador (Franqueada)',   'is_system' => true],
+            ['slug' => 'FINANCIAL',        'label' => 'Financeiro',                   'is_system' => true],
+        ];
+
+        foreach ($types as $type) {
+            UserType::firstOrCreate(['slug' => $type['slug']], $type);
+        }
+    }
+}

+ 7 - 15
routes/authRoutes/user.php

@@ -8,21 +8,13 @@
 
     Route::put('/me', 'updateMe');
 
-    Route::get('/', 'index')
-        ->middleware('permission:config.user,view');
+    Route::get('/unit', 'indexByUnit');
+    Route::get('/all/types', 'getUserTypes');
 
-    Route::post('/', 'store')
-        ->middleware('permission:config.user,add');
+    Route::get('/', 'index');
+    Route::post('/', 'store');
 
-    Route::get('/{id}', 'show')
-        ->middleware('permission:config.user,view');
-
-    Route::put('/{id}', 'update')
-        ->middleware('permission:config.user,edit');
-
-    Route::delete('/{id}', 'destroy')
-        ->middleware('permission:config.user,delete');
-
-    Route::get('/all/types', 'getUserTypes')
-        ->middleware('permission:config.user,view');
+    Route::get('/{id}', 'show');
+    Route::put('/{id}', 'update');
+    Route::delete('/{id}', 'destroy');
 });

+ 10 - 0
routes/authRoutes/user_type.php

@@ -0,0 +1,10 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\UserTypeController;
+
+Route::controller(UserTypeController::class)->prefix('user-type')->group(function () {
+    Route::get('/', 'index');
+    Route::post('/', 'store');
+    Route::delete('/{id}', 'destroy');
+});