Procházet zdrojové kódy

feat: adiciona anexo em contrato e midias

ebagabee před 1 měsícem
rodič
revize
6623c0a54e

+ 3 - 2
app/Http/Controllers/MediaController.php

@@ -6,6 +6,7 @@
 use App\Http\Requests\MediaRequest;
 use App\Http\Resources\MediaResource;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 
 class MediaController extends Controller
 {
@@ -13,9 +14,9 @@ public function __construct(
         protected MediaService $service,
     ) {}
 
-    public function index(): JsonResponse
+    public function index(Request $request): JsonResponse
     {
-        $items = $this->service->getAll();
+        $items = $this->service->getAll($request->only(['origem', 'origem_id']));
         return $this->successResponse(payload: MediaResource::collection($items));
     }
 

+ 8 - 0
app/Http/Controllers/StudentContractController.php

@@ -6,6 +6,7 @@
 use App\Http\Requests\StudentContractRequest;
 use App\Http\Resources\StudentContractResource;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 
 class StudentContractController extends Controller
@@ -42,6 +43,13 @@ public function update(StudentContractRequest $request, int $id): JsonResponse
         return $this->successResponse(payload: new StudentContractResource($item), message: __('messages.updated'));
     }
 
+    public function attachFile(Request $request, int $id): JsonResponse
+    {
+        $request->validate(['file' => 'required|file|mimes:jpeg,png,gif,pdf,mp4,mov,avi|max:20480']);
+        $item = $this->service->attachFile($id, $request->file('file'));
+        return $this->successResponse(payload: new StudentContractResource($item), message: __('messages.updated'));
+    }
+
     public function destroy(int $id): JsonResponse
     {
         $this->service->delete($id);

+ 7 - 17
app/Http/Requests/MediaRequest.php

@@ -9,26 +9,16 @@ class MediaRequest extends FormRequest
     public function rules(): array
     {
         $rules = [
-            // Add your validation rules here
-            //'field' => 'sometimes|string|max:255',
+            'name'      => 'required|string|max:255',
+            'origem'    => 'required|string|max:255',
+            'origem_id' => 'required|integer',
+            'file'      => 'sometimes|file|mimes:jpeg,png,gif,pdf,mp4,mov,avi|max:20480',
         ];
 
-        // Different rules for creation
-        //if ($this->isMethod('POST')) {
-            // Make fields required if needed
-            // $rules['field'] = 'required|string|max:255';
-        //}
+        if ($this->isMethod('POST')) {
+            $rules['file'] = 'required|file|mimes:jpeg,png,gif,pdf,mp4,mov,avi|max:20480';
+        }
 
         return $rules;
     }
-
-    /**
-    * Add custom messages when needed
-    * public function messages(): array
-    * {
-    *   return [
-    *        'field.required' => __('message.algo'),
-    *    ];
-    * }
-    */
 }

+ 8 - 18
app/Http/Resources/MediaResource.php

@@ -6,31 +6,21 @@
 use Illuminate\Http\Request;
 use Illuminate\Http\Resources\Json\JsonResource;
 use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use Illuminate\Support\Facades\Storage;
 use App\Models\Media;
 
 class MediaResource 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,
-            // ]),
-
-            // Relationships
-            // 'user' => new UserResource($this->whenLoaded('user')),
+            'id'         => $this->id,
+            'name'       => $this->name,
+            'origem'     => $this->origem,
+            'origem_id'  => $this->origem_id,
+            'file_url'   => $this->url ? Storage::url($this->url) : null,
+            'file_type'  => $this->file_type,
+            'created_at' => Carbon::parse($this->created_at)->format('d/m/Y'),
         ];
     }
 

+ 3 - 0
app/Http/Resources/StudentContractResource.php

@@ -6,6 +6,7 @@
 use Illuminate\Http\Request;
 use Illuminate\Http\Resources\Json\JsonResource;
 use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use Illuminate\Support\Facades\Storage;
 use App\Models\StudentContract;
 
 class StudentContractResource extends JsonResource
@@ -39,6 +40,8 @@ public function toArray(Request $request): array
             'payment_method'          => $this->payment_method,
             'fine_cancelled'          => $this->fine_cancelled,
             'status'                  => $this->status,
+            'file_url'                => $this->file_url ? Storage::url($this->file_url) : null,
+            'file_type'               => $this->file_type,
             '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'),
         ];

+ 5 - 3
app/Models/Media.php

@@ -4,16 +4,18 @@
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
 
 /**
  * @property int $id
  * @property string $origem
  * @property int $origem_id
+ * @property string|null $name
  * @property string $url
  * @property string $file_type
  * @property \Illuminate\Support\Carbon|null $created_at
  * @property \Illuminate\Support\Carbon|null $updated_at
- * @property string|null $deleted_at
+ * @property \Illuminate\Support\Carbon|null $deleted_at
  * @method static \Illuminate\Database\Eloquent\Builder<static>|Media newModelQuery()
  * @method static \Illuminate\Database\Eloquent\Builder<static>|Media newQuery()
  * @method static \Illuminate\Database\Eloquent\Builder<static>|Media query()
@@ -29,7 +31,7 @@
  */
 class Media extends Model
 {
-    use HasFactory;
+    use HasFactory, SoftDeletes;
 
     protected $table = 'media';
 
@@ -40,7 +42,7 @@ class Media extends Model
     protected $casts = [
         'created_at' => 'datetime',
         'updated_at' => 'datetime',
-        // Add your casts here (e.g., 'is_active' => 'boolean')
+        'deleted_at' => 'datetime',
     ];
 
     // Relationships

+ 2 - 0
app/Models/StudentContract.php

@@ -25,6 +25,8 @@
  * @property int $modality_id
  * @property string|null $notes
  * @property string $status
+ * @property string|null $file_url
+ * @property string|null $file_type
  * @property \Illuminate\Support\Carbon|null $created_at
  * @property \Illuminate\Support\Carbon|null $updated_at
  * @property string|null $deleted_at

+ 36 - 6
app/Services/MediaService.php

@@ -4,13 +4,23 @@
 
 use App\Models\Media;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Storage;
 
 class MediaService
 {
-    public function getAll(): Collection
+    public function getAll(array $filters = []): Collection
     {
-        return Media::orderBy('created_at', 'desc')
-            ->get();
+        $query = Media::orderBy('created_at', 'desc');
+
+        if (!empty($filters['origem'])) {
+            $query->where('origem', $filters['origem']);
+        }
+
+        if (!empty($filters['origem_id'])) {
+            $query->where('origem_id', $filters['origem_id']);
+        }
+
+        return $query->get();
     }
 
     public function findById(int $id): ?Media
@@ -20,7 +30,18 @@ public function findById(int $id): ?Media
 
     public function create(array $data): Media
     {
-        return Media::create($data);
+        /** @var \Illuminate\Http\UploadedFile $file */
+        $file     = $data['file'];
+        $url      = $file->store('student-media');
+        $fileType = $file->getMimeType();
+
+        return Media::create([
+            'name'      => $data['name'],
+            'origem'    => $data['origem'],
+            'origem_id' => $data['origem_id'],
+            'url'       => $url,
+            'file_type' => $fileType,
+        ]);
     }
 
     public function update(int $id, array $data): ?Media
@@ -31,6 +52,15 @@ public function update(int $id, array $data): ?Media
             return null;
         }
 
+        if (isset($data['file'])) {
+            Storage::delete($model->url);
+            /** @var \Illuminate\Http\UploadedFile $file */
+            $file            = $data['file'];
+            $data['url']     = $file->store('student-media');
+            $data['file_type'] = $file->getMimeType();
+            unset($data['file']);
+        }
+
         $model->update($data);
         return $model->fresh();
     }
@@ -43,8 +73,8 @@ public function delete(int $id): bool
             return false;
         }
 
+        Storage::delete($model->url);
+
         return $model->delete();
     }
-
-    // Add custom business logic methods here
 }

+ 26 - 0
app/Services/StudentContractService.php

@@ -5,6 +5,7 @@
 use App\Models\StudentContract;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Storage;
 
 class StudentContractService
 {
@@ -46,6 +47,27 @@ public function update(int $id, array $data): ?StudentContract
         return $model->fresh();
     }
 
+    public function attachFile(int $id, $file): ?StudentContract
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        if ($model->file_url) {
+            Storage::delete($model->file_url);
+        }
+
+        /** @var \Illuminate\Http\UploadedFile $file */
+        $model->update([
+            'file_url'  => $file->store('student-contracts'),
+            'file_type' => $file->getMimeType(),
+        ]);
+
+        return $model->fresh();
+    }
+
     public function delete(int $id): bool
     {
         $model = $this->findById($id);
@@ -54,6 +76,10 @@ public function delete(int $id): bool
             return false;
         }
 
+        if ($model->file_url) {
+            Storage::delete($model->file_url);
+        }
+
         return $model->delete();
     }
 }

+ 22 - 0
database/migrations/2026_05_06_190000_add_name_to_media_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('media', function (Blueprint $table) {
+            $table->string('name')->nullable()->after('origem_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('media', function (Blueprint $table) {
+            $table->dropColumn('name');
+        });
+    }
+};

+ 23 - 0
database/migrations/2026_05_06_191000_add_file_to_student_contracts_table.php

@@ -0,0 +1,23 @@
+<?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('student_contracts', function (Blueprint $table) {
+            $table->string('file_url')->nullable()->after('status');
+            $table->string('file_type')->nullable()->after('file_url');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('student_contracts', function (Blueprint $table) {
+            $table->dropColumn(['file_url', 'file_type']);
+        });
+    }
+};

+ 6 - 0
database/seeders/PermissionSeeder.php

@@ -52,6 +52,12 @@ public function run(): void
                 "bits"        => Permission::ALL_PERMS,
                 "children"    => [],
             ],
+            [
+                "scope"       => "media",
+                "description" => "Mídias de Alunos",
+                "bits"        => Permission::ALL_PERMS,
+                "children"    => [],
+            ],
             [
                 "scope"       => "tbr",
                 "description" => "TBR",

+ 1 - 0
database/seeders/UserTypePermissionSeeder.php

@@ -40,6 +40,7 @@ public function run(): void
                         ['scope' => 'tbr-calculation',                  'bits' => Permission::VIEW],
                         ['scope' => 'inhabitant-classification',        'bits' => Permission::VIEW],
                         ['scope' => 'unit-inhabitant-classification',   'bits' => Permission::ALL_PERMS],
+                        ['scope' => 'media',                            'bits' => Permission::ALL_PERMS],
                     ];
                     break;
                 case UserTypeEnum::GUEST:

+ 5 - 5
routes/authRoutes/media.php

@@ -4,13 +4,13 @@
 use App\Http\Controllers\MediaController;
 
 Route::controller(MediaController::class)->prefix('media')->group(function () {
-    Route::get('/', 'index')->middleware('permission:media,view');
+    Route::get('/', 'index');
 
-    Route::post('/', 'store')->middleware('permission:media,add');
+    Route::post('/', 'store');
 
-    Route::get('/{id}', 'show')->middleware('permission:media,view');
+    Route::get('/{id}', 'show');
 
-    Route::put('/{id}', 'update')->middleware('permission:media,edit');
+    Route::put('/{id}', 'update');
 
-    Route::delete('/{id}', 'destroy')->middleware('permission:media,delete');
+    Route::delete('/{id}', 'destroy');
 });

+ 2 - 0
routes/authRoutes/student_contract.php

@@ -12,5 +12,7 @@
 
     Route::put('/{id}', 'update');
 
+    Route::post('/{id}/file', 'attachFile');
+
     Route::delete('/{id}', 'destroy');
 });