ソースを参照

feat(unit-financial-dashboard): agregação de recebíveis e pagáveis da unidade no mês

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ebagabee 4 週間 前
コミット
89dfb2dce4

+ 27 - 0
app/Http/Controllers/UnitFinancialDashboardController.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Controllers\Concerns\ResolvesActiveUnit;
+use App\Services\UnitFinancialDashboardService;
+use Illuminate\Http\JsonResponse;
+
+class UnitFinancialDashboardController extends Controller
+{
+    use ResolvesActiveUnit;
+
+    public function __construct(
+        protected UnitFinancialDashboardService $service,
+    ) {}
+
+    public function overviewMe(): JsonResponse
+    {
+        $unitId = $this->activeUnitId();
+
+        if (!$unitId) {
+            return $this->errorResponse(message: 'Unidade não encontrada', code: 404);
+        }
+
+        return $this->successResponse(payload: $this->service->overview($unitId));
+    }
+}

+ 56 - 0
app/Services/UnitFinancialDashboardService.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\StudentContractInstallment;
+use App\Models\UnitAccountPayable;
+use Carbon\Carbon;
+
+/**
+ * Visão geral financeira da unidade: agrega Contas a Receber (parcelas de aluno)
+ * e Contas a Pagar (unit_account_payables) do mês corrente.
+ */
+class UnitFinancialDashboardService
+{
+    public function overview(int $unitId): array
+    {
+        $start = Carbon::now()->startOfMonth()->toDateString();
+        $end   = Carbon::now()->endOfMonth()->toDateString();
+        $today = Carbon::today()->toDateString();
+
+        // Recebíveis = parcelas de aluno
+        $recPendingQ  = StudentContractInstallment::where('unit_id', $unitId)->where('status', 'pending');
+        $recReceivedQ = StudentContractInstallment::where('unit_id', $unitId)
+            ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
+        $recOverdueQ  = StudentContractInstallment::where('unit_id', $unitId)
+            ->where('status', 'pending')->where('due_date', '<', $today);
+
+        // Pagáveis
+        $payPendingQ  = UnitAccountPayable::where('unit_id', $unitId)->where('status', 'pending');
+        $payPaidQ     = UnitAccountPayable::where('unit_id', $unitId)
+            ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
+        $payOverdueQ  = UnitAccountPayable::where('unit_id', $unitId)
+            ->where('status', 'pending')->where('due_date', '<', $today);
+
+        $receivedMonth = (float) (clone $recReceivedQ)->sum('paid_value');
+        $paidMonth     = (float) (clone $payPaidQ)->sum('paid_value');
+
+        return [
+            'received_month'           => round($receivedMonth, 2),
+            'received_month_count'     => (clone $recReceivedQ)->count(),
+            'paid_month'               => round($paidMonth, 2),
+            'paid_month_count'         => (clone $payPaidQ)->count(),
+            'result_month'             => round($receivedMonth - $paidMonth, 2),
+
+            'receivable_pending'       => round((float) (clone $recPendingQ)->sum('value'), 2),
+            'receivable_pending_count' => (clone $recPendingQ)->count(),
+            'payable_pending'          => round((float) (clone $payPendingQ)->sum('value'), 2),
+            'payable_pending_count'    => (clone $payPendingQ)->count(),
+
+            'overdue_receivable'       => round((float) (clone $recOverdueQ)->sum('value'), 2),
+            'overdue_receivable_count' => (clone $recOverdueQ)->count(),
+            'overdue_payable'          => round((float) (clone $payOverdueQ)->sum('value'), 2),
+            'overdue_payable_count'    => (clone $payOverdueQ)->count(),
+        ];
+    }
+}

+ 8 - 0
routes/authRoutes/unit_financial_dashboard.php

@@ -0,0 +1,8 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\UnitFinancialDashboardController;
+
+Route::controller(UnitFinancialDashboardController::class)->prefix('unit-financial-dashboard')->group(function () {
+    Route::get('/me', 'overviewMe');
+});