Compare commits
42 Commits
python
...
f36399c1f4
Author | SHA1 | Date | |
---|---|---|---|
f36399c1f4 | |||
5a9dc6602c | |||
d7dfc2d221 | |||
1d62a0c04e | |||
c1eeba04a2 | |||
3cb2a877de | |||
a2a90497ae | |||
b17225549c | |||
925388df92 | |||
af78106700 | |||
665f426011 | |||
56b371d20c | |||
2126d30ee7 | |||
71b4211fc3 | |||
0378a2cf09 | |||
73df98dca5 | |||
4abe3448c0 | |||
f9bbbfd920 | |||
9e29dd09b7 | |||
52443c2226 | |||
572a9dc87c | |||
66882d9f85 | |||
aacda4d1e4 | |||
1a0c83fb2b | |||
f99b984f6c | |||
a5428b252e | |||
4bc1e4ae4d | |||
93f77bfbb8 | |||
fddba2fb87 | |||
79c7d5ad63 | |||
e6ebb2c279 | |||
45952bb3ac | |||
6b03d62ce0 | |||
894cc26b21 | |||
64ffb53f0c | |||
42310ef0e4 | |||
a6362a6770 | |||
e9c63abc3a | |||
9f47c8a85f | |||
34eedb93d7 | |||
0e5714edc8 | |||
f33bddfbea |
@ -1,3 +1,4 @@
|
||||
COMPOSE_PROFILES=
|
||||
MYSQL_HOST=
|
||||
MYSQL_ROOT_PASSWORD=
|
||||
MYSQL_DATABASE=
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,5 +13,3 @@
|
||||
|
||||
# Python
|
||||
**/.idea/
|
||||
|
||||
**/uploads/
|
||||
|
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
81
.idea/contabilidad.iml
generated
81
.idea/contabilidad.iml
generated
@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/kint-php/kint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/zeuxisoo/slim-whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phar-io/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phar-io/manifest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/theseer/tokenizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/webmozart/assert" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/philo/laravel-blade" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/nesbot/carbon" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/type" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/support" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/lines-of-code" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/filesystem" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/object-enumerator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/events" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/comparator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/simple-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/code-unit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/view" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/http-server-handler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/doctrine/instantiator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/exporter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/illuminate/container" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/http-factory" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/doctrine/inflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/cli-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/container" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/http-message" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/complexity" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/http-server-middleware" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/recursion-context" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/psr/log" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/resource-operations" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/global-state" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/composer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/environment" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpdocumentor/reflection-docblock" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpdocumentor/type-resolver" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/polyfill-mbstring" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/sebastian/object-reflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpdocumentor/reflection-common" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/finder" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/deprecation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/translation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/filp/whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/polyfill-ctype" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/debug" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/nyholm/psr7-server" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/translation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/nyholm/psr7" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/symfony/polyfill-php80" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/nikic/php-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/nikic/fast-route" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/php-di/php-di" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/php-di/phpdoc-reader" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/php-di/slim-bridge" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/php-di/invoker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/php-code-coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/phpunit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/php-text-template" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/php-invoker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/php-file-iterator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpunit/php-timer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/myclabs/deep-copy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/phpspec/prophecy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/opis/closure" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/php-http/message-factory" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/rubellum/slim-blade-view" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ui/vendor/slim/slim" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/contabilidad.iml" filepath="$PROJECT_DIR$/.idea/contabilidad.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
87
.idea/php.xml
generated
87
.idea/php.xml
generated
@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/ui/vendor/kint-php/kint" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/zeuxisoo/slim-whoops" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phar-io/version" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phar-io/manifest" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/theseer/tokenizer" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/webmozart/assert" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/philo/laravel-blade" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/nesbot/carbon" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/type" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/support" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/lines-of-code" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/filesystem" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/object-enumerator" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/events" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/comparator" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/contracts" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/simple-cache" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/code-unit" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/view" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/http-server-handler" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/doctrine/instantiator" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/exporter" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/illuminate/container" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/http-factory" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/doctrine/inflector" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/cli-parser" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/container" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/version" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/complexity" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/http-server-middleware" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/recursion-context" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/resource-operations" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/global-state" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/composer" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/environment" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpdocumentor/reflection-docblock" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpdocumentor/type-resolver" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/sebastian/object-reflector" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpdocumentor/reflection-common" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/finder" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/filp/whoops" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/polyfill-ctype" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/debug" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/nyholm/psr7-server" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/nyholm/psr7" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/symfony/polyfill-php80" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/nikic/php-parser" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/nikic/fast-route" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/php-di/php-di" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/php-di/phpdoc-reader" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/php-di/slim-bridge" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/php-di/invoker" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/php-code-coverage" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/phpunit" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/php-text-template" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/php-invoker" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/php-file-iterator" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpunit/php-timer" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/myclabs/deep-copy" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/phpspec/prophecy" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/opis/closure" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/php-http/message-factory" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/rubellum/slim-blade-view" />
|
||||
<path value="$PROJECT_DIR$/ui/vendor/slim/slim" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.0">
|
||||
<option name="suggestChangeDefaultLanguageLevel" value="false" />
|
||||
</component>
|
||||
<component name="PhpUnit">
|
||||
<phpunit_settings>
|
||||
<PhpUnitSettings custom_loader_path="$PROJECT_DIR$/ui/vendor/autoload.php" />
|
||||
</phpunit_settings>
|
||||
</component>
|
||||
</project>
|
1
api/.gitignore
vendored
Normal file
1
api/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
**/uploads/
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -13,33 +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();
|
||||
$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);
|
||||
}
|
||||
|
@ -12,8 +12,13 @@ class Cuentas {
|
||||
use Json;
|
||||
|
||||
public function __invoke(Request $request, Response $response, Factory $factory): Response {
|
||||
$cuentas = $factory->find(Cuenta::class)->array();
|
||||
$cuentas = $factory->find(Cuenta::class)->many();
|
||||
if ($cuentas) {
|
||||
array_walk($cuentas, function (&$item) {
|
||||
$arr = $item->toArray();
|
||||
$arr['categoria'] = $item->categoria()->toArray();
|
||||
$item = $arr;
|
||||
});
|
||||
usort($cuentas, function($a, $b) {
|
||||
$t = strcmp($a['tipo']['descripcion'], $b['tipo']['descripcion']);
|
||||
if ($t != 0) {
|
||||
@ -77,6 +82,15 @@ class Cuentas {
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function categoria(Request $request, Response $response, Factory $factory, $cuenta_id): Response {
|
||||
$cuenta = $factory->find(Cuenta::class)->one($cuenta_id);
|
||||
$output = [
|
||||
'input' => $cuenta_id,
|
||||
'cuenta' => $cuenta?->toArray(),
|
||||
'categoria' => $cuenta?->categoria()->toArray()
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function entradas(Request $request, Response $response, Factory $factory, $cuenta_id): Response {
|
||||
$cuenta = $factory->find(Cuenta::class)->one($cuenta_id);
|
||||
$entradas = null;
|
||||
@ -115,6 +129,8 @@ class Cuentas {
|
||||
$arr['valorFormateado'] = $cuenta->moneda()->format($arr['valor']);
|
||||
}
|
||||
}
|
||||
$arr['debito']['categoria'] = $transaccion->debito()->categoria()->toArray();
|
||||
$arr['credito']['categoria'] = $transaccion->credito()->categoria()->toArray();
|
||||
$transaccion = $arr;
|
||||
}
|
||||
}
|
||||
|
76
api/common/Controller/Files.php
Normal file
76
api/common/Controller/Files.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use ProVM\Common\Define\Controller\Json;
|
||||
use Contabilidad\Common\Service\FileHandler as Handler;
|
||||
use ProVM\Common\Factory\Model as Factory;
|
||||
use Contabilidad\Cuenta;
|
||||
|
||||
class Files {
|
||||
use Json;
|
||||
|
||||
public function __invoke(Request $request, Response $response, Handler $handler): Response {
|
||||
$files = $handler->listFiles();
|
||||
usort($files, function($a, $b) {
|
||||
$f = strcmp($a->folder, $b->folder);
|
||||
if ($f == 0) {
|
||||
return strcmp($a->filename, $b->filename);
|
||||
}
|
||||
return $f;
|
||||
});
|
||||
return $this->withJson($response, compact('files'));
|
||||
}
|
||||
public function upload(Request $request, Response $response, Handler $handler, Factory $factory): Response {
|
||||
$post = $request->getParsedBody();
|
||||
$cuenta = $factory->find(Cuenta::class)->one($post['cuenta']);
|
||||
$file = $request->getUploadedFiles()['archivo'];
|
||||
$new_name = implode(' - ', [$cuenta->nombre, $cuenta->categoria()->nombre, $post['fecha']]);
|
||||
$output = [
|
||||
'input' => [
|
||||
'name' => $file->getClientFilename(),
|
||||
'type' => $file->getClientMediaType(),
|
||||
'size' => $file->getSize(),
|
||||
'error' => $file->getError()
|
||||
],
|
||||
'new_name' => $new_name,
|
||||
'uploaded' => $handler->uploadFile($file, $new_name)
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function get(Request $request, Response $response, Handler $handler, $folder, $filename): Response {
|
||||
$file = $handler->getFile($folder, $filename);
|
||||
return $response
|
||||
->withHeader('Content-Type', $handler->getType($folder))
|
||||
->withHeader('Content-Disposition', 'attachment; filename=' . $filename)
|
||||
->withAddedHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->withHeader('Cache-Control', 'post-check=0, pre-check=0')
|
||||
->withHeader('Pragma', 'no-cache')
|
||||
->withBody($file);
|
||||
}
|
||||
public function edit(Request $request, Response $response, Handler $handler, Factory $factory, $folder, $filename): Response {
|
||||
$post = json_decode($request->getBody());
|
||||
$cuenta = $factory->find(Cuenta::class)->one($post->cuenta);
|
||||
$new_name = implode(' - ', [$cuenta->nombre, $cuenta->categoria()->nombre, $post->fecha]);
|
||||
$output = [
|
||||
'input' => [
|
||||
'folder' => $folder,
|
||||
'filename' => $filename,
|
||||
'post' => $post
|
||||
],
|
||||
'edited' => $handler->editFilename($folder, $filename, $new_name)
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function delete(Request $request, Response $response, Handler $handler, $folder, $filename): Response {
|
||||
$output = [
|
||||
'input' => [
|
||||
'folder' => $folder,
|
||||
'filename' => $filename
|
||||
],
|
||||
'deleted' => $handler->deleteFile($folder, $filename)
|
||||
];
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
112
api/common/Service/FileHandler.php
Normal file
112
api/common/Service/FileHandler.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Nyholm\Psr7\Stream;
|
||||
|
||||
class FileHandler {
|
||||
protected $base_folder;
|
||||
protected $valid_types;
|
||||
protected $folders;
|
||||
public function __construct(object $params) {
|
||||
$this->base_folder = $params->folder;
|
||||
$this->addValidTypes(array_keys($params->types));
|
||||
$this->addFolders($params->types);
|
||||
}
|
||||
public function addFolders(array $folders): FileHandler {
|
||||
foreach ($folders as $type => $folder) {
|
||||
$this->addFolder($type, $folder);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function addFolder(string $type, string $folder): FileHandler {
|
||||
$this->folders[$type] = $folder;
|
||||
return $this;
|
||||
}
|
||||
public function addValidTypes(array $valid_types): FileHandler {
|
||||
foreach ($valid_types as $type) {
|
||||
$this->addValidType($type);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function addValidType(string $type): FileHandler {
|
||||
$this->valid_types []= $type;
|
||||
return $this;
|
||||
}
|
||||
public function getType(string $folder): string {
|
||||
return array_search($folder, $this->folders);
|
||||
}
|
||||
|
||||
public function uploadFile(UploadedFileInterface $file, string $new_name = null): bool {
|
||||
if ($file->getError() !== UPLOAD_ERR_OK) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($file->getClientMediaType(), $this->valid_types)) {
|
||||
return false;
|
||||
}
|
||||
if ($new_name === null) {
|
||||
$new_name = $file->getClientFilename();
|
||||
}
|
||||
$filenfo = new \SplFileInfo($file->getClientFilename());
|
||||
if (!str_contains($new_name, $filenfo->getExtension())) {
|
||||
$new_name .= '.' . $filenfo->getExtension();
|
||||
}
|
||||
$to = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $this->folders[$file->getClientMediaType()], $new_name]);
|
||||
$file->moveTo($to);
|
||||
return file_exists($to);
|
||||
}
|
||||
public function listFiles(): array {
|
||||
$output = [];
|
||||
foreach ($this->folders as $f) {
|
||||
$folder = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $f]);
|
||||
if (!file_exists($folder)) {
|
||||
continue;
|
||||
}
|
||||
$files = new \DirectoryIterator($folder);
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
$output []= (object) ['folder' => $f, 'filename' => $file->getBasename()];
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
protected function validateFilename(string $folder, string $filename): bool|string {
|
||||
if (!in_array($folder, $this->folders)) {
|
||||
return false;
|
||||
}
|
||||
$f = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $folder, $filename]);
|
||||
if (!file_exists($f)) {
|
||||
return false;
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
public function getInfo(string $folder, string $filename): \SplFileInfo|bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return new \SplFileInfo($f);
|
||||
}
|
||||
public function getFile(string $folder, string $filename): StreamInterface|bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return Stream::create(file_get_contents($f));
|
||||
}
|
||||
public function editFilename(string $folder, string $filename, string $new_name): bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
$info = new \SplFileInfo($f);
|
||||
$new = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $folder, $new_name . '.' . $info->getExtension()]);
|
||||
return rename($f, $new);
|
||||
}
|
||||
public function deleteFile(string $folder, string $filename): bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return unlink($f);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ use Carbon\Carbon;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use ProVM\Common\Factory\Model as Factory;
|
||||
use Contabilidad\Moneda;
|
||||
use Contabilidad\TipoCambio;
|
||||
@ -20,30 +21,22 @@ class TiposCambios {
|
||||
$this->base_url = $api_url;
|
||||
$this->key = $api_key;
|
||||
}
|
||||
public function get(string $fecha, int $moneda_id) {
|
||||
$fecha = Carbon::parse($fecha);
|
||||
$moneda = $this->factory->find(Moneda::class)->one($moneda_id);
|
||||
if ($moneda->codigo == 'USD') {
|
||||
if ($fecha->weekday() == 0) {
|
||||
$fecha = $fecha->subWeek()->weekday(5);
|
||||
}
|
||||
if ($fecha->weekday() == 6) {
|
||||
$fecha = $fecha->weekday(5);
|
||||
}
|
||||
protected function getWeekday(\DateTimeInterface $fecha) {
|
||||
if ($fecha->weekday() == 0) {
|
||||
return $fecha->subWeek()->weekday(5);
|
||||
}
|
||||
$cambio = $moneda->cambio($fecha);
|
||||
if ($cambio) {
|
||||
if ($cambio->desde()->id != $moneda->id) {
|
||||
return 1 / $cambio->valor;
|
||||
}
|
||||
return $cambio->valor;
|
||||
if ($fecha->weekday() == 6) {
|
||||
return $fecha->weekday(5);
|
||||
}
|
||||
return $fecha;
|
||||
}
|
||||
protected function getValor(\DateTimeInterface $fecha, string $moneda_codigo) {
|
||||
$data = [
|
||||
'fecha' => $fecha->format('Y-m-d'),
|
||||
'desde' => $moneda->codigo
|
||||
'desde' => $moneda_codigo
|
||||
];
|
||||
$headers = [
|
||||
'Authorization' => 'Bearer ' . $this->key
|
||||
'Authorization' => "Bearer {$this->key}"
|
||||
];
|
||||
$url = implode('/', [
|
||||
$this->base_url,
|
||||
@ -52,15 +45,39 @@ class TiposCambios {
|
||||
]);
|
||||
try {
|
||||
$response = $this->client->request('POST', $url, ['json' => $data, 'headers' => $headers]);
|
||||
} catch (ConnectException | RequestException $e) {
|
||||
} catch (ConnectException | RequestException | ServerException $e) {
|
||||
error_log($e);
|
||||
return null;
|
||||
}
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
error_log('Could not connect to python API.');
|
||||
return null;
|
||||
}
|
||||
$result = json_decode($response->getBody());
|
||||
$valor = $result->serie[0]->valor;
|
||||
if (isset($result->message) and $result->message === 'Not Authorized') {
|
||||
error_log('Not authorized for connecting to python API.');
|
||||
return null;
|
||||
}
|
||||
return $result->serie[0]->valor;
|
||||
}
|
||||
public function get(string $fecha, int $moneda_id) {
|
||||
$fecha = Carbon::parse($fecha);
|
||||
$moneda = $this->factory->find(Moneda::class)->one($moneda_id);
|
||||
if ($moneda->codigo == 'USD') {
|
||||
$fecha = $this->getWeekday($fecha);
|
||||
}
|
||||
// If a value exists in the database
|
||||
$cambio = $moneda->cambio($fecha);
|
||||
if ($cambio !== null) {
|
||||
if ($cambio->desde()->id != $moneda->id) {
|
||||
return 1 / $cambio->valor;
|
||||
}
|
||||
return $cambio->valor;
|
||||
}
|
||||
$valor = $this->getValor($fecha, $moneda->codigo);
|
||||
if ($valor === null) {
|
||||
return 1;
|
||||
}
|
||||
$data = [
|
||||
'fecha' => $fecha->format('Y-m-d H:i:s'),
|
||||
'desde_id' => $moneda->id,
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -5,25 +5,26 @@ 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;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
|
||||
X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'application/json';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
|
||||
X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
|
||||
|
||||
try_files $uri =404;
|
||||
|
@ -1,2 +1,4 @@
|
||||
log_errors = true
|
||||
error_log = /var/log/php/error.log
|
||||
error_log = /var/log/php/error.log
|
||||
upload_max_filesize = 50M
|
||||
max_input_vars = 5000
|
||||
|
Binary file not shown.
Binary file not shown.
@ -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);
|
||||
|
@ -11,6 +11,7 @@ $app->group('/cuenta/{cuenta_id}', function($app) {
|
||||
$app->get('/amount', [Cuentas::class, 'transaccionesAmount']);
|
||||
$app->get('[/{limit:[0-9]+}[/{start:[0-9]+}]]', [Cuentas::class, 'transacciones']);
|
||||
});
|
||||
$app->get('/categoria', [Cuentas::class, 'categoria']);
|
||||
$app->put('/edit', [Cuentas::class, 'edit']);
|
||||
$app->delete('/delete', [Cuentas::class, 'delete']);
|
||||
$app->get('[/]', [Cuentas::class, 'show']);
|
||||
|
12
api/resources/routes/uploads.php
Normal file
12
api/resources/routes/uploads.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
use Contabilidad\Common\Controller\Files;
|
||||
|
||||
$app->group('/uploads', function($app) {
|
||||
$app->post('/add[/]', [Files::class, 'upload']);
|
||||
$app->get('[/]', Files::class);
|
||||
});
|
||||
$app->group('/upload/{folder}/{filename}', function($app) {
|
||||
$app->put('[/]', [Files::class, 'edit']);
|
||||
$app->delete('[/]', [Files::class, 'delete']);
|
||||
$app->get('[/]', [Files::class, 'get']);
|
||||
});
|
@ -19,7 +19,7 @@ return [
|
||||
'public'
|
||||
]);
|
||||
$arr['uploads'] = implode(DIRECTORY_SEPARATOR, [
|
||||
$arr['public'],
|
||||
$arr['base'],
|
||||
'uploads'
|
||||
]);
|
||||
$arr['pdfs'] = implode(DIRECTORY_SEPARATOR, [
|
||||
|
@ -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'));
|
||||
},
|
||||
@ -14,27 +14,27 @@ return [
|
||||
$c->get(Contabilidad\Common\Service\Auth::class)
|
||||
);
|
||||
},
|
||||
Contabilidad\Common\Service\PdfHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\PdfHandler($c->get(GuzzleHttp\Client::class), $c->get('folders')->pdfs, implode('/', [
|
||||
$c->get('urls')->python,
|
||||
'pdf',
|
||||
'parse'
|
||||
]));
|
||||
},
|
||||
Contabilidad\Common\Service\CsvHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\CsvHandler($c->get('folders')->csvs);
|
||||
},
|
||||
Contabilidad\Common\Service\XlsHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\XlsHandler($c->get('folders')->xlss);
|
||||
},
|
||||
Contabilidad\Common\Service\DocumentHandler::class => function(Container $c) {
|
||||
$handlers = [
|
||||
$c->get(Contabilidad\Common\Service\XlsHandler::class),
|
||||
$c->get(Contabilidad\Common\Service\CsvHandler::class),
|
||||
$c->get(Contabilidad\Common\Service\PdfHandler::class)
|
||||
];
|
||||
return new Contabilidad\Common\Service\DocumentHandler($handlers);
|
||||
},
|
||||
Contabilidad\Common\Service\PdfHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\PdfHandler($c->get(GuzzleHttp\Client::class), $c->get('folders')->pdfs, implode('/', [
|
||||
$c->get('urls')->python,
|
||||
'pdf',
|
||||
'parse'
|
||||
]));
|
||||
},
|
||||
Contabilidad\Common\Service\CsvHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\CsvHandler($c->get('folders')->csvs);
|
||||
},
|
||||
Contabilidad\Common\Service\XlsHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\XlsHandler($c->get('folders')->xlss);
|
||||
},
|
||||
Contabilidad\Common\Service\DocumentHandler::class => function(Container $c) {
|
||||
$handlers = [
|
||||
$c->get(Contabilidad\Common\Service\XlsHandler::class),
|
||||
$c->get(Contabilidad\Common\Service\CsvHandler::class),
|
||||
$c->get(Contabilidad\Common\Service\PdfHandler::class)
|
||||
];
|
||||
return new Contabilidad\Common\Service\DocumentHandler($handlers);
|
||||
},
|
||||
Contabilidad\Common\Service\TiposCambios::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\TiposCambios(
|
||||
$c->get(GuzzleHttp\Client::class),
|
||||
@ -42,5 +42,17 @@ return [
|
||||
$c->get('python_api'),
|
||||
$c->get('python_key')
|
||||
);
|
||||
},
|
||||
Contabilidad\Common\Service\FileHandler::class => function(Container $c) {
|
||||
return new Contabilidad\Common\Service\FileHandler((object) [
|
||||
'folder' => $c->get('folders')->uploads,
|
||||
'types' => [
|
||||
'text/csv' => 'csvs',
|
||||
'application/pdf' => 'pdfs',
|
||||
'application/vnd.ms-excel' => 'xlss',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlss',
|
||||
'application/json' => 'jsons'
|
||||
]
|
||||
]);
|
||||
}
|
||||
];
|
||||
|
@ -18,6 +18,11 @@ class Categoria extends Model {
|
||||
public function cuentas() {
|
||||
if ($this->cuentas === null) {
|
||||
$this->cuentas = $this->parentOf(Cuenta::class, [Model::CHILD_KEY => 'categoria_id']);
|
||||
if ($this->cuentas !== null) {
|
||||
usort($this->cuentas, function($a, $b) {
|
||||
return strcmp($a->nombre, $b->nombre);
|
||||
});
|
||||
}
|
||||
}
|
||||
return $this->cuentas;
|
||||
}
|
||||
@ -89,4 +94,10 @@ class Categoria extends Model {
|
||||
}
|
||||
return $this->saldo;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
$arr = parent::toArray();
|
||||
$arr['tipo'] = $this->tipo()->toArray();
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class Cuenta extends Model {
|
||||
public function transacciones($limit = null, $start = 0) {
|
||||
if ($this->transacciones === null) {
|
||||
$transacciones = Model::factory(Transaccion::class)
|
||||
->select('transacciones.*')
|
||||
->join('cuentas', 'cuentas.id = transacciones.debito_id OR cuentas.id = transacciones.credito_id')
|
||||
->whereEqual('cuentas.id', $this->id)
|
||||
->orderByAsc('transacciones.fecha');
|
||||
|
@ -26,7 +26,7 @@ class Moneda extends Model {
|
||||
$cambio = $this->factory->find(TipoCambio::class)
|
||||
->where([['desde_id', $this->id], ['hasta_id', 1], ['fecha', $fecha->format('Y-m-d H:i:s')]])
|
||||
->one();
|
||||
if (!$cambio) {
|
||||
if ($cambio === null) {
|
||||
$cambio = $this->factory->find(TipoCambio::class)
|
||||
->where([['hasta_id', $this->id], ['desde_id', 1], ['fecha', $fecha->format('Y-m-d H:i:s')]])
|
||||
->one();
|
||||
|
@ -10,20 +10,20 @@ 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)
|
||||
->select([['cuentas', '*']])
|
||||
->select('cuentas.*')
|
||||
->join([
|
||||
['tipos_cuenta', 'tipos_cuenta.id', 'cuentas.tipo_id'],
|
||||
['categorias', 'categorias.id', 'cuentas.categoria_id']
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ services:
|
||||
image: php-ui
|
||||
env_file:
|
||||
- .api.env
|
||||
- .env
|
||||
build:
|
||||
context: ui
|
||||
volumes:
|
||||
|
@ -22,7 +22,10 @@ def validate_key(request_obj):
|
||||
if isinstance(auth, list):
|
||||
auth = auth[0]
|
||||
if 'Bearer' in auth:
|
||||
auth = auth.split(' ')[1]
|
||||
try:
|
||||
auth = auth.split(' ')[1]
|
||||
except:
|
||||
return False
|
||||
return auth == api_key
|
||||
if 'API_KEY' in request_obj.values:
|
||||
return request_obj.values.get('API_KEY') == api_key
|
||||
|
@ -1,3 +1,9 @@
|
||||
FROM php:8-fpm
|
||||
|
||||
RUN apt-get update -y && apt-get install -y git libzip-dev zip
|
||||
|
||||
RUN docker-php-ext-install zip
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/bin/composer
|
||||
|
||||
WORKDIR /app
|
||||
|
12
ui/common/Controller/Importar.php
Normal file
12
ui/common/Controller/Importar.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Slim\Views\Blade as View;
|
||||
|
||||
class Importar {
|
||||
public function __invoke(Request $request, Response $response, View $view): Response {
|
||||
return $view->render($response, 'importar');
|
||||
}
|
||||
}
|
24
ui/common/Controller/Uploads.php
Normal file
24
ui/common/Controller/Uploads.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Slim\Views\Blade as View;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Uploads {
|
||||
public function __invoke(Request $request, Response $response, View $view): Response {
|
||||
return $view->render($response, 'uploads.list');
|
||||
}
|
||||
public function get(Request $request, Response $response, Client $client, $folder, $filename): Response {
|
||||
$resp = $client->get(implode('/', ['upload', $folder, $filename]));
|
||||
$file = $resp->getBody();
|
||||
return $response
|
||||
->withHeader('Content-Type', $resp->getHeader('Content-Type'))
|
||||
->withHeader('Content-Disposition', 'attachment; filename=' . $filename)
|
||||
->withAddedHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->withHeader('Cache-Control', 'post-check=0, pre-check=0')
|
||||
->withHeader('Pragma', 'no-cache')
|
||||
->withBody($file);
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
"rubellum/slim-blade-view": "^0.1.1",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"zeuxisoo/slim-whoops": "^0.7.3",
|
||||
"nyholm/psr7": "^1.4"
|
||||
"nyholm/psr7": "^1.4",
|
||||
"guzzlehttp/guzzle": "^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
@ -24,11 +25,5 @@
|
||||
"psr-4": {
|
||||
"Contabilidad\\Common\\": "common"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "http://git.provm.cl/ProVM/controller.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class Transaccion {
|
||||
).append(
|
||||
$('<td></td>').attr('class', 'right aligned').html(format.format(saldo))
|
||||
).append(
|
||||
$('<td></td>').attr('class', 'right aligned')/*.append(
|
||||
$('<td></td>').attr('class', 'right aligned').append(
|
||||
$('<button></button>').attr('class', 'ui tiny circular icon button').append(
|
||||
$('<i></i>').attr('class', 'edit icon')
|
||||
).click((e) => {
|
||||
@ -58,7 +58,7 @@ class Transaccion {
|
||||
this.edit()
|
||||
return false
|
||||
})
|
||||
)*/.append(
|
||||
).append(
|
||||
$('<button></button>').attr('class', 'ui tiny circular red icon button').append(
|
||||
$('<i></i>').attr('class', 'remove icon')
|
||||
).click((e) => {
|
||||
@ -71,7 +71,15 @@ class Transaccion {
|
||||
}
|
||||
edit() {
|
||||
const form = this.modal.find('form')
|
||||
form.find("[name='fecha']")
|
||||
form.trigger('reset')
|
||||
form.find("[name='id']").val(this.id)
|
||||
form.find(".ui.calendar").calendar('set date', new Date(this.fecha.fecha))
|
||||
form.find("[name='cuenta']").dropdown('set selected', (this.isDebito()) ? this.credito_id : this.credito_id)
|
||||
form.find("[name='glosa']").val(this.glosa)
|
||||
form.find("[name='detalle']").val(this.detalle)
|
||||
form.find("[name='valor']").val(((this.isDebito()) ? -1 : 1) * this.valor.valor)
|
||||
modalToEdit(this.modal)
|
||||
this.modal.modal('show')
|
||||
}
|
||||
remove() {
|
||||
sendDelete(_urls.api + '/transaccion/' + this.id + '/delete').then(() => {
|
||||
@ -90,46 +98,51 @@ const transacciones = {
|
||||
get: function() {
|
||||
return {
|
||||
transacciones: () => {
|
||||
this.draw().loading()
|
||||
let promises = []
|
||||
sendGet(_urls.api + '/cuenta/' + this.cuenta_id + '/transacciones/amount').then((data) => {
|
||||
if (data.cuenta === null) {
|
||||
return
|
||||
}
|
||||
this.cuenta = data.cuenta
|
||||
this.saldo = this.cuenta.saldo
|
||||
$('#cuenta').html(this.cuenta.nombre + ' (' + this.cuenta.categoria.nombre + ')').append(
|
||||
$('<i></i>').attr('class', 'square full icon').css('color', '#' + this.cuenta.tipo.color)
|
||||
)
|
||||
const amount = data.transacciones
|
||||
const step = 50
|
||||
for (let i = 0; i < amount; i += step) {
|
||||
promises.push(
|
||||
sendGet(_urls.api + '/cuenta/' + this.cuenta_id + '/transacciones/' + step + '/' + i)
|
||||
sendGet(_urls.api + '/cuenta/' + this.cuenta_id + '/categoria').then((resp) => {
|
||||
this.cuenta.categoria = resp.categoria
|
||||
}).then(() => {
|
||||
this.saldo = this.cuenta.saldo
|
||||
$('#cuenta').html(this.cuenta.nombre + ' (' + this.cuenta.categoria.nombre + ')').append(
|
||||
$('<i></i>').attr('class', 'square full icon').css('color', '#' + this.cuenta.tipo.color)
|
||||
)
|
||||
}
|
||||
if (promises.length > 0) {
|
||||
Promise.all(promises).then((data_arr) => {
|
||||
this.transacciones = []
|
||||
data_arr.forEach(data => {
|
||||
if (data.transacciones === null || data.transacciones.length === 0) {
|
||||
return
|
||||
}
|
||||
$.each(data.transacciones, (i, el) => {
|
||||
const tr = new Transaccion(el)
|
||||
tr.setCuenta(this.cuenta)
|
||||
tr.setModal(this.modal)
|
||||
this.transacciones.push(tr)
|
||||
const amount = data.transacciones
|
||||
const step = 50
|
||||
for (let i = 0; i < amount; i += step) {
|
||||
promises.push(
|
||||
sendGet(_urls.api + '/cuenta/' + this.cuenta_id + '/transacciones/' + step + '/' + i)
|
||||
)
|
||||
}
|
||||
if (promises.length > 0) {
|
||||
Promise.all(promises).then((data_arr) => {
|
||||
this.transacciones = []
|
||||
data_arr.forEach(data => {
|
||||
if (data.transacciones === null || data.transacciones.length === 0) {
|
||||
return
|
||||
}
|
||||
$.each(data.transacciones, (i, el) => {
|
||||
const tr = new Transaccion(el)
|
||||
tr.setCuenta(this.cuenta)
|
||||
tr.setModal(this.modal)
|
||||
this.transacciones.push(tr)
|
||||
})
|
||||
})
|
||||
this.transacciones.sort((a, b) => {
|
||||
return (new Date(b.fecha)) - (new Date(a.fecha))
|
||||
})
|
||||
}).then(() => {
|
||||
this.draw().table()
|
||||
})
|
||||
this.transacciones.sort((a, b) => {
|
||||
return (new Date(b.fecha)) - (new Date(a.fecha))
|
||||
})
|
||||
}).then(() => {
|
||||
this.draw()
|
||||
})
|
||||
} else {
|
||||
this.draw()
|
||||
}
|
||||
} else {
|
||||
this.draw().table()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
cuentas: () => {
|
||||
@ -141,22 +154,46 @@ const transacciones = {
|
||||
}).then(() => {
|
||||
const select = this.modal.find("[name='cuenta']")
|
||||
$.each(this.cuentas, (i, el) => {
|
||||
select.append(
|
||||
$('<option></option>').attr('value', el.id).html(el.nombre + ' (' + el.categoria.nombre + ')')
|
||||
)
|
||||
this.get().categoria(i).then(() => {
|
||||
select.append(
|
||||
$('<option></option>').attr('value', el.id).html(el.nombre + ' (' + el.categoria.nombre + ')')
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
categoria: (idx) => {
|
||||
return sendGet(_urls.api + '/cuenta/' + this.cuentas[idx].id + '/categoria').then((data) => {
|
||||
this.cuentas[idx].categoria = data.categoria
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
draw: function() {
|
||||
const format = Intl.NumberFormat('es-CL', {style: 'currency', currency: this.cuenta.moneda.codigo})
|
||||
const parent = $(this.id)
|
||||
parent.html('')
|
||||
$.each(this.transacciones, (i, el) => {
|
||||
parent.append(el.draw({saldo: this.saldo, format: format}))
|
||||
this.saldo = this.saldo + parseInt(el.valor.valor) * ((el.isIncrement()) ? 1 : -1)
|
||||
})
|
||||
return {
|
||||
loading: () => {
|
||||
const parent = $(this.id)
|
||||
parent.html('')
|
||||
parent.append(
|
||||
$('<tr></tr>').append(
|
||||
$('<td></td>').attr('colspan', 7).append(
|
||||
$('<div></div>').attr('class', 'ui active dimmer').append(
|
||||
$('<div></div>').attr('class', 'ui indeterminate elastic text loader').html('Buscando los datos')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
table: () => {
|
||||
const format = Intl.NumberFormat('es-CL', {style: 'currency', currency: this.cuenta.moneda.codigo})
|
||||
const parent = $(this.id)
|
||||
parent.html('')
|
||||
$.each(this.transacciones, (i, el) => {
|
||||
parent.append(el.draw({saldo: this.saldo, format: format}))
|
||||
this.saldo = this.saldo + parseInt(el.valor.valor) * ((el.isIncrement()) ? 1 : -1)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
add: function() {
|
||||
return {
|
||||
@ -172,7 +209,7 @@ const transacciones = {
|
||||
fecha: fecha,
|
||||
valor: $("[name='cambio']").val()
|
||||
})
|
||||
sendPut(_urls.api + '/tipos/cambios/add', data1)
|
||||
sendPost(_urls.api + '/tipos/cambios/add', data1)
|
||||
|
||||
const valor = $("[name='valor']").val()
|
||||
const cuenta = $("[name='cuenta']").val()
|
||||
@ -191,6 +228,29 @@ const transacciones = {
|
||||
}
|
||||
}
|
||||
},
|
||||
edit: function() {
|
||||
const id = $("[name='id']").val()
|
||||
const fecha = $("[name='fecha']").val()
|
||||
const cuenta = $("[name='cuenta']").val()
|
||||
const glosa = $("[name='glosa']").val()
|
||||
const detalle = $("[name='detalle']").val()
|
||||
const valor = $("[name='valor']").val()
|
||||
const data = JSON.stringify({
|
||||
debito_id: (valor < 0) ? this.cuenta_id : cuenta,
|
||||
credito_id: (valor < 0) ? cuenta : this.cuenta_id,
|
||||
fecha,
|
||||
glosa,
|
||||
detalle,
|
||||
valor: (valor < 0) ? -valor : valor
|
||||
})
|
||||
return sendPut(_urls.api + '/transaccion/' + id + '/edit', data).then(() => {
|
||||
this.modal.modal('hide')
|
||||
this.get().transacciones()
|
||||
})
|
||||
},
|
||||
refresh: function () {
|
||||
this.get().transacciones()
|
||||
},
|
||||
build: function() {
|
||||
return {
|
||||
modal: () => {
|
||||
@ -201,7 +261,12 @@ const transacciones = {
|
||||
})
|
||||
this.modal.find('form').submit((e) => {
|
||||
e.preventDefault()
|
||||
this.add().exec()
|
||||
const add = $(e.currentTarget).find('.plus.icon')
|
||||
if (add.length > 0) {
|
||||
this.add().exec()
|
||||
} else {
|
||||
this.edit()
|
||||
}
|
||||
return false
|
||||
})
|
||||
this.modal.find('.ui.calendar').calendar({
|
||||
@ -223,7 +288,10 @@ const transacciones = {
|
||||
},
|
||||
setup: function() {
|
||||
this.build().modal()
|
||||
$(this.id).parent().find('.ui.button').click(() => {
|
||||
$(this.id).parent().find('#refresh').click(() => {
|
||||
this.refresh()
|
||||
})
|
||||
$(this.id).parent().find('#add').click(() => {
|
||||
this.add().show()
|
||||
})
|
||||
this.get().transacciones()
|
||||
|
@ -39,7 +39,20 @@ class Cuenta {
|
||||
}
|
||||
tr.append(td)
|
||||
})
|
||||
$("[data-id='" + this.categoria_id + "'][data-class='categoria']").after(tr)
|
||||
const prev = this.prev()
|
||||
prev.after(tr)
|
||||
}
|
||||
prev() {
|
||||
let prev = $("[data-id='" + this.categoria_id + "'][data-class='categoria']")
|
||||
let n = 0
|
||||
while (prev.next().attr('data-class') === 'cuenta') {
|
||||
prev = prev.next()
|
||||
n ++;
|
||||
if (n >= 100) {
|
||||
return prev
|
||||
}
|
||||
}
|
||||
return prev
|
||||
}
|
||||
remove() {
|
||||
$("[data-id='" + this.id + "'][data-class='cuenta']").remove()
|
||||
@ -210,29 +223,61 @@ class TipoCategoria {
|
||||
}
|
||||
}
|
||||
const cuentas = {
|
||||
id: 'cuentas',
|
||||
id: '#cuentas',
|
||||
balance: 0,
|
||||
tipos: [],
|
||||
tipos_categorias: [],
|
||||
build: function() {
|
||||
return {
|
||||
parent: (segment) => {
|
||||
const tr = $('<tr></tr>').append(
|
||||
$('<th></th>').attr('colspan', 3).html('Cuenta')
|
||||
)
|
||||
$.each(this.tipos, (i, el) => {
|
||||
tr.append(
|
||||
$('<th></th>').attr('class', 'right aligned').css('color', '#' + el.color).html(el.descripcion)
|
||||
)
|
||||
})
|
||||
const table = $('<table></table>').attr('class', 'ui striped table').append(
|
||||
$('<thead></thead>').append(tr)
|
||||
)
|
||||
const parent = $('<tbody></tbody>')
|
||||
table.append(parent)
|
||||
segment.append(table)
|
||||
return parent
|
||||
},
|
||||
resultado: (segment) => {
|
||||
segment.append(
|
||||
$('<table></table>').attr('class', 'ui collapsing table').append(
|
||||
$('<tr></tr>').append(
|
||||
$('<td></td>').html('Ganancias')
|
||||
).append(
|
||||
$('<td></td>').attr('data-tipo', 'ganancias')
|
||||
)
|
||||
).append(
|
||||
$('<tr></tr>').append(
|
||||
$('<td></td>').html('Perdidas')
|
||||
).append(
|
||||
$('<td></td>').attr('data-tipo', 'perdidas')
|
||||
)
|
||||
).append(
|
||||
$('<tr></tr>').append(
|
||||
$('<td></td>').html('<b>Resultado</b>')
|
||||
).append(
|
||||
$('<td></td>').attr('data-tipo', 'resultado')
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function() {
|
||||
return {
|
||||
parent: () => {
|
||||
let parent = $('#' + this.id)
|
||||
const segment = $(this.id)
|
||||
let parent = segment.find('tbody')
|
||||
if (parent.length === 0) {
|
||||
const tr = $('<tr></tr>').append(
|
||||
$('<th></th>').attr('colspan', 3).html('Cuenta')
|
||||
)
|
||||
$.each(this.tipos, (i, el) => {
|
||||
tr.append(
|
||||
$('<th></th>').attr('class', 'right aligned').css('color', '#' + el.color).html(el.descripcion)
|
||||
)
|
||||
})
|
||||
const table = $('<table></table>').attr('class', 'ui striped table').append(
|
||||
$('<thead></thead>').append(tr)
|
||||
)
|
||||
parent = $('<tbody></tbody>').attr('id', this.id)
|
||||
table.append(parent)
|
||||
$('h1.header').after(table)
|
||||
parent = this.build().parent(segment)
|
||||
}
|
||||
return parent
|
||||
},
|
||||
@ -263,6 +308,8 @@ const cuentas = {
|
||||
this.balance = data
|
||||
}).then(() => {
|
||||
this.draw().balance()
|
||||
}).then(() => {
|
||||
this.draw().resultado()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -298,6 +345,17 @@ const cuentas = {
|
||||
)
|
||||
})
|
||||
foot.append(tr)
|
||||
},
|
||||
resultado: () => {
|
||||
const div = $('#resultado')
|
||||
if (div.find("[data-tipo='resultado']").length === 0) {
|
||||
div.html('')
|
||||
this.build().resultado(div)
|
||||
}
|
||||
const format = Intl.NumberFormat('es-CL', {style: 'currency', currency: 'CLP'})
|
||||
div.find("[data-tipo='ganancias']").html(format.format(this.balance['ganancias']))
|
||||
div.find("[data-tipo='perdidas']").html(format.format(this.balance['perdidas']))
|
||||
div.find("[data-tipo='resultado']").html('<b>' + format.format(this.balance['ganancias'] - this.balance['perdidas']) + '</b>')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -90,32 +90,37 @@ const tipos_categorias = {
|
||||
this.draw()
|
||||
})
|
||||
},
|
||||
getParent: function() {
|
||||
let parent = $(this.id).find('tbody')
|
||||
if (parent.length === 0) {
|
||||
const table = $('<table></table>').attr('class', 'ui table').append(
|
||||
$('<thead></thead>').append(
|
||||
$('<tr></tr>').append(
|
||||
$('<th></th>').attr('class', 'twelve wide').html('Tipo Categoría')
|
||||
).append(
|
||||
$('<th></th>').attr('class', 'two wide').html('Activo')
|
||||
).append(
|
||||
$('<th></th>').attr('class', 'two wide right aligned').append(
|
||||
$('<button></button>').attr('class', 'ui tiny green circular icon button').append(
|
||||
$('<i></i>').attr('class', 'plus icon')
|
||||
)
|
||||
buildParent: function(segment) {
|
||||
const table = $('<table></table>').attr('class', 'ui table').append(
|
||||
$('<thead></thead>').append(
|
||||
$('<tr></tr>').append(
|
||||
$('<th></th>').attr('class', 'twelve wide').html('Tipo Categoría')
|
||||
).append(
|
||||
$('<th></th>').attr('class', 'two wide').html('Activo')
|
||||
).append(
|
||||
$('<th></th>').attr('class', 'two wide right aligned').append(
|
||||
$('<button></button>').attr('class', 'ui tiny green circular icon button').append(
|
||||
$('<i></i>').attr('class', 'plus icon')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
table.find('.ui.button').click((e) => {
|
||||
e.preventDefault()
|
||||
this.add()
|
||||
return false
|
||||
})
|
||||
parent = $('<tbody></tbody>')
|
||||
table.append(parent)
|
||||
$(this.id).append(table)
|
||||
)
|
||||
table.find('.ui.button').click((e) => {
|
||||
e.preventDefault()
|
||||
this.add()
|
||||
return false
|
||||
})
|
||||
parent = $('<tbody></tbody>')
|
||||
table.append(parent)
|
||||
segment.append(table)
|
||||
return parent
|
||||
},
|
||||
getParent: function() {
|
||||
const segment = $(this.id)
|
||||
let parent = segment.find('tbody')
|
||||
if (parent.length === 0) {
|
||||
parent = this.buildParent(segment)
|
||||
}
|
||||
return parent
|
||||
},
|
||||
|
@ -55,6 +55,7 @@ class TipoCuenta {
|
||||
const tipos_cuentas = {
|
||||
id: '#tipos_cuentas',
|
||||
tipos: [],
|
||||
modal: null,
|
||||
getTipos: function() {
|
||||
this.tipos = []
|
||||
return sendGet(_urls.api + '/tipos/cuentas').then((data) => {
|
||||
|
221
ui/public/assets/scripts/uploads.list.js
Normal file
221
ui/public/assets/scripts/uploads.list.js
Normal file
@ -0,0 +1,221 @@
|
||||
class Archivo {
|
||||
constructor({folder, filename}) {
|
||||
this.folder = folder
|
||||
this.filename = filename
|
||||
this.modal = null
|
||||
}
|
||||
setModal(modal) {
|
||||
this.modal = modal
|
||||
return this
|
||||
}
|
||||
draw() {
|
||||
return $('<tr></tr>').append(
|
||||
$('<td></td>').append(
|
||||
$('<a></a>').attr('class', 'item').attr('href', _urls.base + ['upload', this.folder, this.filename].join('/')).html(this.filename)
|
||||
)
|
||||
).append(
|
||||
$('<td></td>').attr('class', 'right aligned').append(
|
||||
$('<button></button>').attr('class', 'ui mini circular icon button').append(
|
||||
$('<i></i>').attr('class', 'edit icon')
|
||||
).click((e) => {
|
||||
e.preventDefault()
|
||||
const t = e.currentTarget
|
||||
this.edit()
|
||||
return false
|
||||
})
|
||||
).append(
|
||||
$('<button></button>').attr('class', 'ui mini red circular icon button').append(
|
||||
$('<i></i>').attr('class', 'remove icon')
|
||||
).click((e) => {
|
||||
e.preventDefault()
|
||||
const t = e.currentTarget
|
||||
this.remove()
|
||||
return false
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
edit() {
|
||||
this.modal.find('form').trigger('reset')
|
||||
this.modal.find('form').find("[name='folder']").val(this.folder)
|
||||
this.modal.find('form').find("[name='old_filename']").val(this.filename)
|
||||
this.modal.find('form').find("[name='filename']").val(this.filename)
|
||||
this.modal.modal('show')
|
||||
}
|
||||
remove() {
|
||||
return sendDelete([_urls.api, 'upload', this.folder, this.filename].join('/')).then((data) => {
|
||||
if (data.deleted) {
|
||||
archivos.get()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const archivos = {
|
||||
id: '#archivos',
|
||||
archivos: [],
|
||||
modals: {
|
||||
add: null,
|
||||
edit: null
|
||||
},
|
||||
build: function() {
|
||||
return {
|
||||
parent: (segment) => {
|
||||
const table = $('<table></table>').attr('class', 'ui striped table').append(
|
||||
$('<thead></thead>').append(
|
||||
$('<tr></tr>').append(
|
||||
$('<th></th>').html('Archivo')
|
||||
).append(
|
||||
$('<th></th>').attr('class', 'right aligned').append(
|
||||
$('<button></button>').attr('class', 'ui tiny green circular icon button').append(
|
||||
$('<i></i>').attr('class', 'plus icon')
|
||||
).click((e) => {
|
||||
e.preventDefault()
|
||||
this.add()
|
||||
return false
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
const parent = $('<tbody></tbody>')
|
||||
table.append(parent)
|
||||
segment.append(table)
|
||||
return parent
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function() {
|
||||
return {
|
||||
parent: () => {
|
||||
const segment = $(this.id)
|
||||
let parent = segment.find('tbody')
|
||||
if (parent.length === 0) {
|
||||
parent = this.build().parent(segment)
|
||||
}
|
||||
return parent
|
||||
},
|
||||
archivos: () => {
|
||||
return sendGet(_urls.api + '/uploads').then((data) => {
|
||||
if (data.files === null || data.files.length === 0) {
|
||||
return
|
||||
}
|
||||
this.archivos = []
|
||||
$.each(data.files, (i, el) => {
|
||||
const arch = new Archivo(el)
|
||||
arch.setModal(this.modals.edit)
|
||||
this.archivos.push(arch)
|
||||
})
|
||||
}).then(() => {
|
||||
this.draw()
|
||||
})
|
||||
},
|
||||
cuentas: () => {
|
||||
return sendGet(_urls.api + '/cuentas')
|
||||
}
|
||||
}
|
||||
},
|
||||
draw: function() {
|
||||
const tbody = this.get().parent()
|
||||
tbody.empty()
|
||||
$.each(this.archivos, (i, el) => {
|
||||
tbody.append(el.draw())
|
||||
})
|
||||
},
|
||||
add: function() {
|
||||
this.modals.add.find('form').trigger('reset')
|
||||
this.modals.add.find("[name='cuenta']").dropdown('clear')
|
||||
this.modals.add.modal('show')
|
||||
},
|
||||
doAdd: function() {
|
||||
const data = new FormData(this.modals.add.find('form')[0])
|
||||
return sendPost(_urls.api + '/uploads/add', data, true).then((resp) => {
|
||||
this.modals.add.modal('hide')
|
||||
this.get().archivos()
|
||||
})
|
||||
},
|
||||
doEdit: function() {
|
||||
const folder = this.modals.edit.find("[name='folder']").val()
|
||||
const filename = this.modals.edit.find("[name='old_filename']").val()
|
||||
const data = JSON.stringify({
|
||||
cuenta: this.modals.edit.find("[name='cuenta']").val(),
|
||||
fecha: this.modals.edit.find("[name='fecha']").val()
|
||||
})
|
||||
sendPut([_urls.api, 'upload', folder, filename].join('/'), data).then((resp) => {
|
||||
this.modals.edit.modal('hide')
|
||||
if (resp.edited) {
|
||||
this.get().archivos()
|
||||
}
|
||||
})
|
||||
},
|
||||
updateCalendar: function(modal) {
|
||||
const today = new Date()
|
||||
const start = new Date(today.getFullYear(), today.getMonth() - 1)
|
||||
modal.find('.ui.calendar').calendar({
|
||||
type: 'month',
|
||||
initialDate: start,
|
||||
maxDate: start,
|
||||
months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
|
||||
monthsShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
|
||||
formatter: {
|
||||
date: function(date, settings) {
|
||||
if (!date) return ''
|
||||
const year = date.getFullYear()
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
||||
return [year, month].join('-')
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
updateCuentas: function(modal, data) {
|
||||
if (data.cuentas === null || data.cuentas.length === 0) {
|
||||
return
|
||||
}
|
||||
const select = modal.find("select[name='cuenta']")
|
||||
let values = []
|
||||
$.each(data.cuentas, (i, el) => {
|
||||
const nombre = [el.nombre, el.categoria.nombre].join(' - ')
|
||||
values.push({
|
||||
name: nombre,
|
||||
value: el.id,
|
||||
text: nombre
|
||||
})
|
||||
})
|
||||
select.dropdown({values})
|
||||
},
|
||||
setupModal: function() {
|
||||
this.modals.add = $('#add_modal')
|
||||
this.modals.edit = $('#edit_modal')
|
||||
$.each(this.modals, (i, el) => {
|
||||
el.modal().find('.close.icon').click(() => {
|
||||
el.modal('hide')
|
||||
})
|
||||
this.updateCalendar(el)
|
||||
})
|
||||
this.modals.add.find('form').submit((e) => {
|
||||
e.preventDefault()
|
||||
this.doAdd()
|
||||
return false
|
||||
})
|
||||
this.modals.add.find('#archivo_btn').css('cursor', 'pointer').click(() => {
|
||||
this.modals.add.find("[name='archivo']").trigger('click')
|
||||
})
|
||||
this.modals.add.find("[name='archivo']").change((e) => {
|
||||
const arch = $(e.currentTarget)
|
||||
const filename = arch[0].files[0].name
|
||||
this.modals.add.find('#archivo_btn').find('input').val(filename)
|
||||
})
|
||||
this.modals.edit.find('form').submit((e) => {
|
||||
e.preventDefault()
|
||||
this.doEdit()
|
||||
return false
|
||||
})
|
||||
this.get().cuentas().then((data) => {
|
||||
this.updateCuentas(this.modals.add, data)
|
||||
this.updateCuentas(this.modals.edit, data)
|
||||
})
|
||||
},
|
||||
setup: function() {
|
||||
this.setupModal()
|
||||
this.get().archivos()
|
||||
}
|
||||
}
|
4
ui/resources/routes/importar.php
Normal file
4
ui/resources/routes/importar.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
use Contabilidad\Common\Controller\Importar;
|
||||
|
||||
$app->get('/importar[/]', Importar::class);
|
10
ui/resources/routes/uploads.php
Normal file
10
ui/resources/routes/uploads.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
use Contabilidad\Common\Controller\Uploads;
|
||||
|
||||
$app->group('/uploads', function($app) {
|
||||
$app->get('/add', [Uploads::class, 'upload']);
|
||||
$app->get('[/]', Uploads::class);
|
||||
});
|
||||
$app->group('/upload/{folder}/{filename}', function($app) {
|
||||
$app->get('[/]', [Uploads::class, 'get']);
|
||||
});
|
@ -8,7 +8,7 @@
|
||||
Categorías
|
||||
@endif
|
||||
</h1>
|
||||
<div class="ui segment">
|
||||
<div class="ui basic fitted segment">
|
||||
@yield('categorias_content')
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -8,7 +8,7 @@
|
||||
Tipos Categoría
|
||||
@endif
|
||||
</h1>
|
||||
<div class="ui segment">
|
||||
<div class="ui basic fitted segment">
|
||||
@yield('tipos_categorias_content')
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -1 +1,8 @@
|
||||
@extends('config.base')
|
||||
|
||||
@section('config_content')
|
||||
<h3>Configuraciones Generales</h3>
|
||||
<div class="ui basic segment">
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -1,4 +1,5 @@
|
||||
<div class="ui vertical fluid borderless menu">
|
||||
@include('config.menu.tipos_categorias')
|
||||
@include('config.menu.tipos_cuentas')
|
||||
@include('config.menu.files')
|
||||
</div>
|
||||
|
4
ui/resources/views/config/menu/files.blade.php
Normal file
4
ui/resources/views/config/menu/files.blade.php
Normal file
@ -0,0 +1,4 @@
|
||||
<a class="item" href="{{$urls->base}}uploads">
|
||||
Archivos
|
||||
</a>
|
||||
|
@ -8,7 +8,7 @@
|
||||
Cuentas
|
||||
@endif
|
||||
</h1>
|
||||
<div class="ui segment">
|
||||
<div class="ui basic fitted segment">
|
||||
@yield('cuentas_content')
|
||||
</div>
|
||||
@endsection
|
||||
|
@ -27,23 +27,16 @@
|
||||
Saldo
|
||||
</th>
|
||||
<th class="right aligned">
|
||||
<button class="ui tiny green circular icon button">
|
||||
<button class="ui tiny blue circular icon button" id="refresh">
|
||||
<i class="refresh icon"></i>
|
||||
</button>
|
||||
<button class="ui tiny green circular icon button" id="add">
|
||||
<i class="plus icon"></i>
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="transacciones">
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<div class="ui active dimmer">
|
||||
<div class="ui indeterminate elastic text loader">
|
||||
Buscando los datos
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody id="transacciones"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="ui modal">
|
||||
|
@ -4,6 +4,8 @@
|
||||
<h1 class="ui header">
|
||||
Contabilidad
|
||||
</h1>
|
||||
<div id="cuentas" class="ui basic fitted segment"></div>
|
||||
<div id="resultado" class="ui basic fitted segment"></div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
|
92
ui/resources/views/importar.blade.php
Normal file
92
ui/resources/views/importar.blade.php
Normal file
@ -0,0 +1,92 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_title')
|
||||
Importar
|
||||
@endsection
|
||||
|
||||
@section('page_content')
|
||||
<h1>Importar</h1>
|
||||
<form class="ui form" action="#" method="post" id="importar_form" enctype="multipart/form-data">
|
||||
<div class="two wide field">
|
||||
<label>Fecha</label>
|
||||
<div class="ui date calendar">
|
||||
<div class="ui icon input">
|
||||
<input type="text" name="fecha" />
|
||||
<i class="calendar outline icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="six wide field">
|
||||
<label>Cuenta</label>
|
||||
<select name="cuenta"></select>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<input type="file" name="archivo" style="display: none;" />
|
||||
<div class="ui labeled icon input" id="archivo_btn">
|
||||
<div class="ui label">Archivo</div>
|
||||
<input type="text" readonly="" />
|
||||
<i class="search icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui button">Importar</button>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
function getCuentas() {
|
||||
sendGet(_urls.api + '/cuentas').then((data) => {
|
||||
if (data.cuentas === null || data.cuentas.length === 0) {
|
||||
return
|
||||
}
|
||||
const select = $("select[name='cuenta']")
|
||||
let values = []
|
||||
$.each(data.cuentas, (i, el) => {
|
||||
const nombre = [el.nombre, el.categoria.nombre].join(' - ')
|
||||
values.push({
|
||||
name: nombre,
|
||||
value: el.id,
|
||||
text: nombre
|
||||
})
|
||||
})
|
||||
select.dropdown({values})
|
||||
})
|
||||
}
|
||||
$(document).ready(() => {
|
||||
getCuentas()
|
||||
const today = new Date()
|
||||
const start = new Date(today.getFullYear(), today.getMonth() - 1)
|
||||
$('.ui.calendar').calendar({
|
||||
type: 'month',
|
||||
initialDate: start,
|
||||
maxDate: start,
|
||||
months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
|
||||
monthsShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
|
||||
formatter: {
|
||||
date: function(date, settings) {
|
||||
if (!date) return ''
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
return [year, month].join('-')
|
||||
}
|
||||
}
|
||||
})
|
||||
$('#archivo_btn').css('cursor', 'pointer').click(() => {
|
||||
$("[name='archivo']").trigger('click')
|
||||
})
|
||||
$("[name='archivo']").change((e) => {
|
||||
const arch = $(e.currentTarget)
|
||||
const filename = arch[0].files[0].name
|
||||
$('#archivo_btn').find('input').val(filename)
|
||||
})
|
||||
$('#importar_form').submit((e) => {
|
||||
e.preventDefault()
|
||||
const data = new FormData(e.currentTarget)
|
||||
sendPost(_urls.api + '/import', data, true).then((resp) => {
|
||||
console.debug(resp)
|
||||
})
|
||||
return false
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endpush
|
@ -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)
|
||||
}
|
||||
|
14
ui/resources/views/uploads/base.blade.php
Normal file
14
ui/resources/views/uploads/base.blade.php
Normal file
@ -0,0 +1,14 @@
|
||||
@extends('config.base')
|
||||
|
||||
@section('config_content')
|
||||
<h1 class="ui header">
|
||||
@hasSection('uploads_title')
|
||||
Archivo @yield('uploads_title')
|
||||
@else
|
||||
Archivos
|
||||
@endif
|
||||
</h1>
|
||||
<div class="ui basic fitted segment">
|
||||
@yield('uploads_content')
|
||||
</div>
|
||||
@endsection
|
70
ui/resources/views/uploads/list.blade.php
Normal file
70
ui/resources/views/uploads/list.blade.php
Normal file
@ -0,0 +1,70 @@
|
||||
@extends('uploads.base')
|
||||
|
||||
@section('uploads_content')
|
||||
<div id="archivos"></div>
|
||||
<div class="ui modal" id="add_modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="content">
|
||||
<form class="ui form" enctype="multipart/form-data">
|
||||
<div class="two wide field">
|
||||
<label>Fecha</label>
|
||||
<div class="ui date calendar">
|
||||
<div class="ui icon input">
|
||||
<input type="text" name="fecha" />
|
||||
<i class="calendar outline icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="six wide field">
|
||||
<label>Cuenta</label>
|
||||
<select name="cuenta"></select>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<input type="file" name="archivo" style="display: none;" />
|
||||
<div class="ui labeled icon input" id="archivo_btn">
|
||||
<div class="ui label">Archivo</div>
|
||||
<input type="text" readonly="" />
|
||||
<i class="search icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui green icon button">
|
||||
<i class="plus icon"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui modal" id="edit_modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="content">
|
||||
<form class="ui form">
|
||||
<input type="hidden" name="folder" />
|
||||
<input type="hidden" name="old_filename" />
|
||||
<div class="two wide field">
|
||||
<label>Fecha</label>
|
||||
<div class="ui date calendar">
|
||||
<div class="ui icon input">
|
||||
<input type="text" name="fecha" />
|
||||
<i class="calendar outline icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="six wide field">
|
||||
<label>Cuenta</label>
|
||||
<select name="cuenta"></select>
|
||||
</div>
|
||||
<button class="ui icon button">
|
||||
<i class="edit icon"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript" src="{{$urls->scripts}}/uploads.list.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(() => {
|
||||
archivos.setup()
|
||||
})
|
||||
</script>
|
||||
@endpush
|
@ -2,15 +2,23 @@
|
||||
use Psr\Container\ContainerInterface as Container;
|
||||
|
||||
return [
|
||||
Slim\Views\Blade::class => function(Container $c) {
|
||||
return new Slim\Views\Blade(
|
||||
$c->get('folders')->templates,
|
||||
$c->get('folders')->cache,
|
||||
null,
|
||||
[
|
||||
'api_key' => $c->get('API_KEY'),
|
||||
'urls' => $c->get('urls')
|
||||
]
|
||||
);
|
||||
}
|
||||
Slim\Views\Blade::class => function(Container $c) {
|
||||
return new Slim\Views\Blade(
|
||||
$c->get('folders')->templates,
|
||||
$c->get('folders')->cache,
|
||||
null,
|
||||
[
|
||||
'api_key' => $c->get('API_KEY'),
|
||||
'urls' => $c->get('urls')
|
||||
]
|
||||
);
|
||||
},
|
||||
GuzzleHttp\Client::class => function(Container $c) {
|
||||
return new GuzzleHttp\Client([
|
||||
'base_uri' => 'http://api-proxy',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $c->get('API_KEY')
|
||||
]
|
||||
]);
|
||||
}
|
||||
];
|
||||
|
Reference in New Issue
Block a user