Преглед изворни кода

feat: implement franchisee receivables endpoint and automate Asaas subaccount and payment synchronization jobs

ebagabee пре 1 недеља
родитељ
комит
6c4414ae9b

+ 38 - 0
app/Http/Controllers/FranchiseeReceivableController.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Controllers\Concerns\ResolvesActiveUnit;
+use App\Models\StudentContractInstallment;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class FranchiseeReceivableController extends Controller
+{
+    use ResolvesActiveUnit;
+
+    public function index(Request $request): JsonResponse
+    {
+        $unitId = $this->activeUnitId();
+
+        if (!$unitId) {
+            return $this->errorResponse(message: 'Unidade não ativa no contexto.', code: 400);
+        }
+
+        $query = StudentContractInstallment::with(['student'])
+            ->where('unit_id', $unitId)
+            ->orderBy('due_date', 'asc');
+
+        if ($request->has('status')) {
+            $query->where('status', $request->query('status'));
+        }
+
+        if ($request->has('student_id')) {
+            $query->where('student_id', $request->query('student_id'));
+        }
+
+        $items = $query->get();
+
+        return $this->successResponse(payload: $items);
+    }
+}

+ 46 - 0
app/Jobs/CreateAsaasSubaccountJob.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Models\Unit;
+use App\Services\Integrations\Asaas\AsaasAccountService;
+use Exception;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Log;
+
+class CreateAsaasSubaccountJob implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    public int $unitId;
+    public int $tries = 3;
+
+    public function __construct(int $unitId)
+    {
+        $this->unitId = $unitId;
+    }
+
+    public function handle(AsaasAccountService $accountService): void
+    {
+        $unit = Unit::find($this->unitId);
+
+        if (!$unit) {
+            Log::warning("CreateAsaasSubaccountJob: Unidade {$this->unitId} não encontrada.");
+            return;
+        }
+
+        try {
+            $accountService->ensureSubaccount($unit);
+            Log::info("CreateAsaasSubaccountJob: Subconta criada com sucesso para a Unidade {$unit->id}.");
+        } catch (Exception $e) {
+            Log::error("CreateAsaasSubaccountJob: Falha ao criar subconta para Unidade {$unit->id}.", [
+                'error' => $e->getMessage()
+            ]);
+            throw $e; // Throw to retry if needed
+        }
+    }
+}

+ 13 - 2
app/Services/StudentContractService.php

@@ -66,9 +66,10 @@ private function generateInstallments(StudentContract $contract): void
         $rows = [];
         $now  = now();
 
-        // --- Matrícula ---
+        // Matrícula
         if ($contract->tax_register && $contract->installments && $contract->enrollment_due_date) {
             $value = round($contract->tax_register / $contract->installments, 2);
+
             $dates = $this->buildInstallmentDates(
                 $contract->enrollment_due_date->format('Y-m-d'),
                 $recurringDay,
@@ -96,9 +97,10 @@ private function generateInstallments(StudentContract $contract): void
             }
         }
 
-        // --- Pacote ---
+        // Pacote
         if ($contract->package_value && $contract->package_installments && $contract->package_due_date) {
             $value = round($contract->package_value / $contract->package_installments, 2);
+           
             $dates = $this->buildInstallmentDates(
                 $contract->package_due_date->format('Y-m-d'),
                 $recurringDay,
@@ -128,6 +130,15 @@ private function generateInstallments(StudentContract $contract): void
 
         if (!empty($rows)) {
             StudentContractInstallment::insert($rows);
+
+            // Dispatch Asaas sync for the generated installments
+            $installments = StudentContractInstallment::where('student_contract_id', $contract->id)
+                ->where('status', 'pending')
+                ->get();
+
+            foreach ($installments as $installment) {
+                \App\Jobs\SyncStudentChargeJob::dispatch($installment->id);
+            }
         }
     }
 

+ 3 - 0
app/Services/UnitService.php

@@ -64,6 +64,9 @@ public function create(array $data): Unit
 
         $this->replicatePackagesToUnit($unit->id);
 
+        // Dispatch Asaas Subaccount creation asynchronously
+        \App\Jobs\CreateAsaasSubaccountJob::dispatch($unit->id);
+
         return $unit;
     }
 

+ 8 - 0
routes/authRoutes/franchisee_receivable.php

@@ -0,0 +1,8 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\FranchiseeReceivableController;
+
+Route::controller(FranchiseeReceivableController::class)->prefix('franchisee-receivable')->group(function () {
+    Route::get('/', 'index');
+});