TreasuryAccountService.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace App\Services;
  3. use App\Models\TreasuryAccount;
  4. use App\Models\TreasuryLaunch;
  5. use Illuminate\Database\Eloquent\Collection;
  6. class TreasuryAccountService
  7. {
  8. /**
  9. * Lista as contas de tesouraria por escopo:
  10. * - franqueador (rede/conta-mãe): sem unit_id => contas com unit_id null;
  11. * - franchisee: unit_id da unidade ativa => contas daquela unidade.
  12. * Cada conta recebe o saldo (entradas - saídas dos lançamentos).
  13. */
  14. public function getAll(?int $unitId = null): Collection
  15. {
  16. $accounts = TreasuryAccount::query()
  17. ->when(
  18. $unitId !== null,
  19. fn ($query) => $query->where('unit_id', $unitId),
  20. fn ($query) => $query->whereNull('unit_id'),
  21. )
  22. ->orderBy('created_at', 'desc')
  23. ->get();
  24. $this->attachBalances($accounts);
  25. return $accounts;
  26. }
  27. /**
  28. * Calcula o saldo de cada conta em duas agregações:
  29. * saldo = soma das entradas (to_account) - soma das saídas (from_account).
  30. */
  31. private function attachBalances(Collection $accounts): void
  32. {
  33. $ids = $accounts->pluck('id');
  34. if ($ids->isEmpty()) {
  35. return;
  36. }
  37. $incoming = TreasuryLaunch::whereIn('to_account_id', $ids)
  38. ->groupBy('to_account_id')
  39. ->selectRaw('to_account_id, SUM(amount) as total')
  40. ->pluck('total', 'to_account_id');
  41. $outgoing = TreasuryLaunch::whereIn('from_account_id', $ids)
  42. ->groupBy('from_account_id')
  43. ->selectRaw('from_account_id, SUM(amount) as total')
  44. ->pluck('total', 'from_account_id');
  45. foreach ($accounts as $account) {
  46. $balance = (float) ($incoming[$account->id] ?? 0) - (float) ($outgoing[$account->id] ?? 0);
  47. $account->setAttribute('balance', $balance);
  48. }
  49. }
  50. public function findById(int $id): ?TreasuryAccount
  51. {
  52. return TreasuryAccount::find($id);
  53. }
  54. public function create(array $data): TreasuryAccount
  55. {
  56. // Sem unit_id => conta da rede (franqueador). Com unit_id => conta da unidade (franchisee).
  57. $data['unit_id'] = $data['unit_id'] ?? null;
  58. return TreasuryAccount::create($data);
  59. }
  60. public function update(int $id, array $data): ?TreasuryAccount
  61. {
  62. $model = $this->findById($id);
  63. if (!$model) {
  64. return null;
  65. }
  66. $model->update($data);
  67. return $model->fresh();
  68. }
  69. public function delete(int $id): bool
  70. {
  71. $model = $this->findById($id);
  72. if (!$model) {
  73. return false;
  74. }
  75. return $model->delete();
  76. }
  77. // Add custom business logic methods here
  78. }