Sfoglia il codice sorgente

feat(packages): pivot class_package_units para visibilidade por unidade

- Migration: tabela class_package_units (class_package_id, unit_id, visible)
- ClassPackage model: relacionamento units() belongsToMany com pivot visible
- ClassPackageService: sincroniza unit_visibilities em create/update
- ClassPackageResource: expõe unit_visibilities no show
- ClassPackageRequest: validação dos campos e unit_visibilities

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ebagabee 1 mese fa
parent
commit
86a5df9017

+ 12 - 20
app/Http/Requests/ClassPackageRequest.php

@@ -8,27 +8,19 @@ class ClassPackageRequest extends FormRequest
 {
     public function rules(): array
     {
-        $rules = [
-            // Add your validation rules here
-            //'field' => 'sometimes|string|max:255',
-        ];
+        $required = $this->isMethod('POST') ? 'required' : 'sometimes';
 
-        // Different rules for creation
-        //if ($this->isMethod('POST')) {
-            // Make fields required if needed
-            // $rules['field'] = 'required|string|max:255';
-        //}
+        return [
+            'name'                    => "$required|string|max:255",
+            'quantity_classes'        => "$required|integer|min:1",
+            'contract_value'          => "$required|numeric|min:0",
+            'contract_material_value' => "$required|numeric|min:0",
+            'contract_register_value' => "$required|numeric|min:0",
+            'contrat_discount_value'  => 'nullable|numeric|min:0',
 
-        return $rules;
+            'unit_visibilities'              => 'nullable|array',
+            'unit_visibilities.*.unit_id'   => 'required|integer|exists:units,id',
+            'unit_visibilities.*.visible'   => 'required|boolean',
+        ];
     }
-
-    /**
-    * Add custom messages when needed
-    * public function messages(): array
-    * {
-    *   return [
-    *        'field.required' => __('message.algo'),
-    *    ];
-    * }
-    */
 }

+ 15 - 17
app/Http/Resources/ClassPackageResource.php

@@ -10,27 +10,25 @@
 
 class ClassPackageResource extends JsonResource
 {
-    /**
-     * Transform the resource into an array.
-     *
-     * @return array<string, mixed>
-     */
     public function toArray(Request $request): array
     {
         return [
-            'id' => $this->id,
-            'name' => $this->name,
-            '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'),
-            // Add your fields here
-
-            // Conditional fields
-            // $this->mergeWhen($request->user()?->isAdmin(), [
-            //     'internal_notes' => $this->internal_notes,
-            // ]),
+            'id'                      => $this->id,
+            'name'                    => $this->name,
+            'quantity_classes'        => $this->quantity_classes,
+            'contract_value'          => $this->contract_value,
+            'contract_material_value' => $this->contract_material_value,
+            'contract_register_value' => $this->contract_register_value,
+            'contrat_discount_value'  => $this->contrat_discount_value,
+            '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'),
 
-            // Relationships
-            // 'user' => new UserResource($this->whenLoaded('user')),
+            'unit_visibilities' => $this->whenLoaded('units', fn() =>
+                $this->units->map(fn($unit) => [
+                    'unit_id' => $unit->id,
+                    'visible' => (bool) $unit->pivot->visible,
+                ])
+            ),
         ];
     }
 

+ 22 - 15
app/Models/ClassPackage.php

@@ -4,34 +4,41 @@
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
 
 /**
  * @property int $id
+ * @property string $name
+ * @property int $quantity_classes
+ * @property float $contract_value
+ * @property float $contract_material_value
+ * @property float $contract_register_value
+ * @property float|null $contrat_discount_value
  * @property \Carbon\Carbon $created_at
  * @property \Carbon\Carbon $updated_at
  */
 class ClassPackage extends Model
 {
-    use HasFactory;
+    use HasFactory, SoftDeletes;
 
     protected $table = 'class_packages';
 
-    protected $guarded = [
-        'id', // Add more fields that shouldn't be edited here
-    ];
+    protected $guarded = ['id'];
 
     protected $casts = [
-        'created_at' => 'datetime',
-        'updated_at' => 'datetime',
-        // Add your casts here (e.g., 'is_active' => 'boolean')
+        'quantity_classes'        => 'integer',
+        'contract_value'          => 'float',
+        'contract_material_value' => 'float',
+        'contract_register_value' => 'float',
+        'contrat_discount_value'  => 'float',
+        'created_at'              => 'datetime',
+        'updated_at'              => 'datetime',
     ];
 
-    // Relationships
-
-    // Business Logic Methods
-
-    // Custom Finders
-
-    // Query Scopes
-
+    public function units()
+    {
+        return $this->belongsToMany(Unit::class, 'class_package_units')
+            ->withPivot('visible')
+            ->withTimestamps();
+    }
 }

+ 49 - 15
app/Services/ClassPackageService.php

@@ -3,48 +3,82 @@
 namespace App\Services;
 
 use App\Models\ClassPackage;
+use App\Models\Unit;
 use Illuminate\Database\Eloquent\Collection;
 
 class ClassPackageService
 {
     public function getAll(): Collection
     {
-        return ClassPackage::orderBy('created_at', 'desc')
-            ->get();
+        return ClassPackage::orderBy('created_at', 'desc')->get();
     }
 
     public function findById(int $id): ?ClassPackage
     {
-        return ClassPackage::find($id);
+        return ClassPackage::with('units')->find($id);
     }
 
     public function create(array $data): ClassPackage
     {
-        return ClassPackage::create($data);
+        $unitVisibilities = $data['unit_visibilities'] ?? [];
+        unset($data['unit_visibilities']);
+
+        $package = ClassPackage::create($data);
+
+        $this->syncUnitVisibilities($package, $unitVisibilities);
+
+        return $package->load('units');
     }
 
     public function update(int $id, array $data): ?ClassPackage
     {
-        $model = $this->findById($id);
+        $package = $this->findById($id);
+        if (!$package) return null;
+
+        $unitVisibilities = $data['unit_visibilities'] ?? null;
+        unset($data['unit_visibilities']);
 
-        if (!$model) {
-            return null;
+        $package->update($data);
+
+        if ($unitVisibilities !== null) {
+            $this->syncUnitVisibilities($package, $unitVisibilities);
         }
 
-        $model->update($data);
-        return $model->fresh();
+        return $package->fresh('units');
     }
 
     public function delete(int $id): bool
     {
-        $model = $this->findById($id);
+        $package = ClassPackage::find($id);
+        if (!$package) return false;
 
-        if (!$model) {
-            return false;
-        }
+        return $package->delete();
+    }
 
-        return $model->delete();
+    public function getAllUnitsWithVisibility(int $packageId): \Illuminate\Support\Collection
+    {
+        $allUnits = Unit::orderBy('fantasy_name')->get(['id', 'fantasy_name']);
+        $package = ClassPackage::with('units')->find($packageId);
+
+        $visibilityMap = $package
+            ? $package->units->keyBy('id')
+            : collect();
+
+        return $allUnits->map(fn($unit) => [
+            'id'           => $unit->id,
+            'fantasy_name' => $unit->fantasy_name,
+            'visible'      => $visibilityMap->has($unit->id)
+                ? (bool) $visibilityMap[$unit->id]->pivot->visible
+                : true,
+        ]);
     }
 
-    // Add custom business logic methods here
+    private function syncUnitVisibilities(ClassPackage $package, array $unitVisibilities): void
+    {
+        $syncData = [];
+        foreach ($unitVisibilities as $uv) {
+            $syncData[$uv['unit_id']] = ['visible' => $uv['visible']];
+        }
+        $package->units()->sync($syncData);
+    }
 }

+ 26 - 0
database/migrations/2026_05_04_000001_create_class_package_units_table.php

@@ -0,0 +1,26 @@
+<?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('class_package_units', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('class_package_id')->constrained('class_packages')->cascadeOnDelete();
+            $table->foreignId('unit_id')->constrained('units')->cascadeOnDelete();
+            $table->boolean('visible')->default(true);
+            $table->timestamps();
+
+            $table->unique(['class_package_id', 'unit_id']);
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('class_package_units');
+    }
+};