| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- <?php
- namespace App\Services;
- use App\Models\TreasuryAccount;
- use App\Models\TreasuryLaunch;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Support\Carbon;
- class TreasuryAccountService
- {
- /**
- * Lista as contas de tesouraria por escopo:
- * - franqueador (rede/conta-mãe): sem unit_id => contas com unit_id null;
- * - franchisee: unit_id da unidade ativa => contas daquela unidade.
- * Cada conta recebe o saldo (entradas - saídas dos lançamentos).
- */
- public function getAll(?int $unitId = null): Collection
- {
- $accounts = TreasuryAccount::query()
- ->when(
- $unitId !== null,
- fn ($query) => $query->where('unit_id', $unitId),
- fn ($query) => $query->whereNull('unit_id'),
- )
- ->orderBy('created_at', 'desc')
- ->get();
- $this->attachBalances($accounts);
- return $accounts;
- }
- /**
- * Calcula o saldo de cada conta:
- * saldo = soma das entradas (to_account) - soma das saídas (from_account).
- *
- * Também expõe `balance_previous` = saldo no fim do mês anterior (saldo atual
- * menos o fluxo líquido do mês corrente), permitindo ao frontend exibir a
- * variação percentual "vs o mês anterior" em cada card.
- */
- private function attachBalances(Collection $accounts): void
- {
- $ids = $accounts->pluck('id');
- if ($ids->isEmpty()) {
- return;
- }
- $incoming = TreasuryLaunch::whereIn('to_account_id', $ids)
- ->groupBy('to_account_id')
- ->selectRaw('to_account_id, SUM(amount) as total')
- ->pluck('total', 'to_account_id');
- $outgoing = TreasuryLaunch::whereIn('from_account_id', $ids)
- ->groupBy('from_account_id')
- ->selectRaw('from_account_id, SUM(amount) as total')
- ->pluck('total', 'from_account_id');
- $monthStart = Carbon::now()->startOfMonth();
- $incomingMonth = TreasuryLaunch::whereIn('to_account_id', $ids)
- ->where('launch_date', '>=', $monthStart)
- ->groupBy('to_account_id')
- ->selectRaw('to_account_id, SUM(amount) as total')
- ->pluck('total', 'to_account_id');
- $outgoingMonth = TreasuryLaunch::whereIn('from_account_id', $ids)
- ->where('launch_date', '>=', $monthStart)
- ->groupBy('from_account_id')
- ->selectRaw('from_account_id, SUM(amount) as total')
- ->pluck('total', 'from_account_id');
- foreach ($accounts as $account) {
- $balance = (float) ($incoming[$account->id] ?? 0) - (float) ($outgoing[$account->id] ?? 0);
- $monthNet = (float) ($incomingMonth[$account->id] ?? 0) - (float) ($outgoingMonth[$account->id] ?? 0);
- $account->setAttribute('balance', $balance);
- $account->setAttribute('balance_previous', $balance - $monthNet);
- }
- }
- public function findById(int $id): ?TreasuryAccount
- {
- return TreasuryAccount::find($id);
- }
- public function findByIdForUnit(int $id, int $unitId): ?TreasuryAccount
- {
- return TreasuryAccount::where('id', $id)->where('unit_id', $unitId)->first();
- }
- public function create(array $data): TreasuryAccount
- {
- // Sem unit_id => conta da rede (franqueador). Com unit_id => conta da unidade (franchisee).
- $data['unit_id'] = $data['unit_id'] ?? null;
- return TreasuryAccount::create($data);
- }
- public function update(int $id, array $data): ?TreasuryAccount
- {
- $model = $this->findById($id);
- if (!$model) {
- return null;
- }
- $model->update($data);
- return $model->fresh();
- }
- public function delete(int $id): bool
- {
- $model = $this->findById($id);
- if (!$model) {
- return false;
- }
- return $model->delete();
- }
- // Add custom business logic methods here
- }
|