categoria === null) { $this->categoria = $this->childOf(Categoria::class, [Model::SELF_KEY => 'categoria_id']); } return $this->categoria; } protected $tipo; public function tipo() { if ($this->tipo === null) { $this->tipo = $this->childOf(TipoCuenta::class, [Model::SELF_KEY => 'tipo_id']); } return $this->tipo; } protected $moneda; public function moneda() { if ($this->moneda === null) { $this->moneda = $this->childOf(Moneda::class, [Model::SELF_KEY => 'moneda_id']); } return $this->moneda; } protected $cargos; public function cargos() { if ($this->cargos === null) { $this->cargos = $this->parentOf(Transaccion::class, [Model::CHILD_KEY => 'credito_id']); } return $this->cargos; } protected $abonos; public function abonos() { if ($this->abonos === null) { $this->abonos = $this->parentOf(Transaccion::class, [Model::CHILD_KEY => 'debito_id']); } return $this->abonos; } protected $consolidados; public function consolidados() { if ($this->consolidados === null) { $this->consolidados = $this->parentOf(Consolidado::class, [Model::CHILD_KEY => 'cuenta_id']); } return $this->consolidados; } public function hasConsolidados(): bool { $t = Carbon::now(); return (bool) Model::factory(Consolidado::class) ->whereEqual('cuenta_id', $this->id) ->count('id'); } public function hasConsolidadosPending(): bool { $t = Carbon::now(); return !(bool) Model::factory(Consolidado::class) ->whereEqual('cuenta_id', $this->id) ->whereGte('fecha', $t->copy()->subMonthNoOverflow()->startOfMonth()->format('Y-m-d')) ->orderByDesc('fecha') ->count('id'); } public function hasTransacciones(): bool { return (bool) Model::factory(Transaccion::class) ->select('transacciones.*') ->join('cuentas', 'cuentas.id = transacciones.debito_id OR cuentas.id = transacciones.credito_id') ->whereEqual('cuentas.id', $this->id) ->count('transacciones.id'); } protected $transacciones; protected function parseTransaccion(Transaccion $transaccion) { $transaccion->setFactory($this->factory); if ($transaccion->debito_id === $this->id) { $transaccion->valor = - $transaccion->valor; } $transaccion->valor = $transaccion->transformar($this->moneda()); return $transaccion; } public function transacciones($limit = null, $start = 0) { $transacciones = Model::factory(Transaccion::class) ->select('transacciones.*') ->join('cuentas', 'cuentas.id = transacciones.debito_id OR cuentas.id = transacciones.credito_id') ->whereEqual('cuentas.id', $this->id) ->orderByAsc('transacciones.fecha'); if ($limit !== null) { $transacciones = $transacciones->limit($limit) ->offset($start); } $transacciones = $transacciones->findMany(); foreach ($transacciones as &$transaccion) { $transaccion = $this->parseTransaccion($transaccion); } return $transacciones; } public function transaccionesMonth(Carbon $month) { $start = $month->copy()->startOfMonth(); $end = $month->copy()->endOfMonth(); $transacciones = Model::factory(Transaccion::class) ->select('transacciones.*') ->join('cuentas', 'cuentas.id = transacciones.debito_id OR cuentas.id = transacciones.credito_id') ->whereEqual('cuentas.id', $this->id) ->whereRaw("transacciones.fecha BETWEEN '{$start->format('Y-m-d')}' AND '{$end->format('Y-m-d')}'") ->orderByAsc('transacciones.fecha'); $transacciones = $transacciones->findMany(); foreach ($transacciones as &$transaccion) { $transaccion = $this->parseTransaccion($transaccion); } return $transacciones; } public function acumulacion(Carbon $date) { $consolidados = $this->consolidados(); $saldo = 0; foreach ($consolidados as $consolidado) { if ($consolidado->fecha() >= $date) { continue; } $saldo += $consolidado->saldo($date); } return $saldo; } protected $saldo; public function saldo(Service $service = null, $in_clp = false) { if ($this->saldo === null) { $this->saldo = 0; if (count($this->transacciones()) > 0) { $this->saldo = array_reduce($this->transacciones(), function($sum, $item) { return $sum + $item->valor; }); } } if ($in_clp and $this->moneda()->codigo !== 'CLP') { $fecha = Carbon::today(); if ($this->moneda()->codigo == 'USD') { $fecha = match ($fecha->weekday()) { 0 => $fecha->subWeek()->weekday(5), 6 => $fecha->weekday(5), default => $fecha }; } $service->get($fecha->format('Y-m-d'), $this->moneda()->id); return $this->moneda()->cambiar($fecha, $this->saldo); } return $this->saldo; } public function format($valor) { return $this->moneda()->format($valor); } public function toArray(Service $service = null, $in_clp = false): array { $arr = parent::toArray(); $arr['tipo'] = $this->tipo()->toArray(); $arr['moneda'] = $this->moneda()->toArray(); $arr['saldo'] = $this->saldo($service, $in_clp); $arr['saldoFormateado'] = $this->format($this->saldo($service, $in_clp)); return $arr; } }