UnitFinancialDashboardService.php 4.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. namespace App\Services;
  3. use App\Models\FranchiseeAccountReceive;
  4. use App\Models\StudentContractInstallment;
  5. use App\Models\UnitAccountPayable;
  6. use App\Models\UnitAccountReceivable;
  7. use Carbon\Carbon;
  8. /**
  9. * Visão geral financeira da unidade: agrega Contas a Receber (parcelas de aluno
  10. * + recebíveis avulsos manuais + contas que a franqueadora vinculou à unidade,
  11. * ligadas ou não ao Asaas) e Contas a Pagar (unit_account_payables, que já
  12. * inclui os lançamentos manuais) do mês corrente.
  13. */
  14. class UnitFinancialDashboardService
  15. {
  16. public function overview(int $unitId): array
  17. {
  18. $start = Carbon::now()->startOfMonth()->toDateString();
  19. $end = Carbon::now()->endOfMonth()->toDateString();
  20. $today = Carbon::today()->toDateString();
  21. // Recebíveis = parcelas de aluno
  22. $recPendingQ = StudentContractInstallment::where('unit_id', $unitId)->where('status', 'pending');
  23. $recReceivedQ = StudentContractInstallment::where('unit_id', $unitId)
  24. ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
  25. $recOverdueQ = StudentContractInstallment::where('unit_id', $unitId)
  26. ->where('status', 'pending')->where('due_date', '<', $today);
  27. // Recebíveis avulsos (manuais)
  28. $manPendingQ = UnitAccountReceivable::where('unit_id', $unitId)->where('status', 'pending');
  29. $manReceivedQ = UnitAccountReceivable::where('unit_id', $unitId)
  30. ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
  31. $manOverdueQ = UnitAccountReceivable::where('unit_id', $unitId)
  32. ->where('status', 'pending')->where('due_date', '<', $today);
  33. // Contas que a franqueadora vinculou à unidade (origin=manual_unit) — mesma
  34. // fonte que entra no faturamento do cálculo de TBR (TbrCalculationService).
  35. // Conta independente de ter ou não cobrança Asaas gerada: o cliente reclama
  36. // se faltar aqui, mesmo sem integração.
  37. $linkedPendingQ = FranchiseeAccountReceive::where('unit_id', $unitId)
  38. ->where('origin', 'manual_unit')->where('status', 'pending');
  39. $linkedReceivedQ = FranchiseeAccountReceive::where('unit_id', $unitId)
  40. ->where('origin', 'manual_unit')
  41. ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
  42. $linkedOverdueQ = FranchiseeAccountReceive::where('unit_id', $unitId)
  43. ->where('origin', 'manual_unit')
  44. ->where('status', 'pending')->where('due_date', '<', $today);
  45. // Pagáveis (unit_account_payables já inclui os manuais, origin='manual')
  46. $payPendingQ = UnitAccountPayable::where('unit_id', $unitId)->where('status', 'pending');
  47. $payPaidQ = UnitAccountPayable::where('unit_id', $unitId)
  48. ->where('status', 'paid')->whereBetween('payment_date', [$start, $end]);
  49. $payOverdueQ = UnitAccountPayable::where('unit_id', $unitId)
  50. ->where('status', 'pending')->where('due_date', '<', $today);
  51. $receivedMonth = (float) (clone $recReceivedQ)->sum('paid_value')
  52. + (float) (clone $manReceivedQ)->sum('paid_value')
  53. + (float) (clone $linkedReceivedQ)->sum('paid_value');
  54. $paidMonth = (float) (clone $payPaidQ)->sum('paid_value');
  55. $receivablePending = (float) (clone $recPendingQ)->sum('value')
  56. + (float) (clone $manPendingQ)->sum('value')
  57. + (float) (clone $linkedPendingQ)->sum('value');
  58. $overdueReceivable = (float) (clone $recOverdueQ)->sum('value')
  59. + (float) (clone $manOverdueQ)->sum('value')
  60. + (float) (clone $linkedOverdueQ)->sum('value');
  61. return [
  62. 'received_month' => round($receivedMonth, 2),
  63. 'received_month_count' => (clone $recReceivedQ)->count() + (clone $manReceivedQ)->count()
  64. + (clone $linkedReceivedQ)->count(),
  65. 'paid_month' => round($paidMonth, 2),
  66. 'paid_month_count' => (clone $payPaidQ)->count(),
  67. 'result_month' => round($receivedMonth - $paidMonth, 2),
  68. 'receivable_pending' => round($receivablePending, 2),
  69. 'receivable_pending_count' => (clone $recPendingQ)->count() + (clone $manPendingQ)->count()
  70. + (clone $linkedPendingQ)->count(),
  71. 'payable_pending' => round((float) (clone $payPendingQ)->sum('value'), 2),
  72. 'payable_pending_count' => (clone $payPendingQ)->count(),
  73. 'overdue_receivable' => round($overdueReceivable, 2),
  74. 'overdue_receivable_count' => (clone $recOverdueQ)->count() + (clone $manOverdueQ)->count()
  75. + (clone $linkedOverdueQ)->count(),
  76. 'overdue_payable' => round((float) (clone $payOverdueQ)->sum('value'), 2),
  77. 'overdue_payable_count' => (clone $payOverdueQ)->count(),
  78. ];
  79. }
  80. }