Quellcode durchsuchen

Merge branch 'feature/SERPRATI-GUS-plataforma-v1' of gogs.softpar.inf.br:Softpar/sfp_api_laravel_serprati into feature/SERPRATI-GUS-plataforma-v1

kayo henrique vor 3 Wochen
Ursprung
Commit
054f049bec

+ 6 - 0
app/Http/Controllers/AppointmentController.php

@@ -25,6 +25,12 @@ class AppointmentController extends Controller
         return $this->successResponse(payload: AppointmentResource::collection($items));
     }
 
+    public function partnerAppointments(): JsonResponse
+    {
+        $items = $this->service->getAllByPartnerUser(Auth::id());
+        return $this->successResponse(payload: AppointmentResource::collection($items));
+    }
+
     public function store(AppointmentRequest $request): JsonResponse
     {
         $item = $this->service->create($request->validated());

+ 47 - 0
app/Http/Controllers/PartnerAgreementController.php

@@ -95,6 +95,53 @@ class PartnerAgreementController extends Controller
         return $this->successResponse(message: __('messages.deleted'), code: 204);
     }
 
+    public function myPartner(): JsonResponse
+    {
+        $item = $this->service->findByUserId(auth()->id());
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        return $this->successResponse(payload: new PartnerAgreementResource($item));
+    }
+
+    public function updateMyPartner(PartnerAgreementRequest $request): JsonResponse
+    {
+        $item = $this->service->findByUserId(auth()->id());
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        $updated = $this->service->update($item->id, $request->validated());
+        return $this->successResponse(payload: new PartnerAgreementResource($updated), message: __('messages.updated'));
+    }
+
+    public function uploadMyLogo(UploadLogoRequest $request): JsonResponse
+    {
+        $item = $this->service->findByUserId(auth()->id());
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        $media = $this->mediaService->uploadLogo($request->file('logo'), $item->id);
+        return $this->successResponse(payload: new MediaResource($media), code: 201);
+    }
+
+    public function uploadMyMedia(UploadMediaRequest $request): JsonResponse
+    {
+        $item = $this->service->findByUserId(auth()->id());
+        if (!$item) {
+            return $this->errorResponse(message: __('messages.not_found'), code: 404);
+        }
+        $file      = $request->file('file');
+        $mediaType = str_starts_with($file->getMimeType(), 'image/') ? 'imagem' : 'documento';
+        $media     = $this->mediaService->upload($file, 'partner_agreement', $item->id, $mediaType);
+        return $this->successResponse(payload: new MediaResource($media), code: 201);
+    }
+
+    public function deleteMyMedia(int $mediaId): JsonResponse
+    {
+        $this->mediaService->delete($mediaId);
+        return $this->successResponse(message: __('messages.deleted'), code: 204);
+    }
+
     public function showDados(int $id): JsonResponse
     {
         $item = $this->service->findDados($id);

+ 6 - 3
app/Http/Requests/PartnerAgreementRequest.php

@@ -3,7 +3,9 @@
 namespace App\Http\Requests;
 
 use App\Enums\PartnerAgreementStatusEnum;
+use App\Models\PartnerAgreement;
 use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Validation\Rule;
 
 class PartnerAgreementRequest extends FormRequest
@@ -11,11 +13,12 @@ class PartnerAgreementRequest extends FormRequest
     public function rules(): array
     {
         $cnpjUnique = 'unique:partner_agreements,cnpj';
-        if ($this->isMethod('put') && $this->route('id')) {
-            $cnpjUnique = 'unique:partner_agreements,cnpj,' . $this->route('id');
+        $partnerId = PartnerAgreement::where('user_id', auth()->id())->value('id');
+        if ($this->isMethod('put') && $partnerId) {
+            $cnpjUnique = 'unique:partner_agreements,cnpj,' . $partnerId;
         }
-
         $rules = [
+            'user_id'             => 'sometimes|nullable|integer|exists:users,id',
             'company_name'        => 'sometimes|string|max:255',
             'cnpj'                => ['sometimes', 'nullable', 'string', 'max:18', $cnpjUnique],
             'category_id'         => 'sometimes|nullable|integer|exists:categories,id',

+ 2 - 0
app/Http/Resources/PartnerAgreementResource.php

@@ -13,6 +13,8 @@ class PartnerAgreementResource extends JsonResource
     {
         return [
             'id'                  => $this->id,
+            'user_id'             => $this->user_id,
+            'user'                => $this->whenLoaded('user', fn() => $this->user ? ['id' => $this->user->id, 'name' => $this->user->name] : null),
             'company_name'        => $this->company_name,
             'cnpj'                => $this->cnpj,
             'category_id'         => $this->category_id,

+ 6 - 0
app/Models/PartnerAgreement.php

@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Database\Eloquent\SoftDeletes;
+use App\Models\User;
 
 class PartnerAgreement extends Model
 {
@@ -25,6 +26,11 @@ class PartnerAgreement extends Model
         ];
     }
 
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class);
+    }
+
     public function category(): BelongsTo
     {
         return $this->belongsTo(Category::class);

+ 8 - 0
app/Services/AppointmentService.php

@@ -25,6 +25,14 @@ class AppointmentService
             ->get();
     }
 
+    public function getAllByPartnerUser(int $userId): Collection
+    {
+        return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
+            ->whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))
+            ->orderBy('date', 'desc')
+            ->get();
+    }
+
     public function findById(int $id): ?Appointment
     {
         return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])->find($id);

+ 18 - 1
app/Services/PartnerAgreementService.php

@@ -44,7 +44,24 @@ class PartnerAgreementService
 
     public function findById(int $id): ?PartnerAgreement
     {
-        return PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media'])->find($id);
+        return PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media', 'user'])->find($id);
+    }
+
+    public function findByUserId(int $userId): ?PartnerAgreement
+    {
+        $partner = PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media'])
+            ->where('user_id', $userId)
+            ->first();
+
+        if(!$partner) {
+          $partner = new PartnerAgreement();
+          $partner->company_name = 'Novo Parceiro';
+          $partner->user_id = $userId;
+          $partner->save();
+          $partner->fresh(['category', 'city', 'state', 'services', 'logo', 'media']);
+        }
+
+        return $partner;
     }
 
     public function findDados(int $id): ?PartnerAgreement

+ 24 - 0
database/migrations/2026_05_20_000001_add_user_id_to_partner_agreements_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::table('partner_agreements', function (Blueprint $table) {
+            $table->foreignId('user_id')->nullable()->after('id')->constrained('users')->nullOnDelete();
+            $table->index('user_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('partner_agreements', function (Blueprint $table) {
+            $table->dropForeign(['user_id']);
+            $table->dropColumn('user_id');
+        });
+    }
+};

+ 7 - 1
database/seeders/PermissionSeeder.php

@@ -182,8 +182,14 @@ class PermissionSeeder extends Seeder
                     [
                        "scope" => "associado.agendamento",
                         "description" => "Agendamento do Associado",
+                        "bits" => Permission::VIEW | Permission::ADD | Permission::EDIT,
+                        "children" => [],
+                    ],
+                    [
+                        "scope" => "associado.notificacao",
+                        "description" => "Notificações do Associado",
                         "bits" => Permission::VIEW,
-                        "children" => [], 
+                        "children" => [],
                     ]
                 ],
             ],

+ 7 - 8
database/seeders/UserTypePermissionSeeder.php

@@ -37,14 +37,9 @@ class UserTypePermissionSeeder extends Seeder
                         ['scope' => 'associado.carteirinha',  'bits' => Permission::VIEW | Permission::MENU],
                         ['scope' => 'associado.convenio',     'bits' => Permission::VIEW | Permission::MENU],
                         ['scope' => 'associado.dependente',   'bits' => Permission::VIEW | Permission::ADD | Permission::EDIT | Permission::DELETE | Permission::MENU],
-                        ['scope' => 'notificacao',            'bits' => Permission::VIEW | Permission::MENU],
+                        ['scope' => 'associado.notificacao',  'bits' => Permission::VIEW | Permission::MENU],
                         ['scope' => 'associado.agendamento',  'bits' => Permission::VIEW | Permission::ADD | Permission::EDIT | Permission::MENU],
-                        ['scope' => 'agendamento',            'bits' => Permission::VIEW | Permission::ADD | Permission::EDIT | Permission::MENU],
-                        ['scope' => 'config.user',            'bits' => Permission::VIEW | Permission::EDIT],
-                        ['scope' => 'parceiro.convenio',      'bits' => Permission::VIEW],
-                        ['scope' => 'parceiro.servico',       'bits' => Permission::VIEW],
-                        ['scope' => 'loja.item',              'bits' => Permission::VIEW],
-                        ['scope' => 'associado.loja',         'bits' => Permission::VIEW | Permission::MENU ],
+                        ['scope' => 'associado.loja',         'bits' => Permission::VIEW | Permission::MENU],
                         ['scope' => 'categoria',              'bits' => Permission::VIEW],
                         ['scope' => 'config.position',        'bits' => Permission::VIEW],
                         ['scope' => 'config.sector',          'bits' => Permission::VIEW],
@@ -59,8 +54,12 @@ class UserTypePermissionSeeder extends Seeder
                         ['scope' => 'parceiro',             'bits' => Permission::VIEW | Permission::EDIT | Permission::MENU],
                         ['scope' => 'parceiro.carteirinha', 'bits' => Permission::VIEW | Permission::MENU],
                         ['scope' => 'parceiro.agendamento', 'bits' => Permission::VIEW | Permission::MENU],
-                        ['scope' => 'parceiro.dados',       'bits' => Permission::VIEW | Permission::MENU],
+                        ['scope' => 'parceiro.dados',       'bits' => Permission::VIEW | Permission::EDIT | Permission::MENU],
+                        ['scope' => 'parceiro.servico',     'bits' => Permission::VIEW | Permission::ADD | Permission::EDIT | Permission::DELETE],
                         ['scope' => 'parceiro.notificacao', 'bits' => Permission::VIEW | Permission::MENU],
+                        ['scope' => 'categoria',            'bits' => Permission::VIEW],
+                        ['scope' => 'config.state',         'bits' => Permission::VIEW],
+                        ['scope' => 'config.city',          'bits' => Permission::VIEW],
                     ];
                     break;
             }

+ 10 - 0
routes/authRoutes/associado_appointment.php

@@ -0,0 +1,10 @@
+<?php
+
+use App\Http\Controllers\AppointmentController;
+use Illuminate\Support\Facades\Route;
+
+Route::controller(AppointmentController::class)->prefix('associado/appointment')->group(function () {
+    Route::get('/my',    'myAppointments')->middleware('permission:associado.agendamento,view');
+    Route::post('/',     'store')         ->middleware('permission:associado.agendamento,add');
+    Route::put('/{id}',  'update')        ->middleware('permission:associado.agendamento,edit');
+});

+ 10 - 0
routes/authRoutes/associado_notification.php

@@ -0,0 +1,10 @@
+<?php
+
+use App\Http\Controllers\NotificationController;
+use Illuminate\Support\Facades\Route;
+
+Route::controller(NotificationController::class)->prefix('associado/notification')->group(function () {
+    Route::get('/my',              'myNotifications')->middleware('permission:associado.notificacao,view');
+    Route::get('/my/unread',       'myUnread')       ->middleware('permission:associado.notificacao,view');
+    Route::patch('/{sendId}/read', 'markAsRead')     ->middleware('permission:associado.notificacao,view');
+});

+ 18 - 0
routes/authRoutes/associado_partner_agreement.php

@@ -0,0 +1,18 @@
+<?php
+
+use App\Http\Controllers\PartnerAgreementController;
+use App\Http\Controllers\PartnerAgreementServiceController;
+use Illuminate\Support\Facades\Route;
+
+Route::prefix('associado')->group(function () {
+    Route::controller(PartnerAgreementController::class)->prefix('partner-agreement')->group(function () {
+        Route::get('/',        'index')     ->middleware('permission:associado.convenio,view');
+        Route::get('/{id}',    'show')      ->middleware('permission:associado.convenio,view');
+        Route::get('/{id}/dados', 'showDados')->middleware('permission:associado.convenio,view');
+    });
+
+    Route::controller(PartnerAgreementServiceController::class)->prefix('partner-agreement-service')->group(function () {
+        Route::get('/partner/{partnerAgreementId}', 'indexByPartner')->middleware('permission:associado.convenio,view');
+        Route::get('/{id}',                         'show')          ->middleware('permission:associado.convenio,view');
+    });
+});

+ 12 - 0
routes/authRoutes/associado_store.php

@@ -0,0 +1,12 @@
+<?php
+
+use App\Http\Controllers\StoreItemController;
+use Illuminate\Support\Facades\Route;
+
+Route::controller(StoreItemController::class)->prefix('associado/store-item')->group(function () {
+    Route::get('/my/interests',      'myInterests')   ->middleware('permission:associado.loja,view');
+    Route::get('/',                  'index')          ->middleware('permission:associado.loja,view');
+    Route::get('/{id}',              'show')           ->middleware('permission:associado.loja,view');
+    Route::post('/{id}/interest',    'toggleInterest') ->middleware('permission:associado.loja,view');
+    Route::get('/{id}/interests',    'getInterests')   ->middleware('permission:associado.loja,view');
+});

+ 9 - 0
routes/authRoutes/parceiro_appointment.php

@@ -0,0 +1,9 @@
+<?php
+
+use App\Http\Controllers\AppointmentController;
+use Illuminate\Support\Facades\Route;
+
+Route::controller(AppointmentController::class)->prefix('parceiro/appointment')->group(function () {
+    Route::get('/',       'partnerAppointments')->middleware('permission:parceiro.agendamento,view');
+    Route::get('/{id}',   'show')               ->middleware('permission:parceiro.agendamento,view');
+});

+ 10 - 0
routes/authRoutes/parceiro_notification.php

@@ -0,0 +1,10 @@
+<?php
+
+use App\Http\Controllers\NotificationController;
+use Illuminate\Support\Facades\Route;
+
+Route::controller(NotificationController::class)->prefix('parceiro/notification')->group(function () {
+    Route::get('/my',              'myNotifications')->middleware('permission:parceiro.notificacao,view');
+    Route::get('/my/unread',       'myUnread')       ->middleware('permission:parceiro.notificacao,view');
+    Route::patch('/{sendId}/read', 'markAsRead')     ->middleware('permission:parceiro.notificacao,view');
+});

+ 6 - 0
routes/authRoutes/partner_agreement.php

@@ -4,6 +4,12 @@ use App\Http\Controllers\PartnerAgreementController;
 use Illuminate\Support\Facades\Route;
 
 Route::controller(PartnerAgreementController::class)->prefix('partner-agreement')->group(function () {
+    Route::get('/my',                        'myPartner')      ->middleware('permission:parceiro.dados,view');
+    Route::put('/my',                        'updateMyPartner')->middleware('permission:parceiro.dados,edit');
+    Route::post('/my/logo',                  'uploadMyLogo')   ->middleware('permission:parceiro.dados,edit');
+    Route::post('/my/media',                 'uploadMyMedia')  ->middleware('permission:parceiro.dados,edit');
+    Route::delete('/my/media/{mediaId}',     'deleteMyMedia')  ->middleware('permission:parceiro.dados,edit');
+
     Route::get('/', 'index')->middleware('permission:parceiro.convenio,view');
 
     Route::get('/paginated', 'indexPaginated')->middleware('permission:parceiro.convenio,view');