175 lines
5.9 KiB
PHP
175 lines
5.9 KiB
PHP
<?php
|
|
namespace Contabilidad;
|
|
|
|
use Carbon\Carbon;
|
|
use ProVM\Common\Alias\Model;
|
|
use Contabilidad\Common\Service\TiposCambios as Service;
|
|
|
|
/**
|
|
* @property int $id
|
|
* @property string $nombre
|
|
* @property Categoria $categoria_id
|
|
* @property TipoCuenta $tipo_id
|
|
* @property Moneda $moneda_id
|
|
*/
|
|
class Cuenta extends Model {
|
|
public static $_table = 'cuentas';
|
|
protected static $fields = ['nombre', 'categoria_id', 'tipo_id', 'moneda_id'];
|
|
|
|
protected $categoria;
|
|
public function categoria() {
|
|
if ($this->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;
|
|
}
|
|
}
|