156 lines
5.2 KiB
PHP
156 lines
5.2 KiB
PHP
<?php
|
|
namespace Contabilidad\Common\Service;
|
|
|
|
use Carbon\Carbon;
|
|
use Contabilidad\Queue;
|
|
use \Model;
|
|
use ProVM\Common\Factory\Model as ModelFactory;
|
|
use Contabilidad\Consolidado;
|
|
use Contabilidad\Cuenta;
|
|
use Contabilidad\Transaccion;
|
|
|
|
class Consolidar {
|
|
protected $factory;
|
|
public function __construct(ModelFactory $factory) {
|
|
$this->factory = $factory;
|
|
}
|
|
protected $cuentas;
|
|
public function getCuentas() {
|
|
if ($this->cuentas === null) {
|
|
$this->cuentas = $this->factory->find(Cuenta::class)->many();
|
|
}
|
|
return $this->cuentas;
|
|
}
|
|
|
|
public function isConsolidado(): bool {
|
|
$cuentas = $this->getCuentas();
|
|
if ($cuentas === null) {
|
|
return true;
|
|
}
|
|
foreach ($cuentas as $cuenta) {
|
|
$transacciones = $cuenta->hasTransacciones();
|
|
if (!$transacciones) {
|
|
continue;
|
|
}
|
|
$pendientes = $cuenta->hasConsolidadosPending();
|
|
if ($pendientes) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public function queue() {
|
|
$data = [
|
|
'command' => 'consolidar',
|
|
'created' => Carbon::now()->format('Y-m-d H:i:s')
|
|
];
|
|
$queue = Queue::add($this->factory, $data);
|
|
$queue->save();
|
|
}
|
|
public function consolidar() {
|
|
ini_set('max_execution_time', 60*5);
|
|
|
|
foreach ($this->getCuentas() as $cuenta) {
|
|
if (!$cuenta->hasTransacciones()) {
|
|
continue;
|
|
}
|
|
$first = $this->getFirst($cuenta);
|
|
$last = $this->getLast($cuenta);
|
|
for ($current = $first->copy()->startOfMonth(); $current < $last->copy()->addMonthWithoutOverflow()->endOfMonth(); $current = $current->copy()->addMonthWithoutOverflow()) {
|
|
$transacciones = $this->getTransacciones($cuenta, $current);
|
|
if (count($transacciones) == 0) {
|
|
continue;
|
|
}
|
|
$f = $this->factory;
|
|
array_walk($transacciones, function(&$item) use ($cuenta, $f) {
|
|
$item->setFactory($f);
|
|
$item->valor = $item->transformar($cuenta->moneda());
|
|
});
|
|
$saldo = array_reduce($transacciones, function($sum, $item) {
|
|
return $sum + $item->valor;
|
|
});
|
|
$data = [
|
|
'cuenta_id' => $cuenta->id,
|
|
'fecha' => $current->format('Y-m-1'),
|
|
'periodo' => 'P1M',
|
|
'saldo' => $saldo
|
|
];
|
|
$consolidado = $this->factory->create(Consolidado::class, $data);
|
|
$consolidado->save();
|
|
}
|
|
}
|
|
}
|
|
public function getFirst(Cuenta $cuenta): ?Carbon {
|
|
$first = [
|
|
Model::factory(Transaccion::class)
|
|
->select('fecha')
|
|
->whereEqual('debito_id', $cuenta->id)
|
|
->orderByAsc('fecha')
|
|
->findOne(),
|
|
Model::factory(Transaccion::class)
|
|
->select('fecha')
|
|
->whereEqual('credito_id', $cuenta->id)
|
|
->orderByAsc('fecha')
|
|
->findOne()
|
|
];
|
|
if (!$first[0]) {
|
|
if (!$first[1]) {
|
|
return null;
|
|
}
|
|
return $first[1]->fecha();
|
|
}
|
|
if (!$first[1]) {
|
|
return $first[0]->fecha();
|
|
}
|
|
if ($first[0]->fecha() < $first[1]->fecha()) {
|
|
return $first[0]->fecha();
|
|
}
|
|
return $first[1]->fecha();
|
|
}
|
|
public function getLast(Cuenta $cuenta): ?Carbon {
|
|
$fechas = [
|
|
Model::factory(Transaccion::class)
|
|
->select('fecha')
|
|
->whereEqual('debito_id', $cuenta->id)
|
|
->orderByDesc('fecha')
|
|
->findOne(),
|
|
Model::factory(Transaccion::class)
|
|
->select('fecha')
|
|
->whereEqual('credito_id', $cuenta->id)
|
|
->orderByDesc('fecha')
|
|
->findOne()
|
|
];
|
|
if (!$fechas[0]) {
|
|
if (!$fechas[1]) {
|
|
return null;
|
|
}
|
|
return $fechas[1]->fecha();
|
|
}
|
|
if (!$fechas[1]) {
|
|
return $fechas[0]->fecha();
|
|
}
|
|
if ($fechas[0]->fecha() > $fechas[1]->fecha()) {
|
|
return $fechas[0]->fecha();
|
|
}
|
|
return $fechas[1]->fecha();
|
|
}
|
|
public function getTransacciones(Cuenta $cuenta, Carbon $fecha) {
|
|
$start = $fecha->copy()->startOfMonth();
|
|
$end = $fecha->copy()->endOfMonth();
|
|
$debitos = Model::factory(Transaccion::class)
|
|
->whereEqual('debito_id', $cuenta->id)
|
|
->whereRaw("fecha BETWEEN '{$start->format('Y-m-d')}' AND '{$end->format('Y-m-d')}'")
|
|
->findMany();
|
|
if ($debitos) {
|
|
array_walk($debitos, function(&$item) {
|
|
$item->valor *= -1;
|
|
});
|
|
}
|
|
$creditos = Model::factory(Transaccion::class)
|
|
->whereEqual('credito_id', $cuenta->id)
|
|
->whereRaw("fecha BETWEEN '{$start->format('Y-m-d')}' AND '{$end->format('Y-m-d')}'")
|
|
->findMany();
|
|
return array_merge($debitos, $creditos);
|
|
}
|
|
}
|