From 674aba801ef7953dcfd178b613a1297fadea74b1 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Wed, 17 Jan 2024 10:33:11 -0300 Subject: [PATCH] Cartolas --- .gitignore | 1 + app/common/Define/Cartola/Banco.php | 9 + app/common/Define/Contabilidad/Exporter.php | 10 + app/composer.json | 1 + .../routes/api/contabilidad/cartolas.php | 9 + .../routes/api/contabilidad/nubox.php | 11 + app/resources/routes/api/inmobiliarias.php | 10 + .../routes/contabilidad/centros_costos.php | 1 + .../centros_costos/asignar.blade.php | 402 ++++++++++++++++++ app/setup/settings/folders.php | 4 +- app/setup/settings/nubox.php | 8 + app/setup/setups/psr7.php | 8 +- app/setup/setups/services.php | 22 + app/src/Controller/API/Contabilidad.php | 52 +++ app/src/Controller/API/Informes.php | 25 ++ app/src/Controller/API/Inmobiliarias.php | 48 +++ app/src/Controller/API/Nubox.php | 90 ++++ app/src/Controller/API/Proyectos.php | 15 + app/src/Controller/CentrosCostos.php | 8 + app/src/Model/Nubox.php | 18 + app/src/Repository/Inmobiliaria.php | 16 + app/src/Repository/Inmobiliaria/Cuenta.php | 52 +++ app/src/Repository/Nubox.php | 55 +++ app/src/Service/Cartola.php | 29 ++ app/src/Service/Cartola/Security.php | 54 +++ .../Service/Contabilidad/Exporter/Nubox.php | 115 +++++ app/src/Service/Contabilidad/Nubox.php | 139 ++++++ 27 files changed, 1210 insertions(+), 2 deletions(-) create mode 100644 app/common/Define/Cartola/Banco.php create mode 100644 app/common/Define/Contabilidad/Exporter.php create mode 100644 app/resources/routes/api/contabilidad/cartolas.php create mode 100644 app/resources/routes/api/contabilidad/nubox.php create mode 100644 app/resources/routes/api/inmobiliarias.php create mode 100644 app/resources/views/contabilidad/centros_costos/asignar.blade.php create mode 100644 app/setup/settings/nubox.php create mode 100644 app/src/Controller/API/Contabilidad.php create mode 100644 app/src/Controller/API/Informes.php create mode 100644 app/src/Controller/API/Inmobiliarias.php create mode 100644 app/src/Controller/API/Nubox.php create mode 100644 app/src/Model/Nubox.php create mode 100644 app/src/Repository/Inmobiliaria/Cuenta.php create mode 100644 app/src/Repository/Nubox.php create mode 100644 app/src/Service/Cartola.php create mode 100644 app/src/Service/Cartola/Security.php create mode 100644 app/src/Service/Contabilidad/Exporter/Nubox.php create mode 100644 app/src/Service/Contabilidad/Nubox.php diff --git a/.gitignore b/.gitignore index 94a1003..1646ae8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ **/cache/ **/modules/ **/.idea/ +**/upload?/ diff --git a/app/common/Define/Cartola/Banco.php b/app/common/Define/Cartola/Banco.php new file mode 100644 index 0000000..2a23f06 --- /dev/null +++ b/app/common/Define/Cartola/Banco.php @@ -0,0 +1,9 @@ +group('/cartolas', function($app) { + $app->post('/procesar[/]', [Contabilidad::class, 'procesarCartola']); +}); +$app->group('/cartola', function($app) { + $app->post('/exportar[/]', [Contabilidad::class, 'exportarCartola']); +}); diff --git a/app/resources/routes/api/contabilidad/nubox.php b/app/resources/routes/api/contabilidad/nubox.php new file mode 100644 index 0000000..e1acbf9 --- /dev/null +++ b/app/resources/routes/api/contabilidad/nubox.php @@ -0,0 +1,11 @@ +group('/nubox/{inmobiliaria_rut}', function($app) { + $app->get('/token[/]', [Nubox::class, 'token']); + $app->get('/sistemas[/]', [Nubox::class, 'sistemas']); + $app->group('/libro', function($app) { + $app->post('/mayor[/]', [Nubox::class, 'libroMayor']); + $app->post('/diario[/]', [Nubox::class, 'libroDiario']); + }); +}); diff --git a/app/resources/routes/api/inmobiliarias.php b/app/resources/routes/api/inmobiliarias.php new file mode 100644 index 0000000..55c61fb --- /dev/null +++ b/app/resources/routes/api/inmobiliarias.php @@ -0,0 +1,10 @@ +group('/inmobiliarias', function($app) { + $app->get('[/]', Inmobiliarias::class); +}); +$app->group('/inmobiliaria/{inmobiliaria_rut}', function($app) { + $app->get('/cuentas[/]', [Inmobiliarias::class, 'cuentas']); + $app->get('/proyectos[/]', [Inmobiliarias::class, 'proyectos']); +}); diff --git a/app/resources/routes/contabilidad/centros_costos.php b/app/resources/routes/contabilidad/centros_costos.php index 8af10b3..d1089a4 100644 --- a/app/resources/routes/contabilidad/centros_costos.php +++ b/app/resources/routes/contabilidad/centros_costos.php @@ -2,5 +2,6 @@ use Incoviba\Controller\CentrosCostos; $app->group('/centros_costos', function($app) { + $app->get('/asignar[/]', [CentrosCostos::class, 'asignar']); $app->get('[/]', CentrosCostos::class); }); diff --git a/app/resources/views/contabilidad/centros_costos/asignar.blade.php b/app/resources/views/contabilidad/centros_costos/asignar.blade.php new file mode 100644 index 0000000..2cf50c2 --- /dev/null +++ b/app/resources/views/contabilidad/centros_costos/asignar.blade.php @@ -0,0 +1,402 @@ +@extends('layout.base') + +@section('page_content') +
+

Asignar Centros de Costos

+
+
+
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+
+
+ + + +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + +
FechaGlosaDocumentoCargoAbonoSaldoCentro de CostoDetalleOrden
+
+@endsection + +@include('layout.head.styles.datatables') +@include('layout.body.scripts.datatables') + +@push('page_scripts') + +@endpush diff --git a/app/setup/settings/folders.php b/app/setup/settings/folders.php index 67694f4..e4d1e05 100644 --- a/app/setup/settings/folders.php +++ b/app/setup/settings/folders.php @@ -6,7 +6,9 @@ return [ 'resources' => DI\String('{base}/resources'), 'routes' => DI\String('{resources}/routes'), 'cache' => DI\String('{base}/cache'), - 'templates' => DI\String('{resources}/views') + 'templates' => DI\String('{resources}/views'), + 'public' => DI\String('{base}/public'), + 'uploads' => DI\String('{public}/uploads') ]); } ]; diff --git a/app/setup/settings/nubox.php b/app/setup/settings/nubox.php new file mode 100644 index 0000000..382f46b --- /dev/null +++ b/app/setup/settings/nubox.php @@ -0,0 +1,8 @@ + function() { + return new DI\Container([ + 'url' => 'https://api.nubox.com/Nubox.API' + ]); + } +]; diff --git a/app/setup/setups/psr7.php b/app/setup/setups/psr7.php index af7ff76..7e86808 100644 --- a/app/setup/setups/psr7.php +++ b/app/setup/setups/psr7.php @@ -2,7 +2,13 @@ use Psr\Container\ContainerInterface; return [ + Psr\Http\Message\StreamFactoryInterface::class => function(ContainerInterface $container) { + return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class); + }, + Psr\Http\Message\RequestFactoryInterface::class => function(ContainerInterface $container) { + return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class); + }, Psr\Http\Message\ResponseFactoryInterface::class => function(ContainerInterface $container) { return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class); - } + }, ]; diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php index 9ba91f9..8b2b709 100644 --- a/app/setup/setups/services.php +++ b/app/setup/setups/services.php @@ -1,4 +1,5 @@ $container->get('REDIS_HOST'), 'port' => $container->get('REDIS_PORT') ]); + }, + Incoviba\Service\Cartola::class => function(ContainerInterface $container) { + return (new Incoviba\Service\Cartola( + $container->get(Psr\Http\Message\StreamFactoryInterface::class), + $container->get(Incoviba\Common\Define\Contabilidad\Exporter::class) + ))->register('security', $container->get(Incoviba\Service\Cartola\Security::class)); + }, + Incoviba\Common\Define\Contabilidad\Exporter::class => function(ContainerInterface $container) { + return $container->get(Incoviba\Service\Contabilidad\Exporter\Nubox::class); + }, + Incoviba\Service\Contabilidad\Exporter\Nubox::class => function(ContainerInterface $container) { + return new Incoviba\Service\Contabilidad\Exporter\Nubox($container->get(Incoviba\Repository\CentroCosto::class), + $container->get('folders')->get('uploads')); + }, + Incoviba\Service\Contabilidad\Nubox::class => function(ContainerInterface $container) { + return new Incoviba\Service\Contabilidad\Nubox( + $container->get(Incoviba\Repository\Nubox::class), + $container->get(Incoviba\Service\Redis::class), + new GuzzleHttp\Client(), + $container->get(Psr\Http\Message\RequestFactoryInterface::class), + $container->get('nubox')->get('url')); } ]; diff --git a/app/src/Controller/API/Contabilidad.php b/app/src/Controller/API/Contabilidad.php new file mode 100644 index 0000000..bf35b84 --- /dev/null +++ b/app/src/Controller/API/Contabilidad.php @@ -0,0 +1,52 @@ +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/Informes.php b/app/src/Controller/API/Informes.php new file mode 100644 index 0000000..5e06ea1 --- /dev/null +++ b/app/src/Controller/API/Informes.php @@ -0,0 +1,25 @@ +getParsedBody(); + $output = [ + 'input' => $body, + 'data' => [] + ]; + try { + $file = $request->getUploadedFiles()['file']; + $output['data'] = $diarioService->process($file); + } catch (\Error) {} + return $this->withJson($response, $output); + } +} diff --git a/app/src/Controller/API/Inmobiliarias.php b/app/src/Controller/API/Inmobiliarias.php new file mode 100644 index 0000000..273e49d --- /dev/null +++ b/app/src/Controller/API/Inmobiliarias.php @@ -0,0 +1,48 @@ + $inmobiliaria_rut, + 'cuentas' => [] + ]; + try { + $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut); + $output['cuentas'] = $cuentaRepository->fetchByInmobiliaria($inmobiliaria->rut); + } catch (EmptyResult) {} + return $this->withJson($response, $output); + } + public function proyectos(ServerRequestInterface $request, ResponseInterface $response, + Repository\Inmobiliaria $inmobiliariaRepository, + Service\Proyecto $proyectoService, int $inmobiliaria_rut): ResponseInterface + { + $output = [ + 'inmobiliaria_rut' => $inmobiliaria_rut, + 'proyectos' => [] + ]; + try { + $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut); + $output['proyectos'] = array_map(function(Model\Proyecto $proyecto) { + $p = json_decode(json_encode($proyecto)); + $p->current_estado = $proyecto->currentEstado(); + $p->estados = $proyecto->estados(); + return $p; + },$proyectoService->getByInmobiliaria($inmobiliaria->rut)); + } catch (EmptyResult) {} + return $this->withJson($response, $output); + } +} diff --git a/app/src/Controller/API/Nubox.php b/app/src/Controller/API/Nubox.php new file mode 100644 index 0000000..cc1d323 --- /dev/null +++ b/app/src/Controller/API/Nubox.php @@ -0,0 +1,90 @@ + $inmobiliaria_rut, + 'token' => '' + ]; + try { + $output['token'] = $nuboxService->getToken($inmobiliaria_rut); + } catch (HttpResponse $exception) { + $output['error'] = [ + 'code' => $exception->getCode(), + 'message' => $exception->getMessage() + ]; + } + return $this->withJson($response, $output); + } + public function sistemas(ServerRequestInterface $request, ResponseInterface $response, + Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface + { + $output = [ + 'inmobiliaria_rut' => $inmobiliaria_rut, + 'sistemas' => [] + ]; + try { + $output['sistemas'] = $nuboxService->getSistemas($inmobiliaria_rut); + } catch (HttpResponse $exception) { + $output['error'] = [ + 'code' => $exception->getCode(), + 'message' => $exception->getMessage() + ]; + } + return $this->withJson($response, $output); + } + public function libroMayor(ServerRequestInterface $request, ResponseInterface $response, + Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface + { + $body = $request->getParsedBody(); + $output = [ + 'inmobiliaria_rut' => $inmobiliaria_rut, + 'input' => $body, + 'libro_mayor' => [] + ]; + try { + $from = new DateTimeImmutable($body['inicio']); + $to = new DateTimeImmutable($body['termino']); + $output['libro_mayor'] = $nuboxService->getLibroMayor($inmobiliaria_rut, $from, $to); + } catch (HttpResponse $exception) { + $output['error'] = [ + 'code' => $exception->getCode(), + 'message' => $exception->getMessage() + ]; + } + return $this->withJson($response, $output); + } + public function libroDiario(ServerRequestInterface $request, ResponseInterface $response, + Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface + { + $body = $request->getParsedBody(); + $output = [ + 'inmobiliaria_rut' => $inmobiliaria_rut, + 'input' => $body, + 'libro_diario' => [] + ]; + try { + $from = new DateTimeImmutable($body['inicio']); + $to = new DateTimeImmutable($body['termino']); + $output['libro_diario'] = $nuboxService->getLibroDiario($inmobiliaria_rut, $from, $to); + } catch (HttpResponse $exception) { + $output['error'] = [ + 'code' => $exception->getCode(), + 'message' => $exception->getMessage() + ]; + } + return $this->withJson($response, $output); + } +} diff --git a/app/src/Controller/API/Proyectos.php b/app/src/Controller/API/Proyectos.php index 616b6eb..dc5e46f 100644 --- a/app/src/Controller/API/Proyectos.php +++ b/app/src/Controller/API/Proyectos.php @@ -155,4 +155,19 @@ class Proyectos } catch (EmptyResult) {} return $this->withJson($response, $output); } + public function tiposUnidades(ServerRequestInterface $request, ResponseInterface $response, + Repository\Proyecto $proyectoRepository, + Repository\Proyecto\TipoUnidad $tipoUnidadRepository, + int $proyecto_id): ResponseInterface + { + $output = [ + 'proyecto_id' => $proyecto_id, + 'tipos' => [] + ]; + try { + $proyecto = $proyectoRepository->fetchById($proyecto_id); + $output['tipos'] = $tipoUnidadRepository->fetchByProyecto($proyecto->id); + } catch (EmptyResult) {} + return $this->withJson($response, $output); + } } diff --git a/app/src/Controller/CentrosCostos.php b/app/src/Controller/CentrosCostos.php index 13fb89a..6854b8b 100644 --- a/app/src/Controller/CentrosCostos.php +++ b/app/src/Controller/CentrosCostos.php @@ -21,4 +21,12 @@ class CentrosCostos return $view->render($response, 'contabilidad.centros_costos', compact('centrosCostos', 'tiposCentros', 'categorias', 'tiposCuentas')); } + public function asignar(ServerRequestInterface $request, ResponseInterface $response, View $view, + Repository\CentroCosto $centroCostoRepository, + Repository\Inmobiliaria $inmobiliariaRepository): ResponseInterface + { + $centrosCostos = $centroCostoRepository->fetchAll(); + $inmobiliarias = $inmobiliariaRepository->fetchAllActive('razon'); + return $view->render($response, 'contabilidad.centros_costos.asignar', compact('centrosCostos', 'inmobiliarias')); + } } diff --git a/app/src/Model/Nubox.php b/app/src/Model/Nubox.php new file mode 100644 index 0000000..05b223a --- /dev/null +++ b/app/src/Model/Nubox.php @@ -0,0 +1,18 @@ +usuario, $this->password])); + } +} diff --git a/app/src/Repository/Inmobiliaria.php b/app/src/Repository/Inmobiliaria.php index 9b4af20..decedf3 100644 --- a/app/src/Repository/Inmobiliaria.php +++ b/app/src/Repository/Inmobiliaria.php @@ -46,4 +46,20 @@ class Inmobiliaria extends Ideal\Repository { return $this->update($model, ['dv', 'razon', 'abreviacion', 'cuenta', 'banco', 'sociedad'], $new_data); } + + public function fetchAllActive(null|string|array $sorting = null): array + { + $query = $this->connection->getQueryBuilder() + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('JOIN proyecto ON a.rut = proyecto.inmobiliaria') + ->joined('JOIN (SELECT ep1.* FROM estado_proyecto ep1 JOIN (SELECT MAX(id) AS id, proyecto FROM estado_proyecto GROUP BY proyecto) ep0 ON ep0.id = ep1.id) ep ON ep.proyecto = proyecto.id') + ->joined('JOIN tipo_estado_proyecto tep ON tep.id = ep.estado') + ->joined('JOIN etapa_proyecto ON etapa_proyecto.id = tep.etapa') + ->where('etapa_proyecto.orden BETWEEN ? AND ?'); + if ($sorting !== null) { + $query->order($sorting); + } + return $this->fetchMany($query, [1, 8]); + } } diff --git a/app/src/Repository/Inmobiliaria/Cuenta.php b/app/src/Repository/Inmobiliaria/Cuenta.php new file mode 100644 index 0000000..71e3b5d --- /dev/null +++ b/app/src/Repository/Inmobiliaria/Cuenta.php @@ -0,0 +1,52 @@ +setTable('cuenta'); + } + + public function create(?array $data = null): Model\Inmobiliaria\Cuenta + { + $map = (new Implement\Repository\MapperParser(['cuenta'])) + ->register('inmobiliaria', (new Implement\Repository\Mapper()) + ->setFunction(function(array $data) { + return $this->inmobiliariaRepository->fetchById($data['inmobiliaria']); + })) + ->register('banco', (new Implement\Repository\Mapper()) + ->setFunction(function(array $data) { + return $this->bancoRepository->fetchById($data['banco']); + })); + return $this->parseData(new Model\Inmobiliaria\Cuenta(), $data, $map); + } + public function save(Define\Model $model): Model\Inmobiliaria\Cuenta + { + $model->id = $this->saveNew(['inmobiliaria', 'banco', 'cuenta'], + [$model->inmobiliaria->rut, $model->banco->id, $model->cuenta]); + return $model; + } + public function edit(Define\Model $model, array $new_data): Model\Inmobiliaria\Cuenta + { + return $this->update($model, ['inmobiliaria', 'banco', 'cuenta'], $new_data); + } + + public function fetchByInmobiliaria(int $inmobiliaria_rut): array + { + $query = $this->connection->getQueryBuilder() + ->select() + ->from($this->getTable()) + ->where('inmobiliaria = ?'); + return $this->fetchMany($query, [$inmobiliaria_rut]); + } +} diff --git a/app/src/Repository/Nubox.php b/app/src/Repository/Nubox.php new file mode 100644 index 0000000..3f91268 --- /dev/null +++ b/app/src/Repository/Nubox.php @@ -0,0 +1,55 @@ +setTable('inmobiliarias_nubox'); + } + + public function create(?array $data = null): Model\Nubox + { + $map = (new Implement\Repository\MapperParser(['usuario', 'alias'])) + ->register('inmobiliaria_rut', (new Implement\Repository\Mapper()) + ->setProperty('inmobiliaria') + ->setFunction(function(array $data) { + return $this->inmobiliariaRepository->fetchById($data['inmobiliaria_rut']); + })) + ->register('contraseña', (new Implement\Repository\Mapper()) + ->setProperty('password')); + return $this->parseData(new Model\Nubox(), $data, $map); + } + public function save(Define\Model $model): Model\Nubox + { + $this->saveNew( + ['inmobiliaria_rut', 'alias', 'usuario', 'contraseña'], + [$model->inmobiliaria->rut, $model->alias, $model->usuario, $model->password] + ); + return $model; + } + public function edit(Define\Model $model, array $new_data): Model\Nubox + { + return $this->update($model, ['inmobiliaria_rut', 'alias', 'usuario', 'contraseña'], $new_data); + } + + public function fetchByInmobiliaria(int $inmobiliaria_rut): Model\Nubox + { + $query = $this->connection->getQueryBuilder() + ->select() + ->from($this->getTable()) + ->where('inmobiliaria_rut = ?'); + return $this->fetchOne($query, [$inmobiliaria_rut]); + } + + protected function getKey(): string + { + return 'inmobiliaria_rut'; + } +} diff --git a/app/src/Service/Cartola.php b/app/src/Service/Cartola.php new file mode 100644 index 0000000..231ba7a --- /dev/null +++ b/app/src/Service/Cartola.php @@ -0,0 +1,29 @@ +bancos[$name] = $banco; + return $this; + } + public function process(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $mes, UploadedFileInterface $file): array + { + return $this->bancos[strtolower($banco->nombre)]->process($file); + } + public function export(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $mes, array $movimientos): string + { + return $this->exporter->export($inmobiliaria, $banco, $mes, $movimientos); + } +} diff --git a/app/src/Service/Cartola/Security.php b/app/src/Service/Cartola/Security.php new file mode 100644 index 0000000..9df63d0 --- /dev/null +++ b/app/src/Service/Cartola/Security.php @@ -0,0 +1,54 @@ +moveTo($filename); + $xlsx = $reader->load($filename); + $worksheet = $xlsx->getActiveSheet(); + $rows = $worksheet->getRowIterator(); + $dataFound = false; + $columns = []; + $data = []; + foreach ($rows as $row) { + $cells = $row->getCellIterator(); + $rowData = []; + foreach ($cells as $cell) { + if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() === "fecha ") { + $cols = $row->getColumnIterator(); + foreach ($cols as $col) { + $columns[$col->getColumn()] = trim($col->getCalculatedValue()); + } + $dataFound = true; + break; + } + if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() === null) { + $dataFound = false; + break; + } + if (!$dataFound) { + break; + } + $col = $columns[$cell->getColumn()]; + $value = $cell->getCalculatedValue(); + if ($col === 'fecha') { + $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue(), 'America/Santiago')->format('Y-m-d'); + } + $rowData[$col] = $value; + } + if (count($rowData) > 0) { + $data []= $rowData; + } + } + unlink($filename); + return $data; + } +} diff --git a/app/src/Service/Contabilidad/Exporter/Nubox.php b/app/src/Service/Contabilidad/Exporter/Nubox.php new file mode 100644 index 0000000..ba32e09 --- /dev/null +++ b/app/src/Service/Contabilidad/Exporter/Nubox.php @@ -0,0 +1,115 @@ +getActiveSheet(); + + $rowIndex = $this->buildHeaders($sheet); + + foreach ($movimientos as $movimiento) { + $tipoCentro = ''; + $cuenta = ''; + $centro = ''; + if ($movimiento->centro_costo !== '') { + $centroCosto = $this->centroCostoRepository->fetchById($movimiento->centro_costo); + $tipoCentro = substr($centroCosto->tipoCentro->descripcion, 0, 1); + $cuenta = $centroCosto->cuentaContable; + $centro = $centroCosto->id; + } + $fecha = (new DateTimeImmutable($movimiento->fecha))->format('d/m/Y'); + $rowIndex = $this->add($sheet, [ + 'Número' => '0', + 'Tipo' => $tipoCentro, + 'Fecha' => $fecha, + 'Glosa' => $movimiento->detalle, + 'Cuenta Detalle' => $cuenta, + 'Glosa Detalle' => '', + 'Centro Costo' => $centro, + 'Sucursal' => '', + 'Debe' => $movimiento->abono === 0 ? '' : $movimiento->abono, + 'Haber' => $movimiento->cargo === 0 ? '' : $movimiento->cargo, + 'Tipo Auxiliar' => 'B', + 'A: Rut Cliente-Proveedor/H: Rut Prestador' => '', + 'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador' => $movimiento->glosa, + 'A: Tipo De Documento/H: Tipo De Boleta Honorario' => '', + 'A: Folio /B: Numero Documento/H: Folio Boleta' => $movimiento->documento, + 'A/B/H: Monto' => ($movimiento->abono === 0) ? $movimiento->cargo : $movimiento->abono, + 'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión (DD/MM/AAAA)' => $fecha + ], $rowIndex); + } + $sheet->getStyle("I1:J{$rowIndex}")->getNumberFormat() + ->setFormatCode('#,##0'); + $sheet->getStyle("O1:O{$rowIndex}")->getNumberFormat() + ->setFormatCode('##0'); + $sheet->getStyle("P1:P{$rowIndex}")->getNumberFormat() + ->setFormatCode('#,##0'); + foreach (range('A', 'Q') as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + $sheet->getSheetView()->setZoomScale(90); + + $writer = PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx'); + $filename = "Cartola {$banco->nombre} - {$inmobiliaria->abreviacion} - {$mes->format('M Y')}.xlsx"; + $writer->save(implode(DIRECTORY_SEPARATOR, [ + $this->uploadFolder, + $filename + ])); + return $filename; + } + + protected function getHeaders(): array + { + return [ + 'Número', + 'Tipo', + 'Fecha', + 'Glosa', + 'Cuenta Detalle', + 'Glosa Detalle', + 'Centro Costo', + 'Sucursal', + 'Debe', + 'Haber', + 'Tipo Auxiliar', + 'A: Rut Cliente-Proveedor/H: Rut Prestador', + 'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador', + 'A: Tipo De Documento/H: Tipo De Boleta Honorario', + 'A: Folio /B: Numero Documento/H: Folio Boleta', + 'A/B/H: Monto', + 'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión (DD/MM/AAAA)' + ]; + } + protected function buildHeaders(PhpSpreadsheet\Worksheet\Worksheet &$sheet, int $rowIndex = 1): int + { + $map = $this->getHeaders(); + foreach ($map as $index => $header) { + $columnIndex = $index + 1; + $sheet->getCell([$columnIndex, $rowIndex])->setValue($header); + } + return $rowIndex + 1; + } + protected function add(PhpSpreadsheet\Worksheet\Worksheet &$sheet, array $row, int $rowIndex): int + { + $headers = $this->getHeaders(); + foreach ($headers as $index => $header) { + $columnIndex = $index + 1; + $sheet->getCell([$columnIndex, $rowIndex])->setValue($row[$header]); + $sheet->getCell([$columnIndex, $rowIndex + 1])->setValue(($header === 'Tipo Auxiliar') ? 'A' : ''); + } + return $rowIndex + 2; + } +} diff --git a/app/src/Service/Contabilidad/Nubox.php b/app/src/Service/Contabilidad/Nubox.php new file mode 100644 index 0000000..01b432a --- /dev/null +++ b/app/src/Service/Contabilidad/Nubox.php @@ -0,0 +1,139 @@ +tokens[$inmobiliaria_rut])) { + $redisKey = "token_nubox:{$inmobiliaria_rut}"; + try { + $this->tokens[$inmobiliaria_rut] = $this->redisService->get($redisKey); + } catch (Exception\EmptyRedis) { + $nubox = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut); + $request = $this->requestFactory + ->createRequest('POST', implode('/', [$this->api_url, 'autenticar'])) + ->withHeader('Authorization', "Basic {$nubox->getLogin()}") + ->withHeader('Content-Type', 'application/json') + ->withHeader('Accept', 'application/json'); + $response = $this->client->sendRequest($request); + if ($response->getStatusCode() !== 200) { + throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode()); + } + $sistemas = json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY); + + $this->setToken($inmobiliaria_rut, $response->getHeaderLine('Token')) + ->setSistemas($inmobiliaria_rut, $sistemas['Sistemas']); + } + } + return $this->tokens[$inmobiliaria_rut]; + } + public function setToken(int $inmobiliaria_rut, string $token): Nubox + { + $this->tokens[$inmobiliaria_rut] = $token; + + $redisKey = "token_nubox:{$inmobiliaria_rut}"; + $this->redisService->set($redisKey, $this->tokens[$inmobiliaria_rut], 60 * 15); + + return $this; + } + + protected array $sistemas; + public function getSistemas(int $inmobiliaria_rut): array + { + if (!isset($this->sistemas[$inmobiliaria_rut])) { + $redisKey = "nubox:{$inmobiliaria_rut}"; + $this->sistemas[$inmobiliaria_rut] = json_decode($this->redisService->get($redisKey)); + } + return $this->sistemas[$inmobiliaria_rut]; + } + public function setSistemas(int $inmobiliaria_rut, array $sistemas): Nubox + { + $this->sistemas[$inmobiliaria_rut] = $sistemas; + + $redisKey = "nubox:{$inmobiliaria_rut}"; + $this->redisService->set($redisKey, json_encode($sistemas)); + + return $this; + } + + public function getLibroMayor(int $inmobiliaria_rut, DateTimeInterface $from, DateTimeInterface $to): array + { + $inmobiliaria = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut); + $query = [ + 'NumeroSerie' => 1, + 'CodigoEmpresa' => $inmobiliaria->alias, + 'DDInicio' => $from->format('j'), + 'MMInicio' => $from->format('n'), + 'YYInicio' => $from->format('Y'), + 'DDTermino' => $to->format('j'), + 'MMTermino' => $to->format('n'), + 'YYTermino' => $to->format('Y'), + 'CodigoCentroDeCosto' => 0, + 'CodigoSucursal' => 0, + 'CodigoCuenta' => 0, + 'ModoIFRS' => 'false', + 'CuentasConSaldo' => 'false', + 'IncluirCodigoCuenta' => 'true', + ]; + $uri = 'contabilidad/libro-mayor?' . http_build_query($query); + $response = $this->send($uri, $inmobiliaria_rut); + if ($response->getStatusCode() !== 200) { + throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode()); + } + return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY); + } + public function getLibroDiario(int $inmobiliaria_rut, DateTimeInterface $from, DateTimeInterface $to): array + { + $inmobiliaria = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut); + $query = [ + 'ModoIFRS' => 0, + 'DDInicio' => $from->format('j'), + 'MMInicio' => $from->format('n'), + 'YYInicio' => $from->format('Y'), + 'DDTermino' => $to->format('j'), + 'MMTermino' => $to->format('n'), + 'YYTermino' => $to->format('Y'), + 'Sucursal' => 0, + 'codigoEmpresa' => $inmobiliaria->alias, + 'NumeroSerie' => 1, + 'CuentasConSaldo' => 0, + 'incluirCodigoCuenta' => 1 + ]; + $uri = 'contabilidad/libro-diario?' . http_build_query($query); + $response = $this->send($uri, $inmobiliaria_rut); + if ($response->getStatusCode() !== 200) { + error_log(var_export($uri,true).PHP_EOL,3,'/logs/debug'); + throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode()); + } + return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY); + } + + private function send(string $uri, int $inmobiliaria_rut, string $method = 'GET', ?StreamInterface $body = null): ResponseInterface + { + $request = $this->requestFactory + ->createRequest($method, implode('/', [$this->api_url, $uri])) + ->withHeader('token', $this->getToken($inmobiliaria_rut)); + if ($body !== null) { + $request = $request->withBody($body); + } + return $this->client->sendRequest($request); + } +}