diff --git a/app/common/Ideal/Cartola/Banco.php b/app/common/Ideal/Cartola/Banco.php
index 16d88e2..253a952 100644
--- a/app/common/Ideal/Cartola/Banco.php
+++ b/app/common/Ideal/Cartola/Banco.php
@@ -2,9 +2,10 @@
namespace Incoviba\Common\Ideal\Cartola;
use Incoviba\Common\Define;
+use Incoviba\Common\Ideal\Service;
use Psr\Http\Message\UploadedFileInterface;
-abstract class Banco implements Define\Cartola\Banco
+abstract class Banco extends Service implements Define\Cartola\Banco
{
public function process(UploadedFileInterface $file): array
{
@@ -14,6 +15,9 @@ abstract class Banco implements Define\Cartola\Banco
foreach ($data as $row) {
$r = [];
foreach ($columns as $old => $new) {
+ if (!isset($row[$old])) {
+ continue;
+ }
$r[$new] = $row[$old];
}
$temp []= $r;
diff --git a/app/resources/routes/api/contabilidad/cartolas.php b/app/resources/routes/api/contabilidad/cartolas.php
index f81baa7..52cdf3c 100644
--- a/app/resources/routes/api/contabilidad/cartolas.php
+++ b/app/resources/routes/api/contabilidad/cartolas.php
@@ -1,9 +1,13 @@
group('/cartolas', function($app) {
- $app->post('/procesar[/]', [Contabilidad::class, 'procesarCartola']);
+ $app->post('/procesar[/]', [Cartolas::class, 'procesar']);
});
$app->group('/cartola', function($app) {
- $app->post('/exportar[/]', [Contabilidad::class, 'exportarCartola']);
+ $app->group('/diaria', function($app) {
+ $app->post('/ayer[/]', [Cartolas::class, 'ayer']);
+ $app->post('/procesar[/]', [Cartolas::class, 'diaria']);
+ });
+ $app->post('/exportar[/]', [Cartolas::class, 'exportar']);
});
diff --git a/app/resources/routes/contabilidad/cartolas.php b/app/resources/routes/contabilidad/cartolas.php
new file mode 100644
index 0000000..7bd0058
--- /dev/null
+++ b/app/resources/routes/contabilidad/cartolas.php
@@ -0,0 +1,6 @@
+group('/cartolas', function($app) {
+ $app->get('/diaria[/]', [Contabilidad::class, 'diaria']);
+});
diff --git a/app/resources/views/contabilidad/cartolas/diaria.blade.php b/app/resources/views/contabilidad/cartolas/diaria.blade.php
new file mode 100644
index 0000000..26b4d66
--- /dev/null
+++ b/app/resources/views/contabilidad/cartolas/diaria.blade.php
@@ -0,0 +1,323 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+
+
+ Hoy |
+ Último Saldo |
+ Saldo Actual |
+ Diferencia |
+
+
+
+
+
+
+
+
+
+ Fecha |
+ Glosa |
+ Documento |
+ Cargo |
+ Abono |
+ Saldo |
+ Orden |
+
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php
index 485eda8..d0e986c 100644
--- a/app/setup/setups/services.php
+++ b/app/setup/setups/services.php
@@ -32,8 +32,12 @@ return [
},
Incoviba\Service\Cartola::class => function(ContainerInterface $container) {
return (new Incoviba\Service\Cartola(
+ $container->get(Psr\Log\LoggerInterface::class),
$container->get(Psr\Http\Message\StreamFactoryInterface::class),
- $container->get(Incoviba\Common\Define\Contabilidad\Exporter::class)
+ $container->get(Incoviba\Common\Define\Contabilidad\Exporter::class),
+ $container->get(Incoviba\Repository\Inmobiliaria\Cuenta::class),
+ $container->get(Incoviba\Repository\Movimiento::class),
+ $container->get(Incoviba\Repository\Cartola::class)
))
->register('security', $container->get(Incoviba\Service\Cartola\Security::class))
->register('itau', $container->get(Incoviba\Service\Cartola\Itau::class))
@@ -48,6 +52,7 @@ return [
},
Incoviba\Service\Contabilidad\Nubox::class => function(ContainerInterface $container) {
return new Incoviba\Service\Contabilidad\Nubox(
+ $container->get(Psr\Log\LoggerInterface::class),
$container->get(Incoviba\Repository\Nubox::class),
$container->get(Incoviba\Service\Redis::class),
new GuzzleHttp\Client(),
diff --git a/app/src/Controller/API/Contabilidad.php b/app/src/Controller/API/Contabilidad.php
index bf35b84..c99ce31 100644
--- a/app/src/Controller/API/Contabilidad.php
+++ b/app/src/Controller/API/Contabilidad.php
@@ -2,51 +2,16 @@
namespace Incoviba\Controller\API;
use DateTimeImmutable;
+use Incoviba\Common\Ideal\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Repository;
use Incoviba\Service;
-class Contabilidad
+class Contabilidad extends Controller
{
use withJson;
- public function procesarCartola(ServerRequestInterface $request, ResponseInterface $response,
- Repository\Inmobiliaria $inmobiliariaRepository,
- Repository\Banco $bancoRepository,
- Service\Cartola $cartolaService): ResponseInterface
- {
- $body = $request->getParsedBody();
- $output = [
- 'input' => $body,
- 'movimientos' => []
- ];
- try {
- $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
- $banco = $bancoRepository->fetchById($body['banco']);
- $mes = new DateTimeImmutable($body['mes']);
- $file = $request->getUploadedFiles()['file'];
- $output['movimientos'] = $cartolaService->process($inmobiliaria, $banco, $mes, $file);
- } catch (EmptyResult) {}
- return $this->withJson($response, $output);
- }
- public function exportarCartola(ServerRequestInterface $request, ResponseInterface $response,
- Repository\Inmobiliaria $inmobiliariaRepository,
- Repository\Banco $bancoRepository,
- Service\Cartola $cartolaService): ResponseInterface
- {
- $body = $request->getParsedBody();
- $output = [
- 'input' => $body,
- 'filename' => ''
- ];
- try {
- $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
- $banco = $bancoRepository->fetchById($body['banco']);
- $mes = new DateTimeImmutable($body['mes']);
- $output['filename'] = $cartolaService->export($inmobiliaria, $banco, $mes, json_decode($body['movimientos']));
- } catch (EmptyResult) {}
- return $this->withJson($response, $output);
- }
+
}
diff --git a/app/src/Controller/API/Contabilidad/Cartolas.php b/app/src/Controller/API/Contabilidad/Cartolas.php
new file mode 100644
index 0000000..299c011
--- /dev/null
+++ b/app/src/Controller/API/Contabilidad/Cartolas.php
@@ -0,0 +1,98 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'movimientos' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
+ $banco = $bancoRepository->fetchById($body['banco']);
+ $mes = new DateTimeImmutable($body['mes']);
+ $file = $request->getUploadedFiles()['file'];
+ $output['movimientos'] = $cartolaService->process($inmobiliaria, $banco, $mes, $file);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function exportar(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Banco $bancoRepository,
+ Service\Cartola $cartolaService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'filename' => ''
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
+ $banco = $bancoRepository->fetchById($body['banco']);
+ $mes = new DateTimeImmutable($body['mes']);
+ $output['filename'] = $cartolaService->export($inmobiliaria, $banco, $mes, json_decode($body['movimientos']));
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function diaria(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Banco $bancoRepository,
+ Service\Cartola $cartolaService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'cartola' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria_rut']);
+ $banco = $bancoRepository->fetchById($body['banco_id']);
+ $fecha = new DateTimeImmutable($body['fecha']);
+ $file = $request->getUploadedFiles()['file'];
+ $output['cartola'] = $cartolaService->diaria($inmobiliaria, $banco, $fecha, $file);
+ } catch (EmptyResult $exception) {
+ $this->logger->debug($exception);
+ }
+ return $this->withJson($response, $output);
+ }
+ public function ayer(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Banco $bancoRepository,
+ Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ Repository\Cartola $cartolaRepository): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'cartola' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria_rut']);
+ $banco = $bancoRepository->fetchById($body['banco_id']);
+ $cuenta = $cuentaRepository->fetchByInmobiliariaAndBanco($inmobiliaria->rut, $banco->id);
+ $fecha = new DateTimeImmutable($body['fecha']);
+ $output['cartola'] = $cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ } catch (EmptyResult $exception) {
+ $this->logger->critical($exception);
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/Contabilidad.php b/app/src/Controller/Contabilidad.php
new file mode 100644
index 0000000..8653d8c
--- /dev/null
+++ b/app/src/Controller/Contabilidad.php
@@ -0,0 +1,31 @@
+fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $inmobiliarias = $inmobiliariaRepository->fetchAll();
+ $this->saveRedis($redisService, $redisKey, $inmobiliarias, 30 * 24 * 60 * 60);
+ } catch (EmptyResult) {}
+ }
+ return $view->render($response, 'contabilidad.cartolas.diaria', compact('inmobiliarias'));
+ }
+}
diff --git a/app/src/Model/Cartola.php b/app/src/Model/Cartola.php
new file mode 100644
index 0000000..49363b6
--- /dev/null
+++ b/app/src/Model/Cartola.php
@@ -0,0 +1,26 @@
+ $this->cuenta->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'cargos' => $this->cargos,
+ 'abonos' => $this->abonos,
+ 'saldo' => $this->saldo
+ ]);
+ }
+}
diff --git a/app/src/Model/Movimiento.php b/app/src/Model/Movimiento.php
new file mode 100644
index 0000000..6ca1a36
--- /dev/null
+++ b/app/src/Model/Movimiento.php
@@ -0,0 +1,29 @@
+ $this->cuenta->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'glosa' => $this->glosa,
+ 'documento' => $this->documento,
+ 'cargo' => $this->cargo,
+ 'abono' => $this->abono,
+ 'saldo' => $this->saldo
+ ]);
+ }
+}
diff --git a/app/src/Repository/Cartola.php b/app/src/Repository/Cartola.php
new file mode 100644
index 0000000..be03b12
--- /dev/null
+++ b/app/src/Repository/Cartola.php
@@ -0,0 +1,60 @@
+setTable('cartolas');
+ }
+
+ public function create(?array $data = null): Model\Cartola
+ {
+ $map = (new Implement\Repository\MapperParser(['cargos', 'abonos', 'saldo']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('cuenta_id', (new Implement\Repository\Mapper())
+ ->setProperty('cuenta')
+ ->setFunction(function($data) {
+ return $this->cuentaRepository->fetchById($data['cuenta_id']);
+ }));
+ return $this->parseData(new Model\Cartola(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Cartola
+ {
+ $model->id = $this->saveNew([
+ 'cuenta_id',
+ 'fecha',
+ 'cargos',
+ 'abonos',
+ 'saldo'
+ ], [
+ $model->cuenta->id,
+ $model->fecha->format('Y-m-d'),
+ $model->cargos,
+ $model->abonos,
+ $model->saldo
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Cartola
+ {
+ return $this->update($model, ['cuenta_id', 'fecha', 'cargos', 'abonos', 'saldo'], $new_data);
+ }
+
+ public function fetchByCuentaAndFecha(int $cuenta_id, DateTimeInterface $fecha): Model\Cartola
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ? AND fecha = ?');
+ return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d')]);
+ }
+}
diff --git a/app/src/Repository/Inmobiliaria/Cuenta.php b/app/src/Repository/Inmobiliaria/Cuenta.php
index 71e3b5d..5005723 100644
--- a/app/src/Repository/Inmobiliaria/Cuenta.php
+++ b/app/src/Repository/Inmobiliaria/Cuenta.php
@@ -6,6 +6,7 @@ use Incoviba\Common\Ideal;
use Incoviba\Repository;
use Incoviba\Model;
use Incoviba\Common\Implement;
+use PhpParser\Node\Expr\BinaryOp\Mod;
class Cuenta extends Ideal\Repository
{
@@ -49,4 +50,12 @@ class Cuenta extends Ideal\Repository
->where('inmobiliaria = ?');
return $this->fetchMany($query, [$inmobiliaria_rut]);
}
+ public function fetchByInmobiliariaAndBanco(int $inmobiliaria_rut, int $banco_id): Model\Inmobiliaria\Cuenta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria = ? AND banco = ?');
+ return $this->fetchOne($query, [$inmobiliaria_rut, $banco_id]);
+ }
}
diff --git a/app/src/Repository/Movimiento.php b/app/src/Repository/Movimiento.php
new file mode 100644
index 0000000..8e11f06
--- /dev/null
+++ b/app/src/Repository/Movimiento.php
@@ -0,0 +1,64 @@
+setTable('movimientos');
+ }
+
+ public function create(?array $data = null): Model\Movimiento
+ {
+ $map = (new Implement\Repository\MapperParser(['cargo', 'abono', 'saldo', 'glosa', 'documento']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('cuenta_id', (new Implement\Repository\Mapper())
+ ->setProperty('cuenta')
+ ->setFunction(function($data) {
+ return $this->cuentaRepository->fetchById($data['cuenta_id']);
+ })
+ );
+ return $this->parseData(new Model\Movimiento(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Movimiento
+ {
+ $model->id = $this->saveNew([
+ 'cuenta_id',
+ 'fecha',
+ 'glosa',
+ 'documento',
+ 'cargo',
+ 'abono',
+ 'saldo'
+ ], [
+ $model->cuenta->id,
+ $model->fecha->format('Y-m-d'),
+ $model->glosa,
+ $model->documento,
+ $model->cargo,
+ $model->abono,
+ $model->saldo
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Movimiento
+ {
+ return $this->update($model, ['cuenta_id', 'fecha', 'glosa', 'documento', 'cargo', 'abono', 'saldo'], $new_data);
+ }
+
+ public function fetchByCuentaAndFechaAndMonto(int $cuenta_id, DateTimeInterface $fecha, int $monto): Model\Movimiento
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ? AND fecha = ? AND (cargo = ? OR abono = ?)');
+ return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d'), $monto, $monto]);
+ }
+}
diff --git a/app/src/Service/Cartola.php b/app/src/Service/Cartola.php
index 231ba7a..ae7f927 100644
--- a/app/src/Service/Cartola.php
+++ b/app/src/Service/Cartola.php
@@ -2,15 +2,26 @@
namespace Incoviba\Service;
use DateTimeInterface;
+use DateTimeImmutable;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileInterface;
+use Psr\Log\LoggerInterface;
+use Incoviba\Common\Ideal\Service;
use Incoviba\Common\Define\Cartola\Banco;
use Incoviba\Common\Define\Contabilidad\Exporter;
+use Incoviba\Common\Implement\Exception;
use Incoviba\Model;
+use Incoviba\Repository;
-class Cartola
+class Cartola extends Service
{
- public function __construct(protected StreamFactoryInterface $streamFactory, protected Exporter $exporter) {}
+ public function __construct(LoggerInterface $logger,
+ protected StreamFactoryInterface $streamFactory, protected Exporter $exporter,
+ protected Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ protected Repository\Movimiento $movimientoRepository,
+ protected Repository\Cartola $cartolaRepository) {
+ parent::__construct($logger);
+ }
protected array $bancos;
public function register(string $name, Banco $banco): Cartola
@@ -26,4 +37,75 @@ class Cartola
{
return $this->exporter->export($inmobiliaria, $banco, $mes, $movimientos);
}
+ public function diaria(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $fecha, UploadedFileInterface $file): array
+ {
+ $cuenta = $this->cuentaRepository->fetchByInmobiliariaAndBanco($inmobiliaria->rut, $banco->id);
+
+ $ms = $this->getMovimientosDiarios($banco, $file);
+
+ $cartolaData = [
+ 'cargos' => 0,
+ 'abonos' => 0,
+ 'saldo' => 0
+ ];
+ $movimientos = [];
+ foreach ($ms as $m) {
+ $movimiento = $this->buildMovimiento($cuenta, $m);
+
+ if ($movimiento->fecha->getTimestamp() === $fecha->getTimestamp()) {
+ $movimientos []= $movimiento;
+ $cartolaData['cargos'] += $movimiento->cargo;
+ $cartolaData['abonos'] += $movimiento->abono;
+ }
+ $cartolaData['saldo'] = $movimiento->saldo;
+ }
+ $cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
+ return compact('cartola', 'movimientos');
+ }
+
+ protected function getMovimientosDiarios(Model\Banco $banco, UploadedFileInterface $file): array
+ {
+ $movimientos = $this->bancos[strtolower($banco->nombre)]->process($file);
+ switch (strtolower($banco->nombre)) {
+ case 'security':
+ $movimientos = $this->processMovimientosDiariosSecurity($movimientos);
+ break;
+ case 'itau':
+ case 'santander':
+ break;
+ }
+ return $movimientos;
+ }
+ protected function processMovimientosDiariosSecurity(array $movimientos): array
+ {
+ $movimientos = array_reverse($movimientos);
+ array_shift($movimientos);
+ return $movimientos;
+ }
+ protected function buildCartola(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, array $data): Model\Cartola
+ {
+ try {
+ return $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ } catch (Exception\EmptyResult) {
+ $data['cuenta_id'] = $cuenta->id;
+ $data['fecha'] = $fecha->format('Y-m-d');
+ $cartola = $this->cartolaRepository->create($data);
+ return $this->cartolaRepository->save($cartola);
+ }
+ }
+ protected function buildMovimiento(Model\Inmobiliaria\Cuenta $cuenta, array $data): Model\Movimiento
+ {
+ try {
+ return $this->movimientoRepository
+ ->fetchByCuentaAndFechaAndMonto(
+ $cuenta->id,
+ new DateTimeImmutable($data['fecha']),
+ $data['cargo'] ?? $data['abono']
+ );
+ } catch (Exception\EmptyResult) {
+ $data['cuenta_id'] = $cuenta->id;
+ $movimiento = $this->movimientoRepository->create($data);
+ return $this->movimientoRepository->save($movimiento);
+ }
+ }
}
diff --git a/app/src/Service/Cartola/Security.php b/app/src/Service/Cartola/Security.php
index 28323a2..c00861c 100644
--- a/app/src/Service/Cartola/Security.php
+++ b/app/src/Service/Cartola/Security.php
@@ -24,8 +24,10 @@ class Security extends Banco
'fecha' => 'fecha',
'descripción' => 'glosa',
'número de documentos' => 'documento',
+ 'nº documento' => 'documento',
'cargos' => 'cargo',
- 'abonos' => 'abono'
+ 'abonos' => 'abono',
+ 'saldos' => 'saldo'
];
}
@@ -33,10 +35,9 @@ class Security extends Banco
{
$filename = '/tmp/cartola.xls';
$file->moveTo($filename);
- $reader = PhpSpreadsheet\IOFactory::createReader('Xls');
- $xlsx = $reader->load($filename);
+ $xlsx = @PhpSpreadsheet\IOFactory::load($filename);
$worksheet = $xlsx->getActiveSheet();
- $rows = $worksheet->getRowIterator();
+ $rows = $worksheet->getRowIterator(3);
$dataFound = false;
$columns = [];
$data = [];
@@ -44,10 +45,10 @@ class Security extends Banco
$cells = $row->getCellIterator();
$rowData = [];
foreach ($cells as $cell) {
- if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() === "fecha ") {
+ if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() !== null and strtolower($cell->getCalculatedValue()) === "fecha ") {
$cols = $row->getColumnIterator();
foreach ($cols as $col) {
- $columns[$col->getColumn()] = trim($col->getCalculatedValue());
+ $columns[$col->getColumn()] = trim(strtolower($col->getCalculatedValue()), ' ');
}
$dataFound = true;
break;
@@ -62,7 +63,11 @@ class Security extends Banco
$col = $columns[$cell->getColumn()];
$value = $cell->getCalculatedValue();
if ($col === 'fecha') {
- $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue(), 'America/Santiago')->format('Y-m-d');
+ if ((int) $cell->getValue() !== $cell->getValue()) {
+ $value = implode('-', array_reverse(explode('-', $cell->getValue())));
+ } else {
+ $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue(), 'America/Santiago')->format('Y-m-d');
+ }
}
$rowData[$col] = $value;
}