瀏覽代碼

feat: cria estudante

ebagabee 2 周之前
父節點
當前提交
115ce45555

+ 12 - 4
app/Http/Controllers/StudentController.php

@@ -6,6 +6,7 @@
 use App\Http\Requests\StudentRequest;
 use App\Http\Resources\StudentResource;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Auth;
 
 class StudentController extends Controller
 {
@@ -15,14 +16,18 @@ public function __construct(
 
     public function index(): JsonResponse
     {
-        $items = $this->service->getAll();
+        $items = $this->service->getAll(Auth::user());
         return $this->successResponse(payload: StudentResource::collection($items));
     }
 
     public function store(StudentRequest $request): JsonResponse
     {
-        $item = $this->service->create($request->validated());
-        return $this->successResponse(payload: new StudentResource($item), message: __('messages.created'), code: 201);
+        $item = $this->service->create(Auth::user(), $request->validated());
+        return $this->successResponse(
+            payload: new StudentResource($item),
+            message: __('messages.created'),
+            code: 201,
+        );
     }
 
     public function show(int $id): JsonResponse
@@ -34,7 +39,10 @@ public function show(int $id): JsonResponse
     public function update(StudentRequest $request, int $id): JsonResponse
     {
         $item = $this->service->update($id, $request->validated());
-        return $this->successResponse(payload: new StudentResource($item), message: __('messages.updated'));
+        return $this->successResponse(
+            payload: new StudentResource($item),
+            message: __('messages.updated'),
+        );
     }
 
     public function destroy(int $id): JsonResponse

+ 20 - 17
app/Http/Requests/StudentRequest.php

@@ -9,26 +9,29 @@ class StudentRequest extends FormRequest
     public function rules(): array
     {
         $rules = [
-            // Add your validation rules here
-            //'field' => 'sometimes|string|max:255',
+            'birth_date'          => 'sometimes|nullable|date',
+            'document_number'     => 'sometimes|nullable|string|max:20',
+            'gender'              => 'sometimes|nullable|string|in:no_preference,male,female,other',
+            'email'               => 'sometimes|nullable|email',
+            'phone'               => 'sometimes|nullable|string|max:20',
+            'postal_code'         => 'sometimes|nullable|string|max:10',
+            'street'              => 'sometimes|nullable|string|max:255',
+            'address_number'      => 'sometimes|nullable|string|max:20',
+            'neighborhood'        => 'sometimes|nullable|string|max:255',
+            'state_id'            => 'sometimes|nullable|integer|exists:states,id',
+            'complement'          => 'sometimes|nullable|string|max:255',
+            'payer_name'          => 'sometimes|nullable|string|max:255',
+            'how_did_you_know_us' => 'sometimes|nullable|string|in:referral,social_media,google,other',
+            'notes'               => 'sometimes|nullable|string',
         ];
 
-        // Different rules for creation
-        //if ($this->isMethod('POST')) {
-            // Make fields required if needed
-            // $rules['field'] = 'required|string|max:255';
-        //}
+        if ($this->isMethod('post')) {
+            $rules['name']  = 'required|string|max:255';
+            $rules['email'] = 'sometimes|nullable|email|unique:students,email';
+        } else {
+            $rules['name'] = 'sometimes|string|max:255';
+        }
 
         return $rules;
     }
-
-    /**
-    * Add custom messages when needed
-    * public function messages(): array
-    * {
-    *   return [
-    *        'field.required' => __('message.algo'),
-    *    ];
-    * }
-    */
 }

+ 22 - 24
app/Http/Resources/StudentResource.php

@@ -4,40 +4,38 @@
 
 use Carbon\Carbon;
 use Illuminate\Http\Request;
-use Illuminate\Http\Resources\Json\JsonResource;
 use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
-use App\Models\Student;
+use Illuminate\Http\Resources\Json\JsonResource;
 
 class StudentResource 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,
+            'unit_id'             => $this->unit_id,
+            'name'                => $this->name,
+            'birth_date'          => $this->birth_date?->format('Y-m-d'),
+            'document_number'     => $this->document_number,
+            'gender'              => $this->gender,
+            'email'               => $this->email,
+            'phone'               => $this->phone,
+            'postal_code'         => $this->postal_code,
+            'street'              => $this->street,
+            'address_number'      => $this->address_number,
+            'neighborhood'        => $this->neighborhood,
+            'city_id'             => $this->city_id,
+            'state_id'            => $this->state_id,
+            'complement'          => $this->complement,
+            'payer_name'          => $this->payer_name,
+            'how_did_you_know_us' => $this->how_did_you_know_us,
+            'notes'               => $this->notes,
+            'status'              => $this->status,
+            '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'),
         ];
     }
 
-    /**
-     * @param \Illuminate\Database\Eloquent\Collection<Student> $resource
-     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<StudentResource>
-     */
     public static function collection($resource): AnonymousResourceCollection
     {
         return parent::collection($resource);

+ 10 - 18
app/Models/Student.php

@@ -4,34 +4,26 @@
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
 
-/**
- * @property int $id
- * @property \Carbon\Carbon $created_at
- * @property \Carbon\Carbon $updated_at
- */
 class Student extends Model
 {
-    use HasFactory;
+    use HasFactory, SoftDeletes;
 
     protected $table = 'students';
 
-    protected $guarded = [
-        'id', // Add more fields that shouldn't be edited here
-    ];
+    protected $guarded = ['id'];
 
     protected $casts = [
+        'birth_date' => 'date',
         'created_at' => 'datetime',
         'updated_at' => 'datetime',
-        // Add your casts here (e.g., 'is_active' => 'boolean')
+        'deleted_at' => 'datetime',
     ];
 
-    // Relationships
-
-    // Business Logic Methods
-
-    // Custom Finders
-
-    // Query Scopes
-
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class, 'unit_id');
+    }
 }

+ 7 - 0
app/Models/User.php

@@ -10,6 +10,7 @@
 use Illuminate\Notifications\Notifiable;
 use Laravel\Sanctum\HasApiTokens;
 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
+use App\Models\Unit;
 use Carbon\Carbon;
 
 /**
@@ -82,6 +83,12 @@ public function state(): \Illuminate\Database\Eloquent\Relations\BelongsTo
         return $this->belongsTo(\App\Models\State::class, 'state_id');
     }
 
+    public function units(): BelongsToMany
+    {
+        return $this->belongsToMany(Unit::class, 'unit_users', 'user_id', 'unit_id')
+            ->withTimestamps();
+    }
+
     /**
      * Create a new access token for the user.
      */

+ 16 - 5
app/Services/StudentService.php

@@ -3,13 +3,17 @@
 namespace App\Services;
 
 use App\Models\Student;
+use App\Models\User;
 use Illuminate\Database\Eloquent\Collection;
 
 class StudentService
 {
-    public function getAll(): Collection
+    public function getAll(User $user): Collection
     {
-        return Student::orderBy('created_at', 'desc')
+        $unitId = $this->resolveUnitId($user);
+
+        return Student::where('unit_id', $unitId)
+            ->orderBy('created_at', 'desc')
             ->get();
     }
 
@@ -18,9 +22,11 @@ public function findById(int $id): ?Student
         return Student::find($id);
     }
 
-    public function create(array $data): Student
+    public function create(User $user, array $data): Student
     {
-        return Student::create($data);
+        $unitId = $this->resolveUnitId($user);
+
+        return Student::create(array_merge($data, ['unit_id' => $unitId]));
     }
 
     public function update(int $id, array $data): ?Student
@@ -46,5 +52,10 @@ public function delete(int $id): bool
         return $model->delete();
     }
 
-    // Add custom business logic methods here
+    private function resolveUnitId(User $user): int
+    {
+        $unit = $user->units()->first();
+        abort_if(!$unit, 403, 'Usuário sem unidade associada.');
+        return $unit->id;
+    }
 }

+ 51 - 0
database/migrations/2026_04_15_000010_update_students_table.php

@@ -0,0 +1,51 @@
+<?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('students', function (Blueprint $table) {
+            // Link student to a unit
+            $table->foreignId('unit_id')->after('id')->constrained('units');
+
+            // Replace city_id FK (cities table) with a plain text city field
+            $table->dropForeign(['city_id']);
+            $table->dropColumn('city_id');
+            $table->string('city')->nullable()->after('neighborhood');
+
+            // Make address and personal fields optional
+            $table->date('birth_date')->nullable()->change();
+            $table->string('document_number')->nullable()->change();
+            $table->string('email')->nullable()->change();
+            $table->string('phone')->nullable()->change();
+            $table->string('postal_code')->nullable()->change();
+            $table->string('street')->nullable()->change();
+            $table->string('neighborhood')->nullable()->change();
+            $table->string('payer_name')->nullable()->change();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('students', function (Blueprint $table) {
+            $table->dropForeign(['unit_id']);
+            $table->dropColumn('unit_id');
+
+            $table->dropColumn('city');
+            $table->foreignId('city_id')->constrained('cities');
+
+            $table->date('birth_date')->nullable(false)->change();
+            $table->string('document_number')->nullable(false)->change();
+            $table->string('email')->nullable(false)->change();
+            $table->string('phone')->nullable(false)->change();
+            $table->string('postal_code')->nullable(false)->change();
+            $table->string('street')->nullable(false)->change();
+            $table->string('neighborhood')->nullable(false)->change();
+            $table->string('payer_name')->nullable(false)->change();
+        });
+    }
+};

+ 32 - 0
database/migrations/2026_04_15_000011_update_students_city_state_fields.php

@@ -0,0 +1,32 @@
+<?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('students', function (Blueprint $table) {
+            // Remove the plain city string added in the previous migration
+            $table->dropColumn('city');
+
+            // Restore city_id as a nullable FK (student may not have city set yet)
+            $table->foreignId('city_id')->nullable()->after('neighborhood')->constrained('cities');
+
+            // Make state_id nullable (it was NOT NULL from original migration)
+            $table->unsignedBigInteger('state_id')->nullable()->change();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('students', function (Blueprint $table) {
+            $table->dropForeign(['city_id']);
+            $table->dropColumn('city_id');
+            $table->string('city')->nullable()->after('neighborhood');
+            $table->unsignedBigInteger('state_id')->nullable(false)->change();
+        });
+    }
+};

+ 2 - 2
routes/authRoutes/student.php

@@ -4,9 +4,9 @@
 use App\Http\Controllers\StudentController;
 
 Route::controller(StudentController::class)->prefix('student')->group(function () {
-    Route::get('/', 'index')->middleware('permission:student,view');
+    Route::get('/', 'index');
 
-    Route::post('/', 'store')->middleware('permission:student,add');
+    Route::post('/', 'store');
 
     Route::get('/{id}', 'show')->middleware('permission:student,view');