diff --git a/api/common/Controller/Base.php b/api/common/Controller/Base.php index ea2e716..8153b7b 100644 --- a/api/common/Controller/Base.php +++ b/api/common/Controller/Base.php @@ -24,4 +24,11 @@ class Base { $key = urlencode(base64_encode($signature)); return $this->withJson($response, ['key' => $key]); } + public function info(Request $request, Response $response): Response { + ob_start(); + phpinfo(); + $data = ob_get_clean(); + $response->getBody()->write($data); + return $response; + } } diff --git a/api/common/Controller/Categorias.php b/api/common/Controller/Categorias.php index 48c2227..d19dc65 100644 --- a/api/common/Controller/Categorias.php +++ b/api/common/Controller/Categorias.php @@ -13,35 +13,35 @@ class Categorias { public function __invoke(Request $request, Response $response, Factory $factory, Service $service): Response { $categorias = $factory->find(Categoria::class)->many(); - array_walk($categorias, function(&$item) use ($service) { - $arr = $item->toArray(); - if ($item->cuentas()) { - $arr['cuentas'] = array_map(function($item) { - return $item->toArray(); - }, $item->cuentas()); - } - $maps = ['activo', 'pasivo', 'ganancia', 'perdida']; - foreach ($maps as $m) { - $p = $m . 's'; - $t = ucfirst($m); - $cuentas = $item->getCuentasOf($t); - if ($cuentas === false or $cuentas === null) { - $arr[$p] = 0; - continue; + if ($categorias !== null) { + array_walk($categorias, function(&$item) use ($service) { + $arr = $item->toArray(); + if ($item->cuentas()) { + $arr['cuentas'] = array_map(function($item) { + return $item->toArray(); + }, $item->cuentas()); } - $arr[$p] = array_reduce($cuentas, function($sum, $item) use($service) { - return $sum + $item->saldo($service, true); - }); - } - $item = $arr; - }); - if ($categorias) { - usort($categorias, function($a, $b) { - return strcmp($a['nombre'], $b['nombre']); - }); + $maps = ['activo', 'pasivo', 'ganancia', 'perdida']; + foreach ($maps as $m) { + $p = $m . 's'; + $t = ucfirst($m); + $cuentas = $item->getCuentasOf($t); + if ($cuentas === false or $cuentas === null) { + $arr[$p] = 0; + continue; + } + $arr[$p] = array_reduce($cuentas, function($sum, $item) use($service) { + return $sum + $item->saldo($service, true); + }); + } + $item = $arr; + }); + usort($categorias, function($a, $b) { + return strcmp($a['nombre'], $b['nombre']); + }); } $output = [ - 'categorias' => $categorias + 'categorias' => $categorias ]; return $this->withJson($response, $output); } diff --git a/api/common/Controller/Import.php b/api/common/Controller/Import.php index 17dee20..48d091c 100644 --- a/api/common/Controller/Import.php +++ b/api/common/Controller/Import.php @@ -3,19 +3,47 @@ namespace Contabilidad\Common\Controller; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; +use Psr\Container\ContainerInterface as Container; use ProVM\Common\Define\Controller\Json; use ProVM\Common\Factory\Model as Factory; use Contabilidad\Common\Service\DocumentHandler as Handler; +use Contabilidad\Cuenta; class Import { use Json; - public function __invoke(Request $request, Response $response, Factory $factory): Response { - $post = $request->getParsedBody(); - return $this->withJson($response, $post); + public function __invoke(Request $request, Response $response, Factory $factory, Container $container): Response { + $post =$request->getParsedBody(); + $cuenta = $factory->find(Cuenta::class)->one($post['cuenta']); + $file = $request->getUploadedFiles()['archivo']; + $valid_media = [ + 'text/csv' => 'csvs', + 'application/pdf' => 'pdfs', + 'application/vnd.ms-excel' => 'xlss', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlss', + 'application/json' => 'jsons' + ]; + if ($file->getError() === 0 and in_array($file->getClientMediaType(), array_keys($valid_media))) { + $filenfo = new \SplFileInfo($file->getClientFilename()); + $new_name = implode('.', [implode(' - ', [$cuenta->nombre, $cuenta->categoria()->nombre, $post['fecha']]), $filenfo->getExtension()]); + $to = implode(DIRECTORY_SEPARATOR, [$container->get('folders')->uploads, $valid_media[$file->getClientMediaType()], $new_name]); + $file->moveTo($to); + $status = file_exists($to); + } + $output = [ + 'input' => [ + 'name' => $file->getClientFilename(), + 'type' => $file->getClientMediaType(), + 'size' => $file->getSize(), + 'error' => $file->getError() + ], + 'new_name' => $new_name, + 'uploaded' => $status + ]; + return $this->withJson($response, $output); } public function uploads(Request $request, Response $response, Handler $handler): Response { - $output = $handler->handle(); - return $this->withJson($response, $output); + $output = $handler->handle(); + return $this->withJson($response, $output); } } diff --git a/api/common/Controller/TiposCategorias.php b/api/common/Controller/TiposCategorias.php index fa3b113..1d34274 100644 --- a/api/common/Controller/TiposCategorias.php +++ b/api/common/Controller/TiposCategorias.php @@ -13,31 +13,34 @@ class TiposCategorias { public function __invoke(Request $request, Response $response, Factory $factory, Service $service): Response { $tipos = $factory->find(TipoCategoria::class)->many(); - array_walk($tipos, function(&$item) use ($service) { - $arr = $item->toArray(); - $arr['categorias'] = array_map(function($item) { - return $item->toArray(); - }, $item->categorias()); - $arr['saldo'] = abs($item->saldo($service)); - $maps = ['activo', 'pasivo', 'ganancia', 'perdida']; - foreach ($maps as $m) { - $p = $m . 's'; - $t = ucfirst($m); - $cuentas = $item->getCuentasOf($t); - if ($cuentas === false or $cuentas === null) { - $arr[$p] = 0; - continue; + if ($tipos !== null) { + array_walk($tipos, function(&$item) use ($service) { + $arr = $item->toArray(); + $arr['categorias'] = $item->categorias(); + if ($arr['categorias'] !== null) { + $arr['categorias'] = array_map(function($item) { + return $item->toArray(); + }, $item->categorias()); } - $arr[$p] = array_reduce($cuentas, function($sum, $item) use($service) { - return $sum + $item->saldo($service, true); - }); - } - $item = $arr; - }); - if ($tipos) { - usort($tipos, function($a, $b) { - return strcmp($a['descripcion'], $b['descripcion']); - }); + $arr['saldo'] = abs($item->saldo($service)); + $maps = ['activo', 'pasivo', 'ganancia', 'perdida']; + foreach ($maps as $m) { + $p = $m . 's'; + $t = ucfirst($m); + $cuentas = $item->getCuentasOf($t); + if ($cuentas === false or $cuentas === null) { + $arr[$p] = 0; + continue; + } + $arr[$p] = array_reduce($cuentas, function($sum, $item) use($service) { + return $sum + $item->saldo($service, true); + }); + } + $item = $arr; + }); + usort($tipos, function($a, $b) { + return strcmp($a['descripcion'], $b['descripcion']); + }); } $output = [ 'tipos' => $tipos diff --git a/api/db/migrations/20211029150754_tipo_cuenta.php b/api/db/migrations/20211029150754_tipo_cuenta.php index d72ff70..98b7ba1 100644 --- a/api/db/migrations/20211029150754_tipo_cuenta.php +++ b/api/db/migrations/20211029150754_tipo_cuenta.php @@ -20,7 +20,7 @@ final class TipoCuenta extends AbstractMigration { $this->table('tipos_cuenta') ->addColumn('descripcion', 'string') - ->addColumn('color', 'string', ['length' => 6]) + ->addColumn('color', 'string', ['length' => 6, 'default' => 'ffffff']) ->create(); } } diff --git a/api/nginx.conf b/api/nginx.conf index 44c93fd..5d96382 100644 --- a/api/nginx.conf +++ b/api/nginx.conf @@ -5,6 +5,8 @@ server { access_log /var/log/nginx/access.log; root /app/public; + client_max_body_size 50M; + location / { try_files $uri $uri/ /index.php?$query_string; } diff --git a/api/php.ini b/api/php.ini index e145929..c7681b7 100644 --- a/api/php.ini +++ b/api/php.ini @@ -1,2 +1,4 @@ log_errors = true -error_log = /var/log/php/error.log \ No newline at end of file +error_log = /var/log/php/error.log +upload_max_filesize = 50M +max_input_vars = 5000 diff --git a/api/resources/routes/base.php b/api/resources/routes/base.php index c818f29..2be3305 100644 --- a/api/resources/routes/base.php +++ b/api/resources/routes/base.php @@ -3,4 +3,5 @@ use Contabilidad\Common\Controller\Base; $app->get('/key/generate[/]', [Base::class, 'generate_key']); $app->get('/balance[/]', [Contabilidad\Common\Controller\TiposCategorias::class, 'balance']); +$app->get('/info', [Base::class, 'info']); $app->get('/', Base::class); diff --git a/api/setup/setups/02_common.php b/api/setup/setups/02_common.php index 08015fb..27836d5 100644 --- a/api/setup/setups/02_common.php +++ b/api/setup/setups/02_common.php @@ -2,9 +2,9 @@ use Psr\Container\ContainerInterface as Container; return [ - GuzzleHttp\Client::class => function(Container $c) { - return new GuzzleHttp\Client(); - }, + GuzzleHttp\Client::class => function(Container $c) { + return new GuzzleHttp\Client(); + }, Contabilidad\Common\Service\Auth::class => function(Container $c) { return new Contabilidad\Common\Service\Auth($c->get('api_key')); }, diff --git a/api/src/TipoCategoria.php b/api/src/TipoCategoria.php index c21b187..1f5d342 100644 --- a/api/src/TipoCategoria.php +++ b/api/src/TipoCategoria.php @@ -10,16 +10,16 @@ use Contabilidad\Common\Service\TiposCambios as Service; * @property int $activo */ class TipoCategoria extends Model { - public static $_table = 'tipos_categoria'; - protected static $fields = ['descripcion', 'activo']; + public static $_table = 'tipos_categoria'; + protected static $fields = ['descripcion', 'activo']; - protected $categorias; - public function categorias() { - if ($this->categorias === null) { - $this->categorias = $this->parentOf(Categoria::class, [Model::CHILD_KEY => 'tipo_id']); + protected $categorias; + public function categorias() { + if ($this->categorias === null) { + $this->categorias = $this->parentOf(Categoria::class, [Model::CHILD_KEY => 'tipo_id']); + } + return $this->categorias; } - return $this->categorias; - } public function getCuentasOf($tipo) { return $this->factory->find(Cuenta::class) @@ -37,7 +37,7 @@ class TipoCategoria extends Model { protected $saldo; public function saldo(Service $service = null) { if ($this->saldo === null) { - $this->saldo = array_reduce($this->categorias(), function($sum, $item) use ($service) { + $this->saldo = array_reduce($this->categorias() ?? [], function($sum, $item) use ($service) { return $sum + $item->saldo($service); }); } diff --git a/docker-compose.yml b/docker-compose.yml index 5cdf395..e59f2b4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,7 @@ services: image: php-ui env_file: - .api.env + - .env build: context: ui volumes: diff --git a/ui/Dockerfile b/ui/Dockerfile index da7c7c5..952159e 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -1,3 +1,5 @@ FROM php:8-fpm +COPY --from=composer /usr/bin/composer /usr/bin/composer + WORKDIR /app diff --git a/ui/common/Controller/Importar.php b/ui/common/Controller/Importar.php new file mode 100644 index 0000000..dca07df --- /dev/null +++ b/ui/common/Controller/Importar.php @@ -0,0 +1,12 @@ +render($response, 'importar'); + } +} diff --git a/ui/resources/routes/importar.php b/ui/resources/routes/importar.php new file mode 100644 index 0000000..d25cc39 --- /dev/null +++ b/ui/resources/routes/importar.php @@ -0,0 +1,4 @@ +get('/importar[/]', Importar::class); diff --git a/ui/resources/views/importar.blade.php b/ui/resources/views/importar.blade.php new file mode 100644 index 0000000..a9171cf --- /dev/null +++ b/ui/resources/views/importar.blade.php @@ -0,0 +1,92 @@ +@extends('layout.base') + +@section('page_title') + Importar +@endsection + +@section('page_content') +

Importar

+
+
+ +
+
+ + +
+
+
+
+ + +
+
+ +
+
Archivo
+ + +
+
+ +
+@endsection + +@push('scripts') + +@endpush diff --git a/ui/resources/views/layout/body/menu.blade.php b/ui/resources/views/layout/body/menu.blade.php index 80944d6..54d2603 100644 --- a/ui/resources/views/layout/body/menu.blade.php +++ b/ui/resources/views/layout/body/menu.blade.php @@ -2,6 +2,7 @@ Inicio @include('layout.body.menu.cuentas') @include('layout.body.menu.categorias') + Importar diff --git a/ui/resources/views/layout/body/scripts.blade.php b/ui/resources/views/layout/body/scripts.blade.php index e9c687d..bfec9fc 100644 --- a/ui/resources/views/layout/body/scripts.blade.php +++ b/ui/resources/views/layout/body/scripts.blade.php @@ -7,7 +7,18 @@ base: '{{$urls->base}}', api: '{{$urls->api}}' } - function buildAjax(url, method) { + function buildAjax(url, method, files=false) { + if (files) { + return { + url: url, + headers: { + 'Authorization': 'Bearer ' + API_KEY + }, + method: method, + processData: false, + contentType: false + } + } return { url: url, headers: { @@ -21,8 +32,8 @@ let ajax_obj = buildAjax(url, 'GET') return $.ajax(ajax_obj) } - function sendPost(url, data) { - let ajax_obj = buildAjax(url, 'POST') + function sendPost(url, data, files=false) { + let ajax_obj = buildAjax(url, 'POST', files) ajax_obj['data'] = data return $.ajax(ajax_obj) }