Consolidar
This commit is contained in:
53
api/common/Controller/Consolidados.php
Normal file
53
api/common/Controller/Consolidados.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use ProVM\Common\Factory\Model as Factory;
|
||||
use ProVM\Common\Define\Controller\Json;
|
||||
use Contabilidad\Common\Service\Consolidar as Service;
|
||||
use Contabilidad\Consolidado;
|
||||
|
||||
class Consolidados {
|
||||
use Json;
|
||||
|
||||
public function __invoke(Request $request, Response $response, Factory $factory, $cuenta_id): Response {
|
||||
$consolidados = $factory->find(Consolidados::class)->where([['cuenta_id' => $cuenta_id]])->many();
|
||||
$output = [
|
||||
'consolidados' => array_map(function($item) {
|
||||
return $item->toArray();
|
||||
}, $consolidados)
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function add(Request $request, Response $response, Factory $factory): Response {
|
||||
$input = json_decode($request->getBody()->getContents());
|
||||
$output = [
|
||||
'input' => $input,
|
||||
'consolidados' => []
|
||||
];
|
||||
if (!is_array($input)) {
|
||||
$input = [$input];
|
||||
}
|
||||
foreach ($input as $data) {
|
||||
$consolidado = Consolidado::add($factory, $data);
|
||||
$status = $consolidado->save();
|
||||
$output['consolidados'] []= [
|
||||
'consolidado' => $consolidado->toArray(),
|
||||
'added' => $status
|
||||
];
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function cli(Request $request, Response $response, Service $service): Response {
|
||||
try {
|
||||
if (!$service->isConsolidado()) {
|
||||
$service->consolidar();
|
||||
}
|
||||
} catch (\Error | \Exception $e) {
|
||||
error_log($e);
|
||||
throw $e;
|
||||
}
|
||||
return $this->withJson($response);
|
||||
}
|
||||
}
|
20
api/common/Middleware/Consolidar.php
Normal file
20
api/common/Middleware/Consolidar.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Middleware;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\RequestHandlerInterface as Handler;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Contabilidad\Common\Service\Consolidar as ConsolidarService;
|
||||
|
||||
class Consolidar {
|
||||
protected $service;
|
||||
public function __construct(ConsolidarService $service) {
|
||||
$this->service = $service;
|
||||
}
|
||||
public function __invoke(Request $request, Handler $handler): Response {
|
||||
if (!$this->service->isConsolidado()) {
|
||||
$this->service->consolidar();
|
||||
}
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
148
api/common/Service/Consolidar.php
Normal file
148
api/common/Service/Consolidar.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
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() {
|
||||
$consolidado = true;
|
||||
$cuentas = $this->getCuentas();
|
||||
if ($cuentas === null) {
|
||||
return false;
|
||||
}
|
||||
foreach ($cuentas as $cuenta) {
|
||||
$transacciones = $cuenta->hasTransacciones();
|
||||
if (!$transacciones) {
|
||||
continue;
|
||||
}
|
||||
$consolidados = $cuenta->hasConsolidados();
|
||||
if (!$consolidados and $transacciones) {
|
||||
$consolidado = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $consolidado;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user