GenerateMonthlyTbrCommand.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Enums\NotificationType;
  4. use App\Services\NotificationService;
  5. use App\Services\TbrCalculationService;
  6. use Carbon\Carbon;
  7. use Illuminate\Console\Command;
  8. /**
  9. * Geração automática do TBR do mês fechado (roda no schedule mensal).
  10. *
  11. * Sem opções, gera o TBR do MÊS ANTERIOR (já fechado) — ex.: rodando em 01/ago,
  12. * gera as contas referentes a julho. Idempotente: pula o que já foi gerado.
  13. */
  14. class GenerateMonthlyTbrCommand extends Command
  15. {
  16. protected $signature = 'tbr:generate-monthly {--year=} {--month=}';
  17. protected $description = 'Gera automaticamente as cobranças do TBR do mês fechado';
  18. private const MONTHS = [
  19. 1 => 'janeiro', 2 => 'fevereiro', 3 => 'março', 4 => 'abril',
  20. 5 => 'maio', 6 => 'junho', 7 => 'julho', 8 => 'agosto',
  21. 9 => 'setembro', 10 => 'outubro', 11 => 'novembro', 12 => 'dezembro',
  22. ];
  23. public function handle(TbrCalculationService $service, NotificationService $notifications): int
  24. {
  25. $reference = Carbon::now()->subMonthNoOverflow();
  26. $year = (int) ($this->option('year') ?: $reference->year);
  27. $month = (int) ($this->option('month') ?: $reference->month);
  28. $this->info("Gerando TBR automático para {$month}/{$year}...");
  29. $result = $service->generateBatch($year, $month, null);
  30. $this->info(sprintf(
  31. '%d gerado(s), %d pulado(s), %d erro(s).',
  32. $result['generated_count'],
  33. $result['skipped_count'],
  34. $result['error_count'],
  35. ));
  36. if ($result['generated_count'] > 0) {
  37. $this->notifyMonthClosed($notifications, $year, $month, $result['generated']);
  38. }
  39. return self::SUCCESS;
  40. }
  41. /**
  42. * Notifica a matriz (contas a receber) e cada unidade (conta a pagar).
  43. */
  44. private function notifyMonthClosed(
  45. NotificationService $notifications,
  46. int $year,
  47. int $month,
  48. array $generated,
  49. ): void {
  50. $monthLabel = (self::MONTHS[$month] ?? $month) . "/{$year}";
  51. $count = count($generated);
  52. // Matriz: visão consolidada no Contas a Receber.
  53. $notifications->dispatch([
  54. 'origin_table' => 'tbr_calculations',
  55. 'origin_id' => $year * 100 + $month,
  56. 'type' => NotificationType::TBR_MONTH_CLOSED->value,
  57. 'title' => 'Fechamento do mês',
  58. 'message' => "As cobranças de {$monthLabel} foram geradas no Contas a Receber "
  59. . "({$count} unidade(s)).",
  60. 'url' => '/financial/accounts-receivable',
  61. 'action_text' => 'Ver Contas a Receber',
  62. 'priority' => 'normal',
  63. 'recipient_user_ids' => $notifications->matrizUserIds(),
  64. ]);
  65. // Cada unidade: sua conta a pagar (TBR) do mês.
  66. foreach ($generated as $item) {
  67. $unitId = $item['unit_id'] ?? null;
  68. if (!$unitId) {
  69. continue;
  70. }
  71. $notifications->dispatch([
  72. 'origin_table' => 'unit_account_payables',
  73. 'origin_id' => $item['receivable_id'] ?? ($year * 100 + $month),
  74. 'unit_id' => $unitId,
  75. 'type' => NotificationType::TBR_MONTH_CLOSED->value,
  76. 'title' => 'Conta a pagar gerada',
  77. 'message' => "Sua cobrança (TBR) referente a {$monthLabel} foi gerada em Contas a Pagar.",
  78. 'url' => '/financial/accounts-payable',
  79. 'action_text' => 'Ver Contas a Pagar',
  80. 'priority' => 'normal',
  81. 'recipient_user_ids' => $notifications->unitUserIds($unitId),
  82. ]);
  83. }
  84. }
  85. }