Browse Source

feat: add permissions relacionadas a inhabitant_classifications e ajusta autorizacoes nas services

Gustavo Mantovani 1 month ago
parent
commit
68172797db

+ 23 - 3
app/Http/Requests/InhabitantClassificationRequest.php

@@ -3,6 +3,7 @@
 namespace App\Http\Requests;
 
 use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Validation\Rule;
 
 class InhabitantClassificationRequest extends FormRequest
 {
@@ -10,10 +11,29 @@ public function rules(): array
     {
         $id = $this->route('id');
 
-        return [
-            'description' => ['required', 'string', 'max:150'],
-            'acronym'     => ['required', 'string', 'max:2', "unique:inhabitant_classifications,acronym,{$id}"],
+        $rules = [
+            'description' => ['sometimes', 'string', 'max:150'],
+
+            'acronym' => [
+                'sometimes',
+                'string',
+                'max:2',
+                Rule::unique('inhabitant_classifications', 'acronym')->ignore($id),
+            ],
         ];
+
+        if ($this->isMethod('post')) {
+            $rules['description'][0] = 'required|string|max:150';
+
+            $rules['acronym'][0] = [
+                'required',
+                'string',
+                'max:2',
+                Rule::unique('inhabitant_classifications', 'acronym')->ignore($id),
+            ];
+        }
+
+        return $rules;
     }
 
     public function messages(): array

+ 8 - 4
app/Services/InhabitantClassificationService.php

@@ -11,12 +11,12 @@ class InhabitantClassificationService
 {
     public function getAll(): Collection
     {
-        return InhabitantClassification::orderBy('description')->get();
+        return InhabitantClassification::orderBy('id')->get();
     }
 
     public function getSelectList(): Collection
     {
-        return InhabitantClassification::orderBy('description')
+        return InhabitantClassification::orderBy('id')
             ->get(['id', 'description', 'acronym']);
     }
 
@@ -62,6 +62,8 @@ public function delete(int $id): bool
         return $model->delete();
     }
 
+    //
+
     private function propagateToAllUnits(InhabitantClassification $parent): void
     {
         $existingUnitIds = UnitInhabitantClassification::where('acronym', $parent->acronym)
@@ -79,7 +81,8 @@ private function propagateToAllUnits(InhabitantClassification $parent): void
 
     private function propagateUpdateToUnits(InhabitantClassification $parent, string $oldDescription, string $oldAcronym): void
     {
-        // Update copies that were in sync with the old parent values
+        // propaga a atualizacao para as classificacoes de unidades que tenham a mesma descricao e sigla antigas
+
         UnitInhabitantClassification::where('acronym', $oldAcronym)
             ->where('description', $oldDescription)
             ->update([
@@ -87,11 +90,12 @@ private function propagateUpdateToUnits(InhabitantClassification $parent, string
                 'acronym'     => $parent->acronym,
             ]);
 
-        // Create copies for units that have no record for either the old or new acronym
         $coveredUnitIds = UnitInhabitantClassification::whereIn('acronym', array_unique([$parent->acronym, $oldAcronym]))
             ->pluck('unit_id')
             ->unique();
 
+        // garante que todas as unidades tenham a classificacao atualizada, criando para as que ainda nao tem
+
         Unit::whereNotIn('id', $coveredUnitIds)
             ->each(function (Unit $unit) use ($parent) {
                 UnitInhabitantClassification::create([

+ 27 - 0
app/Services/UnitInhabitantClassificationService.php

@@ -3,7 +3,10 @@
 namespace App\Services;
 
 use App\Models\UnitInhabitantClassification;
+use App\Models\User;
+use Illuminate\Auth\Access\AuthorizationException;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Auth;
 
 class UnitInhabitantClassificationService
 {
@@ -25,6 +28,8 @@ public function update(int $id, array $data): ?UnitInhabitantClassification
             return null;
         }
 
+        $this->authorizeUnitAccess($model->unit_id);
+
         $model->update($data);
         return $model->fresh();
     }
@@ -37,6 +42,8 @@ public function delete(int $id): bool
             return false;
         }
 
+        $this->authorizeUnitAccess($model->unit_id);
+
         return $model->delete();
     }
 
@@ -44,6 +51,8 @@ public function delete(int $id): bool
 
     public function getByUnit(int $unitId): Collection
     {
+        $this->authorizeUnitAccess($unitId);
+
         return UnitInhabitantClassification::where('unit_id', $unitId)
             ->orderBy('description')
             ->get();
@@ -55,4 +64,22 @@ public function getSelectList(int $unitId): Collection
             ->orderBy('description')
             ->get(['id', 'description', 'acronym', 'unit_id']);
     }
+
+    //
+
+    private function authorizeUnitAccess(int $unitId): void
+    {
+        /** @var User $user */
+        $user = Auth::user();
+
+        if ($user->isAdmin()) {
+            return;
+        }
+
+        $hasUnit = $user->units()->where('units.id', $unitId)->exists();
+
+        if (!$hasUnit) {
+            throw new AuthorizationException('Acesso negado: você não tem permissão para esta unidade.');
+        }
+    }
 }

+ 66 - 53
database/seeders/PermissionSeeder.php

@@ -3,8 +3,8 @@
 namespace Database\Seeders;
 
 use App\Models\Permission;
-use Illuminate\Database\Seeder;
 use App\Services\PermissionService;
+use Illuminate\Database\Seeder;
 
 class PermissionSeeder extends Seeder
 {
@@ -16,107 +16,119 @@ public function run(): void
     {
         $permissions = [
             [
-                "scope" => "dashboard",
+                "scope"       => "dashboard",
                 "description" => "Dashboard",
-                "bits" => Permission::ALL_PERMS,
-                "children" => [],
+                "bits"        => Permission::ALL_PERMS,
+                "children"    => [],
             ],
             [
-                "scope" => "franchisee",
+                "scope"       => "franchisee",
                 "description" => "Franchisee",
-                "bits" => Permission::MENU | Permission::VIEW,
-                "children" => [
+                "bits"        => Permission::MENU | Permission::VIEW,
+                "children"    => [
                     [
-                        "scope" => "unit",
+                        "scope"       => "unit",
                         "description" => "Unidades",
-                        "bits" => Permission::ALL_PERMS,
-                        "children" => [],
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                 ],
             ],
             [
-                "scope" => "class-package",
+                "scope"       => "class-package",
                 "description" => "Pacotes (Franqueadora)",
-                "bits" => Permission::ALL_PERMS,
-                "children" => [],
+                "bits"        => Permission::ALL_PERMS,
+                "children"    => [],
             ],
             [
-                "scope" => "class-package-unit",
+                "scope"       => "class-package-unit",
                 "description" => "Pacotes (Unidade)",
-                "bits" => Permission::ALL_PERMS,
-                "children" => [],
+                "bits"        => Permission::ALL_PERMS,
+                "children"    => [],
             ],
             [
-                "scope" => "tbr",
+                "scope"       => "tbr",
                 "description" => "TBR",
-                "bits" => Permission::ALL_PERMS,
-                "children" => [
+                "bits"        => Permission::ALL_PERMS,
+                "children"    => [
                     [
-                        "scope" => "royalties-base-bracket",
+                        "scope"       => "royalties-base-bracket",
                         "description" => "Faixas de Royalties Base",
-                        "bits" => Permission::ALL_PERMS,
-                        "children" => [],
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "fnm-base-bracket",
+                        "scope"       => "fnm-base-bracket",
                         "description" => "Faixas de FNM Base",
-                        "bits" => Permission::ALL_PERMS,
-                        "children" => [],
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "maintenance-base-bracket",
+                        "scope"       => "maintenance-base-bracket",
                         "description" => "Faixas de Manutenção Base",
-                        "bits" => Permission::ALL_PERMS,
-                        "children" => [],
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "franchisee-tbr",
+                        "scope"       => "franchisee-tbr",
                         "description" => "TBR por Franqueado",
-                        "bits" => Permission::ALL_PERMS,
-                        "children" => [],
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "tbr-calculation",
+                        "scope"       => "tbr-calculation",
                         "description" => "Cálculo de TBR",
-                        "bits" => Permission::VIEW | Permission::ADD,
-                        "children" => [],
+                        "bits"        => Permission::VIEW | Permission::ADD,
+                        "children"    => [],
+                    ],
+                    [
+                        "scope"       => "inhabitant-classification",
+                        "description" => "Classificações de Habitantes",
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
+                    ],
+                    [
+                        "scope"       => "unit-inhabitant-classification",
+                        "description" => "Classificações de Habitantes por Unidade",
+                        "bits"        => Permission::ALL_PERMS,
+                        "children"    => [],
                     ],
                 ],
             ],
             [
-                "scope" => "config",
+                "scope"       => "config",
                 "description" => "Configurações",
-                "bits" => Permission::MENU | Permission::VIEW,
-                "children" => [
+                "bits"        => Permission::MENU | Permission::VIEW,
+                "children"    => [
                     [
-                        "scope" => "config.user",
+                        "scope"       => "config.user",
                         "description" => "Configurações de Usuários",
-                        "bits" => Permission::CRUD,
-                        "children" => [],
+                        "bits"        => Permission::CRUD,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "config.permission",
+                        "scope"       => "config.permission",
                         "description" => "Configurações de Permissões",
-                        "bits" => Permission::CRUD,
-                        "children" => [],
+                        "bits"        => Permission::CRUD,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "config.city",
+                        "scope"       => "config.city",
                         "description" => "Configurações de Cidades",
-                        "bits" => Permission::CRUD,
-                        "children" => [],
+                        "bits"        => Permission::CRUD,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "config.country",
+                        "scope"       => "config.country",
                         "description" => "Configurações de Países",
-                        "bits" => Permission::CRUD,
-                        "children" => [],
+                        "bits"        => Permission::CRUD,
+                        "children"    => [],
                     ],
                     [
-                        "scope" => "config.state",
+                        "scope"       => "config.state",
                         "description" => "Configurações de Estados",
-                        "bits" => Permission::CRUD,
-                        "children" => [],
+                        "bits"        => Permission::CRUD,
+                        "children"    => [],
                     ],
                 ],
             ],
@@ -137,6 +149,7 @@ private function createPermissionsAndChildren(
     ): void {
         foreach ($permissions as $permissionData) {
             $children = $permissionData["children"];
+
             unset($permissionData["children"]);
 
             $permissionNode = Permission::updateOrCreate(
@@ -151,7 +164,7 @@ private function createPermissionsAndChildren(
             if (!empty($children)) {
                 $this->createPermissionsAndChildren(
                     permissions: $children,
-                    parent: $permissionNode,
+                    parent:      $permissionNode,
                 );
             }
         }

+ 16 - 12
database/seeders/UserTypePermissionSeeder.php

@@ -2,18 +2,20 @@
 
 namespace Database\Seeders;
 
+use App\Enums\UserTypeEnum;
 use App\Models\Permission;
 use App\Models\UserTypePermission;
 use Illuminate\Database\Seeder;
-use App\Enums\UserTypeEnum;
 
 class UserTypePermissionSeeder extends Seeder
 {
     public function run(): void
     {
         $allPermissions = Permission::all()->keyBy('scope');
+
         foreach (UserTypeEnum::cases() as $userType) {
             $dataToSync = [];
+
             switch ($userType) {
                 case UserTypeEnum::ADMIN:
                     foreach ($allPermissions as $scope => $perm) {
@@ -25,17 +27,19 @@ public function run(): void
                     break;
                 case UserTypeEnum::USER:
                     $dataToSync = [
-                        ['scope' => 'dashboard',               'bits' => Permission::VIEW],
-                        ['scope' => 'config.user',             'bits' => Permission::VIEW | Permission::EDIT],
-                        ['scope' => 'config.city',             'bits' => Permission::VIEW],
-                        ['scope' => 'config.country',          'bits' => Permission::VIEW],
-                        ['scope' => 'config.state',            'bits' => Permission::VIEW],
-                        ['scope' => 'tbr',                     'bits' => Permission::VIEW],
-                        ['scope' => 'royalties-base-bracket',  'bits' => Permission::VIEW],
-                        ['scope' => 'fnm-base-bracket',        'bits' => Permission::VIEW],
-                        ['scope' => 'maintenance-base-bracket','bits' => Permission::VIEW],
-                        ['scope' => 'franchisee-tbr',          'bits' => Permission::VIEW],
-                        ['scope' => 'tbr-calculation',         'bits' => Permission::VIEW],
+                        ['scope' => 'dashboard',                        'bits' => Permission::VIEW],
+                        ['scope' => 'config.user',                      'bits' => Permission::VIEW | Permission::EDIT],
+                        ['scope' => 'config.city',                      'bits' => Permission::VIEW],
+                        ['scope' => 'config.country',                   'bits' => Permission::VIEW],
+                        ['scope' => 'config.state',                     'bits' => Permission::VIEW],
+                        ['scope' => 'tbr',                              'bits' => Permission::VIEW],
+                        ['scope' => 'royalties-base-bracket',           'bits' => Permission::VIEW],
+                        ['scope' => 'fnm-base-bracket',                 'bits' => Permission::VIEW],
+                        ['scope' => 'maintenance-base-bracket',         'bits' => Permission::VIEW],
+                        ['scope' => 'franchisee-tbr',                   'bits' => Permission::VIEW],
+                        ['scope' => 'tbr-calculation',                  'bits' => Permission::VIEW],
+                        ['scope' => 'inhabitant-classification',        'bits' => Permission::VIEW],
+                        ['scope' => 'unit-inhabitant-classification',   'bits' => Permission::ALL_PERMS],
                     ];
                     break;
                 case UserTypeEnum::GUEST: