Parcourir la source

feat: adiciona congelamento de contrato

ebagabee il y a 2 semaines
Parent
commit
e9865e71bc

+ 28 - 1
app/Http/Controllers/StudentContractController.php

@@ -2,9 +2,11 @@
 
 namespace App\Http\Controllers;
 
+use App\Models\UnitFinancial;
 use App\Services\StudentContractService;
 use App\Http\Requests\StudentContractRequest;
 use App\Http\Resources\StudentContractResource;
+use App\Http\Resources\StudentContractInstallmentResource;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
@@ -70,9 +72,34 @@ public function attachFile(Request $request, int $id): JsonResponse
         return $this->successResponse(payload: new StudentContractResource($item), message: __('messages.updated'));
     }
 
+    public function installments(int $id): JsonResponse
+    {
+        $items = $this->service->getInstallments($id);
+        return $this->successResponse(payload: StudentContractInstallmentResource::collection($items));
+    }
+
     public function freeze(int $id): JsonResponse
     {
-        $item = $this->service->freeze($id);
+        $months = request()->integer('months', 0);
+
+        if ($months < 1) {
+            return $this->errorResponse(message: 'Informe o tempo de trancamento em meses.', code: 422);
+        }
+
+        $contract = $this->service->findById($id);
+        if (!$contract) {
+            return $this->errorResponse(message: 'Contrato não encontrado.', code: 404);
+        }
+
+        $financial = UnitFinancial::where('unit_id', $contract->unit_id)->first();
+        if ($financial && $financial->max_freeze_count !== null && $months > $financial->max_freeze_count) {
+            return $this->errorResponse(
+                message: "Não é possível trancar por mais de {$financial->max_freeze_count} mês(es).",
+                code: 422,
+            );
+        }
+
+        $item = $this->service->freeze($id, $months);
         return $this->successResponse(payload: new StudentContractResource($item), message: __('messages.updated'));
     }
 

+ 30 - 0
app/Http/Resources/StudentContractInstallmentResource.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class StudentContractInstallmentResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'                 => $this->id,
+            'type'               => $this->type,
+            'history'            => $this->history,
+            'order'              => $this->order, // "1/12" via accessor
+            'installment_number' => $this->installment_number,
+            'total_installments' => $this->total_installments,
+            'value'              => (float) $this->value,
+            'paid_value'         => (float) $this->paid_value,
+            'discount'           => (float) $this->discount,
+            'fine'               => (float) $this->fine,
+            'due_date'           => $this->due_date
+                                        ? Carbon::parse($this->due_date)->format('d/m/Y')
+                                        : null,
+            'status'             => $this->status,
+        ];
+    }
+}

+ 20 - 1
app/Services/StudentContractService.php

@@ -198,7 +198,16 @@ public function attachFile(int $id, $file): ?StudentContract
         return $model->fresh();
     }
 
-    public function freeze(int $id): ?StudentContract
+    public function getInstallments(int $contractId): Collection
+    {
+        return StudentContractInstallment::where('student_contract_id', $contractId)
+            ->where('status', 'pending')
+            ->orderBy('due_date')
+            ->orderBy('installment_number')
+            ->get();
+    }
+
+    public function freeze(int $id, int $months = 0): ?StudentContract
     {
         $model = $this->findById($id);
 
@@ -206,6 +215,16 @@ public function freeze(int $id): ?StudentContract
             return null;
         }
 
+        if ($months > 0) {
+            StudentContractInstallment::where('student_contract_id', $id)
+                ->where('status', 'pending')
+                ->get()
+                ->each(function ($installment) use ($months) {
+                    $newDate = Carbon::parse($installment->due_date)->addMonths($months);
+                    $installment->update(['due_date' => $newDate->format('Y-m-d')]);
+                });
+        }
+
         $model->update(['status' => 'frozen']);
         return $model->fresh();
     }

+ 2 - 0
routes/authRoutes/student_contract.php

@@ -18,6 +18,8 @@
 
     Route::post('/{id}/file', 'attachFile')->middleware('permission:student-contract,edit');
 
+    Route::get('/{id}/installments', 'installments')->middleware('permission:student-contract,view');
+
     Route::post('/{id}/freeze', 'freeze')->middleware('permission:student-contract,edit');
 
     Route::post('/{id}/cancel', 'cancel')->middleware('permission:student-contract,edit');