diff --git a/.adminer.env b/.adminer.env
deleted file mode 100644
index 7e78794..0000000
--- a/.adminer.env
+++ /dev/null
@@ -1,2 +0,0 @@
-ADMINER_DESIGN=dracula
-ADMINER_PLUGINS=dump-json
diff --git a/.adminer.env.sample b/.adminer.env.sample
deleted file mode 100644
index 7e78794..0000000
--- a/.adminer.env.sample
+++ /dev/null
@@ -1,2 +0,0 @@
-ADMINER_DESIGN=dracula
-ADMINER_PLUGINS=dump-json
diff --git a/.db.env b/.db.env
deleted file mode 100644
index 16b5aed..0000000
--- a/.db.env
+++ /dev/null
@@ -1,5 +0,0 @@
-MYSQL_DATABASE=incoviba
-MYSQL_PASSWORD=5GQYFvRjVw2A4KcD
-MYSQL_ROOT_PASSWORD=password
-MYSQL_USER=incoviba
-MYSQL_PORT=3307
diff --git a/.env.sample b/.env.sample
index 76074d2..91c2a2f 100644
--- a/.env.sample
+++ b/.env.sample
@@ -1,3 +1,6 @@
-COMPOSE_PROFILES=
-BASE_URL=
-MYSQL_HOST=
+COMPOSE_PATH_SEPARATOR=:
+COMPOSE_FILE=./docker-compose.yml:./adminer-compose.yml
+COMPOSE_PROFILES=app,db,cli,cache
+APP_PATH=./app
+CLI_PATH=./cli
+APP_PORT=8080
diff --git a/.gitignore b/.gitignore
index 94a1003..d25a303 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@
**/cache/
**/modules/
**/.idea/
+**/upload?/
+**/informe?/
diff --git a/.key.env.sample b/.key.env.sample
new file mode 100644
index 0000000..48204cd
--- /dev/null
+++ b/.key.env.sample
@@ -0,0 +1 @@
+API_KEY=
diff --git a/CLI.Dockerfile b/CLI.Dockerfile
new file mode 100644
index 0000000..87fcff6
--- /dev/null
+++ b/CLI.Dockerfile
@@ -0,0 +1,19 @@
+FROM php:8.2-cli
+
+ENV TZ "${TZ}"
+ENV APP_NAME "${APP_NAME}"
+ENV API_URL "${API_URL}"
+
+RUN apt-get update && apt-get install -y --no-install-recommends cron rsyslog nano && rm -r /var/lib/apt/lists/*
+
+RUN pecl install xdebug-3.2.2 \
+ && docker-php-ext-enable xdebug \
+ && echo "#/bin/bash\nprintenv >> /etc/environment\ncron -f -L 11" > /root/entrypoint && chmod a+x /root/entrypoint
+
+COPY ./php-errors.ini /usr/local/etc/php/conf.d/docker-php-errors.ini
+
+WORKDIR /code/bin
+
+COPY --chmod=644 ./cli/crontab /var/spool/cron/crontabs/root
+
+CMD [ "/root/entrypoint" ]
diff --git a/Dockerfile b/Dockerfile
index 509141c..16bbecf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
FROM php:8.1-fpm
-RUN apt-get update && apt-get install -y libzip-dev libicu-dev git libpng-dev unzip \
+RUN apt-get update && apt-get install -y --no-install-recommends libzip-dev libicu-dev git libpng-dev unzip tzdata \
&& rm -r /var/lib/apt/lists/*
RUN docker-php-ext-install pdo pdo_mysql zip intl gd bcmath
@@ -8,6 +8,8 @@ RUN docker-php-ext-install pdo pdo_mysql zip intl gd bcmath
RUN pecl install xdebug-3.1.3 \
&& docker-php-ext-enable xdebug
+COPY ./php-errors.ini /usr/local/etc/php/conf.d/docker-php-errors.ini
+
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR /code
diff --git a/adminer-compose.yml b/adminer-compose.yml
new file mode 100644
index 0000000..5f877dc
--- /dev/null
+++ b/adminer-compose.yml
@@ -0,0 +1,15 @@
+services:
+ adminer:
+ profiles:
+ - db
+ container_name: incoviba_adminer
+ image: adminer
+ restart: unless-stopped
+ env_file: ${APP_PATH:-.}/.adminer.env
+ networks:
+ - adminer_network
+ ports:
+ - "8083:8080"
+
+networks:
+ adminer_network: {}
diff --git a/aldarien/asset/.gitignore b/aldarien/asset/.gitignore
deleted file mode 100644
index 3b12249..0000000
--- a/aldarien/asset/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-#Eclipse IDE
-.settings
-.buildpath
-.project
diff --git a/aldarien/asset/LICENSE b/aldarien/asset/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/asset/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/asset/README.md b/aldarien/asset/README.md
deleted file mode 100644
index 1580798..0000000
--- a/aldarien/asset/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# asset
-Asset manager module for my apps
diff --git a/aldarien/asset/app/Contract/Asset.php b/aldarien/asset/app/Contract/Asset.php
deleted file mode 100644
index 30b02c2..0000000
--- a/aldarien/asset/app/Contract/Asset.php
+++ /dev/null
@@ -1,21 +0,0 @@
-get($identifier);
- }
-}
-?>
diff --git a/aldarien/asset/app/Helper/functions.php b/aldarien/asset/app/Helper/functions.php
deleted file mode 100644
index b0688e2..0000000
--- a/aldarien/asset/app/Helper/functions.php
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/asset/app/Service/Asset.php b/aldarien/asset/app/Service/Asset.php
deleted file mode 100644
index e7c36b7..0000000
--- a/aldarien/asset/app/Service/Asset.php
+++ /dev/null
@@ -1,88 +0,0 @@
-dir = config('locations.public');
- }
- public function get($identifier)
- {
- $asset = $this->find($identifier);
- return $asset->url;
- }
- protected function find($identifier)
- {
- $type = $this->getType($identifier);
- $asset = null;
- if ($type == false) {
- foreach (array_keys($this->assets) as $type) {
- if (($asset = $this->getAsset($identifier, $type))) {
- break;
- }
- }
- } else {
- $asset = $this->getAsset($identifier, $type);
- }
- return $asset;
- }
- protected function getType($identifier)
- {
- if (strpos($identifier, '.') !== false) {
- list($name, $ext) = explode('.', $identifier);
- return $ext;
- }
- return false;
- }
- protected function getAsset($identifier, $type)
- {
- if (!isset($this->assets[$type])) {
- $this->loadAssets($type);
- }
- if (!isset($this->assets[$type])) {
- return null;
- }
-
- foreach ($this->assets[$type] as $asset) {
- if ($this->compareIdentifier($asset, $identifier)) {
- return $asset;
- }
- }
- return null;
- }
- protected function loadAssets($type)
- {
- $dir = $this->dir . '/' . $type . '/*.' . $type;
- $files = glob($dir);
- foreach ($files as $file) {
- $url = $this->url($file);
- $identifier = pathinfo($file)['filename'];
-
- $this->assets[$type] []= (object) ['identifier' => $identifier, 'url' => $url, 'type' => $type];
- }
- }
- protected function url($file)
- {
- $url = '/' . config('app.project') . '/' . str_replace('\\', '/', str_replace(realpath(config('locations.public')), '', dirname(realpath($file)))) . '/' . basename(realpath($file));
- $url = preg_replace('/\/+/', '/', $url);
- return $url;
- }
- protected function compareIdentifier($asset, $identifier)
- {
- if (strpos($identifier, '.') !== false) {
- list($name, $ext) = explode('.', $identifier);
- if ($asset->identifier == $name and $asset->type == $ext) {
- return true;
- }
- } else {
- if ($asset->identifier == $identifier) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/aldarien/asset/composer.json b/aldarien/asset/composer.json
deleted file mode 100644
index dd2c217..0000000
--- a/aldarien/asset/composer.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name" : "aldarien/asset",
- "description" : "Asset manager module for my apps",
- "type" : "library",
- "require" : {
- "aldarien/config" : "*",
- "aldarien/contract" : "*"
- },
- "require-dev" : {
- "phpunit/phpunit" : "*"
- },
- "license" : "MIT",
- "authors" : [{
- "name" : "Aldarien",
- "email" : "aldarien85@gmail.com"
- }
- ],
- "autoload" : {
- "psr-4" : {
- "App\\" : "app"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- }
-}
diff --git a/aldarien/asset/phpunit.xml b/aldarien/asset/phpunit.xml
deleted file mode 100644
index e60ecbd..0000000
--- a/aldarien/asset/phpunit.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./app
-
-
-
\ No newline at end of file
diff --git a/aldarien/asset/tests/AssetTest.php b/aldarien/asset/tests/AssetTest.php
deleted file mode 100644
index e53f0ad..0000000
--- a/aldarien/asset/tests/AssetTest.php
+++ /dev/null
@@ -1,25 +0,0 @@
-assertEquals(asset('style.css'), '/css/style.css');
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/config/.gitignore b/aldarien/config/.gitignore
deleted file mode 100644
index 47c4114..0000000
--- a/aldarien/config/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-config
-
-# Eclipse IDE
-.settings
-.buildpath
-.project
\ No newline at end of file
diff --git a/aldarien/config/.travis.yml b/aldarien/config/.travis.yml
deleted file mode 100644
index a792980..0000000
--- a/aldarien/config/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-language: php
-php: '7.1'
-install: composer update
diff --git a/aldarien/config/LICENSE b/aldarien/config/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/config/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/config/README.md b/aldarien/config/README.md
deleted file mode 100644
index dfed35b..0000000
--- a/aldarien/config/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# config
-Config module that recovers configuration files
-
-[](https://travis-ci.org/Aldarien/config)
diff --git a/aldarien/config/app/Contract/Config.php b/aldarien/config/app/Contract/Config.php
deleted file mode 100644
index 9664aca..0000000
--- a/aldarien/config/app/Contract/Config.php
+++ /dev/null
@@ -1,31 +0,0 @@
-get($name);
- }
- public static function set($name, $value)
- {
- $instance = self::getInstance();
- return $instance->set($name, $value);
- }
- public static function addFile($filename)
- {
- $instance = self::getInstance();
- return $instance->loadFile($filename);
- }
-}
-?>
diff --git a/aldarien/config/app/Contract/YamlWrapper.php b/aldarien/config/app/Contract/YamlWrapper.php
deleted file mode 100644
index 0ab60f6..0000000
--- a/aldarien/config/app/Contract/YamlWrapper.php
+++ /dev/null
@@ -1,21 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/config/app/Helper/functions.php b/aldarien/config/app/Helper/functions.php
deleted file mode 100644
index e073f18..0000000
--- a/aldarien/config/app/Helper/functions.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/aldarien/config/app/Service/Config.php b/aldarien/config/app/Service/Config.php
deleted file mode 100644
index 072e38f..0000000
--- a/aldarien/config/app/Service/Config.php
+++ /dev/null
@@ -1,150 +0,0 @@
-dir = $dir;
- $this->load();
- }
- protected function load()
- {
- $files = glob($this->dir . '/*.{php,json,yml}', GLOB_BRACE);
- foreach ($files as $file) {
- $info = pathinfo($file);
- $name = $info['filename'];
-
- $d = $this->getData($file);
- $data[$name] = $d;
- $data = array_merge($data, $this->translateArray($d, $name));
- foreach ($data as $key => $value) {
- $this->add($key, $value);
- }
- }
- }
- public function loadFile(string $filename)
- {
- if (!file_exists(realpath($filename))) {
- return false;
- }
- $info = pathinfo($filename);
- $name = $info['filename'];
- $d = $this->getData($filename);
- $data[$name] = $d;
- $data = array_merge($data, $this->translateArray($d, $name));
- foreach ($data as $key => $value) {
- $this->add($key, $value);
- }
- return true;
- }
- protected function getData($filename)
- {
- $info = pathinfo($filename);
-
- switch ($info['extension']) {
- case 'php':
- return include_once $filename;
- case 'json':
- return json_decode(file_get_contents($filename), true);
- case 'yml':
- return YamlWrapper::load($filename);
- default:
- throw new \DomainException('Invalid file extension for ' . $filename);
- }
- }
- protected function translateArray($array, $level)
- {
- $output = [];
- foreach ($array as $k1 => $l1) {
- $key = $level . '.' . $k1;
- if (is_array($l1)) {
- $output[$key] = $l1;
- $output = array_merge($output, $this->translateArray($l1, $key));
- } else {
- $output[$key] = $l1;
- }
- }
- return $output;
- }
- protected function add($field, $value)
- {
- if (isset($this->data[$field])) {
- if ($this->data[$field] == $value) {
- return;
- }
- if (is_array($this->data[$field])) {
- $this->data[$field] = $this->merge($this->data[$field], $this->replace($value));
- } else {
- $this->data[$field] = $this->replace($value);
- }
- } else {
- $this->data[$field] = $this->replace($value);
- }
- }
- protected function merge($arr1, $arr2)
- {
- $output = $arr1;
- foreach ($arr2 as $k => $value) {
- if (isset($arr1[$k])) {
- if ($arr1[$k] == $value) {
- continue;
- }
- if (is_array($arr1[$k])) {
- $output[$k] = $this->merge($arr1[$k], $value);
- } else {
- $output[$k] = array_merge([$arr1[$k]], $value);
- }
- } else {
- $output[$k] = $value;
- }
- }
- return $output;
- }
- protected function replace($value)
- {
- if (is_array($value)) {
- foreach ($value as $k => $v) {
- $value[$k] = $this->replace($v);
- }
- return $value;
- }
- if (strpos($value, '{') !== false) {
- while(strpos($value, '{') !== false) {
- $ini = strpos($value, '{') + 1;
- $end = strpos($value, '}', $ini);
- $rep = substr($value, $ini, $end - $ini);
- $new = $this->get($rep);
- if ($new === null) {
- $new = '';
- }
- $value = str_replace('{' . $rep . '}', $new, $value);
- }
- }
- return $value;
- }
-
- public function get($name = null)
- {
- if ($name == null) {
- return $this->data;
- }
- if (isset($this->data[$name])) {
- return $this->data[$name];
- }
- return null;
- }
- public function set($name, $value)
- {
- $this->add($name, $value);
- }
-}
-?>
diff --git a/aldarien/config/bootstrap/autoload.php b/aldarien/config/bootstrap/autoload.php
deleted file mode 100644
index 42765bd..0000000
--- a/aldarien/config/bootstrap/autoload.php
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/aldarien/config/composer.json b/aldarien/config/composer.json
deleted file mode 100644
index ff4255b..0000000
--- a/aldarien/config/composer.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "aldarien/config",
- "description": "Config module for my apps",
- "type": "library",
- "license": "MIT",
- "authors": [
- {
- "name": "Aldarien",
- "email": "aldarien85@gmail.com"
- }
- ],
- "require": {
- "aldarien/contract": "*",
- "aldarien/root": "*",
- "symfony/yaml": "*"
- },
- "autoload": {
- "psr-4": {
- "App\\": "app"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- },
- "require-dev": {
- "phpunit/phpunit": "^6.3"
- }
-}
diff --git a/aldarien/config/phpunit.xml b/aldarien/config/phpunit.xml
deleted file mode 100644
index db312e1..0000000
--- a/aldarien/config/phpunit.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./app
-
-
-
\ No newline at end of file
diff --git a/aldarien/config/tests/ConfigTest.php b/aldarien/config/tests/ConfigTest.php
deleted file mode 100644
index 187e0a3..0000000
--- a/aldarien/config/tests/ConfigTest.php
+++ /dev/null
@@ -1,90 +0,0 @@
- 'Config', 'test_array' => ['data1' => 1, 'data2' => 2]]; ?>";
- file_put_contents(dirname(__DIR__) . '/config/app.php', $str);
- $data = ['name' => 'Config', 'test_array' => ['data1' => 1, 'data2' => 2]];
- file_put_contents(dirname(__DIR__) . '/config/json.json', json_encode($data));
- file_put_contents(dirname(__DIR__) . '/config/yaml.yml', YamlWrapper::dump($data));
- $data = ['last_name' => 'Config'];
- file_put_contents(dirname(__DIR__) . '/config/yaml.json', json_encode($data));
- }
- public function testGetNamePhp()
- {
- $name = 'Config';
-
- $this->assertEquals($name, config('app.name'));
- }
- public function testGetNameJson()
- {
- $name = 'Config';
-
- $this->assertEquals($name, config('json.name'));
- }
- public function testGetNameYaml()
- {
- $name = 'Config';
-
- $this->assertEquals($name, config('yaml.name'));
- }
- public function testSetNamehp()
- {
- $new_name = 'Config_Test';
- config('app.name', $new_name);
- $this->assertEquals($new_name, config('app.name'));
- }
- public function testSetNameJson()
- {
- $new_name = 'Config_Test';
- config('json.name', $new_name);
- $this->assertEquals($new_name, config('json.name'));
- }
- public function testSetNameYaml()
- {
- $new_name = 'Config_Test';
- config('yaml.name', $new_name);
- $this->assertEquals($new_name, config('yaml.name'));
- }
- public function testArrayGetPhp()
- {
- $this->assertArrayHasKey('data1', config('app.test_array'));
- }
- public function testArrayGetJson()
- {
- $this->assertArrayHasKey('data1', config('json.test_array'));
- }
- public function testArrayGetYaml()
- {
- $this->assertArrayHasKey('data1', config('yaml.test_array'));
- }
- public function testSameSectionName()
- {
- $this->assertEquals('Config', config('yaml.last_name'));
- }
- public function testDuplicateValue()
- {
- config('json.name', 'Config2');
- $this->assertEquals('Config2', config('json.name'));
- }
- public function testAddFile()
- {
- $filename = dirname(__DIR__) . '/composer.json';
- App\Contract\Config::addFile($filename);
- $this->assertEquals('aldarien/config', config('composer.name'));
- }
- public function tearDown()
- {
- unlink(dirname(__DIR__) . '/config/app.php');
- unlink(dirname(__DIR__) . '/config/json.json');
- unlink(dirname(__DIR__) . '/config/yaml.yml');
- unlink(dirname(__DIR__) . '/config/yaml.json');
- rmdir(dirname(__DIR__) . '/config');
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/contract/.gitignore b/aldarien/contract/.gitignore
deleted file mode 100644
index c422267..0000000
--- a/aldarien/contract/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
diff --git a/aldarien/contract/LICENSE b/aldarien/contract/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/contract/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/contract/app/Definition/Contract.php b/aldarien/contract/app/Definition/Contract.php
deleted file mode 100644
index 4cc88ca..0000000
--- a/aldarien/contract/app/Definition/Contract.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/aldarien/contract/composer.json b/aldarien/contract/composer.json
deleted file mode 100644
index 96ef067..0000000
--- a/aldarien/contract/composer.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "aldarien/contract",
- "description": "Contract trait for my apps",
- "type": "library",
- "license": "MIT",
- "authors": [
- {
- "name": "Aldarien",
- "email": "aldarien85@gmail.com"
- }
- ],
- "require": {},
- "autoload": {
- "psr-4": {
- "App\\": "app"
- }
- }
-}
diff --git a/aldarien/format/.gitignore b/aldarien/format/.gitignore
deleted file mode 100644
index 6ee50e6..0000000
--- a/aldarien/format/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-# Eclipse IDE
-.settings
-.buildpath
-.project
\ No newline at end of file
diff --git a/aldarien/format/LICENSE b/aldarien/format/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/format/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/format/README.md b/aldarien/format/README.md
deleted file mode 100644
index d4f839f..0000000
--- a/aldarien/format/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# format
-Module for formatting data, mostly numbers
diff --git a/aldarien/format/app/Helper/Format.php b/aldarien/format/app/Helper/Format.php
deleted file mode 100644
index 9836f38..0000000
--- a/aldarien/format/app/Helper/Format.php
+++ /dev/null
@@ -1,43 +0,0 @@
-format("d \d\\e F Y");
- }
- public static function shortDate(string $date)
- {
- $d = \Carbon\Carbon::parse($date, config('app.timezone'));
- return $d->format('d-m-Y');
- }
- public static function localDate(string $date)
- {
- $d = \Carbon\Carbon::parse($date, config('app.timezone'));
- setlocale(LC_TIME, 'es');
- return $d->formatLocalized('%d de %B de %Y');
- }
- public static function m2(float $number, bool $print = false)
- {
- return self::number($number, 2) . (($print) ? ' m²' : '');
- }
- public static function percent(float $number, bool $print = false)
- {
- return self::number($number, 2) . (($print) ? '%' : '');
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/format/composer.json b/aldarien/format/composer.json
deleted file mode 100644
index 59d058d..0000000
--- a/aldarien/format/composer.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name" : "aldarien/format",
- "description" : "Module for formatting data, mostly numbers",
- "type" : "library",
- "require-dev" : {
- "phpunit/phpunit" : "*",
- "aldarien/config": "*"
- },
- "license" : "MIT",
- "authors" : [{
- "name" : "Aldarien",
- "email" : "aldarien85@gmail.com"
- }
- ],
- "autoload" : {
- "psr-4" : {
- "App\\" : "app"
- }
- },
- "require": {
- "nesbot/carbon": "^2"
- }
-}
diff --git a/aldarien/format/config/app.php b/aldarien/format/config/app.php
deleted file mode 100644
index 9e747f9..0000000
--- a/aldarien/format/config/app.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'America/Santiago'
-];
-?>
\ No newline at end of file
diff --git a/aldarien/format/phpunit.xml b/aldarien/format/phpunit.xml
deleted file mode 100644
index e60ecbd..0000000
--- a/aldarien/format/phpunit.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./app
-
-
-
\ No newline at end of file
diff --git a/aldarien/format/tests/FormatTest.php b/aldarien/format/tests/FormatTest.php
deleted file mode 100644
index bcc6bd5..0000000
--- a/aldarien/format/tests/FormatTest.php
+++ /dev/null
@@ -1,59 +0,0 @@
-number, 3);
- $this->assertEquals($output, $result);
- }
- public function testPesosPrint()
- {
- $output = '$ 5.049.872';
- $result = Format::pesos($this->number, true);
- $this->assertEquals($output, $result);
- }
- public function testUFPrint()
- {
- $output = '5.049.872,32 UF';
- $result = Format::ufs($this->number, true);
- $this->assertEquals($output, $result);
- }
- public function testDate()
- {
- $output = '25 de March 2016';
- $result = Format::date($this->date);
- $this->assertEquals($output, $result);
- }
- public function testShortDate()
- {
- $output = '25-03-2016';
- $result = Format::shortDate($this->date);
- $this->assertEquals($output, $result);
- }
- public function testLocalDate()
- {
- $output = '25 de marzo de 2016';
- $result = Format::localDate($this->date);
- $this->assertEquals($output, $result);
- }
- public function testM2Print()
- {
- $output = '5.049.872,32 m²';
- $result = Format::m2($this->number, true);
- $this->assertEquals($output, $result);
- }
- public function testPercentPrint()
- {
- $output = '5.049.872,32%';
- $result = Format::percent($this->number, true);
- $this->assertEquals($output, $result);
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/response/.gitignore b/aldarien/response/.gitignore
deleted file mode 100644
index 265bf84..0000000
--- a/aldarien/response/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-#Eclipse IDE
-.settings
-.buildpath
-.project
-
-#Composer
-vendor
diff --git a/aldarien/response/LICENSE b/aldarien/response/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/response/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/response/README.md b/aldarien/response/README.md
deleted file mode 100644
index 80c6096..0000000
--- a/aldarien/response/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# response
-Response handler module for my apps
diff --git a/aldarien/response/app/Contract/Response.php b/aldarien/response/app/Contract/Response.php
deleted file mode 100644
index 4b0089e..0000000
--- a/aldarien/response/app/Contract/Response.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/response/app/Helper/functions.php b/aldarien/response/app/Helper/functions.php
deleted file mode 100644
index 32c48f8..0000000
--- a/aldarien/response/app/Helper/functions.php
+++ /dev/null
@@ -1,11 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/response/app/Service/Response.php b/aldarien/response/app/Service/Response.php
deleted file mode 100644
index d0f3e24..0000000
--- a/aldarien/response/app/Service/Response.php
+++ /dev/null
@@ -1,62 +0,0 @@
-gump = new \GUMP();
- }
- public function sanitize()
- {
- if ($_POST) {
- $this->post = $this->correctNumbers($this->gump->sanitize($_POST));
- }
- if ($_GET) {
- $this->get = $this->correctNumbers($this->gump->sanitize($_GET));
- }
- }
- public function correctNumbers(array $data)
- {
- $output = [];
- foreach ($data as $key => $value) {
- if (is_float(str_replace(',', '.', $value))) {
- $output[$key] = str_replace(',', '.', $value);
- } else {
- $output[$key] = $value;
- }
- }
- return $output;
- }
- public function get($query = null)
- {
- if ($this->get == null) {
- $this->sanitize();
- }
- if ($query == null) {
- return $this->get;
- }
- if (isset($this->get[$query])) {
- return $this->get[$query];
- }
- return false;
- }
- public function post($query = null)
- {
- if ($this->post == null) {
- $this->sanitize();
- }
- if ($query == null) {
- return $this->post;
- }
- if (isset($this->post[$query])) {
- return $this->post[$query];
- }
- return false;
- }
-}
-?>
diff --git a/aldarien/response/bootstrap/autoload.php b/aldarien/response/bootstrap/autoload.php
deleted file mode 100644
index b5e8220..0000000
--- a/aldarien/response/bootstrap/autoload.php
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/response/composer.json b/aldarien/response/composer.json
deleted file mode 100644
index a337f86..0000000
--- a/aldarien/response/composer.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name" : "aldarien/response",
- "description" : "Response handler module for my apps",
- "type" : "library",
- "require" : {
- "wixel/gump" : "^2.0.0",
- "aldarien/contract" : "*"
- },
- "require-dev" : {
- "phpunit/phpunit" : "*"
- },
- "license" : "MIT",
- "authors" : [{
- "name" : "Aldarien",
- "email" : "jpvial@gmail.com"
- }
- ],
- "autoload" : {
- "psr-4" : {
- "App\\" : "app"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- }
-}
diff --git a/aldarien/response/phpunit.xml b/aldarien/response/phpunit.xml
deleted file mode 100644
index db312e1..0000000
--- a/aldarien/response/phpunit.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./app
-
-
-
\ No newline at end of file
diff --git a/aldarien/response/tests/ResponseTest.php b/aldarien/response/tests/ResponseTest.php
deleted file mode 100644
index 67d603c..0000000
--- a/aldarien/response/tests/ResponseTest.php
+++ /dev/null
@@ -1,22 +0,0 @@
-value;
- $_POST['test'] = $this->value;
- }
- public function testGet()
- {
- $this->assertEquals($this->value, get('test'));
- }
- public function testPost()
- {
- $this->assertEquals($this->value, post('test'));
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/root/.gitignore b/aldarien/root/.gitignore
deleted file mode 100644
index f7e7961..0000000
--- a/aldarien/root/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.buildpath
-.project
-.settings
-*.lock
-vendor
\ No newline at end of file
diff --git a/aldarien/root/LICENSE b/aldarien/root/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/root/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/root/README.md b/aldarien/root/README.md
deleted file mode 100644
index 039cbc3..0000000
--- a/aldarien/root/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# root
-get root directory path for your project
-
-## Usage
-
-add `Root::root('project')` or `root('project')` or `Root::root()` or `root()` where you need the root directory of your proyect.
-
-## Example
-
-For the structure:
-
-~~~
-/usr/share/www/projects
-- myProject
--- src
--- tests
-~~~
-
-using `Root::root('myProject')`
-
-outputs:
-`/usr/share/www/projects/myProject`
diff --git a/aldarien/root/app/Helper/functions.php b/aldarien/root/app/Helper/functions.php
deleted file mode 100644
index 86fd2eb..0000000
--- a/aldarien/root/app/Helper/functions.php
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/root/composer.json b/aldarien/root/composer.json
deleted file mode 100644
index 784dfb7..0000000
--- a/aldarien/root/composer.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name" : "aldarien/root",
- "description" : "Find the root path for your proyect",
- "authors" : [{
- "name" : "Aldarien"
- }
- ],
- "license": "MIT",
- "require-dev" : {
- "phpunit/phpunit" : "*",
- "kint-php/kint" : "*"
- },
- "autoload" : {
- "psr-4" : {
- "Proyect\\Root\\" : "src"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- }
-}
diff --git a/aldarien/root/phpunit.xml b/aldarien/root/phpunit.xml
deleted file mode 100644
index 63ecd1c..0000000
--- a/aldarien/root/phpunit.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- tests
-
-
-
-
- src
-
-
-
diff --git a/aldarien/root/src/Root.php b/aldarien/root/src/Root.php
deleted file mode 100644
index 13058df..0000000
--- a/aldarien/root/src/Root.php
+++ /dev/null
@@ -1,48 +0,0 @@
-$proyect_name/public/index.php calls for $proyect_name/bootstrap/autoload.php
,
- * you just need to
- *
- * include root() . '/bootstrap/autoload.php'
- *
- * @param string $proyect_name
- * @return string
- */
- public static function root(string $proyect_name = '')
- {
- $dir = realpath(__DIR__);
- if ($proyect_name == '') {
- return self::findComposerFile($dir);
- } else {
- $ini = strpos($dir, $proyect_name) + strlen($proyect_name);
- }
- $path = substr($dir, $ini);
- $cnt = substr_count($path, DIRECTORY_SEPARATOR);
- $root = DIRECTORY_SEPARATOR;
- for ($i = 0; $i < $cnt; $i ++) {
- $root .= '..' . DIRECTORY_SEPARATOR;
- }
-
- return realpath($dir . $root);
- }
- protected static function findComposerFile($dir)
- {
- if (file_exists($dir . '/vendor/')) {
- return $dir;
- }
-
- $root = realpath('/');
- if (realpath($dir) == $root) {
- return null;
- }
-
- $dir = dirname($dir);
- return self::findComposerFile($dir);
- }
-}
-?>
diff --git a/aldarien/root/tests/RootTest.php b/aldarien/root/tests/RootTest.php
deleted file mode 100644
index 1deed6c..0000000
--- a/aldarien/root/tests/RootTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-getCurrentDir();
- $this->assertEquals($this->getRoot(), $this->current_dir);
- $this->assertEquals($this->getBaseRoot(), $this->current_dir);
- }
- public function testBaseRootFunction()
- {
- $this->getCurrentDir();
- $this->assertEquals($this->getFRoot(), $this->current_dir);
- $this->assertEquals($this->getFBaseRoot(), $this->current_dir);
- }
- public function testSrcRoot()
- {
- $this->changeDir('src');
- $this->assertEquals(realpath($this->getRoot() . '/src'), $this->current_dir);
- $this->assertEquals(realpath($this->getBaseRoot() . '/src'), $this->current_dir);
- }
- public function testSrcRootFunction()
- {
- $this->changeDir('src');
- $this->assertEquals(realpath($this->getFRoot() . '/src'), $this->current_dir);
- $this->assertEquals(realpath($this->getFBaseRoot() . '/src'), $this->current_dir);
- }
-
- private function getCurrentDir()
- {
- $this->current_dir = getcwd();
- }
- private function changeDir($dir)
- {
- chdir($dir);
- $this->getCurrentDir();
- }
- private function getRoot()
- {
- return Root::root($this->proyect_name);
- }
- private function getBaseRoot()
- {
- return Root::root();
- }
- private function getFRoot()
- {
- return root($this->proyect_name);
- }
- private function getFBaseRoot()
- {
- return root();
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/session/.gitignore b/aldarien/session/.gitignore
deleted file mode 100644
index 6ee50e6..0000000
--- a/aldarien/session/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-# Eclipse IDE
-.settings
-.buildpath
-.project
\ No newline at end of file
diff --git a/aldarien/session/LICENSE b/aldarien/session/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/session/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/session/README.md b/aldarien/session/README.md
deleted file mode 100644
index 6825213..0000000
--- a/aldarien/session/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# session
-Session wrapper for aura/session
diff --git a/aldarien/session/app/Contract/Session.php b/aldarien/session/app/Contract/Session.php
deleted file mode 100644
index 2968a8f..0000000
--- a/aldarien/session/app/Contract/Session.php
+++ /dev/null
@@ -1,29 +0,0 @@
-newInstance($_COOKIE);
- }
- public static function get($segment, $name)
- {
- $instance = self::getInstance();
- $segment = $instance->getSegment($segment);
- return $segment->get($name);
- }
- public static function set($segment, $name, $value)
- {
- $instance = self::getInstance();
- $segment = $instance->getSegment($segment);
- $segment->set($name, $value);
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/session/composer.json b/aldarien/session/composer.json
deleted file mode 100644
index 7fe764d..0000000
--- a/aldarien/session/composer.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "aldarien/session",
- "description": "Session wrapper for aura/session",
- "type": "library",
- "require": {
- "aura/session": "*",
- "aldarien/contract": "*"
- },
- "require-dev": {
- "phpunit/phpunit": "*"
- },
- "license": "MIT",
- "authors": [
- {
- "name": "Aldarien",
- "email": "aldarien85@gmail.com"
- }
- ],
- "autoload": {
- "psr-4": {
- "App\\": "app"
- }
- }
-}
diff --git a/aldarien/url/.gitignore b/aldarien/url/.gitignore
deleted file mode 100644
index a06a2f1..0000000
--- a/aldarien/url/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-.settings
-.buildpath
-.project
-
-# Eclipse IDE
\ No newline at end of file
diff --git a/aldarien/url/LICENSE b/aldarien/url/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/url/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/url/README.md b/aldarien/url/README.md
deleted file mode 100644
index 0c1a426..0000000
--- a/aldarien/url/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# url
-Get relative path url
diff --git a/aldarien/url/app/Contract/URL.php b/aldarien/url/app/Contract/URL.php
deleted file mode 100644
index 14d7ef0..0000000
--- a/aldarien/url/app/Contract/URL.php
+++ /dev/null
@@ -1,21 +0,0 @@
-url($path, $variables);
- }
-}
-?>
\ No newline at end of file
diff --git a/aldarien/url/app/Helper/functions.php b/aldarien/url/app/Helper/functions.php
deleted file mode 100644
index 6e9435e..0000000
--- a/aldarien/url/app/Helper/functions.php
+++ /dev/null
@@ -1,8 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/url/app/Service/URL.php b/aldarien/url/app/Service/URL.php
deleted file mode 100644
index 49a601d..0000000
--- a/aldarien/url/app/Service/URL.php
+++ /dev/null
@@ -1,83 +0,0 @@
-root = $this->findRoot();
- $this->relative = $this->findRelative();
- }
-
- protected function findRoot()
- {
- $base = $_SERVER['HTTP_HOST'] . ((isset($_SERVER['HTTP_PORT'])) ? ':' . $_SERVER['HTTP_PORT'] : '');
- $scheme = 'http';
- if (isset($_SERVER['REQUEST_SCHEME'])) {
- $scheme = $_SERVER['REQUEST_SCHEME'];
- }
- if (isset($_SERVER['HTTPS'])) {
- $scheme = 'https';
- }
- $uri = Http::createFromString(\Sabre\Uri\resolve($scheme . '://' . $base, $_SERVER['SCRIPT_NAME']));
- $host = new Host($uri->getHost());
- if ($host->isAbsolute()) {
- return $host->getRegistrableDomain();
- }
- $base = $host . (($uri->getPort()) ? ':' . $uri->getPort() : '');
- return ($uri->getScheme() ?: 'http') . '://' . $base;
- }
- protected function findRelative()
- {
- $uri = Http::createFromString($_SERVER['SCRIPT_NAME']);
- $normalized = (new HierarchicalPath($uri->getPath()))->withoutLeadingSlash()->withoutTrailingSlash()->withoutDotSegments()->withoutEmptySegments();
- if ($normalized->getDirname() == '.') {
- return '';
- }
- return $normalized->getDirname();
- }
-
-
- public function url($path = '', $variables = null)
- {
- $uri = Http::createFromString($path);
- if ($uri->getHost() != $this->root and $uri->getHost() != '') {
- return $path;
- }
-
- $uri = \Sabre\Uri\resolve($this->getBaseUrl(), $path);
- try {
- $host = new Host(Http::createFromString($uri)->getHost());
- } catch (\League\Uri\Exception $e) {
- $uri = \Sabre\Uri\resolve($this->getBaseUrl(), '../../') . '/' . basename($path);
- $host = new Host(Http::createFromString($uri)->getHost());
- }
-
- $base = new Host(Http::createFromString($this->root)->getHost());
- if ($host . '' != $base . '') {
- $host = new Host(Http::createFromString($this->root)->getHost());
- $page = str_replace($this->root, '', $uri);
- $uri = \Sabre\Uri\resolve(Http::createFromString($this->root)->getScheme() . '://' . $host->getRegistrableDomain(). '/', $page);
- }
-
- if ($variables != null) {
- $uri = \Sabre\Uri\resolve($uri, '?' . http_build_query($variables));
- }
- $uri = \Sabre\Uri\normalize($uri);
-
- return $uri;
- }
- protected function getBaseUrl()
- {
- $url = \Sabre\Uri\normalize(trim($this->root . '/' . $this->relative, '/') . '/');
- return $url;
- }
-}
-?>
diff --git a/aldarien/url/composer.json b/aldarien/url/composer.json
deleted file mode 100644
index 779ed73..0000000
--- a/aldarien/url/composer.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name" : "aldarien/url",
- "description" : "Get relative path uri",
- "type" : "library",
- "require" : {
- "aldarien/contract" : "*",
- "aldarien/root" : "*",
- "league/uri": "*",
- "league/uri-components": "*",
- "sabre/uri": "*"
- },
- "require-dev" : {
- "phpunit/phpunit" : "*"
- },
- "license" : "MIT",
- "authors" : [{
- "name" : "Aldarien",
- "email" : "jpvial@gmail.com"
- }
- ],
- "autoload" : {
- "psr-4" : {
- "App\\" : "app"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- }
-}
diff --git a/aldarien/view/.gitignore b/aldarien/view/.gitignore
deleted file mode 100644
index 120b68f..0000000
--- a/aldarien/view/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
-
-.settings
-.buildpath
-.project
diff --git a/aldarien/view/LICENSE b/aldarien/view/LICENSE
deleted file mode 100644
index 55dc05a..0000000
--- a/aldarien/view/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Aldarien
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/aldarien/view/README.md b/aldarien/view/README.md
deleted file mode 100644
index b888dbd..0000000
--- a/aldarien/view/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# view
-View module for my apps
diff --git a/aldarien/view/app/Contract/View.php b/aldarien/view/app/Contract/View.php
deleted file mode 100644
index 1d0c5b9..0000000
--- a/aldarien/view/app/Contract/View.php
+++ /dev/null
@@ -1,30 +0,0 @@
- "http://{$remote->getIP()}:8008",
- 'headers' => ['Accept' => 'application/json']
- ])));
- return new ViewService(['money' => $money]);
- }
- public static function show($template, $variables = null)
- {
- $instance = self::getInstance();
- return $instance->show($template, $variables);
- }
-}
-?>
diff --git a/aldarien/view/app/Helper/functions.php b/aldarien/view/app/Helper/functions.php
deleted file mode 100644
index ba0e9e1..0000000
--- a/aldarien/view/app/Helper/functions.php
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/aldarien/view/app/Service/View.php b/aldarien/view/app/Service/View.php
deleted file mode 100644
index 7217696..0000000
--- a/aldarien/view/app/Service/View.php
+++ /dev/null
@@ -1,27 +0,0 @@
-views = config('locations.views');
- $this->cache = config('locations.cache');
-
- $this->blade = new BladeOne($this->views, $this->cache, null, $variables);
- }
- public function show($template, $vars = null)
- {
- if ($vars) {
- return $this->blade->run($template, $vars);
- }
- return $this->blade->run($template);
- }
-}
-?>
diff --git a/aldarien/view/cache/26fae499b6e99106ff3bd673b8eb7319ae68e7ae.php b/aldarien/view/cache/26fae499b6e99106ff3bd673b8eb7319ae68e7ae.php
deleted file mode 100644
index 8cafca1..0000000
--- a/aldarien/view/cache/26fae499b6e99106ff3bd673b8eb7319ae68e7ae.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- View
-
-
-View test
-
-
\ No newline at end of file
diff --git a/aldarien/view/composer.json b/aldarien/view/composer.json
deleted file mode 100644
index 5d283ab..0000000
--- a/aldarien/view/composer.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "aldarien/view",
- "description": "View module for my apps",
- "type": "library",
- "require": {
- "eftec/bladeone": "*",
- "aldarien/contract": "*",
- "aldarien/config": "*"
- },
- "license": "MIT",
- "authors": [
- {
- "name": "Aldarien",
- "email": "aldarien85@gmail.com"
- }
- ],
- "autoload": {
- "psr-4": {
- "App\\": "app"
- },
- "files": [
- "app/Helper/functions.php"
- ]
- },
- "require-dev": {
- "phpunit/phpunit": "*"
- }
-}
diff --git a/aldarien/view/config/locations.php b/aldarien/view/config/locations.php
deleted file mode 100644
index 1dd0425..0000000
--- a/aldarien/view/config/locations.php
+++ /dev/null
@@ -1,8 +0,0 @@
- root(),
- 'cache' => '{locations.base}/cache',
- 'resources' => '{locations.base}/resources',
- 'views' => '{locations.resources}/views'
-];
-?>
\ No newline at end of file
diff --git a/aldarien/view/phpunit.xml b/aldarien/view/phpunit.xml
deleted file mode 100644
index e60ecbd..0000000
--- a/aldarien/view/phpunit.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./app
-
-
-
\ No newline at end of file
diff --git a/aldarien/view/public/index.php b/aldarien/view/public/index.php
deleted file mode 100644
index 1070f11..0000000
--- a/aldarien/view/public/index.php
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/aldarien/view/resources/views/base.blade.php b/aldarien/view/resources/views/base.blade.php
deleted file mode 100644
index 8cafca1..0000000
--- a/aldarien/view/resources/views/base.blade.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- View
-
-
-View test
-
-
\ No newline at end of file
diff --git a/aldarien/view/tests/ViewTest.php b/aldarien/view/tests/ViewTest.php
deleted file mode 100644
index 85f4aa6..0000000
--- a/aldarien/view/tests/ViewTest.php
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- View
-
-
-View test
-
-
-DATA;
- $this->assertEquals($output, view('base'));
- }
-}
-?>
\ No newline at end of file
diff --git a/app/.adminer.env.sample b/app/.adminer.env.sample
new file mode 100644
index 0000000..b44b711
--- /dev/null
+++ b/app/.adminer.env.sample
@@ -0,0 +1 @@
+ADMINER_DESIGN=dracula
diff --git a/.db.env.sample b/app/.db.env.sample
similarity index 100%
rename from .db.env.sample
rename to app/.db.env.sample
index 18b1117..6e2de9c 100644
--- a/.db.env.sample
+++ b/app/.db.env.sample
@@ -1,4 +1,4 @@
-MYSQL_DATABASE=
-MYSQL_PASSWORD=
MYSQL_ROOT_PASSWORD=
+MYSQL_DATABASE=
MYSQL_USER=
+MYSQL_PASSWORD=
diff --git a/app/.env.sample b/app/.env.sample
new file mode 100644
index 0000000..3483fc3
--- /dev/null
+++ b/app/.env.sample
@@ -0,0 +1,11 @@
+APP_URL=
+
+MYSQL_HOST=db
+
+COOKIE_NAME=
+COOKIE_DOMAIN=
+COOKIE_PATH=/
+MAX_LOGIN_HOURS=120
+
+REDIS_HOST=redis
+REDIS_PORT=6379
diff --git a/resources/views/layout/footer.blade.php b/app/.redis.env.sample
similarity index 100%
rename from resources/views/layout/footer.blade.php
rename to app/.redis.env.sample
diff --git a/app/Alias/Connection.php b/app/Alias/Connection.php
deleted file mode 100644
index 1eea52a..0000000
--- a/app/Alias/Connection.php
+++ /dev/null
@@ -1,50 +0,0 @@
-connection)) {
- $r = 0;
- $exception = null;
- while ($r < $this->retries) {
- try {
- $dsn = $this->getDsn();
- $this->connection = new PDO($dsn, $this->username, $this->password);
- return $this->connection;
- } catch (PDOException $e) {
- if ($exception !== null) {
- $e = new PDOException($e->getMessage(), $e->getCode(), $exception);
- }
- $exception = $e;
- usleep(500);
- }
- $r ++;
- }
- throw $exception;
- }
- return $this->connection;
- }
- protected function getDsn(): string
- {
- $dsn = "mysql:host={$this->host};dbname={$this->database}";
- if (isset($this->port)) {
- $dsn .= ";port={$this->port}";
- }
- return $dsn;
- }
-}
diff --git a/app/Alias/Excel/Style/Mes.php b/app/Alias/Excel/Style/Mes.php
deleted file mode 100644
index 368246b..0000000
--- a/app/Alias/Excel/Style/Mes.php
+++ /dev/null
@@ -1,18 +0,0 @@
-setNumFormat('mmm-YY');
- $format->setAlign('center');
- }
-}
diff --git a/app/Alias/Format.php b/app/Alias/Format.php
deleted file mode 100644
index f2067aa..0000000
--- a/app/Alias/Format.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
\ No newline at end of file
diff --git a/app/Alias/Model.php b/app/Alias/Model.php
deleted file mode 100644
index 9f8f579..0000000
--- a/app/Alias/Model.php
+++ /dev/null
@@ -1,87 +0,0 @@
-id;
- $orm = $this->orm;
- $ref = new \ReflectionObject($orm);
- if (!$ref->hasProperty('_dirty_fields')) {
- return;
- }
- $dirty = $ref->getProperty('_dirty_fields');
- $dirty->setAccessible(true);
- $new_values = $dirty->getValue($orm);
- $changes = array_combine(array_keys($new_values), array_fill(0, count($new_values), ['old' => '', 'new' => '']));
- if ($this->isNew()) {
- $old = (object) array_combine(array_keys($new_values), array_fill(0, count($new_values), ''));
- } else {
- $old = model(get_called_class())->findOne($this->{$this->getId()});
- }
- foreach ($new_values as $column => $value) {
- $changes[$column] = ['column' => $column, 'old' => $old->$column, 'new' => $value];
- }
- $action = '[' . get_called_class() . ']';
- doLog($user, $action, $changes);
- }
- public function getId()
- {
- if (property_exists(get_called_class(), '_id_column')) {
- return static::$_id_column;
- }
- return $this->id;
- }
- public function save()
- {
- $ref = new \ReflectionObject($this);
- if ($ref->hasProperty('_timestamps')) {
- $ref = $ref->getProperty('_timestamps');
- $ref->setAccessible(true);
- if ($ref->getValue()) {
- if ($this->is_new()) {
- $this->setExpr('created_at', 'NOW()');
- }
- $this->setExpr('updated_at', 'NOW()');
- }
- }
- if (!\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->beginTransaction();
- }
- try {
- parent::save();
- if (\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->commit();
- }
- } catch (\Exception $e) {
- if (\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->rollBack();
- }
- throw $e;
- }
- $this->log();
- }
- public function __call($method, $args)
- {
- if (!method_exists($this, $method)) {
- $str = '' . Stringy::create($method)->underscored();
- if (method_exists($this, $str)) {
- return call_user_func_array([$this, $str], $args);
- }
- throw new \BadMethodCallException($method . ' not found in ' . get_class($this));
- }
- return call_user_func_array([$this, $str], $args);
- }
-}
-?>
diff --git a/app/Alias/NewEstado.php b/app/Alias/NewEstado.php
deleted file mode 100644
index 4bf9089..0000000
--- a/app/Alias/NewEstado.php
+++ /dev/null
@@ -1,20 +0,0 @@
-fecha, config('app.timezone'));
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Alias/NewModel.php b/app/Alias/NewModel.php
deleted file mode 100644
index 1c513b4..0000000
--- a/app/Alias/NewModel.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
\ No newline at end of file
diff --git a/app/Alias/NewTipo.php b/app/Alias/NewTipo.php
deleted file mode 100644
index b5fa3fb..0000000
--- a/app/Alias/NewTipo.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
\ No newline at end of file
diff --git a/app/Alias/OldModel.php b/app/Alias/OldModel.php
deleted file mode 100644
index b3f9730..0000000
--- a/app/Alias/OldModel.php
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/app/Alias/PHPExcel.php b/app/Alias/PHPExcel.php
deleted file mode 100644
index de0ac75..0000000
--- a/app/Alias/PHPExcel.php
+++ /dev/null
@@ -1,155 +0,0 @@
-name = $name;
- $this->filename = $filename;
- }
- public function addColumns($fields)
- {
- $columns = [];
- foreach ($fields as $i => $field) {
- if (is_object($field)) {
- if (isset($field->style)) {
- $style = $this->getExcelStyle($field->style);
- } else {
- $style = $this->getExcelStyle();
- }
- $column = new ExcelHelper\Column($field->name, $field->name, 10, $style);
- } elseif (is_array($field)) {
- if (isset($field['style'])) {
- $style = $this->getExcelStyle($field['style']);
- } else {
- $style = $this->getExcelStyle();
- }
- $column = new ExcelHelper\Column($field['name'], $field['name'], 10, $style);
- } else {
- $style = $this->getExcelStyle();
- $column = new ExcelHelper\Column($field, $field, 10, $style);
- }
- $columns []= $column;
- }
- $collection = new ExcelHelper\ColumnCollection($columns);
- $this->columns = $collection;
- }
- protected function getExcelStyle($style = 'text')
- {
- switch (strtolower($style)) {
- case 'date':
- return new ExcelHelper\CellStyle\Date();
- case 'mes':
- return new Excel\Style\Mes();
- case 'currency':
- case 'amount':
- return new ExcelHelper\CellStyle\Amount();
- case 'number':
- case 'integer':
- return new ExcelHelper\CellStyle\Integer();
- case 'percent':
- case 'percentage':
- return new ExcelHelper\CellStyle\Percentage();
- case 'text':
- case 'string':
- default:
- return new ExcelHelper\CellStyle\Text();
- }
- }
- public function addData($data)
- {
- if ($this->data == null) {
- $this->data = [];
- }
- $this->data = array_merge($data);
- }
- public function addRow($rowData)
- {
- if ($this->data == null) {
- $this->data = [];
- }
- $this->data []= $rowData;
- }
- public function addTotals($totals)
- {
- $columns = (array) $this->columns;
- $columns = array_pop($columns);
- $ts = [];
- foreach ($columns as $column) {
- $col = $column->getHeading();
- if (isset($totals[$col])) {
- $ts[$col] = $this->getTotal($col, $totals[$col]);
- continue;
- }
- $ts[$col] = '';
- }
- $this->data []= $ts;
- }
- protected function getTotal($col, $aggr)
- {
- $col_num = $this->getColNumber($col);
- $col = $this->getColName($col_num);
- switch(strtolower($aggr)) {
- case 'sum':
- $num = 109;
- break;
- case 'count':
- $num = 102;
- break;
- case 'counta':
- $num = 103;
- break;
- default:
- $num = 0;
- }
- if ($num > 0) {
- $end = count($this->data) + 2;
- $str = "=SUBTOTAL({$num};{$col}3:{$col}{$end})";
- return $str;
- }
- return $aggr;
- }
- protected function getColNumber($col)
- {
- $columns = (array) $this->columns;
- $columns = array_keys(array_pop($columns));
- return array_search($col, $columns);
- }
- protected function getColName($col_num)
- {
- $cols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
- $N = strlen($cols);
- $name = '';
- if ($col_num > $N) {
- $name .= $cols[floor($col_num / $N)];
- $col_num = $N * ($col_num / $N - floor($col_num / $N));
- }
- $name .= $cols[$col_num];
- return $name;
- }
- public function informe()
- {
- header("Content-Type: application/octet-stream; charset=utf-8");
- header('Content-Transfer-Encoding: binary');
- header('Content-Disposition: attachment; filename="' . $this->filename . '"');
- header('Cache-Control: max-age=0');
-
- $pE = new ExcelHelper\TableWorkbook('php://output');
- $ws = $pE->addWorksheet($this->name);
-
- $table = new ExcelHelper\Table($ws, 0, 0, $this->name, new \ArrayIterator($this->data));
- $table->setColumnCollection($this->columns);
-
- $pE->writeTable($table);
-
- $pE->close();
- }
-}
diff --git a/app/Alias/RemoteConnection.php b/app/Alias/RemoteConnection.php
deleted file mode 100644
index 475225e..0000000
--- a/app/Alias/RemoteConnection.php
+++ /dev/null
@@ -1,17 +0,0 @@
-retries
- );
- }
-}
diff --git a/app/Command/Money/Get.php b/app/Command/Money/Get.php
deleted file mode 100644
index 9228582..0000000
--- a/app/Command/Money/Get.php
+++ /dev/null
@@ -1,86 +0,0 @@
-title('Get Money');
-
- $dates = $this->getDates();
- foreach ($dates as $date_string => $ids) {
- $date = $this->parseDate($date_string);
- $response = $this->service->getUF($date);
- if ($response->total === 0) {
- continue;
- }
- foreach ($ids as $id) {
- $this->queueUpdate($id, $response->uf->value);
- }
- }
- $this->updateUF();
- }
-
- protected function getDates(): array
- {
- $query = "SELECT id, fecha FROM pago WHERE uf IS NULL AND fecha BETWEEN 0 AND DATE_ADD(CURDATE(), INTERVAL 9 DAY) ORDER BY fecha";
- $statement = $this->connection->connect()->query($query);
- $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
- if (count($rows) === 0) {
- return [];
- }
- $dates = [];
- foreach ($rows as $row) {
- if (!isset($dates[$row['fecha']])) {
- $dates[$row['fecha']] = [];
- }
- $dates[$row['fecha']] []= (int) $row['id'];
- }
- return $dates;
- }
- protected function parseDate(string $date_string): DateTimeInterface
- {
- return new DateTimeImmutable($date_string);
- }
- protected array $rows;
- protected function queueUpdate(int $id, float $value): void
- {
- $this->rows []= [$value, $id];
- }
- protected function updateUF(): void
- {
- $query = "UPDATE pago SET uf = ? WHERE id = ?";
- $statement = $this->connection->connect()->prepare($query);
- foreach ($this->rows as $row) {
- $this->connection->connect()->beginTransaction();
- try {
- $statement->execute($row);
- $this->connection->connect()->commit();
- } catch (PDOException $e) {
- $this->connection->connect()->rollBack();
- }
- }
- }
-}
diff --git a/app/Command/Money/Lookup.php b/app/Command/Money/Lookup.php
deleted file mode 100644
index 43b85b9..0000000
--- a/app/Command/Money/Lookup.php
+++ /dev/null
@@ -1,51 +0,0 @@
-title('Lookup Money');
-
- while (true) {
- $io->info('Checking pending');
- if ($this->hasPendingMoney()) {
- $io->success('Running money get UF');
- $io->note($this->runGetUF());
- }
- }
- }
-
- protected function hasPendingMoney(): bool
- {
- $query = "SELECT 1 FROM pago WHERE uf IS NULL AND fecha BETWEEN 0 AND DATE_ADD(CURDATE(), INTERVAL 9 DAY)";
- $statement = $this->connection->connect()->query($query);
- return $statement->rowCount() > 0;
- }
- protected function runGetUF(): string
- {
- $command = "/code/bin/console money:uf:get";
- $result = shell_exec($command);
- if (!$result or $result === null) {
- throw new \Exception();
- }
- return $result;
- }
-}
diff --git a/app/Contract/Auth.php b/app/Contract/Auth.php
deleted file mode 100644
index fb2e3b6..0000000
--- a/app/Contract/Auth.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
\ No newline at end of file
diff --git a/app/Contract/Route.php b/app/Contract/Route.php
deleted file mode 100644
index fd4a84c..0000000
--- a/app/Contract/Route.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
\ No newline at end of file
diff --git a/app/Controller/API/Unidades.php b/app/Controller/API/Unidades.php
deleted file mode 100644
index b7abead..0000000
--- a/app/Controller/API/Unidades.php
+++ /dev/null
@@ -1,41 +0,0 @@
-findOne($id_proyecto);
- if (!$proyecto) {
- throw new \InvalidArgumentException('Proyecto identificado por ' . $id_proyecto . ' no existe.');
- }
- $unidades = $proyecto->unidades($id_tipo);
- $unidades = array_filter($unidades, function($item) {
- return !$item->isVendida() and !$item->isReservada();
- });
- $unidades = array_map(function($item) {
- return $item->asArray();
- }, $unidades);
- usort($unidades, function($a, $b) {
- $ap = strpos($a['descripcion'], ' ');
- $ad = $a['descripcion'];
- if ($ap != false) {
- $ad = substr($ad, 0, $ap);
- }
- $bd = $b['descripcion'];
- $bp = strpos($b['descripcion'], ' ');
- if ($bp != false) {
- $bd = substr($bd, 0, $bp);
- }
- return strcmp(
- str_pad($ad, 4, '0', \STR_PAD_LEFT),
- str_pad($bd, 4, '0', \STR_PAD_LEFT)
- );
- });
- $output = array_values($unidades);
- $response->getBody()->write(\json_encode($output));
- return $response->withHeader('Content-Type', 'application/json');
- }
-}
diff --git a/app/Controller/Admin.php b/app/Controller/Admin.php
deleted file mode 100644
index 137057c..0000000
--- a/app/Controller/Admin.php
+++ /dev/null
@@ -1,233 +0,0 @@
-list();
- }
- public static function listNamespaces()
- {
- $base = [
- 'Common',
- 'Inmobiliaria',
- 'Proyecto',
- 'Venta'
- ];
- $nss = [
- 'Incoviba' => [
- 'old' => $base,
- 'new' => $base
- ]
- ];
-
- echo json_encode(['namespaces' => self::collapseMultiArray($nss)]);
- }
- protected static function collapseMultiArray($array, $level = '')
- {
- $output = [];
- foreach ($array as $key => $subarray) {
- if (is_array($subarray)) {
- $output = array_merge($output, self::collapseMultiArray($subarray, $level . '\\' . $key));
- } else {
- $output []= $level . '\\' . $subarray;
- }
- }
-
- return $output;
- }
- public static function createModel()
- {
- $db = post('database');
- $ns = post('namespace');
- $table = post('table');
-
- $modeler = new DBToModel($db);
- echo $modeler->create($ns, $table);
- }
- public static function list_roles()
- {
- $roles = \Model::factory(\Incoviba\common\Role::class)->findMany();
- echo view('admin.roles.list', compact('roles'));
- }
- public static function add_role()
- {
- echo view('admin.roles.add');
- }
- public static function do_add_role()
- {
- $role = \Model::factory(\Incoviba\common\Role::class)->where('description', post('description'))->findOne();
- if ($role === false) {
- $role = \Model::factory(\Incoviba\common\Role::class)->create(['description' => post('description')]);
- $role->save();
- }
- header('Location: ' . nUrl('admin', 'add_role'));
- }
- public static function role()
- {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne(get('role'));
- $actions = model(Action::class)->orderByAsc('description')->findMany();
- $permissions = [];
- foreach ($actions as $action) {
- $permissions []= (object) ['description' => $action->description, 'status' => false, 'inherited' => false];
- }
- array_walk($permissions, function(&$el, $i, $role) {
- if ($role->checkAccess($el->description)) {
- $el->status = true;
- if ($role->isInherited($el->description)) {
- $el->inherited = true;
- }
- }
- }, $role);
- echo view('admin.roles.show', compact('role', 'permissions'));
- }
- public static function add_role_permissions()
- {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne(get('role'));
- $locations = \Model::factory(\Incoviba\common\Location::class)->findMany();
- $actions = model(\Incoviba\common\Action::class)->findMany();
- echo view('admin.roles.add_permissions', compact('role', 'locations', 'actions'));
- }
- public static function do_add_role_permissions()
- {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne(get('role'));
- $actions = model(\Incoviba\common\Action::class)->findMany();
- foreach ($actions as $action) {
- $p = \Model::factory(\Incoviba\common\Permission::class)->where('type', 2)->where('ext_id', $role->id)->where('action_id', $action->id)->findOne();
- if (array_search($action->id, post('allowed'))) {
- if (!$p) {
- $data = [
- 'type' => 2,
- 'ext_id' => $role->id,
- 'action_id' => $action->id
- ];
- $p = model(\Incoviba\common\Permission::class)->create($data);
- }
- $p->status = 1;
- } else {
- if ($p !== false) {
- $p->status = 0;
- }
- }
- if ($p !== false) {
- $p->save();
- }
- }
- header('Location: ' . nUrl('admin', 'role', ['role' => $role->id]));
- }
- public static function list_users()
- {
- $users = \Model::factory(\Incoviba\common\User::class)->orderByAsc('name')->findMany();
- echo view('admin.users.list', compact('users'));
- }
- public static function add_user()
- {
- echo view('admin.users.add');
- }
- public static function do_add_user()
- {
- $user = \Model::factory(\Incoviba\common\User::class)->where('name', post('name'))->findOne();
- if ($user === false) {
- $user = \Model::factory(\Incoviba\common\User::class)->create();
- $user->name = post('name');
- $user->password(post('password'));
-
- $user->save();
- }
- header('Location: ' . url('', ['p' => 'admin', 'a' => 'add_user']));
- }
- public static function user()
- {
- $user = \Model::factory(\Incoviba\common\User::class)->findOne(get('user'));
- echo view('admin.users.show', compact('user'));
- }
- public static function add_user_role()
- {
- if (get('user') !== false) {
- $user = \Model::factory(\Incoviba\common\User::class)->findOne(get('user'));
- $roles = \Model::factory(\Incoviba\common\Role::class)->findMany();
- return view('admin.users.add_role', compact('user', 'roles'));
- } elseif (get('role') !== false) {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne(get('role'));
- $users = \Model::factory(\Incoviba\common\User::class)->findMany();
- return view('admin.roles.add_users', compact('users', 'role'));
- }
- }
- public static function do_add_user_role()
- {
- if (get('user') !== false) {
- $user = \Model::factory(\Incoviba\common\User::class)->findOne(get('user'));
- foreach (post('role') as $r_id) {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne($r_id);
-
- $usrRl = \Model::factory(\Incoviba\common\UserRole::class)->where('user', $user->id)->where('role', $role->id)->findOne();
- if ($usrRl === false) {
- $usrRl = \Model::factory(\Incoviba\common\UserRole::class)->create(['user' => $user->id, 'role' => $role->id]);
- $usrRl->save();
- }
- }
- header('Location: ' . url('', ['p' => 'admin', 'a' => 'user', 'user' => $user->id]));
- } elseif (get('role') !== false) {
- $role = \Model::factory(\Incoviba\common\Role::class)->findOne(get('role'));
- foreach (post('users') as $u_id) {
- $user = \Model::factory(\Incoviba\common\User::class)->findOne($u_id);
-
- $usrRl = \Model::factory(\Incoviba\common\UserRole::class)->where('user', $user->id)->where('role', $role->id)->findOne();
- if ($usrRl === false) {
- $usrRl = \Model::factory(\Incoviba\common\UserRole::class)->create(['user' => $user->id, 'role' => $role->id]);
- $usrRl->save();
- }
- }
- header('Location: ' . url('', ['p' => 'admin', 'a' => 'role', 'role' => $role->id]));
- }
- }
- public static function remove_user_role()
- {
- $q = "DELETE FROM user_roles WHERE user = ? AND role = ?";
- $st = \ORM::getDb()->prepare($q);
- $st->execute([get('user'), get('role')]);
- header('Location: ' . nUrl('admin'));
- }
- public static function delete_user()
- {
- $q = "DELETE FROM user_roles WHERE user = ?";
- $st = \ORM::getDb()->prepare($q);
- $st->execute([get('user')]);
- $q = "DELETE FROM logins WHERE user = ?";
- $st = \ORM::getDb()->prepare($q);
- $st->execute([get('user')]);
- $q = "DELETE FROM permissions WHERE type = 1 AND ext_id = ?";
- $st = \ORM::getDb()->prepare($q);
- $st->execute([get('user')]);
- $user = \model(\Incoviba\common\User::class)->findOne(get('user'));
- $user->delete();
- header('Location: ' . nUrl('admin', 'list_users'));
- }
- public static function reset_user()
- {
- $user = model(\Incoviba\common\User::class)->findOne(get('user'));
- $user->password('123456');
- $user->save();
- header('Location: ' . nUrl('admin', 'user', ['user' => $user->id]));
- }
-}
-?>
diff --git a/app/Controller/Ajax.php b/app/Controller/Ajax.php
deleted file mode 100644
index 912c979..0000000
--- a/app/Controller/Ajax.php
+++ /dev/null
@@ -1,215 +0,0 @@
-whereNotEqual('nombre', '')->order_by_asc('nombre')->findMany();
- foreach ($bancos as &$banco) {
- $banco = $banco->as_array('nombre')['nombre'];
- }
- return json_encode($bancos);
- }
- protected static function buscarBanco()
- {
- $q = get('q');
- if ($q == null) {
- $q = get('query');
- if ($q == null) {
- return '';
- }
- }
- $bancos = \Model::factory(\Incoviba\old\Common\Banco::class)->whereLike('nombre', '%' . $q . '%')->order_by_asc('nombre')->findMany();
- foreach ($bancos as &$banco) {
- $banco = $banco->as_array('nombre')['nombre'];
- }
- return json_encode($bancos);
- }
- public static function comunas()
- {
- $id = post('region');
- $comunas = \Model::factory(\Incoviba\old\Common\Comuna::class)
- ->select('comuna.*')
- ->join('provincia', ['provincia.id', '=', 'comuna.provincia'])
- ->where('provincia.region', $id)
- ->order_by_asc('comuna.descripcion')
- ->findMany();
-
- foreach ($comunas as &$comuna) {
- $comuna = $comuna->as_array('id', 'descripcion');
- }
- return json_encode($comunas);
- }
- public static function propietario()
- {
- $id = post('rut');
- $propietario = \Model::factory(\Incoviba\old\Venta\Propietario::class)->where('rut', $id)->findOne();
- if ($propietario) {
- $propietario = $propietario->as_array();
- return json_encode($propietario);
- }
- return null;
- }
- public static function direccion()
- {
- $id = post('direccion');
- $direccion = \Model::factory(\Incoviba\old\Common\Direccion::class)->findOne($id);
- $comuna = $direccion->comuna();
- $provincia = $comuna->provincia();
- $region = $provincia->region();
- $direccion = $direccion->as_array();
- $direccion['comuna'] = $comuna->as_array();
- $direccion['comuna']['provincia'] = $provincia->as_array();
- $direccion['comuna']['provincia']['region'] = $region->as_array();
- return json_encode($direccion);
- }
- public static function tipo_unidades()
- {
- $id = post('proyecto');
- $proyecto = \Model::factory(\Incoviba\old\Proyecto\Proyecto::class)->findOne($id);
- $tipos = $proyecto->tipoUnidades();
- foreach ($tipos as &$tipo) {
- $tipo = $tipo->as_array();
- }
- return json_encode($tipos);
- }
- public static function unidades()
- {
- $id_proyecto = post('proyecto');
- $id_tipo = post('tipo');
-
- $proyecto = model(\Incoviba\old\Proyecto\Proyecto::class)->findOne($id_proyecto);
- $unidades = $proyecto->unidadesDisponibles($id_tipo);
- foreach ($unidades as &$unidad) {
- $tipologia = $unidad->tipologia();
- $unidad = $unidad->as_array();
- $unidad['tipologia'] = $tipologia->as_array();
- if ($tipologia->tipologia()) {
- $unidad['tipologia']['tipologia'] = (array) $tipologia->tipologia();
- continue;
- }
- $unidad['tipologia']['tipologia'] = ['descripcion' => $tipologia->abreviacion];
- }
- return json_encode($unidades);
- }
- public static function unidades_precios()
- {
- $proyecto = model(\Incoviba\old\Proyecto\Proyecto::class)->findOne(post('proyecto'));
- $unidades = $proyecto->unidades();
- usort($unidades, function($a, $b) {
- $t = $a->tipo - $b->tipo;
- if ($t == 0) {
- return (int) $a->descripcion - (int) $b->descripcion;
- }
- return $t;
- });
- $output = [];
- foreach ($unidades as $u) {
- $info = [
- 'id' => $u->id,
- 'abreviacion' => $u->abreviacion,
- 'descripcion' => $u->descripcion,
- 'valor' => '--'
- ];
- if ($u->precio()) {
- $info['valor'] = format('ufs', $u->precio()->valor, null, true);
- }
- $output []= $info;
- }
- return json_encode($output);
- }
- public static function operadores()
- {
- $id_proyecto = post('proyecto');
- $proyecto = \Model::factory(\Incoviba\old\Proyecto\Proyecto::class)->findOne($id_proyecto);
- $operadores = $proyecto->operadores();
- foreach ($operadores as &$operador) {
- $operador = [
- 'id' => $operador->id,
- 'abreviacion' => $operador->abreviacion
- ];
- }
- return json_encode($operadores);
- }
- public static function promociones()
- {
- $id = post('proyecto');
- $proyecto = \Model::factory(\Incoviba\old\Proyecto\Proyecto::class)->findOne($id);
- $promociones = $proyecto->promociones();
- foreach ($promociones as &$promocion) {
- $promocion = $promocion->as_array();
- }
- return json_encode($promociones);
- }
- public static function nombres()
- {
- $nss = model(Propietario::class)->select('nombres')->orderByAsc('nombres')->findMany();
- $nombres = [];
- foreach ($nss as $n) {
- $ns = explode(' ', $n->nombres);
- foreach ($ns as $nombre) {
- $nombres []= $nombre;
- }
- }
- $nombres = array_values(array_unique($nombres));
- return json_encode($nombres);
- }
- public static function apellidos()
- {
- $aps = model(Propietario::class)->select('apellido_paterno')->orderByAsc('apellido_paterno')->findMany();
- $apellidos = [];
- foreach ($aps as $ap) {
- $apellidos []= $ap->apellido_paterno;
- }
- $aps = model(Propietario::class)->select('apellido_materno')->orderByAsc('apellido_materno')->findMany();
- foreach ($aps as $ap) {
- $apellidos []= $ap->apellido_paterno;
- }
- $apellidos = array_values(array_unique($apellidos));
- sort($apellidos);
- return json_encode($apellidos);
- }
- public static function calles()
- {
- $results = model(Direccion::class)->select('calle')->orderByAsc('calle')->findMany();
- $calles = [];
- foreach ($results as $result) {
- $calles []= $result->calle;
- }
- $calles = array_values(array_unique($calles));
- return json_encode($calles);
- }
- public static function inmobiliarias()
- {
- $q = post('rut');
- $inmobiliaria = model(Inmobiliaria::class)->findOne($q);
- return json_encode($inmobiliaria->as_array());
- }
-}
-?>
diff --git a/app/Controller/Auth.php b/app/Controller/Auth.php
deleted file mode 100644
index c7ca497..0000000
--- a/app/Controller/Auth.php
+++ /dev/null
@@ -1,56 +0,0 @@
- 'auth', 'a' => 'login']));
- }
- }
- public static function logout()
- {
- sAuth::logout();
- header('Location: .');
- }
- public static function check_pass()
- {
- if (\password_verify(post('password'), sAuth::User()->password)) {
- return 'OK';
- }
- return 'KO';
- }
- public static function change_pass()
- {
- return view('auth.change_pass');
- }
- public static function do_change_pass()
- {
- if (\password_verify(post('old'), sAuth::User()->password)) {
- if (post('new') == post('new2')) {
- $user = sAuth::User();
- $user->password(post('new'));
- $user->save();
- header('Location: .');
- die();
- }
- }
- header('Location: ' . url('', ['p' => 'auth', 'a' => 'change_pass']));
- }
-}
-?>
diff --git a/app/Controller/Bonos.php b/app/Controller/Bonos.php
deleted file mode 100644
index 32daaa5..0000000
--- a/app/Controller/Bonos.php
+++ /dev/null
@@ -1,67 +0,0 @@
-findOne($id_venta);
- return view('ventas.bonos.add', compact('venta'));
- }
- public static function do_add()
- {
- $id_venta = get('venta');
- $venta = model(Venta::class)->findOne($id_venta);
- if ($venta->bono_pie != 0) {
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- return;
- }
- $uf = uf($venta->fecha());
- $valor = post('valor');
- $data = [
- 'fecha' => $venta->fecha,
- 'valor' => $valor * $uf->uf->value,
- 'tipo' => 8,
- 'uf' => $uf->uf->value
- ];
- $pago = model(Pago::class)->create($data);
- $pago->save();
- $data = [
- 'valor' => $valor,
- 'pago' => $pago->id
- ];
- $bono = model(BonoPie::class)->create($data);
- $bono->save();
- $venta->bono_pie = $bono->id;
- $venta->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
- public static function edit()
- {
- $id_venta = get('venta');
- $venta = model(Venta::class)->findOne($id_venta);
- return view('ventas.bonos.edit', compact('venta'));
- }
- public static function do_edit()
- {
- $id_venta = get('venta');
- $venta = model(Venta::class)->findOne($id_venta);
- $bono = $venta->bonoPie();
- $valor = post('valor') * $bono->pago()->uf();
- $pago = $bono->pago();
- if ($valor != $bono->pago()->valor()) {
- $pago->valor = $valor;
- $pago->save();
- }
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- exit();
- }
-}
diff --git a/app/Controller/Buscar.php b/app/Controller/Buscar.php
deleted file mode 100644
index ef62a9e..0000000
--- a/app/Controller/Buscar.php
+++ /dev/null
@@ -1,340 +0,0 @@
- $results]);
- }
- protected static function getResults()
- {
- $q = get('q');
- if ($q == null) {
- $q = get('query');
- }
- $t = get('t');
- if ($t == null) {
- $t = get('tipo');
- }
- $t = urldecode($t);
- if ($t == null) {
- $t = 'cualquiera';
- }
-
- $results = null;
- if ($q != null) {
- $q = urldecode($q);
- $results = self::buscar($q, $t);
- }
- return $results;
- }
- public static function buscar($query, $tipo)
- {
- $method = 'buscar' . str_replace(' ', '', ucwords($tipo));
- if (is_callable(['self', $method])) {
- $results = self::$method(self::prepareQuery($query));
- $results = self::removeDuplicates($results);
- $results = self::sort($results);
- return $results;
- }
- return [];
- }
- protected static function prepareQuery($query)
- {
- $query = str_replace('"', '"', $query);
- $data = explode(' ', $query);
- $regex = "~(?=\\S)[^'\"\\s]*(?:'[^']*'[^'\"\\s]*|\"[^\"]*\"[^'\"\\s]*)*~";
- preg_match_all($regex, $query, $data);
- $data = $data[0];
- foreach ($data as &$l) {
- $l = str_replace('"', '', str_replace("'", '', $l));
- }
- if (is_array($data) and count($data) == 1) {
- $data = $data[0];
- }
- return $data;
- }
- protected static function removeDuplicates($results)
- {
- $output = [];
- foreach ($results as $result) {
- if (array_search($result, $output) === false) {
- $output []= $result;
- }
- }
- return $output;
- }
- protected static function sort($results)
- {
- usort($results, function($a, $b) {
- $py = strcmp($a->proyecto()->descripcion, $b->proyecto()->descripcion);
- if ($py == 0) {
- if (!method_exists($a, 'unidad') and !method_exists($b, 'unidad')) {
- return $a->descripcion - $b->descripcion;
- }
- if (!method_exists($a, 'unidad')) {
- return $a->descripcion - $b->unidad()->descripcion;
- }
- if (!method_exists($b, 'unidad')) {
- return $a->unidad()->descripcion - $b->descripcion;
- }
-
- $u = $a->unidad()->descripcion - $b->unidad()->descripcion;
- if ($u == 0) {
- return strcmp($a->propietario()->apellido_paterno, $b->propietario()->apellido_paterno);
- }
- return $u;
- }
- return $py;
- });
- return $results;
- }
- protected static function buscarCualquiera($query)
- {
- $results = [];
- foreach (self::$tipos as $tipo) {
- if ($tipo == 'cualquiera') {
- continue;
- }
- $method = 'buscar' . str_replace(' ', '', ucwords($tipo));
-
- if (is_callable(['self', $method])) {
- $results = array_merge($results, self::$method($query));
- }
- }
- return $results;
- }
- protected static function buscarDepartamento($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarDepartamento($segment));
- }
- } else {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->whereLike('unidad.descripcion', '%' . $query . '%')
- ->findMany();
- }
- return $results;
- }
- protected static function buscarEstacionamiento($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarEstacionamiento($segment));
- }
- } else {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', "`propiedad`.`estacionamientos` LIKE `unidad`.`id` OR `propiedad`.`estacionamientos` LIKE CONCAT('%;', `unidad`.`id`) OR `propiedad`.`estacionamientos` LIKE CONCAT(`unidad`.`id`, ';%') OR `propiedad`.`estacionamientos` LIKE CONCAT('%;', `unidad`.`id`, ';%')")
- ->where('unidad.descripcion', $query)
- ->findMany();
- }
- return $results;
- }
- protected static function buscarBodega($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarBodega($segment));
- }
- } else {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', "`propiedad`.`bodegas` LIKE `unidad`.`id` OR `propiedad`.`bodegas` LIKE CONCAT('%;', `unidad`.`id`) OR `propiedad`.`bodegas` LIKE CONCAT(`unidad`.`id`, ';%') OR `propiedad`.`bodegas` LIKE CONCAT('%;', `unidad`.`id`, ';%')")
- ->where('unidad.descripcion', $query)
- ->findMany();
- }
- return $results;
- }
- protected static function buscarPropietario($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarPropietario($segment));
- }
- } else {
- $results = self::buscarPropietarioNombres($query);
- $results = array_merge($results, self::buscarPropietarioApellido($query));
- $results = array_merge($results, self::buscarPropietarioNombreCompleto($query));
- }
- return $results;
- }
- protected static function buscarPropietarioNombres($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
- ->whereLike('propietario.nombres', '%' . $query . '%')
- ->findMany();
- return $results;
- }
- protected static function buscarPropietarioApellido($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
- ->whereAnyIs([
- ['propietario.apellido_paterno' => '%' . $query . '%'],
- ['propietario.apellido_materno' => '%' . $query . '%']
- ], 'LIKE')
- ->findMany();
- return $results;
- }
- protected static function buscarPropietarioNombreCompleto($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('propietario', ['propietario.rut', '=', 'venta.propietario'])
- ->whereRaw("CONCAT_WS(' ', propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) LIKE '%" . $query . "%'")
- ->findMany();
- return $results;
- }
- protected static function buscarPrecioVenta($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarPrecioVenta($segment));
- }
- } else {
- $query = str_replace([',', '.'], ['.', ''], $query);
- $results = \Model::factory(Venta::class)->where('valor_uf', $query)->findMany();
- }
- return $results;
- }
- protected static function buscarProyecto($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarProyecto($segment));
- }
- } else {
- $results = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
- ->whereLike('proyecto.descripcion', '%' . $query . '%')
- ->findMany();
- }
- return $results;
- }
- protected static function buscarPago($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarPrecioVenta($segment));
- }
- } else {
- $query = str_replace(',', '.', str_replace('.', '', $query));
- $query2 = (float) $query;
- if ($query != $query2) {
- return [];
- }
- if (!is_float($query2)) {
- return [];
- }
- $query = $query2;
- $results = self::buscarValorCuota($query);
- $results = array_merge($results, self::buscarReajuste($query));
- $results = array_merge($results, self::buscarEscritura($query));
- $results = array_merge($results, self::buscarSubsidio($query));
- $results = array_merge($results, self::buscarCredito($query));
- }
- return $results;
- }
- protected static function buscarValorCuota($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('cuota', ['cuota.pie', '=', 'venta.pie'])
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
- ->findMany();
- return $results;
- }
- protected static function buscarReajuste($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('pie', ['pie.id', '=', 'venta.pie'])
- ->join('pago', ['pago.id', '=', 'pie.reajuste'])
- ->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
- ->findMany();
- return $results;
- }
- protected static function buscarEscritura($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('escritura', ['escritura.id', '=', 'venta.escritura'])
- ->join('pago', ['pago.id', '=', 'escritura.pago'])
- ->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
- ->findMany();
- return $results;
- }
- protected static function buscarSubsidio($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('subsidio', ['subsidio.id', '=', 'venta.subsidio'])
- ->join('pago', ['pago.id', '=', 'subsidio.pago'])
- ->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
- ->findMany();
- return $results;
- }
- protected static function buscarCredito($query)
- {
- $results = \Model::factory(Venta::class)
- ->select('venta.*')
- ->join('credito', ['credito.id', '=', 'venta.credito'])
- ->join('pago', ['pago.id', '=', 'credito.pago'])
- ->whereRaw("`pago`.`valor` = " . $query . " OR `pago`.`valor` / `pago`.`uf` = " . $query)
- ->findMany();
- return $results;
- }
- protected static function buscarUnidad($query)
- {
- if (is_array($query)) {
- $results = [];
- foreach ($query as $segment) {
- $results = array_merge($results, self::buscarUnidad($segment));
- }
- } else {
- $results = model(Unidad::class)->where('descripcion', $query)->findMany();
- foreach ($results as $i => $u) {
- if ($u->venta()) {
- unset($results[$i]);
- }
- }
- }
- return $results;
- }
-}
-?>
diff --git a/app/Controller/Cierres.php b/app/Controller/Cierres.php
deleted file mode 100644
index 46a76b9..0000000
--- a/app/Controller/Cierres.php
+++ /dev/null
@@ -1,428 +0,0 @@
-select('proyecto.*')
- ->join('estado_proyecto', ['estado.proyecto', '=', 'proyecto.id'], 'estado')
- ->join('tipo_estado_proyecto', ['tipo.id', '=', 'estado.estado'], 'tipo')
- ->join('etapa_proyecto', ['etapa.id', '=', 'tipo.etapa'], 'etapa')
- ->whereGte('etapa.orden', 3)
- ->orderByAsc('proyecto.descripcion')
- ->groupBy('proyecto.id')
- ->findMany();
- $regiones = model(Region::class)->order_by_asc('numeracion')->findMany();
- return view('ventas.cierres.add', compact('proyectos', 'regiones'));
- }
- public static function agregar()
- {
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $id_proyecto = post('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $id_agente = post('agente');
- $agente = model(Agente::class)->findOne($id_agente);
-
- $direccion = model(Direccion::class)
- ->where('calle', post('calle'))
- ->where('numero', post('numero'))
- ->where('extra', post('extra'))
- ->where('comuna', post('comuna'))
- ->findOne();
- if (!$direccion) {
- $data = [
- 'calle' => post('calle'),
- 'numero' => post('numero'),
- 'extra' => post('extra'),
- 'comuna' => post('comuna')
- ];
- $direccion = model(Direccion::class)->create($data);
- $direccion->save();
- }
-
- list($rut, $dv) = explode('-', str_replace('.', '', post('rut')));
- $propietario = model(Propietario::class)->findOne($rut);
- if (!$propietario) {
- $data = [
- 'rut' => $rut,
- 'dv' => $dv,
- 'nombres' => trim(post('nombres')),
- 'apellido_paterno' => post('paterno'),
- 'apellido_materno' => post('materno'),
- 'sexo' => post('sexo'),
- 'estado_civil' => post('estado_civil'),
- 'profesion' => post('profesion'),
- 'direccion' => $direccion->id,
- 'telefono' => post('codigo_telefono') . post('telefono'),
- 'email' => post('email') . '@' . post('email_domain'),
- 'representante' => 0,
- 'otro' => 0
- ];
- $propietario = model(Propietario::class)->create($data);
- $propietario->save();
- }
-
- $unis = json_decode(post('unidades'));
- $id_principal = array_shift($unis);
- $unidad = model(Unidad::class)->findOne(post('unidad' . $id_principal));
- $u = model(U::class)->findOne($unidad->id);
- if (!$u) {
- $unidad->save();
- }
- $data = [
- 'unidad_id' => $unidad->id
- ];
- $reserva = model(Reserva::class)->create($data);
- $reserva->save();
- foreach ($unis as $id_unidad) {
- $unidad = model(Unidad::class)->findOne(post('unidad' . $id_unidad));
- $data = [
- 'reserva_id' => $reserva->id,
- 'unidad_id' => $unidad->id
- ];
- $ur = model(UnidadReserva::class)->create($data);
- $ur->save();
- }
-
- $data = [
- 'proyecto_id' => $proyecto->id,
- 'agente_id' => $agente->id,
- 'propietario_rut' => $propietario->rut,
- 'reserva_id' => $reserva->id,
- 'fecha' => $f->format('Y-m-d'),
- 'valor' => correctNumber(post('valor')),
- 'pie' => correctNumber(post('pie')),
- 'credito' => correctNumber(post('credito')),
- 'estado' => 1
- ];
- $cierre = model(Cierre::class)->create($data);
- $cierre->save();
- header('Location: ' . url('', ['p' => 'cierres', 'a' => 'list']));
- }
- public static function list()
- {
- $proyectos = Cierre::proyectos();
-
- return view('ventas.cierres.list', compact('proyectos'));
- }
- public static function show()
- {
- $id = get('cierre');
- $cierre = model(Cierre::class)->findOne($id);
-
- return view('ventas.cierres.show', compact('cierre'));
- }
- public static function guardar()
- {
- $proyecto = \model(Proyecto::class)->findOne(post('proyecto'));
- $fecha = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $unidad = \model(Unidad::class)->findOne(post('departamento'));
- $relacionado = (post('relacionado') === true) ? true : false;
- $subrelacionado = (post('subrelacionado') === true) ? true : false;
- $precio = (float) post('precio') ?: 0;
- $input = [
- 'proyecto' => $proyecto,
- 'fecha' => $fecha,
- 'departamento' => $unidad,
- 'precio' => $precio,
- 'relacionado' => $relacionado,
- 'subrelacionado' => $subrelacionado,
- 'unidades' => [],
- 'pie' => (float) post('pie')
- ];
- $ebs = 0;
- if (post('unidades') != '') {
- $unidades = json_decode(html_entity_decode(post('unidades')), true);
- foreach ($unidades as $un) {
- $u = \model(Unidad::class)->findOne($un);
- $input['unidades'] []= $u;
- if ($u->precio($fecha) !== false) {
- $ebs += $u->precio($fecha)->valor;
- }
- }
- }
- $promo = 0;
- if (post('promocion') != null) {
- $promo = (float) post('promocion');
- $input['promocion'] = $promo;
- }
- $bono = 0;
- if (post('bono') != null) {
- $bono = (float) post('bono');
- $input['bono'] = $bono;
- }
- $operador = 0;
- if (post('operador') != null) {
- $operador = ($precio - $bono - $promo) * (float) post('operador') / 100;
- $input['operador'] = $operador;
- }
-
- $cierre = Cierre::find($proyecto, $unidad, $precio)->findOne();
- if ($cierre === false) {
- $cierre = model(Cierre::class)->create();
- $cierre->guardar((object) $input);
- }
- $output = ['status' => 'ok', 'cierre' => $cierre->asArray()];
- return json_encode($output);
- }
- public static function aprobar()
- {
- $fecha = Carbon::today(config('app.timezone'));
- $cierre = model(Cierre::class)->findOne(post('cierre'));
- if ($cierre->estado()->tipo()->descripcion == "revisado" or $cierre->estado()->tipo()->descripcion == "rechazado") {
- $cierre->aprobar($fecha);
- return json_encode(['estado' => 'aprobado']);
- }
- return json_encode(['estado' => 'no vigente']);
- }
- public static function rechazar()
- {
- $fecha = Carbon::today(config('app.timezone'));
- $cierre = model(Cierre::class)->findOne(post('cierre'));
- if ($cierre->estado()->tipo()->vigente == 1) {
- $cierre->rechazar($fecha);
- return json_encode(['estado' => 'rechazado']);
- }
- return json_encode(['estado' => 'no vigente']);
- }
- public static function abandonar()
- {
- $id = get('cierre');
- $cierre = model(Cierre::class)->findOne($id);
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'abandonado')->findOne();
- $today = Carbon::today(config('app.timezone'));
- $data = [
- 'cierre' => $cierre->id,
- 'tipo' => $tipo->id,
- 'fecha' => $today->format('Y-m-d')
- ];
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'cierres', 'a' => 'list']));
- }
- public static function promesar()
- {
- $id = get('cierre');
- $cierre = model(Cierre::class)->findOne($id);
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'promesado')->findOne();
- $today = Carbon::today(config('app.timezone'));
- $data = [
- 'cierre' => $cierre->id,
- 'tipo' => $tipo->id,
- 'fecha' => $today->format('Y-m-d')
- ];
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'cierres', 'a' => 'show', 'cierre' => $cierre->id]));
- }
- public static function borrador()
- {
- $id = get('cierre');
- $cierre = model(Cierre::class)->findOne($id);
-
- $borrador = new Borrador($cierre);
- d($borrador->show());
- $borrador->create();
- }
- public static function evalue()
- {
- $proyectos = \model(Proyecto::class)->orderByAsc('descripcion')->findMany();
- return view('ventas.cierres.evaluar', ['proyectos' => $proyectos, 'locations' => config('locations')]);
- }
- public static function evaluar()
- {
- $proyecto = \model(Proyecto::class)->findOne(post('proyecto'));
- $fecha = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $unidad = \model(Unidad::class)->findOne(post('departamento'));
- $relacionado = (post('relacionado') === 'true') ? true : false;
- $subrelacionado = (post('subrelacionado') === 'true') ? true : false;
- $precio = (float) post('precio') ?: 0;
- $neto = $precio;
- $ebs = 0;
- if (post('unidades') != '') {
- $unidades = json_decode(html_entity_decode(post('unidades')), true);
- foreach ($unidades as $un) {
- $u = \model(Unidad::class)->findOne($un);
- if ($u->precio($fecha) !== false) {
- $ebs += $u->precio($fecha)->valor;
- }
- }
- }
- $promocion = 0;
- if (post('promocion') != null) {
- $promocion = (float) post('promocion');
- }
- $bono = 0;
- if (post('bono') != null) {
- $bono = (float) post('bono');
- }
- $operador = 0;
- if (post('operador') != null) {
- $operador = ($precio - $bono - $promocion) * (float) post('operador') / 100;
- }
- $rel = 0;
- if ($relacionado) {
- $rel = ($unidad->precio($fecha)->valor) * 6 / 100;
- }
- if ($subrelacionado) {
- $rel = ($unidad->precio($fecha)->valor) * 3 / 100;
- }
- $neto = $precio - $bono - $promocion - $operador - $ebs;
-
- $output = [
- 'unidad' => [
- 'tipo' => [
- 'nombre' => $unidad->tipologia()->nombre,
- 'tipologia' => $unidad->tipologia()->tipologia()->descripcion
- ],
- 'superficie' => format('m2', $unidad->m2()) . ' m²'
- ],
- 'oferta' => [
- 'bruto' => format('ufs', $precio, null, true),
- 'neto' => format('ufs', $neto, null, true),
- 'uf_m2' => format('ufs', $neto / $unidad->m2('vendible'), null, true) . '/m²',
- 'fecha' => format('shortDate', $unidad->precio($fecha)->inicio()->fecha())
- ],
- 'lista' => [
- 'precio' => format('ufs', $unidad->precio($fecha)->valor, null, true),
- 'uf_m2' => format('ufs', $unidad->precio($fecha)->valor / $unidad->m2('vendible'), null, true) . '/m²'
- ],
- 'precios' => [
- 'bruto' => format('ufs', $precio, null, true),
- 'neto' => format('ufs', $neto, null, true),
- 'departamento' => format('ufs', $unidad->precio($fecha)->valor, null, true),
- 'relacionado' => format('ufs', $unidad->precio($fecha)->valor - $rel, null, true),
- 'fecha' => format('shortDate', $unidad->precio($fecha)->inicio()->fecha())
- ],
- 'uf_m2' => [
- 'neto' => format('ufs', $neto / $unidad->m2('vendible'), null, true) . '/m²',
- 'departamento' => format('ufs', $unidad->precio($fecha)->valor / $unidad->m2('vendible'), null, true) . '/m²',
- 'relacionado' => format('ufs', ($unidad->precio($fecha)->valor - $rel) / $unidad->m2('vendible'), null, true) . '/²'
- ],
- 'evaluacion' => Cierre::evaluar($neto, $unidad, $fecha, $rel),
- 'estado' => ['id' => 0, 'descripcion' => 'no existe']
- ];
- if ($rel > 0) {
- $output ['relacionado'] = [
- 'precio' => format('ufs', $unidad->precio($fecha)->valor - $rel, null, true),
- 'uf_m2' => format('ufs', ($unidad->precio($fecha)->valor - $rel) / $unidad->m2('vendible'), null, true) . '/²'
- ];
- }
- $estado = Cierre::find($proyecto, $unidad, $precio)->findOne();
- if ($estado) {
- $output['estado'] = [
- 'id' => $estado->estado()->tipo()->id,
- 'cierre' => $estado->id,
- 'descripcion' => $estado->estado()->tipo()->descripcion,
- 'fecha' => format('shortDate', $estado->estado()->fecha)
- ];
- }
-
- return json_encode($output);
- }
- public static function edit()
- {
- $cierre = model(Cierre::class)->findOne(get('cierre'));
- $proyectos = model(Proyecto::class)->findMany();
- $regiones = model(Region::class)->findMany();
- $valores = model(TipoValorCierre::class)->findMany();
- return view('ventas.cierres.edit', compact('cierre', 'proyectos', 'regiones', 'valores'));
- }
- public static function do_edit()
- {
- $cierre = model(Cierre::class)->findOne(get('cierre'));
-
- $data = [
- 'calle' => post('calle'),
- 'numero' => post('numero'),
- 'extra' => post('extra'),
- 'comuna' => post('comuna')
- ];
- $direccion = (new Factory(Direccion::class))->where($data)->find();
- if (!$direccion) {
- $direccion = model(Direccion::class)->create($data);
- $direccion->save();
- }
- if (post('rut') != '') {
- $data = [
- 'rut' => explode('-', str_replace('.', '', post('rut')))[0],
- ];
- $propietario = (new Factory(Propietario::class))->where($data)->find();
- if (!$propietario) {
- $data = array_merge($data, [
- 'nombres' => post('nombres'),
- 'apellido_paterno' => post('paterno'),
- 'apellido_materno' => post('materno'),
- 'dv' => (post('rut')) ? explode('-', str_replace('.', '', post('rut')))[1] : '',
- 'sexo' => post('sexo'),
- 'estado_civil' => post('estado_civil'),
- 'profesion' => post('profesion'),
- 'telefono' => post('codigo_telefono') . post('telefono'),
- 'email' => post('email') . '@' . post('email_domain'),
- 'direccion' => $direccion->id
- ]);
- $propietario = model(Propietario::class)->create($data);
- $propietario->save();
- }
- }
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $data = [
- 'proyecto' => post('proyecto'),
- 'precio' => post('precio'),
- 'fecha' => $f->format('Y-m-d'),
- 'relacionado' => (post('relacionado')) ? 1 : 0,
- 'propietario' => (isset($propietario) and $propietario) ? $propietario->rut : 0
- ];
- foreach ($data as $field => $value) {
- if ($value != $cierre->$field) {
- $cierre->$field = $value;
- }
- }
- $cierre->save();
-
- $valores = model(TipoValorCierre::class)->findMany();
- foreach ($valores as $valor) {
- if (post($valor->descripcion) == '') {
- continue;
- }
- if ($cierre->valor($valor->descripcion)) {
- if ($cierre->valor($valor->descripcion)->valor != post($valor->descripcion)) {
- $v = $cierre->valor($valor->descripcion);
- $v->valor = post($valor->descripcion);
- $v->save();
- }
- continue;
- }
- $data = [
- 'tipo' => $valor->descripcion,
- 'valor' => post($valor->descripcion)
- ];
- $cierre->addValor($data);
- }
- header('Location: ' . nUrl('cierres', 'show', ['cierre' => $cierre->id]));
- }
-}
-?>
diff --git a/app/Controller/Comentarios.php b/app/Controller/Comentarios.php
deleted file mode 100644
index 494fcc6..0000000
--- a/app/Controller/Comentarios.php
+++ /dev/null
@@ -1,39 +0,0 @@
-findOne(get('venta'));
- echo view('ventas.comentarios.add', compact('venta'));
- }
- public static function agregar()
- {
- $venta = \Model::factory(\Incoviba\old\Venta\Venta::class)->findOne(get('venta'));
- if ($venta === false) {
- throw new Exception('Venta no existe.');
- }
- $data = [
- 'venta' => $venta->id,
- 'fecha' => \Carbon\Carbon::now(config('app.timezone'))->format('Y-m-d H:i:s'),
- 'texto' => post('comentario')
- ];
- $comentario = \Model::factory(\Incoviba\old\Venta\Comentario::class)->create($data);
- $comentario->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
- public static function delete()
- {
- $comentario = \Model::factory(\Incoviba\old\Venta\Comentario::class)->findOne(get('comentario'));
- $venta = $comentario->venta();
- $comentario->estado = 0;
- $comentario->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
-}
-?>
diff --git a/app/Controller/Contabilidad.php b/app/Controller/Contabilidad.php
deleted file mode 100644
index 4b19a77..0000000
--- a/app/Controller/Contabilidad.php
+++ /dev/null
@@ -1,100 +0,0 @@
-orderByAsc('descripcion')->findMany();
- foreach ($proyectos as &$proyecto) {
- $arr = $proyecto->asArray();
- $arr['direccion'] = $proyecto->direccion()->asArray();
- $arr['direccion']['comuna'] = $proyecto->direccion()->comuna()->asArray();
- $arr['inmobiliaria'] = $proyecto->inmobiliaria()->asArray();
- $proyecto = $arr;
- }
- return json_encode(compact('proyectos'));
- }
- public static function get_fechas() {
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $cuotas = [];
- foreach ($proyecto->ventas() as $venta) {
- $cs = $venta->pie()->cuotas();
- $cuotas = array_merge($cs, array_filter($cs, function($item) {
- $tipo = $item->pago()->estado()->tipo();
- return ($tipo == 'depositado' or $tipo == 'abonado');
- }));
- }
- $fechas = array_map(function($item) {
- return [
- 'timestamp' => $item->pago()->estado()->fecha()->timestamp,
- 'short' => $item->pago()->estado()->fecha()->format('Y-m-d'),
- 'long' => $item->pago()->estado()->fecha()->format('d / m / Y')
- ];
- }, $cuotas);
- usort($fechas, function($a, $b) {
- return $b['timestamp'] - $a['timestamp'];
- });
- return json_encode(compact('fechas'));
- }
- public static function get_pagos_fechas() {
- $id_proyecto = get('proyecto');
- $fecha = Carbon::parse(get('fecha'));
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $pagos = [];
- foreach ($proyecto->ventas() as $venta) {
- foreach ($venta->pie()->cuotas() as $cuota) {
- if ($cuota->pago()->estado()->fecha() == $fecha) {
- $pagos []= [
- 'Departamento' => $venta->propiedad()->unidad()->descripcion,
- 'Valor' => [
- 'UF' => $cuota->pago()->valor('ufs'),
- 'Pesos' => $cuota->pago()->valor()
- ],
- 'Numero' => $cuota->numero(),
- 'Total' => $venta->pie()->cuotas
- ];
- break;
- }
- }
- }
- return json_encode(compact('pagos'));
- }
- public static function pagos_fecha() {
- $fecha = Carbon::now();
- return view('contabilidad.pagos', compact('fecha'));
- }
- public static function show_pagos() {
- $id_proyecto = get('proyecto');
- $fecha = Carbon::parse(get('fecha'));
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $pagos = [];
- foreach ($proyecto->ventas() as $venta) {
- foreach ($venta->pie()->cuotas() as $cuota) {
- if ($cuota->pago()->estado()->fecha() == $fecha) {
- $pagos []= (object) [
- 'Departamento' => $venta->propiedad()->unidad()->descripcion,
- 'Valor' => (object) [
- 'UF' => $cuota->pago()->valor('ufs'),
- 'Pesos' => $cuota->pago()->valor()
- ],
- 'Numero' => $cuota->numero(),
- 'Total' => $venta->pie()->cuotas
- ];
- break;
- }
- }
- }
- return view('contabilidad.pago', compact('proyecto', 'fecha', 'pagos'));
- }
-}
diff --git a/app/Controller/Creditos.php b/app/Controller/Creditos.php
deleted file mode 100644
index 60a72da..0000000
--- a/app/Controller/Creditos.php
+++ /dev/null
@@ -1,207 +0,0 @@
-findOne($id);
- return view('ventas.creditos.add', compact('venta'));
- }
- public static function agregado()
- {
- $id = get('venta');
- if ($id == null) {
- header('Location: .');
- }
- $venta = \Model::factory(Venta::class)->findOne($id);
-
- $banco = \Model::factory(Banco::class)->where('nombre', post('banco'))->findOne();
- $f = Carbon::createFromDate(post('y'), post('m'), post('d'), config('app.timezone'));
- $uf = uf($f);
-
- $pago = \Model::factory(Pago::class)->create();
- $pago->banco = $banco->id;
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = $uf->uf->value;
- $pago->valor = post('valor') * $pago->uf;
- $pago->tipo = 2;
-
- $credito = \Model::factory(Credito::class)->create();
- $credito->banco = $pago->banco;
- $credito->valor = $pago->valor;
- $credito->fecha = $pago->fecha;
- $credito->uf = $pago->uf;
-
- $pago->new();
-
- $credito->pago = $pago->id;
- $credito->save();
-
- $venta->credito = $credito->id;
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function pagar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- return view('ventas.creditos.pagar', compact('venta'));
- }
- public static function pagando()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- $valor = str_replace(',', '.', str_replace('.', '', post('valor')));
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $pago = $venta->credito()->pago();
- if ($pago->valor != $valor) {
- $pago->valor = $valor;
- }
-
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $pago->id;
- $estado->fecha = $f->format('Y-m-d');
- $estado->estado = 1;
- $estado->save();
-
- if ($pago->is_dirty('valor')) {
- $pago->save();
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function abonar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- return view('ventas.creditos.abonar', compact('venta'));
- }
- public static function abonando()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- $valor = str_replace(',', '.', str_replace('.', '', post('valor')));
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $pago = $venta->credito()->pago();
- if ($pago->valor != $valor) {
- $pago->valor = $valor;
- }
-
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $pago->id;
- $estado->fecha = $f->format('Y-m-d');
- $estado->estado = 2;
-
- $estado->save();
-
- if ($pago->is_dirty('valor')) {
- $pago->save();
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function show()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.creditos.show', compact('venta'));
- }
- public static function edit()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.creditos.edit', compact('venta'));
- }
- public static function editado()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $pago = $venta->credito()->pago();
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
- $banco = model(Banco::class)->where('nombre', post('banco'))->findOne();
- $valor = correctNumber(post('valor')) * $uf->uf->value;
-
- $fields = ['valor', 'uf', 'fecha', 'banco'];
- $data = ['valor' => $valor, 'uf' => $uf->uf->value, 'fecha' => $f->format('Y-m-d'), 'banco' => $banco->id];
-
- $change = false;
- foreach ($fields as $field) {
- if ($pago->$field != $data[$field]) {
- $change = true;
- $pago->$field = $data[$field];
- if ($field == 'fecha') {
- $eps = $pago->estados();
- foreach ($eps as $ep) {
- if ($ep->estado == 0) {
- $ep->fecha = $data[$field];
- $ep->save();
- break;
- }
- }
- }
- }
- }
-
- if ($change) {
- $pago->save();
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function remove()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $pago = $venta->credito()->pago();
- $f = Carbon::today(config('app.timezone'));
-
- $data = [
- 'pago' => $pago->id,
- 'estado' => -3,
- 'fecha' => $f->format('Y-m-d')
- ];
- $estado = model(EstadoPago::class)->create($data);
- $estado->save();
- $venta->credito = 0;
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function pendientes()
- {
- $creditos = model(Credito::class)
- ->select('credito.*')
- ->join('venta', ['venta.credito', '=', 'credito.id'])
- ->join('pago', ['pago.id', '=', 'credito.pago'])
- ->rawJoin('JOIN (SELECT ep.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago ep ON ep.id = e0.id)', ['estado_pago.pago', '=', 'pago.id'], 'estado_pago')
- ->whereLt('estado_pago.estado', 2)
- ->where('venta.estado', 1)
- ->orderByAsc('estado_pago.fecha')
- ->findMany();
- return view('ventas.creditos.pendientes', compact('creditos'));
- }
-}
-?>
diff --git a/app/Controller/Cuotas.php b/app/Controller/Cuotas.php
deleted file mode 100644
index 4d457ba..0000000
--- a/app/Controller/Cuotas.php
+++ /dev/null
@@ -1,230 +0,0 @@
-findOne($id);
-
- return view('ventas.pies.cuotas.show', compact('cuota'));
- }
- public static function edit()
- {
- $id = get('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
- return view('ventas.pies.cuotas.edit', compact('cuota'));
- }
- public static function editar()
- {
- $id = get('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
-
- $cuota->numero = post('numero');
- $cuota->{'valor_$'} = post('valor');
- $banco = \Model::factory(\Incoviba\old\Common\Banco::class)->where('nombre', post('banco'))->findOne();
- if ($banco) {
- $cuota->banco = $banco->id;
- } else {
- $cuota->banco = 0;
- }
- $f = \Carbon\Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $cuota->fecha = $f->format('Y-m-d');
- $pago = $cuota->pago();
- $pago->valor = post('valor');
- $pago->banco = $banco->id;
- $pago->identificador = post('identificador');
- $pago->fecha = $f->format('Y-m-d');
- $uf = uf($f);
- if ($uf->total > 0) {
- $pago->uf = $uf->uf->value;
- } else {
- $pago->uf = 0;
- }
-
- $pago->save();
- $cuota->save();
- header('Location: ' . url('', ['p' => 'pies', 'a' => 'resumen', 'pie' => $cuota->pie()->id]));
- }
- public static function edited()
- {
- $id = get('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
- $pago = $cuota->pago();
- foreach ($_POST as $key => $value) {
- $pago->$key = $value;
- }
- $pago->save();
- }
- public static function pendientes()
- {
- $f = \Carbon\Carbon::today(config('app.timezone'));
- $cuotas = \Model::factory(Cuota::class)
- ->select('cuota.*')
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->join('venta', ['venta.pie', '=', 'cuota.pie'])
- ->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->where('ep.estado', 0)
- ->where('venta.estado', 1)
- ->whereLte('pago.fecha', $f->format('Y-m-d'))
- ->order_by_asc('pago.fecha')
- ->findMany();
- $sum = 0;
- if (count($cuotas) > 0) {
- $sum = array_reduce($cuotas, function($carry, $item) {
- $carry += $item->pago()->valor;
- return $carry;
- });
- }
- setlocale(LC_TIME, 'es');
- return view('ventas.pies.cuotas.pendientes', compact('cuotas', 'sum'));
- }
- public static function depositar()
- {
- $id = post('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
- if ($cuota->pago()->estado()->estado == 1) {
- return 'ok';
- }
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $cuota->pago()->id;
- $estado->estado = 1;
- $f = Carbon::parse(post('fecha'), config('app.timezone'));
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
- return 'ok';
- }
- public static function remove()
- {
- $id = get('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
-
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $cuota->pago()->id;
- $estado->estado = -3;
- $f = Carbon::today(config('app.timezone'));
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
- header('Location: ' . url('', ['p' => 'pies', 'a' => 'resumen', 'pie' => $cuota->pie()->id]));
- }
- public static function para_abonar()
- {
- $cuotas = \Model::factory(Cuota::class)
- ->select('cuota.*')
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->join('venta', ['venta.pie', '=', 'cuota.pie'])
- ->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->where('ep.estado', 1)
- ->where('venta.estado', 1)
- ->order_by_asc('ep.fecha')
- ->findMany();
- $ini = get('start');
- if ($ini == null) {
- $ini = 0;
- }
- $n = get('step');
- if ($n == 0) {
- $n = 30;
- }
- $total = count($cuotas);
- $cuotas = array_slice($cuotas, $ini, $n);
- $pages = ceil($total / $n);
- $current = ($ini + $n) / $n;
- return view('ventas.pies.cuotas.abonar', compact('cuotas', 'total', 'pages', 'current'));
- }
- public static function abonar()
- {
- $id = post('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
- if ($cuota->pago()->estado()->estado == 2) {
- return 'ok';
- }
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $cuota->pago()->id;
- $estado->estado = 2;
- $f = Carbon::parse(post('fecha'), config('app.timezone'));
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
- return 'ok';
- }
- public static function rebotar()
- {
- $id = post('cuota');
- $cuota = \Model::factory(Cuota::class)->findOne($id);
- if ($cuota->pago()->estado()->estado == -1) {
- return 'ok';
- }
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $cuota->pago()->id;
- $estado->estado = -1;
- $f = Carbon::parse(post('fecha'), config('app.timezone'));
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
- return 'ok';
- }
- public static function add()
- {
- $id = get('pie');
- $pie = \Model::factory(Pie::class)->findOne($id);
- return view('ventas.pies.cuotas.add', compact('pie'));
- }
- public static function agregar()
- {
- $id = get('pie');
- $pie = \Model::factory(Pie::class)->findOne($id);
-
- $cant = $pie->cuotas - count($pie->cuotas());
- for ($i = 0; $i < $cant; $i ++) {
- if (trim(post('valor' . $i)) == '') {
- continue;
- }
- $banco = \Model::factory(Banco::class)->where('nombre', post('banco' . $i))->findOne();
- $f = Carbon::createFromDate(post('year' . $i), post('month' . $i), post('day' . $i), config('app.timezone'));
- $uf = uf($f);
- $valor = correctNumber(post('valor' . $i));
-
- $pago = \Model::factory(Pago::class)->create();
- $pago->banco = $banco->id;
- $pago->fecha = $f->format('Y-m-d');
- if ($uf and $uf->total > 0) {
- $pago->uf = $uf->uf->value;
- } else {
- $pago->uf = 0;
- }
- $pago->tipo = 1;
- $pago->valor = $valor;
- $pago->identificador = post('identificador' . $i);
-
- $cuota = \Model::factory(Cuota::class)->create();
- $cuota->pie = $pie->id;
- $cuota->fecha = $pago->fecha;
- $cuota->{'valor_$'} = $pago->valor;
- $cuota->estado = 0;
- $cuota->banco = $pago->banco;
- $cuota->uf = $pago->uf;
- $cuota->numero = post('numero' . $i);
-
- $pago->new();
-
- $cuota->pago = $pago->id;
- $cuota->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $pie->venta()->id]));
- }
- }
-}
-?>
diff --git a/app/Controller/Devoluciones.php b/app/Controller/Devoluciones.php
deleted file mode 100644
index 8d9c41c..0000000
--- a/app/Controller/Devoluciones.php
+++ /dev/null
@@ -1,19 +0,0 @@
-findOne($id);
-
- return view('print.devolucion', compact('venta'));
- }
-}
-?>
diff --git a/app/Controller/Escrituras.php b/app/Controller/Escrituras.php
deleted file mode 100644
index f2cb056..0000000
--- a/app/Controller/Escrituras.php
+++ /dev/null
@@ -1,212 +0,0 @@
-findOne($id);
- return view('ventas.escrituras.add', compact('venta'));
- }
- public static function agregar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('escritura_year'), post('escritura_month'), post('escritura_day'), config('app.timezone'));
- $venta->escriturado = $f->format('Y-m-d');
-
- if (post('valor_reajuste')) {
- $reajuste = \Model::factory(Pago::class)->create();
- $reajuste->valor = correctNumber(post('valor_reajuste'));
- $fp = Carbon::createFromDate(post('reajuste_year'), post('reajuste_month'), post('reajuste_day'), config('app.timezone'));
- $reajuste->fecha = $fp->format('Y-m-d');
- $reajuste->uf = (float) uf($fp)->uf->value;
- $reajuste->newPagado();
-
- $pie = $venta->pie();
- $pie->reajuste = $reajuste->id;
- $pie->save();
- }
- if (post('escritura_valor') or post('escritura_valor_uf')) {
- $pago = \Model::factory(Pago::class)->create();
- $fp = Carbon::createFromDate(post('pago_escritura_year'), post('pago_escritura_month'), post('pago_escritura_day'), config('app.timezone'));
- $pago->fecha = $fp->format('Y-m-d');
- $pago->uf = (float) uf($fp)->uf->value;
- if (post('escritura_valor')) {
- $pago->valor = correctNumber(post('escritura_valor'));
- $pago->newPagado();
- } else {
- $pago->valor = correctNumber(post('escritura_valor_uf')) * $pago->uf;
- $pago->new();
- }
-
- $escritura = \Model::factory(Escritura::class)->create();
- $escritura->pago = $pago->id;
- $escritura->valor = $pago->valor('uf');
- $escritura->fecha = $pago->fecha;
- $escritura->save();
-
- $venta->escritura = $escritura->id;
- }
- if (post('subsidio_ahorrado') or post('subsidio_valor')) {
- $total = post('subsidio_ahorrado') + post('subsidio_valor');
- $subsidio = \Model::factory(Subsidio::class)->create();
- $pago = \Model::factory(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = (float) uf($f)->uf->value;
- $pago->valor = correctNumber(post('subsidio_ahorrado')) * $pago->uf;
- $pago->new();
- $subsidio->pago = $pago->id;
- $pago = \Model::factory(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = (float) uf($f)->uf->value;
- $pago->valor = correctNumber(post('subsidio_valor')) * $pago->uf;
- $pago->new();
- $subsidio->subsidio = $pago->id;
- $subsidio->save();
-
- $venta->subsidio = $subsidio->id;
- }
- if (post('credito_valor')) {
- $pago = \Model::factory(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = (float) uf($f)->uf->value;
- $valor = post('credito_valor');
- if (strpos($valor, ',') !== false) {
- $valor = correctNumber($valor);
- }
- $pago->valor = $valor * $pago->uf;
- $banco = \Model::factory(Banco::class)->where('nombre', post('credito_banco'))->findOne();
- $pago->banco = $banco->id;
- $pago->new();
-
- $credito = \Model::factory(Credito::class)->create();
- $credito->pago = $pago->id;
- $credito->save();
-
- $venta->credito = $credito->id;
- } elseif (post('credito_banco')) {
- $pago = $venta->credito()->pago();
- $banco = \Model::factory(Banco::class)->where('nombre', post('credito_banco'))->findOne();
- $pago->banco = $banco->id;
- $pago->save();
- }
-
- $tipo = \Model::factory(TipoEstadoVenta::class)->where('descripcion', 'escriturando')->findOne();
- $data = [
- 'venta' => $venta->id,
- 'estado' => $tipo->id,
- 'fecha' => $venta->escriturado
- ];
- $estado = \Model::factory(EstadoVenta::class)->create($data);
- $estado->save();
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function edit()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- echo view('ventas.escrituras.edit', compact('venta'));
- }
- public static function editar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
-
- $valor = correctNumber(post('valor'));
- if ($valor == '') {
- $valor_uf = correctNumber(post('valor_uf'));
- $valor = $valor_uf * $uf->uf->value;
- }
- $pago = $venta->escritura()->pago();
- if ($pago->valor != $valor) {
- $pago->valor = $valor;
- }
- if ($pago->fecha != $f->format('Y-m-d')) {
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = $uf->uf->value;
- }
-
- $pago->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function informe()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- return view('ventas.escrituras.informe', compact('venta'));
- }
- public static function pagar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.escrituras.pagar', compact('venta'));
- }
- public static function pagado()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $data = [
- 'pago' => $venta->escritura()->pago()->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => 1
- ];
- $estado = model(EstadoPago::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function abonar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.escrituras.abonar', compact('venta'));
- }
- public static function abonado()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $data = [
- 'pago' => $venta->escritura()->pago()->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => 2
- ];
- $estado = model(EstadoPago::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
-}
-?>
diff --git a/app/Controller/FormaPago.php b/app/Controller/FormaPago.php
deleted file mode 100644
index 6ccc7b3..0000000
--- a/app/Controller/FormaPago.php
+++ /dev/null
@@ -1,98 +0,0 @@
-findOne($id);
-
- return view('ventas.forma_pago.edit', compact('venta'));
- }
- public static function editar()
- {
- d(post());
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $valor = correctNumber(post('valor_pie'));
- $cuotas = post('cuotas_pie');
- if ($venta->pie != 0) {
- $pie = $venta->pie();
- $changed = false;
- if ($pie->valor != $valor) {
- $pie->valor = $valor;
- $changed = true;
- }
- if ($pie->cuotas != $cuotas) {
- $pie->cuotas = $cuotas;
- $changed = true;
- }
- if ($changed) {
- d($pie);
- }
-
- $valor = correctNumber(post('valor_reajuste'));
- $f = Carbon::createFromDate(post('year_reajuste'), post('month_reajuste'), post('day_reajuste'), config('app.timezone'));
- $uf = uf($f);
- $reajuste = $pie->reajuste();
- $changed = false;
- if ($reajuste->valor != $valor) {
- $reajuste->valor = $valor;
- $changed = true;
- }
- if ($reajuste->fecha != $f->format('Y-m-d')) {
- $reajuste->fecha = $f->format('Y-m-d');
- $reajuste->uf = $uf->uf->value;
- $changed = true;
- }
- if ($changed) {
- d($reajuste);
- }
- } elseif ($valor != '') {
- $f = Carbon::parse($venta->fecha, config('app.timezone'));
- $uf = uf($f);
- $data = [
- 'valor' => $valor,
- 'cuotas' => $cuotas,
- 'uf' => $uf->uf->value,
- 'fecha' => $f->format('Y-m-d')
- ];
- $pie = model(Pie::class)->create($data);
- d($pie);
- }
-
- $valor = correctNumber(post('valor_escritura'));
- $f = Carbon::createFromDate(post('year_escritura'), post('month_escritura'), post('day_escritura'), config('app.timezone'));
- if ($venta->escritura != 0) {
- $escritura = $venta->escritura();
- d($escritura);
- } elseif ($valor != '') {
- $data = [
- 'valor' => $valor,
- 'fecha' => $f->format('Y-m-d'),
- 'uf' => $uf->uf->value,
- 'tipo' => 7
- ];
- $pago = model(Pago::class)->create($data);
- $pago->newPagado();
- $data['pago'] = $pago->id;
- unset($data['tipo']);
- $escritura = model(Escritura::class)->create($data);
- $escritura->save();
- $venta->escritura = $escritura->id;
- $venta->save();
- }
- }
-}
-?>
diff --git a/app/Controller/Informes.php b/app/Controller/Informes.php
deleted file mode 100644
index bc40396..0000000
--- a/app/Controller/Informes.php
+++ /dev/null
@@ -1,832 +0,0 @@
-find_one($id_proyecto);
- $ini = \Carbon\Carbon::parse($proyecto->estado()->fecha, config('app.timezone'));
- #$informe = new Informador('Carta Gantt Proyecto - ' . $proyecto->descripcion);
- $name = 'Carta Gantt Proyecto - ' . $proyecto->descripcion;
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $hoy->format('Y-m-d') . '.xls');
- $informe = new PHPExcel($name, $filename);
-
- $columnas = ['Departamento', 'Propietario', 'Entrega', 'Estado'];
- $today = \Carbon\Carbon::today(config('app.timezone'));
- $end = $today->copy()->addDays(30);
- $dif = $end->diffInDays($ini);
- for ($i = 0; $i <= $dif; $i ++) {
- $f = $ini->copy()->addDays($i);
- if ($f->isWeekend()) {
- continue;
- }
- $columnas []= $f->format('Y-m-d');
- }
- $informe->addColumns($columnas);
-
- $data = [];
- foreach ($proyecto->entregas() as $venta) {
- $info = [];
- $info []= $venta->unidad()->descripcion;
- $info []= $venta->propietario()->findOne()->nombreCompleto();
- $fe = Carbon::parse($venta->entrega()->find_one()->fecha, config('app.timezone'));
- $info []= $fe->format('Y-m-d');
- $info []= '';
-
- for ($i = 0; $i <= $dif; $i ++) {
- $f = $ini->copy()->addDays($i);
- if ($f->isWeekend()) {
- continue;
- }
- if ($f >= $fe and $f <= $fe->copy()->addDays(14)) {
- $info []= 'X';
- } else {
- $info []= '';
- }
- }
-
- $data []= $info;
- }
- $informe->addDatas($data);
-
- return $informe->informe();
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.gantt_entregas', compact('proyectos'));
- }
- }
- public static function escrituras()
- {
- if (get('proyecto')) {
- set_time_limit(60);
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->find_one($id_proyecto);
-
- #$informe = new Informador('Escrituras - ' . $proyecto->descripcion);
- $name = 'Escrituras';
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $proyecto->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xls');
- $informe = new PHPExcel($name, $filename);
-
- $columnas = [
- 'Departamento',
- 'Estacionamientos',
- 'Bodegas',
- 'Propietario',
- (object) ['name' => 'Promesa', 'style' => 'number'],
- ['name' => 'Bono Pie', 'style' => 'amount'],
- ['name' => 'Pie Pagado', 'style' => 'amount'],
- ['name' => 'Reajuste', 'style' => 'amount'],
- ['name' => 'Abono Contado', 'style' => 'amount'],
- ['name' => 'Subsidio', 'style' => 'amount'],
- 'Estado Subsidio',
- ['name' => 'Credito', 'style' => 'amount'],
- 'Banco',
- 'Estado Credito',
- ['name' => 'Saldo', 'style' => 'amount'],
- ['name' => 'Escritura', 'style' => 'amount'],
- ['name' => 'Entrega', 'style' => 'date']
- ];
- $informe->addColumns($columnas);
-
- //$ventas = $proyecto->escrituras();
- $ventas = $proyecto->ventas();
-
- $data = [];
- foreach ($ventas as $venta) {
- $info = [];
- $info['Departamento'] = $venta->unidad()->descripcion;
- $ests = [];
- foreach ($venta->propiedad()->estacionamientos() as $e) {
- $ests []= $e->descripcion;
- }
- $bods = [];
- foreach ($venta->propiedad()->bodegas() as $b) {
- $bods []= $b->descripcion;
- }
- $info['Estacionamientos'] = implode(' - ', $ests);
- $info['Bodegas'] = implode(' - ', $bods);
- $info['Propietario'] = $venta->propietario()->nombreCompleto();
- $info['Promesa'] = $venta->valor_uf;
- $saldo = $venta->valor_uf;
- $info['Bono Pie'] = '';
- if ($venta->bono_pie != 0) {
- $info['Bono Pie'] = $venta->bonoPie()->pago()->valor('ufs');
- $saldo -= $venta->bonoPie()->pago()->valor('ufs');
- }
- $info['Pie'] = '';
- $info['Reajuste'] = '';
- if ($venta->pie != 0) {
- $info['Pie'] = $venta->pie()->valorPagado();
- $saldo -= $venta->pie()->valorPagado();
- if ($venta->pie()->reajuste != 0) {
- $info['Reajuste'] = $venta->pie()->reajuste()->valor('ufs');
- $saldo -= $venta->pie()->reajuste()->valor('ufs');
- }
- }
- $info['Abono Contado'] = '';
- if ($venta->escritura != 0) {
- $info['Abono Contado'] = $venta->escritura()->pago()->valor('ufs');
- $saldo -= $venta->escritura()->pago()->valor('ufs');
- }
- $info['Subsidio'] = '';
- $info['Estado Subsidio'] = '';
- if ($venta->subsidio != 0) {
- $info['Subsidio'] = $venta->subsidio()->total('ufs');
- $info['Estado Subsidio'] = implode(' - ', [
- $venta->subsidio()->subsidio()->estado()->tipo()->descripcion,
- $venta->subsidio()->pago()->estado()->tipo()->descripcion
- ]);
- $saldo -= $venta->subsidio()->total('ufs');
- }
- $info['Credito'] = '';
- $info['Banco'] = '';
- $info['Estado Credito'] = '';
- if ($venta->credito != 0) {
- $info['Credito'] = $venta->credito()->pago()->valor('ufs');
- $saldo -= $venta->credito()->pago()->valor('ufs');
- if ($venta->credito()->pago()->banco != 0) {
- $info['Banco'] = $venta->credito()->pago()->banco()->nombre;
- }
- $info['Estado Credito'] = $venta->credito()->pago()->estado()->tipo()->descripcion;
- }
- $info['Saldo'] = -$saldo;
- $info['Escritura'] = '';
- if ($venta->escriturado != 0) {
- $info['Escritura'] = $venta->escriturado;
- }
- $info['Entrega'] = '';
- if ($venta->entregado != 0) {
- $info['Entrega'] = $venta->entregado;
- }
-
- $data []= $info;
- }
- $informe->addData($data);
-
- return $informe->informe();
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.escrituras', compact('proyectos'));
- }
- }
- public static function consolidacion()
- {
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
-
- $ventas = $proyecto->ventas();
- set_time_limit(count($ventas));
-
- $f = Carbon::today(config('app.timezone'));
- setlocale(LC_TIME, 'es');
-
- $data = [
- [$proyecto->descripcion],
- [strftime('%d de %B de %Y', $f->timestamp)],
- [''],
- ['']
- ];
- $columns = [
- ['name' => 'Fecha', 'style' => 'date'],
- 'Glosa',
- ['name' => 'Debe', 'style' => 'number'],
- ['name' => 'Haber', 'style' => 'number'],
- ['name' => 'Saldo', 'style' => 'number'],
- 'Comentario'
- ];
- $bold_rows = [];
-
- foreach ($ventas as $venta) {
- $data []= ['Departamento ' . $venta->unidad()->descripcion . ' (' . format('ufs', $venta->valor_uf) . ' UF)'];
- $data []= $columns;
- $bold_rows []= count($data) - 1;
- $ufs = 0;
- $debe = 0;
- $haber = 0;
- $sum = 0;
- if ($venta->pie != 0) {
- $cuotas = $venta->pie()->cuotas();
- foreach ($cuotas as $cuota) {
- $sum += $cuota->pago()->valor();
- $ufs += $cuota->pago()->valor('ufs');
- $haber += $cuota->pago()->valor();
- $info = [
- $cuota->pago()->estado()->fecha,
- 'Pie - Cuota ' . $cuota->numero() . ' - ' . $venta->pie()->cuotas . ' (' . format('ufs', $cuota->pago()->valor('ufs')) . ' UF)',
- '',
- $cuota->pago()->valor(),
- $sum
- ];
- if ($cuota->pago()->estado()->estado < 2) {
- $info []= 'No ha sido abonada.';
- }
- $data []= $info;
- }
- if ($venta->pie()->reajuste != 0) {
- $sum += $venta->pie()->reajuste()->valor();
- $ufs += $venta->pie()->reajuste()->valor('ufs');
- $haber += $venta->pie()->reajuste()->valor();
- $info = [
- $venta->pie()->reajuste()->estado()->fecha,
- 'Reajuste (' . format('ufs', $venta->pie()->reajuste()->valor('ufs')) . ' UF)',
- '',
- $venta->pie()->reajuste()->valor(),
- $sum
- ];
- if ($venta->pie()->reajuste()->estado()->estado < 2) {
- $info []= 'No ha sido abonado.';
- }
- $data []= $info;
- }
- }
- if ($venta->escritura != 0) {
- $sum += $venta->escritura()->pago()->valor();
- $ufs += $venta->escritura()->pago()->valor('ufs');
- $haber += $venta->escritura()->pago()->valor();
- $info = [
- $venta->escritura()->pago()->estado()->fecha,
- 'Abono Escritura (' . format('ufs', $venta->escritura()->pago()->valor('ufs')) . ' UF)',
- '',
- $venta->escritura()->pago()->valor(),
- $sum
- ];
- if ($venta->escritura()->pago()->estado()->estado < 2) {
- $info []= 'No ha sido abonado.';
- }
- $data []= $info;
- }
- if ($venta->credito != 0) {
- $sum += $venta->credito()->pago()->valor();
- $ufs += $venta->credito()->pago()->valor('ufs');
- $haber += $venta->credito()->pago()->valor();
- $info = [
- $venta->credito()->pago()->estado()->fecha,
- 'Crédito (' . format('ufs', $venta->credito()->pago()->valor('ufs')) . ' UF)',
- '',
- $venta->credito()->pago()->valor(),
- $sum
- ];
- if ($venta->credito()->pago()->estado()->estado < 2) {
- $info []= 'No ha sido pagado.';
- }
- $data []= $info;
- }
- if ($venta->bono_pie != 0) {
- try {
- $sum -= $venta->bonoPie()->pago()->valor();
- $debe += $venta->bonoPie()->pago()->valor();
- $info = [
- $venta->bonoPie()->pago()->estado()->fecha,
- 'Bono Pie (' . format('ufs', $venta->bonoPie()->pago()->valor('ufs')) . ' UF)'.
- $venta->bonoPie()->pago()->valor(),
- '',
- $sum
- ];
- $data []= $info;
- $sum += $venta->bonoPie()->pago()->valor();
- $haber += $venta->bonoPie()->pago()->valor();
- $info = [
- $venta->bonoPie()->pago()->estado()->fecha,
- 'Bono Pie (' . format('ufs', $venta->bonoPie()->pago()->valor('ufs')) . ' UF)'.
- '',
- $venta->bonoPie()->pago()->valor(),
- $sum
- ];
- $data []= $info;
- } catch (\Exception $e) {
-
- }
- }
- $info = [
- '',
- 'TOTAL (' . format('ufs', $ufs) . ' UF)',
- $debe,
- $haber,
- $sum
- ];
- $data []= $info;
- $bold_rows []= count($data) - 1;
-
- $data []= [''];
- }
- /**
- * Departamento #
- * Fecha |Glosa |Debe |Haber |Saldo
- * |Pie - Cuota 1 - n (# UF) |- |$# |
- * |Reajuste (# UF) |- |$# |
- * |Abono Escritura (# UF) |- |$# |
- * |Crédito (# UF) |- |$# |
- * |Bono Pie (# UF) |$# |- |
- * |Bono Pie (# UF) |- |$# |
- * |Devolución (# UF) |$# |- |
- * - |TOTAL (# UF) | | |
- */
-
- array_walk($data, function(&$e, $i) use ($columns) {
- if (count($e) < count($columns)) {
- $n = count($columns) - count($e);
- for ($j = 0; $j < $n; $j ++) {
- $e []= '';
- }
- }
- });
-
- #$informe = new Informador('Consolidación - ' . $proyecto->descripcion);
- $name = 'Consolidación';
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $proyecto->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xls');
- $informe = new PHPExcel($name, $filename);
- $informe->addColumns($columns);
- $informe->addData($data);
-
- return $informe->informe();
- }
- public static function creditos_pendientes()
- {
- function creditos() {
- $creditos = model(Credito::class)
- ->select('credito.*')
- ->join('venta', ['venta.credito', '=', 'credito.id'])
- ->join('pago', ['pago.id', '=', 'credito.pago'])
- ->rawJoin('JOIN (SELECT ep.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago ep ON ep.id = e0.id)', ['estado_pago.pago', '=', 'pago.id'], 'estado_pago')
- ->whereLt('estado_pago.estado', 2)
- ->where('venta.estado', 1)
- ->orderByAsc('estado_pago.fecha')
- ->findMany();
- foreach ($creditos as $credito) {
- yield $credito;
- }
- }
- $informe = new Informador('Créditos Pendientes');
-
- $columnas = ['Proyecto', 'Departamento', 'Valor', 'Fecha Escritura', 'Estado'];
- $informe->addColumns($columnas);
-
- $row = 0;
- foreach (creditos() as $credito) {
- $informe->addData($row, $credito->venta()->proyecto()->descripcion, 'Proyecto');
- $informe->addData($row, $credito->venta()->unidad()->descripcion, 'Departamento');
- $informe->addData($row, $credito->pago()->valor('ufs'), 'Valor');
- $informe->addData($row, (($credito->venta()->escriturado) ? $credito->venta()->escriturado : $credito->pago()->estado()->fecha), 'Fecha Escritura');
- $informe->addData($row, ucwords($credito->pago()->estado()->tipo()->descripcion), 'Estado');
-
- $row ++;
- }
-
- $date = [
- 'numberFormat' => ['short-date']
- ];
- $ufs = [
- 'numberFormat' => ['thousands']
- ];
- $formats = ['Valor' => $ufs, 'Fecha Escritura' => $date];
- $informe->addFormats($formats);
-
- return $informe->informe();
- }
- public static function ventas()
- {
- if (get('proyecto')) {
- ini_set('memory_limit', "1G");
- ini_set('max_execution_time', '3600');
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $ventas = $proyecto->ventas();
-
- /*usort($ventas, function($a, $b) {
- return $a->fecha()->timestamp - $b->fecha()->timestamp;
- });*/
-
- $procasa = model(Agente::class)->findOne(1);
- $pa = model(ProyectoAgente::class)->where('agente', $procasa->id)->where('proyecto', $proyecto->id)->findOne();
- if ($pa) {
- $comision = $pa->comision / 100;
- } else {
- $comision = 0.03;
- }
-
- #$informe = new Informador('Ventas - ' . $proyecto->descripcion);
- $name = 'Informe de Ventas';
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $proyecto->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xlsx');
- //$informe = new PHPExcel($name, $filename);
-
- $columnas = [
- 'Propietario',
- 'Departamento',
- ['name' => 'Estacionamientos', 'style' => 'number'],
- ['name' => 'Bodegas', 'style' => 'number'],
- 'Fecha Venta',
- ['name' => 'Mes', 'style' => 'mes'],
- 'Tipo',
- ['name' => 'm² Ponderados', 'style' => 'amount'],
- ['name' => 'Valor Promesa', 'style' => 'amount'],
- ['name' => 'Pie', 'style' => 'amount'],
- ['name' => 'Pie Pagado', 'style' => 'amount'],
- ['name' => '% Pie Pagado', 'style' => 'percent'],
- ['name' => 'Bono Pie', 'style' => 'amount'],
- 'Operador',
- ['name' => 'Valor Operador', 'style' => 'amount'],
- ['name' => 'Premios', 'style' => 'amount'],
- ['name' => 'Subsidio', 'style' => 'amount'],
- ['name' => 'Ahorro', 'style' => 'amount'],
- ['name' => 'Credito', 'style' => 'amount'],
- 'Banco',
- ['name' => 'Valor Ests & Bods', 'style' => 'amount'],
- ['name' => 'Valor Neto', 'style' => 'amount'],
- ['name' => 'UF/m²*', 'style' => 'amount'],
- ['name' => 'Comision', 'style' => 'amount'],
- ['name' => 'Venta s/Comision', 'style' => 'amount'],
- ['name' => 'Precio', 'style' => 'Amount']
- ];
- //$informe->addColumns($columnas);
-
- $data = [];
- foreach ($ventas as $venta) {
- $info = [];
- $info['Propietario'] = mb_strtoupper($venta->propietario()->nombreCompleto());
- $info['Departamento'] = implode(' - ', array_map(function($item) {
- return $item->descripcion;
- }, $venta->propiedad()->departamentos()));
- $es = $venta->propiedad()->estacionamientos();
- $info['Estacionamientos'] = implode(', ', array_map(function($item) {
- return $item->descripcion;
- }, $es));
- $bs = $venta->propiedad()->bodegas();
- $info['Bodegas'] = implode(', ', array_map(function($item) {
- return $item->descripcion;
- }, $bs));
- $info['Fecha Venta'] = $venta->fecha()->format('Y-m-d');
- $info['Mes'] = $venta->fecha()->format('M-y');
- $info['Tipo'] = $venta->unidad()->abreviacion;
- $info['m² Ponderados'] = $venta->unidad()->m2('vendible');
- $info['Valor Promesa'] = $venta->valor_uf;
- $info['Pie'] = 0;
- if ($venta->pie()) {
- $info['Pie'] = $venta->pie()->valor;
- }
- $info['Pie Pagado'] = 0;
- $info['% Pie Pagado'] = 0;
- if ($venta->pie()) {
- $info['Pie Pagado'] = $venta->pie()->valorPagado('uf');
- $info['% Pie Pagado'] = $venta->pie()->valorPagado('uf') / $venta->valor_uf;
- }
-
- $info['Bono Pie'] = ($venta->bono_pie == 0 or $venta->bonoPie() === false) ? '' : $venta->bonoPie()->pago()->valor('ufs');
- $info['Operador'] = ($venta->agente and $venta->agente()->agente()->tipo == 19) ? $venta->agente()->agente()->descripcion : '';
- $info['Valor Operador'] = $venta->valorComision();
- //$promos = 0;
- $ps = $venta->promociones();
- $info['Premios'] = array_reduce($ps, function($sum, $item) {
- return $sum + $item->valor;
- });
- $info['Subsidio'] = 0;
- $info['Ahorro'] = 0;
- if ($venta->subsidio != 0) {
- $info['Subsidio'] = $venta->subsidio()->subsidio()->valor('ufs');
- $info['Ahorro'] = $venta->subsidio()->pago()->valor('ufs');
- }
- $info['Credito'] = 0;
- $info['Banco'] = '';
- if ($venta->credito != 0 and $venta->credito()->pago()) {
- $info['Credito'] = $venta->credito()?->pago()->valor('ufs');
- if ($venta->credito()?->pago()->banco != 0) {
- $info['Banco'] = $venta->credito()?->pago()->banco()->nombre;
- }
- }
- $info['Valor Ests & Bods'] = $venta->valorEstacionamientosYBodegas();
- $info['Valor Neto'] = $venta->valorFinal();
- $info['UF/m²*'] = $venta->uf_m2();
- $info['Comision'] = $venta->valorFinal() * $comision;
- $info['Venta s/Comision'] = $venta->valorFinal() - $info['Comision'];
- $fecha = $venta->fecha();
- $info['Precio'] = 0;
- try {
- $info['Precio'] = array_reduce($venta->propiedad()->departamentos(), function($sum, $item) use ($fecha) {
- if (!$item->precio($fecha)) {
- return $sum;
- }
- return $sum + $item->precio($fecha)->valor;
- });
- } catch (\Exception $e) {
- }
-
- $data []= $info;
- }
-
- $body = [
- "Proyecto" => $proyecto->descripcion,
- "Compañía" => $proyecto->inmobiliaria()->abreviacion,
- "data" => $data
- ];
- $client = new Client(['base_uri' => "{$_ENV['PYTHON_HOST']}"]);
- $response = $client->post('/ventas', ['json' => $body]);
-
- header("Content-Type: application/octet-stream; charset=utf-8");
- header('Content-Transfer-Encoding: binary');
- header('Content-Disposition: attachment; filename="' . $filename . '"');
- header('Cache-Control: max-age=0');
- return $response->getBody();
- //file_put_contents('php://output', $output);
-
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.ventas', compact('proyectos'));
- }
- }
- public static function resumen_contabilidad()
- {
- if (get('proyecto')) {
- $id = get('proyecto');
- $fecha = get('fecha');
-
- $service = new Resumen();
- $service->build($id, new \DateTimeImmutable($fecha));
- return '';
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.resumen_contabilidad', compact('proyectos'));
- }
- }
- public static function contabilidad()
- {
- if (get('proyecto')) {
- $id = get('proyecto');
- $fecha = get('fecha');
- $mes = null;
- if ($fecha != null) {
- $mes = Carbon::parse($fecha);
- }
- $proyecto = model(Proyecto::class)->findOne($id);
- $q = "SELECT pago.*, venta.id AS vid, venta.tipo AS ctipo, venta.pie AS pie
- FROM (
- SELECT pago.id, banco.nombre AS banco, pago.fecha, pago.valor, pago.uf, ep.estado, ep.fecha AS efecha
- FROM pago JOIN banco ON banco.id = pago.banco JOIN ((
- SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago ep ON ep.id = e0.id) ON ep.pago = pago.id
- WHERE ep.estado > 0 ";
- if ($mes != null) {
- $q .= "AND (pago.fecha BETWEEN '" . $mes->format('Y-m-01') . "' AND '" . $mes->format('Y-m-t') . "'
- OR ep.fecha BETWEEN '" . $mes->format('Y-m-01') . "' AND '" . $mes->format('Y-m-t') . "')";
- }
- $q .= ") pago JOIN (SELECT venta.*
- FROM ((
- SELECT venta.id, venta.pie, venta.propiedad, credito.pago, 'credito' AS tipo
- FROM venta JOIN credito ON credito.id = venta.credito)
- UNION ALL (
- SELECT venta.id, venta.pie, venta.propiedad, escritura.pago, 'escritura' AS tipo
- FROM venta JOIN escritura ON escritura.id = venta.escritura)
- UNION ALL (
- SELECT venta.id, venta.pie, venta.propiedad, cuota.pago, 'cuota' AS tipo
- FROM venta JOIN cuota ON cuota.pie = venta.pie)) venta
- JOIN propiedad ON propiedad.id = venta.propiedad
- JOIN unidad ON unidad.id = propiedad.unidad_principal
- WHERE unidad.proyecto = ?) venta
- ON venta.pago = pago.id";
- $st = \ORM::getDB()->prepare($q);
- $st->execute([$id]);
- if ($st->rowCount() > 0) {
- $R = $st->fetchAll(\PDO::FETCH_OBJ);
-
- //$informe = new Informador('Contabilidad - ' . (($mes != null) ? $mes->format('Y-m') . ' - ' : '') . $proyecto->descripcion);
- $name = 'Contabilidad';
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', 'Contabilidad - ' . (($mes != null) ? $mes->format('Y-m') . ' - ' : '') . $proyecto->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xls');
-
- $informe = new PHPExcel($name, $filename);
-
- $columnas = ['Proyecto', 'Fecha', 'Banco', 'Departamento', 'RUT', 'Propietario', 'Glosa', 'Glosa2', (object) ['name' => 'Valor', 'style' => 'integer'], (object) ['name' => 'Valor UF', 'style' => 'currency']];
- $informe->addColumns($columnas);
- $data = [];
- foreach ($R as $r) {
- $info = [];
- $info['Proyecto'] = $proyecto->descripcion;
- $f1 = \Carbon\Carbon::parse($r->fecha, config('app.timezone'));
- $f2 = \Carbon\Carbon::parse($r->efecha, config('app.timezone'));
- $info['Fecha'] = ($f1->max($f2))->format('Y-m-d');
- $info['Banco'] = $r->banco;
- $venta = model(Venta::class)->findOne($r->vid);
- $info['Departamento'] = $venta->unidad()->descripcion;
- $info['RUT'] = $venta->propietario()->rut();
- $info['Propietario'] = $venta->propietario()->nombreCompleto();
- $info['Glosa'] = ucwords($r->ctipo);
- $info['Glosa2'] = '';
- if ($r->ctipo == 'cuota') {
- $cuota = model(Cuota::class)->where('pago', $r->id)->findOne();
-
- $info['Glosa'] = 'Pie - ' . format('ufs', $cuota->pie()->valor('ufs'), null, true);
-
- $info['Glosa2'] = $cuota->numero() . ' - ' . $cuota->pie()->cuotas;
- }
- $info['Valor'] = $r->valor;
- $info['Valor UF'] = '0';
- if ($r->uf > 0) {
- $info['Valor UF'] = $r->valor / $r->uf;
- }
- $data []= $info;
- }
-
- $informe->addData($data);
-
- return $informe->informe();
- }
- } else {
- setlocale(LC_TIME, 'es_ES');
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.contabilidad', compact('proyectos'));
- }
- }
- public static function para_comision()
- {
- $proyectos = model(Proyecto::class)->orderByAsc('descripcion')->findMany();
- return view('informes.para_comision', compact('proyectos'));
- }
- public static function comisiones()
- {
- $id = post('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $unidades = explode('-', str_replace([';', '.', ':', ' ', PHP_EOL, '|', '+', ','], '-', post('unidades')));
- $ventas = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->where('unidad.proyecto', $proyecto->id)
- ->where('venta.estado', 1)
- ->whereIn('unidad.descripcion', $unidades)
- ->orderByExpr('FIELD(unidad.descripcion, ' . implode(', ', $unidades) . ')')
- ->findMany();
- $ids = [];
- $totales = (object) ['precio' => 0, 'neto' => 0, 'comision' => 0];
- foreach ($ventas as $venta) {
- $ids []= $venta->id;
- $totales->precio += $venta->valor_uf;
- $totales->neto += $venta->valorCorredora();
- $totales->comision += $venta->valorCorredora() * 1.5 / 100;
- }
- return view('informes.comisiones', compact('ventas', 'proyecto', 'totales', 'ids'));
- }
- public static function comisiones_xlsx()
- {
- $id_ventas = explode(',', get('ventas'));
- $ventas = model(Venta::class)
- ->whereIn('id', $id_ventas)
- ->orderByExpr('FIELD(id, ' . implode(', ', $id_ventas) . ')')
- ->findMany();
-
- $informe = new Informador('Comisiones - ' . $ventas[0]->proyecto()->descripcion);
- $columnas = ['Departamento', 'Estacionamientos', 'Bodegas', 'Propietario', 'Precio', '% Com', 'Com UF'];
- $informe->addColumns($columnas);
- $data = [];
- foreach ($ventas as $venta) {
- $info = [];
- $info['Departamento'] = $venta->unidad()->descripcion;
- $info['Estacionamientos'] = implode(' - ', $venta->propiedad()->estacionamientos('array'));
- $info['Bodegas'] = implode(' - ', $venta->propiedad()->bodegas('array'));
- $info['Propietario'] = $venta->propietario()->nombreCompleto();
- $info['Precio'] = "'" . format('ufs', $venta->valorCorredora());
- $info['% Com'] = '1,5 %';
- $info['Com UF'] = "'" . format('ufs', $venta->valorCorredora() * 1.5 / 100);
- $data []= $info;
- }
-
- $informe->addDatas($data);
-
- return $informe->informe();
- }
- public static function cuotas()
- {
- $id_venta = get('venta');
- $venta = model(Venta::class)->findOne($id_venta);
-
- $name = 'Cuotas - ' . $venta->unidad()->descripcion;
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $venta->proyecto()->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xls');
- $informe = new PHPExcel($name, $filename);
- $columnas = [
- ['name' => 'Cuota', 'style' => 'number'],
- ['name' => 'Fecha Cuota', 'style' => 'date'],
- 'Banco',
- 'Identificador',
- ['name' => 'Valor $', 'style' => 'number'],
- ['name' => 'Valor UF', 'style' => 'currency'],
- ['name' => 'Fecha Pago', 'style' => 'date']
- ];
- $informe->addColumns($columnas);
- $data = [];
- foreach ($venta->pie()->cuotas() as $cuota) {
- $info = [];
- $info['Cuota'] = $cuota->numero();
- $info['Fecha Cuota'] = $cuota->pago()->fecha()->format('Y-m-d');
- $info['Banco'] = $cuota->pago()->banco()->descripcion;
- $info['Identificador'] = $cuota->pago()->identificador;
- $info['Valor $'] = $cuota->pago()->valor();
- $info['Valor UF'] = $cuota->pago()->valor('ufs');
- $info['Fecha Pago'] = $cuota->pago()->estado()->fecha()->format('Y-m-d');
- $data []= $info;
- }
- $informe->addData($data);
-
- return $informe->informe();
- }
- public static function resciliaciones()
- {
- if (get('proyecto')) {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $ventas = $proyecto->resciliaciones();
-
- usort($ventas, function($a, $b) {
- return $a->fecha()->timestamp - $b->fecha()->timestamp;
- });
-
- $name = 'Resciliaciones';
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $name . ' - ' . $proyecto->descripcion . ' - ' . $hoy->format('Y-m-d') . '.xls');
- $informe = new PHPExcel($name, $filename);
-
- $columnas = [
- 'Propietario',
- ['name' => 'Departamento', 'style' => 'number'],
- ['name' => 'Estacionamientos', 'style' => 'number'],
- ['name' => 'Bodegas', 'style' => 'number'],
- 'Fecha Venta',
- 'Fecha Resciliación',
- ['name' => 'Mes', 'style' => 'mes'],
- 'Tipo',
- ['name' => 'm² Ponderados', 'style' => 'amount'],
- ['name' => 'Valor Promesa', 'style' => 'amount'],
- ];
- $informe->addColumns($columnas);
-
- $data = [];
- foreach ($ventas as $venta) {
- $info = [];
- $info['Propietario'] = mb_strtoupper($venta->propietario()->nombreCompleto());
- $info['Departamento'] = $venta->unidad()->descripcion;
- $ests = [];
- if ($venta->propiedad()->estacionamientos != '') {
- $es = $venta->propiedad()->estacionamientos();
- foreach ($es as $e) {
- $ests []= $e->descripcion;
- }
- }
- $info['Estacionamientos'] = implode(', ', $ests);
- $bods = [];
- if ($venta->propiedad()->bodegas != '') {
- $bs = $venta->propiedad()->bodegas();
- foreach ($bs as $b) {
- $bods []= $b->descripcion;
- }
- }
- $info['Bodegas'] = implode(', ', $bods);
- $info['Fecha Venta'] = $venta->fecha()->format('d.m.Y');
- $info['Fecha Resciliación'] = $venta->estado()->fecha()->format('d.m.Y');
- $info['Mes'] = $venta->estado()->fecha()->format('M-y');
- $info['Tipo'] = $venta->unidad()->abreviacion;
- $info['m² Ponderados'] = $venta->unidad()->m2('vendible');
- $info['Valor Promesa'] = $venta->valor_uf;
-
- $data []= $info;
- }
- $informe->addData($data);
-
- $totals = [
- 'Departamento' => 'count',
- 'Estacionamientos' => 'count',
- 'Bodegas' => 'count',
- 'm² Ponderados' => 'sum',
- 'Valor Promesa' => 'sum'
- ];
- $informe->addTotals($totals);
-
- return $informe->informe();
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('informes.resciliaciones', compact('proyectos'));
- }
- }
-}
diff --git a/app/Controller/Inmobiliarias.php b/app/Controller/Inmobiliarias.php
deleted file mode 100644
index f0b8910..0000000
--- a/app/Controller/Inmobiliarias.php
+++ /dev/null
@@ -1,74 +0,0 @@
-orderByAsc('abreviacion')->findMany();
- return view('inmobiliarias.list', compact('inmobiliarias'));
- }
- public static function show()
- {
- $rut = get('rut');
- $inmobiliaria = model(Inmobiliaria::class)->findOne($rut);
- return view('inmobiliarias.show', compact('inmobiliaria'));
- }
- public static function add()
- {
- $sociedades = model(TipoSociedad::class)->findMany();
- return view('inmobiliarias.add', compact('sociedades'));
- }
- public static function agregar()
- {
- list($rut, $dv) = explode('-', str_replace('.', '', post('rut')));
-
- $inmobiliaria = model(Inmobiliaria::class)->findOne($rut);
- if ($inmobiliaria) {
- header('Location: ' . url('', ['p' => 'inmobiliarias', 'a' => 'show', 'rut' => $inmobiliaria->rut]));
- die();
- }
-
- $inmobiliaria = model(Inmobiliaria::class)->create();
- $inmobiliaria->rut = $rut;
- $inmobiliaria->dv = $dv;
- $inmobiliaria->razon = post('razon');
- $inmobiliaria->abreviacion = post('abrev');
- $inmobiliaria->sociedad = post('sociedad');
-
- $inmobiliaria->save();
- header('Location: ' . url('', ['p' => 'inmobiliarias', 'a' => 'show', 'rut' => $inmobiliaria->rut]));
- }
- public static function edit()
- {
- $sociedades = model(TipoSociedad::class)->findMany();
- $rut = get('rut');
- $inmobiliaria = model(Inmobiliaria::class)->findOne($rut);
- $bancos = model(Banco::class)->findMany();
- usort($bancos, function($a, $b) {
- return strcmp($a->nombre, $b->nombre);
- });
- return view('inmobiliarias.edit', compact('inmobiliaria', 'bancos', 'sociedades'));
- }
- public static function do_edit()
- {
- $rut = get('rut');
- $inmobiliaria = model(Inmobiliaria::class)->findOne($rut);
- foreach (post() as $field => $value) {
- if ($value != '' and $inmobiliaria->{$field} != $value) {
- $inmobiliaria->{$field} = $value;
- }
- }
-
- $inmobiliaria->save();
- header('Location: ' . nUrl('inmobiliarias', 'show', ['rut' => $inmobiliaria->rut]));
- }
-}
-?>
diff --git a/app/Controller/Operadores.php b/app/Controller/Operadores.php
deleted file mode 100644
index 765ba2a..0000000
--- a/app/Controller/Operadores.php
+++ /dev/null
@@ -1,47 +0,0 @@
-findOne(get('proyecto'));
- $operadores = model(Agente::class)
- ->select('agente.*')
- ->join('agente_tipo', ['agente_tipo.agente', '=', 'agente.id'])
- ->join('tipo_agente', ['tipo_agente.id', '=', 'agente_tipo.tipo'])
- ->where('tipo_agente.descripcion', 'operador')
- ->orderByAsc('agente.abreviacion')
- ->findMany();
- $vigentes = array_map(function($item) {
- return $item->agente()->agente();
- }, $proyecto->operadoresVigentes());
- echo view('proyectos.operadores.add', compact('proyecto', 'operadores', 'vigentes'));
- }
- public static function add()
- {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- $fecha = Carbon::today(config('app.timezone'));
- foreach (post('operadores') as $op) {
- $operador = model(Agente::class)->findOne($op);
- $at = $operador->tipos(19);
- $data = [
- 'proyecto' => $proyecto->id,
- 'agente' => $at->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'comision' => 2
- ];
- $pa = model(ProyectoAgente::class)->create($data);
- $pa->new();
- }
- header('Location: ' . nUrl('proyectos', 'show', ['proyecto' => $proyecto->id]));
- }
-}
diff --git a/app/Controller/Other.php b/app/Controller/Other.php
deleted file mode 100644
index eb90f31..0000000
--- a/app/Controller/Other.php
+++ /dev/null
@@ -1,71 +0,0 @@
-create();
- $unidad = \Model::factory(Unidad::class)->where('descripcion', $info[0])->where('proyecto', post('proyecto'))->find_one();
- if (!$unidad->venta()->find_one()) {
- echo 'x';
- continue;
- }
- $venta = $unidad->venta()->find_one();
- $entrega->fecha = \Carbon\Carbon::parse($info[1])->format('Y-m-d');
- if ($venta->entrega == '0') {
- $entrega->save();
- $venta->entrega = $entrega->id;
- $venta->save();
- echo '.';
- } else {
- echo 'x';
- }
- }
- } else {
- $proyectos = \Model::factory(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('other.entregar_multiple', compact('proyectos'));
- }
- }
- public static function capacidades()
- {
- $capacidades = [];
- $controllers = glob(config('locations.app') . '/Controller/*.php');
- foreach ($controllers as $controller) {
- if (basename($controller) == 'Admin.php' or basename($controller) == 'Other.php') {
- continue;
- }
- $class = Stringy::create($controller)->replace(config('locations.app'), '/App')->replace('.php', '')->replace('/', '\\')->__toString();
- $ref = new \ReflectionClass($class);
- $static = $ref->getMethods(\ReflectionMethod::IS_STATIC && \ReflectionMethod::IS_PUBLIC);
- foreach ($static as $method) {
- if ($method->name == 'setDefault' or $method->name == 'index') {
- continue;
- }
- $capacidades []= $method;
- }
- }
- return view('other.capacidades', compact('capacidades'));
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Controller/Pagares.php b/app/Controller/Pagares.php
deleted file mode 100644
index f05b24e..0000000
--- a/app/Controller/Pagares.php
+++ /dev/null
@@ -1,271 +0,0 @@
-findOne(get('pagare'));
- return view('proyectos.pagares.show', compact('pagare'));
- }
- public static function add()
- {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- return view('proyectos.pagares.add', compact('proyecto'));
- }
- public static function do_add()
- {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- $data = post();
-
- $data['id'] = $data['numero'];
- unset($data['numero']);
- $data['proyecto'] = $proyecto->id;
- $moneda = model(TipoMonedaPagare::class)->where('descripcion', $data['moneda'])->findOne();
- $data['moneda'] = $moneda->id;
-
- $fecha = ['year', 'month', 'day'];
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha'] = implode('-', $fecha_arr);
-
- foreach ($fecha as &$key) {
- $key .= '_banco';
- }
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha_banco'] = implode('-', $fecha_arr);
-
- $data['abonado'] = (int) $data['abonado'];
- if ($data['abonado'] == 0) {
- $data['fecha'] = '0000-00-00';
- }
-
- $pagare = model(Pagare::class)->create($data);
- $pagare->save();
- header('Location: ' . nUrl('pagares', 'show', ['pagare' => $pagare->id]));
- }
- public static function edit()
- {
- $pagare = model(Pagare::class)->findOne(get('pagare'));
- return view('proyectos.pagares.edit', compact('pagare'));
- }
- public static function do_edit()
- {
- $pagare = model(Pagare::class)->findOne(get('pagare'));
-
- $data = post();
- if ($pagare->id != $data['numero']) {
- foreach ($pagare->renovaciones() as $renovacion) {
- $renovacion->pagare = $data['numero'];
- $renovacion->save();
- }
- $pagare->id = $data['numero'];
- $changed = true;
- }
- unset($data['numero']);
- $moneda = model(TipoMonedaPagare::class)->where('descripcion', $data['moneda'])->findOne();
- $data['moneda'] = $moneda->id;
- $fecha = ['year', 'month', 'day'];
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha'] = implode('-', $fecha_arr);
-
- foreach ($fecha as &$key) {
- $key .= '_banco';
- }
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha_banco'] = implode('-', $fecha_arr);
-
- $data['abonado'] = (int) $data['abonado'];
- if ($data['abonado'] == 0) {
- $data['fecha'] = '0000-00-00';
- }
-
- $changed = false;
- foreach ($data as $k => $v) {
- if ($pagare->$k != $v) {
- $pagare->$k = $v;
- $changed = true;
- if (strpos($k, 'fecha') !== false) {
- $pagare->uf = 0;
- }
- }
- }
-
- if ($changed) {
- $pagare->save();
- }
- header('Location: ' . nUrl('pagares', 'show', ['pagare' => $pagare->id]));
- }
- public static function edit_renovacion()
- {
- $renovacion = model(RenovacionPagare::class)->findOne(get('renovacion'));
- return view('proyectos.pagares.edit_renovacion', compact('renovacion'));
- }
- public static function do_edit_renovacion()
- {
- $renovacion = model(RenovacionPagare::class)->findOne(get('renovacion'));
-
- $data = post();
- $fecha = ['year', 'month', 'day'];
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha'] = implode('-', $fecha_arr);
-
- foreach ($fecha as &$key) {
- $key .= '_banco';
- }
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha_banco'] = implode('-', $fecha_arr);
-
- $changed = false;
- foreach ($data as $k => $v) {
- if ($renovacion->$k != $v) {
- $renovacion->$k = $v;
- $changed = true;
- if (strpos($k, 'fecha') !== false) {
- $renovacion->uf = 0;
- }
- }
- }
- if ($changed) {
- $renovacion->save();
- }
- header('Location: ' . nUrl('pagares', 'show', ['pagare' => $renovacion->pagare]));
- }
- public static function add_renovacion()
- {
- $pagare = model(Pagare::class)->findOne(get('pagare'));
- return view('proyectos.pagares.add_renovacion', compact('pagare'));
- }
- public static function do_add_renovacion()
- {
- $pagare = model(Pagare::class)->findOne(get('pagare'));
- $data = post();
-
- $data['pagare'] = $pagare->id;
- $fecha = ['year', 'month', 'day'];
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha'] = implode('-', $fecha_arr);
-
- foreach ($fecha as &$key) {
- $key .= '_banco';
- }
- $fecha_arr = array_filter($data, function($item) use ($fecha) {
- return (array_search($item, $fecha) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- uksort($fecha_arr, function($a, $b) use ($fecha) {
- return array_search($a, $fecha) - array_search($b, $fecha);
- });
- foreach ($fecha as $f) {
- unset($data[$f]);
- }
- array_walk($fecha_arr, function(&$item) {
- if (strlen($item) < 4) {
- $item = str_pad($item, 2, '0', \STR_PAD_LEFT);
- }
- });
- $data['fecha_banco'] = implode('-', $fecha_arr);
-
- $renovacion = model(RenovacionPagare::class)->create($data);
- $renovacion->save();
-
- header('Location: ' . nUrl('pagares', 'show', ['pagare' => $renovacion->pagare]));
- }
-}
diff --git a/app/Controller/Pagos.php b/app/Controller/Pagos.php
deleted file mode 100644
index f279b9e..0000000
--- a/app/Controller/Pagos.php
+++ /dev/null
@@ -1,358 +0,0 @@
-findOne($id);
- $tipos = model(TipoPago::class)->orderByAsc('descripcion')->findMany();
- $estados = model(TipoEstadoPago::class)->orderByAsc('descripcion')->findMany();
-
- return view('ventas.pagos.edit', compact('pago', 'asociado', 'id_asociado', 'tipos', 'estados'));
- }
- public static function editar()
- {
- $id = get('pago');
- $pago = model(Pago::class)->findOne($id);
-
- $fp = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $tipo = model(TipoPago::class)->findOne(post('tipo'));
- $valor = correctNumber(post('valor'));
- $banco = model(Banco::class)->where('nombre', post('banco'))->findOne();
-
- $fe = Carbon::createFromDate(post('yearestado'), post('monthestado'), post('dayestado'), config('app.timezone'));
- $estado = model(TipoEstadoPago::class)->findOne(post('estado'));
- $uf = uf($fe);
-
- $est = $pago->estado();
- if ($est->fecha != $fe->format('Y-m-d')) {
- $est->fecha = $fe->format('Y-m-d');
- $pago->uf = $uf->uf->value;
- }
- if ($est->estado != $estado->id) {
- $est->estado = $estado->id;
- }
-
- if ($pago->fecha != $fp->format('Y-m-d')) {
- $pago->fecha = $fp->format('Y-m-d');
- }
- if ($pago->tipo != $tipo->id) {
- $pago->tipo = $tipo->id;
- }
- if ($pago->valor != $valor) {
- $pago->valor = $valor;
- }
- if ($pago->identificador != post('identificador')) {
- $pago->identificador = post('identificador');
- }
- if ($pago->pagador != post('pagador')) {
- $pago->pagador = post('pagador');
- }
- if ($pago->banco != $banco->id) {
- $pago->banco = $banco->id;
- }
-
- $est->save();
- $pago->save();
- header('Location: ' . url('', ['p' => get('asociado') . 's', 'a' => 'show', get('asociado') => get(get('asociado'))]));
- }
- public static function pendientes()
- {
- $ventas = model(Venta::class)
- ->select('venta.*')
- ->rawJoin('JOIN (SELECT e1.* FROM estado_venta e1 JOIN (SELECT venta, MAX(id) AS id FROM estado_venta GROUP BY venta) e0 ON e0.id = e1.id)', ['ev.venta', '=', 'venta.id'], 'ev')
- ->join('tipo_estado_venta', ['te.id', '=', 'ev.estado'], 'te')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
- ->where('te.activa', 1)
- ->orderByAsc('proyecto.descripcion')
- ->orderByExpr('LPAD(unidad.descripcion, 4, "0")')
- ->findMany();
- $n = 30;
- $mod = floor(count($ventas) / $n);
- $i_rest = count($ventas) - count($ventas) % $mod + 1;
- $rest = count($ventas) - $i_rest;
- $lots = (object) ['size' => $mod, 'N' => $n, 'rest' => (object) [
- 'size' => $rest,
- 'start' => $i_rest
- ]
- ];
- return view('ventas.pagos.pendientes', compact('ventas', 'lots'));
- }
- public static function para_pendientes()
- {
- $timezone = config('app.timezone');
- $today = Carbon::today($timezone);
- $days = [];
- $fechas = [];
- for ($i = $today->copy()->subDays(15); $i <= $today->copy()->addDays(15); $i = $i->copy()->addDay()) {
- $days []= $i->format('Y-m-d');
- $fechas []= $i->format('d-m-Y');
- }
- $pagos_pendientes = model(Pago::class)
- ->select('estado_pago.fecha')
- ->selectExpr('COUNT(pago.id)', 'cantidad')
- ->join('cuota', ['cuota.pago', '=', 'pago.id'])
- ->join('venta', ['venta.pie', '=', 'cuota.pie'])
- ->filter('filterEstado')
- ->where('estado_pago.estado', 0)
- ->where('venta.estado', 1)
- ->whereGte('estado_pago.fecha', $today->copy()->subDays(15)->format('Y-m-d'))
- ->whereLte('estado_pago.fecha', $today->copy()->addDays(15)->format('Y-m-d'))
- ->orderByAsc('estado_pago.fecha')
- ->groupBy('estado_pago.fecha')
- ->findMany();
- $valores = array_fill(0, count($days), 0);
- $anteriores = model(Pago::class)
- ->join('cuota', ['cuota.pago', '=', 'pago.id'])
- ->join('venta', ['venta.pie', '=', 'cuota.pie'])
- ->filter('filterEstado')
- ->where('estado_pago.estado', 0)
- ->where('venta.estado', 1)
- ->whereLt('estado_pago.fecha', $today->copy()->subDays(15)->format('Y-m-d'))
- ->count();
- foreach ($pagos_pendientes as $pago) {
- $valores[array_search($pago->fecha()->format('Y-m-d'), $days)] = $pago->cantidad;
- }
- $acum = [];
- $sum = 0;
- foreach ($valores as $valor) {
- $sum += $valor;
- $acum []= $sum;
- }
- $t = array_search($today->format('Y-m-d'), $days);
- $color = array_merge(
- array_fill(0, $t, 'red'),
- ['blue'],
- array_fill(0, count($days) - $t, 'green')
- );
- $pagos = ['data' => $acum, 'historico' => $anteriores, 'backgroundColor' => $color];
- $abonos_pendientes = model(Pago::class)
- ->select('estado_pago.fecha')
- ->selectExpr('COUNT(pago.id)', 'cantidad')
- ->filter('filterEstado')
- ->where('estado_pago.estado', 1)
- ->whereGte('estado_pago.fecha', $today->copy()->subDays(15)->format('Y-m-d'))
- ->whereLt('estado_pago.fecha', $today->copy()->format('Y-m-d'))
- ->orderByAsc('estado_pago.fecha')
- ->groupBy('estado_pago.fecha')
- ->findMany();
- $anteriores = model(Pago::class)
- ->join('cuota', ['cuota.pago', '=', 'pago.id'])
- ->join('venta', ['venta.pie', '=', 'cuota.pie'])
- ->filter('filterEstado')
- ->where('estado_pago.estado', 1)
- ->where('venta.estado', 1)
- ->whereLt('estado_pago.fecha', $today->copy()->subDays(15)->format('Y-m-d'))
- ->count();
- $valores = array_fill(0, count($days), 0);
- foreach ($abonos_pendientes as $pago) {
- $valores[array_search($pago->fecha()->format('Y-m-d'), $days)] = $pago->cantidad;
- }
- $acum = [];
- $sum = 0;
- foreach ($valores as $valor) {
- $sum += $valor;
- $acum []= $sum;
- }
- $color = array_fill(0, count($pagos), 'rgb(200, 0, 0)');
- $abonos = ['data' => $acum, 'historico' => $anteriores, 'backgroundColor' => $color];
- $output = ['count' => count($days), 'fechas' => $fechas, 'pagos' => $pagos, 'abonos' => $abonos];
- echo json_encode($output);
- }
- public static function para_abonar()
- {
- $ids = json_decode(post('ids'));
- //$id = get('id');
- function checkPago(&$pagos, $tipo, $pago) {
- if (!$pago) {
- return;
- }
- if (!$pago->estado()) {
- $pagos []= [
- 'tipo' => $tipo,
- 'pago' => $pago->asArray(),
- 'estado' => -1
- ];
- return;
- }
- if ($pago->estado()->tipo()->descripcion == 'depositado') {
- $pagos []= [
- 'tipo' => $tipo,
- 'pago' => $pago->asArray(),
- 'fecha' => format('shortDate', $pago->estado()->fecha),
- 'valor' => format('pesos', $pago->valor, true),
- 'estado' => 1
- ];
- }
- }
- $output = [];
- foreach ($ids as $id) {
- $venta = model(Venta::class)->findOne($id);
- if ($venta->estado()->tipo()->activa == 0) {
- $output []= ['status' => -1, 'venta' => $venta->id];
- continue;
- }
- $pagos = [];
- if ($venta->pie()) {
- foreach ($venta->pie()->cuotas() as $cuota) {
- checkPago($pagos, 'Pie', $cuota->pago());
- }
- if ($venta->pie()->reajuste()) {
- checkPago($pagos, 'Reajuste', $venta->pie()->reajuste());
- }
- }
- if ($venta->credito()) {
- checkPago($pagos, 'Credito', $venta->credito()->pago());
- }
- if ($venta->escritura()) {
- checkPago($pagos, 'Abono Escritura', $venta->escritura()->pago());
- }
- if ($venta->subsidio()) {
- checkPago($pagos, 'Subsidio', $venta->subsidio()->subsidio());
- checkPago($pagos, 'Ahorro', $venta->subsidio()->pago());
- }
- if (count($pagos) <= 0) {
- $output []= ['status' => -1, 'venta' => $venta->id];
- continue;
- }
- $output []= [
- 'status' => 1,
- 'proyecto' => $venta->proyecto()->descripcion,
- 'venta' => $venta->id,
- 'propietario' => $venta->propietario()->nombreCompleto(),
- 'departamento' => $venta->unidad()->descripcion,
- 'pagos' => $pagos
- ];
- }
- return json_encode($output);
- }
- public static function rebotes()
- {
- $ids = json_decode(post('ids'));
- $response = [];
- foreach ($ids as $id) {
- //$id = get('id');
- $venta = model(Venta::class)->findOne($id);
- $rebotes = $venta->pagos(-1);
- if (count($rebotes) < 1) {
- $response []= ['status' => -1, 'venta' => $venta->id];
- continue;
- }
- usort($rebotes, function($a, $b) {
- return $b->estado()->fecha()->diffInDays($a->estado()->fecha(), false);
- });
-
- $output = [];
- $textos = [];
- foreach ($rebotes as $rebote) {
- $fuente = $rebote->fuente()[0];
- $text = '' . ucwords(str_replace('_', ' ', $fuente->tipo)) . ' | ';
- $info = ['tipo' => ucwords(str_replace('_', ' ', $fuente->tipo))];
- switch ($fuente->tipo) {
- case('cuota'):
- $text .= '' . $fuente->obj->pie()->venta()->proyecto()->descripcion
- . ' | ' . $fuente->obj->pie()->venta()->unidad()->descripcion . ' | '
- . $fuente->obj->pie()->venta()->propietario()->nombreCompleto()
- . ' | ' . format('shortDate', $rebote->estado()->fecha) . ' | ';
- $info['proyecto'] = $fuente->obj->pie()->venta()->proyecto()->descripcion;
- $info['venta'] = $fuente->obj->pie()->venta()->id;
- $info['departamento'] = $fuente->obj->pie()->venta()->unidad()->descripcion;
- $info['propietario'] = $fuente->obj->pie()->venta()->propietario()->nombreCompleto();
- $info['fecha'] = format('shortDate', $rebote->estado()->fecha);
- break;
- }
- $text .= '' . format('pesos', $rebote->valor('pesos'), true) . ' | ';
- $info['valor'] = format('pesos', $rebote->valor('pesos'), true);
- $output []= array_merge(['id' => $rebote->id], $info);
- $textos []= ['id' => $rebote->id, 'text' => $text];
- }
- $response []= ['status' => 1, 'venta' => $venta->id, 'textos' => $textos, 'rebotes' => $output];
- }
-
- return json_encode($response);
- }
- public static function show()
- {
- $id = get('pago');
- $asociado = get('asociado');
- $id_asociado = get($asociado);
-
- $pago = model(Pago::class)->findOne($id);
-
- return view('ventas.pagos.show', compact('pago', 'asociado', 'id_asociado'));
- }
- public static function pagar()
- {
- $id = get('pago');
- $pago = model(Pago::class)->findOne($id);
- $asociado = get('asociado');
- $id_asociado = get($asociado);
-
- return view('ventas.pagos.pagar', compact('pago', 'asociado', 'id_asociado'));
- }
- public static function pagando()
- {
- $id = get('pago');
- $pago = model(Pago::class)->findOne($id);
- $asociado = get('asociado');
- $id_asociado = get($asociado);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $data = [
- 'fecha' => $f->format('Y-m-d'),
- 'pago' => $pago->id,
- 'estado' => 1
- ];
- $estado = model(EstadoPago::class)->create($data);
-
- $estado->save();
- header('Location: ' . url('', ['p' => $asociado . 's', 'a' => 'show', $asociado => $id_asociado]));
- }
- public static function abonar()
- {
- $id = get('pago');
- $pago = model(Pago::class)->findOne($id);
- $asociado = get('asociado');
- $id_asociado = get($asociado);
-
- return view('ventas.pagos.abonar', compact('pago', 'asociado', 'id_asociado'));
- }
- public static function abonando()
- {
- $id = get('pago');
- $pago = model(Pago::class)->findOne($id);
- $asociado = get('asociado');
- $id_asociado = get($asociado);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $data = [
- 'fecha' => $f->format('Y-m-d'),
- 'pago' => $pago->id,
- 'estado' => 2
- ];
- $estado = model(EstadoPago::class)->create($data);
-
- $estado->save();
- header('Location: ' . url('', ['p' => $asociado . 's', 'a' => 'show', $asociado => $id_asociado]));
- }
-}
-?>
diff --git a/app/Controller/Pies.php b/app/Controller/Pies.php
deleted file mode 100644
index 38c2fcb..0000000
--- a/app/Controller/Pies.php
+++ /dev/null
@@ -1,104 +0,0 @@
-findOne($proyecto);
- $ventas = $proyecto->ventas();
- self::sort($ventas);
- return view('ventas.list', compact('proyecto', 'ventas'));
- }
- public static function listProyectos()
- {
- $proyectos = \Model::factory(Proyecto::class)
- ->select('proyecto.*')
- ->join('estado_proyecto', ['estado.proyecto', '=', 'proyecto.id'], 'estado')
- ->join('tipo_estado_proyecto', ['tipo.id', '=', 'estado.estado'], 'tipo')
- ->join('etapa_proyecto', ['etapa.id', '=', 'tipo.etapa'], 'etapa')
- ->whereGte('etapa.orden', 4)
- ->groupBy('proyecto.id')
- ->findMany();
- echo view('ventas.proyectos', compact('proyectos'));
- }
- public static function resumen()
- {
- $id = get('pie');
- $pie = \Model::factory(\Incoviba\old\Venta\Pie::class)->findOne($id);
- $venta = $pie->venta();
- return view('ventas.pies.resumen', compact('venta'));
- }
- public static function reajustar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- return view('ventas.pies.reajustar', compact('venta'));
- }
- public static function reajuste()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $pago = \Model::factory(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = (float) uf($f)->uf->value;
- $pago->valor = str_replace('.', '', post('valor'));
-
- $pago->new();
-
- $pie = $venta->pie();
- $pie->reajuste = $pago->id;
- $pie->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function edit()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- return view('ventas.pies.edit', compact('venta'));
- }
- public static function editar()
- {
- $id = get('venta');
- $venta = \Model::factory(Venta::class)->findOne($id);
- $pie = $venta->pie();
- $valor = correctNumber(post('valor'));
- if ($pie->valor != $valor) {
- $pie->valor = $valor;
- }
- if ($pie->cuotas != post('cuotas')) {
- $pie->cuotas = post('cuotas');
- }
-
- $pie->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function asociar()
- {
- $id = get('pie');
- $pie = \Model::factory(Pie::class)->findOne($id);
- $pie->asociado = post('asociado');
-
- $pie->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $pie->venta()->id]));
- }
-}
-?>
diff --git a/app/Controller/Postventas.php b/app/Controller/Postventas.php
deleted file mode 100644
index 7b38cb6..0000000
--- a/app/Controller/Postventas.php
+++ /dev/null
@@ -1,69 +0,0 @@
-findOne($id);
-
- return view('ventas.postventas.add', compact('venta'));
- }
- public static function agregar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $observaciones = json_decode(post('observaciones'));
- $postventa = model(Postventa::class)->create();
- $postventa->venta_id = $venta->id;
- $postventa->save();
-
- $estado = model(EstadoPostventa::class)->create();
- $estado->postventa_id = $postventa->id;
- $estado->tipo_estado_postventa_id = 1;
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
-
- foreach ($observaciones as $o) {
- $observacion = model(Observacion::class)->create();
- $observacion->texto = post('observacion' . $o);
-
- $observacion->save();
-
- $estado = model(EstadoObservacion::class)->create();
- $estado->observacion_id = $observacion->id;
- $estado->tipo_estado_observacion_id = 1;
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
-
- $po = model(PostventaObservacion::class)->create();
- $po->postventa_id = $postventa->id;
- $po->observacion_id = $observacion->id;
- $po->save();
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function show()
- {
- $id = get('postventa');
- $postventa = model(Postventa::class)->findOne($id);
- $venta = model(Venta::class)->findOne($postventa->venta_id);
-
- return view('ventas.postventas.show', compact('postventa', 'venta'));
- }
-}
-?>
diff --git a/app/Controller/Precios.php b/app/Controller/Precios.php
deleted file mode 100644
index 20db97b..0000000
--- a/app/Controller/Precios.php
+++ /dev/null
@@ -1,177 +0,0 @@
-orderByAsc('descripcion')->findMany();
- return view('ventas.precios.proyectos', compact('proyectos'));
- }
- public static function list()
- {
- $proyecto = \model(Proyecto::class)->findOne(get('proyecto'));
- return view('ventas.precios.list', compact('proyecto'));
- }
- public static function import()
- {
- $proyectos = \model(Proyecto::class)->orderByAsc('descripcion')->findMany();
- return view('ventas.precios.import', compact('proyectos'));
- }
- public static function importar()
- {
- $proyecto = \model(Proyecto::class)->findOne(post('proyecto'));
- $fecha = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $file = explode(PHP_EOL, trim(file_get_contents($_FILES['archivo']['tmp_name'])));
- $columnas = explode(';', array_shift($file));
- $tr = model(TipoEstadoPrecio::class)->where('descripcion', 'reemplazado')->findOne()->id;
- $tv = model(TipoEstadoPrecio::class)->where('descripcion', 'vigente')->findOne()->id;
- foreach ($file as $line) {
- if (trim($line) == '') {
- continue;
- }
- $info = explode(';', $line);
- $tipo = \model(TipoUnidad::class)->where('descripcion', $info[0])->findOne();
- $unidad = \model(Unidad::class)->where('tipo', $tipo->id)->where('descripcion', $info[1])->where('proyecto', $proyecto->id)->findOne();
- if (!$unidad) {
- continue;
- }
-
- try {
- self::reemplazar($unidad->id, $info[2], $fecha, $tr, $tv);
- } catch (\Exception $e) {
- continue;
- }
- }
- header('Location: ' . nUrl('precios', 'list', ['proyecto' => $proyecto->id]));
- }
- public static function add()
- {
- $proyecto = \model(Proyecto::class)->findOne(get('proyecto'));
- return view('ventas.precios.add', compact('proyecto'));
- }
- public static function agregar()
- {
- $proyecto = get('proyecto');
- $fecha = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $precios = [];
- foreach (post() as $name => $valor) {
- if ($valor == '' or strpos($name, 'precio') === false) {
- continue;
- }
- list($tipo, $id) = explode(':', $name);
- $tipo = trim(str_replace('precio', '', $tipo), '_');
- $id = explode('-', $id);
- switch (count($id)) {
- case 1:
- $precios []= ['tipo' => 'pt', 'id' => $id[0], 'valor' => $valor];
- break;
- case 2:
- $exists = false;
- foreach ($precios as $precio) {
- if ($precio['tipo'] == 'pt' and $precio['id'] == $id[0]) {
- $exists = true;
- break;
- }
- }
- if (!$exists) {
- $precios []= ['tipo' => 'subtipo', 'id' => $id[1], 'pt' => $id[0], 'valor' => $valor];
- }
- break;
- case 3:
- $exists = false;
- foreach ($precios as $precio) {
- if ($precio['tipo'] == 'pt' and $precio['id'] == $id[0]) {
- $exists = true;
- break;
- }
- if ($precio['tipo'] == 'subtipo' and 'id' == $id[1] and 'pt' == $id[0]) {
- $exists = true;
- break;
- }
- }
- if (!$exists) {
- $precios []= ['tipo' => 'unidad', 'id' => $id[2], 'valor' => $valor];
- }
- break;
- }
- }
- foreach ($precios as $precio) {
- $precio = (object) $precio;
- try {
- switch ($precio->tipo) {
- case 'pt':
- $pt = model(ProyectoTipoUnidad::class)->findOne($precio->id);
- $pt->setPrecios($fecha, $precio->valor);
- break;
- case 'subtipo':
- $pt = model(ProyectoTipoUnidad::class)->findOne($precio->pt);
- $pt->setPreciosSubtipo($precios->id, $fecha, $precio->valor);
- break;
- case 'unidad':
- $unidad = model(Unidad::class)->findOne($precio->id);
- $unidad->setPrecio($fecha, $precio->valor);
- break;
- }
- } catch(\Exception $e) {
- continue;
- }
- }
- header('Location: ' . nUrl('precios', 'list', ['proyecto' => $proyecto]));
- }
- protected static function reemplazar(int $unidad_id, float $valor, \DateTime $fecha, int $tr = 0, int $tv = 0)
- {
- if ($tr == 0) {
- $tr = model(TipoEstadoPrecio::class)->where('descripcion', 'reemplazado')->findOne()->id;
- }
- if ($tv == 0) {
- $tv = model(TipoEstadoPrecio::class)->where('descripcion', 'vigente')->findOne()->id;
- }
- $olds = \model(Precio::class)->where('unidad', $unidad_id)->findMany();
- if ($olds !== false) {
- foreach ($olds as $old) {
- if (!$old->vigente()) {
- continue;
- }
- $data = [
- 'precio' => $old->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'estado' => $tr
- ];
- $estado = \model(EstadoPrecio::class)->create($data);
- $estado->save();
- }
- }
- $data = [
- 'unidad' => $unidad_id,
- 'valor' => $valor
- ];
- $precio = (new Factory(Precio::class))->where($data)->find();
- if (!$precio) {
- $precio = \model(Precio::class)->create($data);
- $precio->save();
- }
- $data = [
- 'precio' => $precio->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'estado' => $tv
- ];
- $estado = \model(EstadoPrecio::class)->create($data);
- $estado->save();
- }
-}
diff --git a/app/Controller/Propietarios.php b/app/Controller/Propietarios.php
deleted file mode 100644
index 5d38ee7..0000000
--- a/app/Controller/Propietarios.php
+++ /dev/null
@@ -1,129 +0,0 @@
-findOne($id);
- $propietario = $venta->propietario();
- $regiones = model(Region::class)->orderByAsc('numeracion')->findMany();
-
- return view('ventas.propietarios.edit', compact('venta', 'propietario', 'regiones'));
- }
- public static function editar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $info = post();
- list($info['rut'], $info['dv']) = explode('-', str_replace('.', '', $info['rut']));
- $propietario = model(Propietario::class)->findOne($info['rut']);
- if (!$propietario) {
- $propietario = model(Propietario::class)->create();
- }
- if ($propietario->direccion != 0) {
- $direccion = $propietario->direccion();
- } else {
- $direccion = model(Direccion::class)
- ->where('calle', post('calle'))
- ->where('numero', post('numero'))
- ->where('extra', post('extra'))
- ->where('comuna', post('comuna'))
- ->findOne();
- if (!$direccion) {
- $data = [
- 'calle' => post('calle'),
- 'numero' => post('numero'),
- 'extra' => post('extra'),
- 'comuna' => post('comuna')
- ];
- $direccion = model(Direccion::class)->create($data);
- }
- }
-
- if (isset($info['empresa'])) {
- $info['apellido_paterno'] = '';
- $info['apellido_materno'] = '';
- }
-
- if ($propietario->representante != 0) {
- list($info['rep_rut'], $info['rep_dv']) = explode('-', str_replace('.', '', $info['rep_rut']));
- $representante = $propietario->representante();
- } elseif (isset($info['rep_rut'])) {
- list($info['rep_rut'], $info['rep_dv']) = explode('-', str_replace('.', '', $info['rep_rut']));
- $representante= model(Propietario::class)->findOne($info['rep_rut']);
- if (!$representante) {
- $representante= model(Propietario::class)->create();
- }
- }
-
- $fields = ['rut', 'dv', 'nombres', 'apellido_paterno', 'apellido_materno'];
- $change = false;
- foreach ($fields as $key) {
- if ($propietario->$key != $info[$key]) {
- $propietario->$key = $info[$key];
- $change = true;
- }
- }
- if ($direccion->isNew()) {
- $direccion->save();
- }
- if ($propietario->direccion != $direccion->id) {
- $propietario->direccion = $direccion->id;
- $change = true;
- }
- if ($change) {
- d($propietario);
- $propietario->save();
- }
-
- if (isset($info['rep_rut'])) {
- $change = false;
- if ($representante->rut != $info['rep_rut']) {
- $representante->rut = $info['rep_rut'];
- $representante->dv = $info['rep_dv'];
- $change = true;
- }
- if ($representante->nombres != $info['rep_nombres']) {
- $representante->nombres = $info['rep_nombres'];
- $change = true;
- }
- if ($representante->apellido_paterno != $info['rep_apaterno']) {
- $representante->apellido_paterno = $info['rep_apaterno'];
- $change = true;
- }
- if ($representante->apellido_materno != $info['rep_amaterno']) {
- $representante->apellido_materno = $info['rep_amaterno'];
- $change = true;
- }
- if ($representante->direccion != $direccion->id) {
- $representante->direccion = $direccion->id;
- $change = true;
- }
- if ($change) {
- $representante->save();
- }
- if ($propietario->representante != $representante->rut) {
- $propietario->representante = $representante->rut;
- $propietario->save();
- }
- }
-
- if ($venta->propietario != $propietario->rut) {
- $venta->propietario = $propietario->rut;
- $venta->save();
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
-}
-?>
diff --git a/app/Controller/ProyectoTipoUnidades.php b/app/Controller/ProyectoTipoUnidades.php
deleted file mode 100644
index 32c0c1d..0000000
--- a/app/Controller/ProyectoTipoUnidades.php
+++ /dev/null
@@ -1,77 +0,0 @@
-findOne($id);
- $tipos = model(TipoUnidad::class)->findMany();
-
- return view('proyectos.tipo_unidades.edit', compact('tipo', 'tipos'));
- }
- public static function editar()
- {
- $id = get('tipo_unidad');
- $tipo = model(ProyectoTipoUnidad::class)->findOne($id);
-
- $changed = false;
- foreach (post() as $field => $value) {
- if ($tipo->{$field} != $value) {
- $tipo->{$field} = $value;
- $changed = true;
- }
- }
- if ($changed) {
- $tipo->save();
- }
- header('Location: ' . nUrl('proyectos', 'list_unidades', ['proyecto' => $tipo->proyecto()->id]));
- }
- public static function add_unidad()
- {
- $id = get('tipo_unidad');
- $tipo = model(ProyectoTipoUnidad::class)->findOne($id);
- if ($tipo->tipo()->descripcion == 'departamento') {
- return view('proyectos.unidades.add', compact('tipo'));
- }
- return view('proyectos.unidades.add2', compact('tipo'));
- }
- public static function assign()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $tipos = model(ProyectoTipoUnidad::class)->where('proyecto', $proyecto->id)->findMany();
- $libres = model(Unidad::class)->where('proyecto', $proyecto->id)->where('pt', 0)->findMany();
-
- return view('proyectos.unidades.assign', compact('proyecto', 'tipos', 'libres'));
- }
- public static function asignar()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
-
- $libres = model(Unidad::class)->where('proyecto', $proyecto->id)->where('pt', 0)->findMany();
- foreach ($libres as $unidad) {
- $unidad->pt = post('tipo' . $unidad->id);
- $unidad->save();
- }
- header('Location: ' . nUrl('proyectos', 'list_unidades', ['proyecto' => $proyecto->id]));
- }
-}
diff --git a/app/Controller/Proyectos.php b/app/Controller/Proyectos.php
deleted file mode 100644
index 9c69ad5..0000000
--- a/app/Controller/Proyectos.php
+++ /dev/null
@@ -1,327 +0,0 @@
-where('inmobiliaria', $id_inmobiliaria);
- } else {
- $proyectos = model(Proyecto::class);
- }
- $proyectos = $proyectos->order_by_asc('descripcion')->findMany();
- return view('proyectos.list', compact('proyectos'));
- }
- public static function show()
- {
- $id_proyecto = get('proyecto');
- if ($id_proyecto == null) {
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'list']));
- }
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $estados = model(TipoEstadoProyecto::class)->findMany();
- foreach ($estados as &$estado) {
- $estado = $estado->asArray()['orden'] + 1;
- }
- $colors = [];
-
- $ventas_pt = (object) ['fields' => [], 'data' => [], 'totales' => [], 'vendidas' => []];
- $ventas = $proyecto->ventas('fecha');
- $months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
- if (count($ventas) > 0) {
- $inicio = $ventas[0]->fecha()->format('Y');
- $fin = $ventas[count($ventas) - 1]->fecha()->format('Y');
- $end = $ventas[count($ventas) - 1]->fecha()->format('M');
- for ($y = $inicio; $y <= $fin; $y ++) {
- foreach ($months as $month) {
- $ventas_pt->fields []= $y . ' ' . $month;
- if ($y == $fin and $month == $end) {
- break;
- }
- }
- }
- }
-
- foreach ($proyecto->tipologias() as $tipo) {
- if (!isset($ventas_pt->data[$tipo->tipologia->descripcion])) {
- $ventas_pt->data[$tipo->tipologia->descripcion] = [];
- $ventas_pt->data[$tipo->tipologia->descripcion] = array_fill(0, count($ventas_pt->fields), 0);
- $ventas_pt->totales[$tipo->tipologia->descripcion] = 0;
- $ventas_pt->vendidas[$tipo->tipologia->descripcion] = 0;
- }
- foreach ($tipo->tipos as $pt) {
- foreach ($pt->ventas('fecha') as $venta) {
- $ventas_pt->data[$tipo->tipologia->descripcion][array_search($venta->fecha()->format('Y M'), $ventas_pt->fields)] ++;
- $ventas_pt->vendidas[$tipo->tipologia->descripcion] ++;
- }
- $ventas_pt->totales[$tipo->tipologia->descripcion] += count($pt->unidades());
- }
- }
- foreach ($ventas_pt->data as $tipo => $data) {
- $acum = 0;
- foreach ($data as $i => $cantidad) {
- $acum += $cantidad;
- $ventas_pt->data[$tipo][$i] = round($acum / $ventas_pt->totales[$tipo] * 100, 2);
- }
- }
- $meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
- array_walk($ventas_pt->fields, function(&$item) use ($meses, $months) {
- $item = str_replace($months, $meses, $item);
- });
-
- for ($i = 0; $i < 10; $i ++) {
- $colors[$i] = 'rgb(' . mt_rand(0, 255) . ', ' . mt_rand(0, 255) . ', ' . mt_rand(0, 255) . ')';
- }
- return view('proyectos.show', compact('proyecto', 'estados', 'colors', 'ventas_pt'));
- }
- public static function historial()
- {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- return view('proyectos.historia', compact('proyecto'));
- }
- public static function advance()
- {
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $estados = model(TipoEstadoProyecto::class)->whereGt('orden', $proyecto->estado()->tipo()->orden)->orderByAsc('orden')->findMany();
-
- return view('proyectos.advance', compact('proyecto', 'estados'));
- }
- public static function avanzar()
- {
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $id_tipo = post('estado');
- $tipo = model(TipoEstadoProyecto::class)->findOne($id_tipo);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $tipos = model(TipoEstadoProyecto::class)
- ->whereGt('orden', $proyecto->estado()->tipo()->orden)
- ->whereLte('orden', $tipo->orden)
- ->orderByAsc('orden')
- ->findMany();
-
- foreach ($tipos as $t) {
- $estado = model(EstadoProyecto::class)->create();
- $estado->proyecto = $proyecto->id;
- $estado->estado = $t->id;
- $estado->fecha = $f->format('Y-m-d');
- $estado->save();
- }
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'show', 'proyecto' => $proyecto->id]));
- }
- public static function avance()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $av = post('avance') / 100;
- $ep = (double) post('estado_pago');
- $avance = model(AvanceConstruccion::class)
- ->where('proyecto', $proyecto->id)
- ->where('fecha', $f->format('Y-m-d'))
- ->findOne();
- if (!$avance) {
- $data = [
- 'proyecto' => $proyecto->id,
- 'fecha' => $f->format('Y-m-d'),
- 'numero' => post('numero'),
- 'avance' => $av,
- 'estado_pago' => $ep
- ];
- $avance = model(AvanceConstruccion::class)->create($data);
- }
- $avance->save();
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'historial', 'proyecto' => $proyecto->id]));
- }
- public static function add()
- {
- $rut = get('inmobiliaria');
-
- $inmobiliarias = model(Inmobiliaria::class)->orderByAsc('abreviacion')->findMany();
- $regiones = model(Region::class)->orderByAsc('numeracion')->findMany();
-
- return view('proyectos.add', compact('inmobiliarias', 'rut', 'regiones'));
- }
- public static function agregar()
- {
- $proyecto = model(Proyecto::class)->where('descripcion', post('descripcion'))->where('inmobiliaria', post('inmobiliaria'))->find_one();
- if ($proyecto) {
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'show', 'proyecto' => $proyecto->id]));
- die();
- }
- $proyecto = model(Proyecto::class)->create();
- $proyecto->descripcion = post('descripcion');
- $proyecto->inmobiliaria = post('inmobiliaria');
-
- $direccion = model(Direccion::class)
- ->where('calle', post('calle'))
- ->where('numero', post('numero'))
- ->where('extra', post('extra'))
- ->where('comuna', post('comuna'))
- ->findOne();
- if (!$direccion) {
- $direccion = model(Direccion::class)->create();
- $direccion->calle = post('calle');
- $direccion->numero = post('numero');
- $direccion->extra = post('extra');
- $direccion->comuna = post('comuna');
- $direccion->save();
- }
-
- $proyecto->direccion = $direccion->id;
- $proyecto->save();
-
- $fecha = Carbon::parse(post('year'), post('month'), post('day'), config('app.timezone'));
- $estado = model(EstadoProyecto::class)->create();
- $estado->proyecto = $proyecto->id;
- $estado->estado = 1;
- $estado->fecha = $fecha->format('Y-m-d');
- $estado->save();
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'show', 'proyecto' => $proyecto->id]));
- }
- public static function disponibles()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
-
- return view('proyectos.disponibles', compact('proyecto'));
- }
- public static function list_unidades()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $libres = model(Unidad::class)->where('proyecto', $proyecto->id)->where('pt', 0)->findMany();
-
- return view('proyectos.unidades.list', compact('proyecto', 'libres'));
- }
- public static function add_tipo_unidad()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $tipos = model(TipoUnidad::class)->findMany();
-
- return view('proyectos.tipo_unidades.add', compact('proyecto', 'tipos'));
- }
- public static function agregar_tipo_unidad()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- $data = post();
- $data['proyecto'] = $proyecto->id;
- $tipo = model(ProyectoTipoUnidad::class)->where('proyecto', $data['proyecto'])
- ->where('tipo', $data['tipo'])->where('nombre', $data['nombre'])->findOne();
- if ($tipo === false) {
- $tipo = model(ProyectoTipoUnidad::class)->create($data);
- $tipo->save();
- }
- header('Location: ' . nUrl('proyectos', 'list_unidades', ['proyecto' => $proyecto->id]));
- }
- public static function construccion()
- {
- $id = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id);
- return view('proyectos.construccion', compact('proyecto'));
- }
- public static function editar_avance()
- {
- $avance = model(AvanceConstruccion::class)->findOne(get('avance'));
- return view('proyectos.avances.edit', compact('avance'));
- }
- public static function edit_avance()
- {
- $avance = model(AvanceConstruccion::class)->findOne(get('avance'));
- $cols = [
- 'day',
- 'month',
- 'year',
- 'avance',
- 'estado_pago',
- 'pagado',
- 'day_pago',
- 'month_pago',
- 'year_pago'
- ];
- $data = array_filter(post(), function($key) use ($cols) {
- return (array_search($key, $cols) !== false);
- }, \ARRAY_FILTER_USE_KEY);
- $data['fecha'] = implode('-', [$data['year'], $data['month'], $data['day']]);
- unset($data['year']);
- unset($data['month']);
- unset($data['day']);
- $data['fecha_pagado'] = implode('-', [$data['year_pago'], $data['month_pago'], $data['day_pago']]);
- unset($data['year_pago']);
- unset($data['month_pago']);
- unset($data['day_pago']);
- $data['avance'] /= 100;
- $avance->edit($data);
-
- header('Location: ' . nUrl('proyectos', 'construccion', ['proyecto' => $avance->proyecto]));
- }
- public static function reservas()
- {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- $pisos = [];
- $totales = [];
- foreach ($proyecto->unidades('departamento') as $unidad) {
- if (!isset($pisos[$unidad->piso - 1])) {
- $piso = (object) ['descripcion' => $unidad->piso, 'unidades' => []];
- $pisos[$unidad->piso - 1] = $piso;
- }
- if (!isset($totales[$unidad->linea()])) {
- $totales[$unidad->linea()] = (object) ['ventas' => 0, 'reservas' => 0];
- }
- $pisos[$unidad->piso - 1]->unidades[$unidad->linea()] = $unidad;
- if ($unidad->isVendida()) {
- $totales[$unidad->linea()]->ventas ++;
- }
- if ($unidad->isReservada()) {
- $totales[$unidad->linea()]->reservas ++;
- }
- }
- ksort($pisos);
- $max_unidades = 0;
- foreach ($pisos as $piso) {
- if (count($piso->unidades) > $max_unidades) {
- $max_unidades = count($piso->unidades);
- }
- }
- return view('proyectos.reservas.base', compact('proyecto', 'pisos', 'max_unidades', 'totales'));
- }
- public static function unidades()
- {
- if (get('proyecto')) {
- $proyecto = model(Proyecto::class)->findOne(get('proyecto'));
- $libres = model(Unidad::class)->where('proyecto', $proyecto->id)->where('pt', 0)->findMany();
-
- return view('proyectos.unidades.list', compact('proyecto', 'libres'));
- }
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->findMany();
- return view('proyectos.unidades.proyectos', compact('proyectos'));
- }
-}
-?>
diff --git a/app/Controller/Reajustes.php b/app/Controller/Reajustes.php
deleted file mode 100644
index 4c6c938..0000000
--- a/app/Controller/Reajustes.php
+++ /dev/null
@@ -1,90 +0,0 @@
-findOne($id);
- return view('ventas.pies.reajustes.edit', compact('venta'));
- }
- public static function editar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
-
- $valor = correctNumber(post('valor'));
- if ($valor == '') {
- $valor_uf = correctNumber(post('valor_uf'));
- $valor = $valor_uf * $uf->uf->value;
- }
- $pago = $venta->pie()->reajuste();
- if ($pago->valor != $valor) {
- $pago->valor = $valor;
- }
- if ($pago->fecha != $f->format('Y-m-d')) {
- $pago->fecha = $f->format('Y-m-d');
- $pago->uf = $uf->uf->value;
- }
-
- $pago->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function pagar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.pies.reajustes.pagar', compact('venta'));
- }
- public static function pagado()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $data = [
- 'pago' => $venta->pie()->reajuste()->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => 1
- ];
- $estado = model(EstadoPago::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function abonar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.pies.reajustes.abonar', compact('venta'));
- }
- public static function abonado()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- $data = [
- 'pago' => $venta->pie()->reajuste()->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => 2
- ];
- $estado = model(EstadoPago::class)->create($data);
- $estado->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
-}
-?>
diff --git a/app/Controller/Registros.php b/app/Controller/Registros.php
deleted file mode 100644
index 546fece..0000000
--- a/app/Controller/Registros.php
+++ /dev/null
@@ -1,39 +0,0 @@
-orderByDesc('time')->findMany();
- $ini = new Color(0, 100, 0);
- $end = new Color(255, 255, 255);
- $colores = self::colores($end, $ini, 100);
- return view('admin.registros.list', compact('registros', 'colores'));
- }
- public static function show()
- {
- $registro = model(RModel::class)->findOne(get('registro'));
- $ini = new Color(0, 100, 0);
- $end = new Color(255, 255, 255);
- $colores = self::colores($end, $ini, 100);
- return view('admin.registros.show', compact('registro', 'colores'));
- }
- protected static function colores($ini, $end, $max)
- {
- $current = $ini->toVector();
- $colores = [];
- $line = new Line($ini->toVector(), $end->toVector());
- for ($i = 0; $i < $max; $i ++) {
- $colores[$i] = new Color($current);
- $current = $line->move($current, $line->length() / $max);
- }
- return $colores;
- }
-}
diff --git a/app/Controller/Subsidios.php b/app/Controller/Subsidios.php
deleted file mode 100644
index 5107fc3..0000000
--- a/app/Controller/Subsidios.php
+++ /dev/null
@@ -1,184 +0,0 @@
-findOne($id);
- echo view('ventas.subsidios.add', compact('venta'));
- }
- public static function do_add()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
-
- $pago1 = model(Pago::class)->create();
- $valor = post('ahorro_uf') * $uf->uf->value;
- if (post('ahorro') != null) {
- $valor = post('ahorro');
- }
- $pago1->valor = $valor;
- $pago1->fecha = $f->format('Y-m-d');
- $pago1->uf = $uf->uf->value;
-
- $pago2 = model(Pago::class)->create();
- $valor = post('subsidio_uf') * $uf->uf->value;
- if (post('subsidio') != null) {
- $valor = post('subsidio');
- }
- $pago2->valor = $valor;
- $pago2->fecha = $f->format('Y-m-d');
- $pago2->uf = $uf->uf->value;
-
- $pago1->new();
- $pago2->new();
-
- $subsidio = model(Subsidio::class)->create();
- $subsidio->pago = $pago1->id;
- $subsidio->subsidio = $pago2->id;
-
- $subsidio->save();
- $venta->subsidio = $subsidio->id();
- $venta->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
- public static function edit()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- echo view('ventas.subsidios.edit', compact('venta'));
- }
- public static function do_edit()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
-
- $pago1 = $venta->subsidio()->pago();
- $valor = post('ahorro_uf') * $uf->uf->value;
- if (post('ahorro') != null) {
- $valor = post('ahorro');
- }
- $pago1->valor = $valor;
- $pago1->fecha = $f->format('Y-m-d');
- $pago1->uf = $uf->uf->value;
-
- $pago2 = $venta->subsidio()->subsidio();
- $valor = post('subsidio_uf') * $uf->uf->value;
- if (post('subsidio') != null) {
- $valor = post('subsidio');
- }
- $pago2->valor = $valor;
- $pago2->fecha = $f->format('Y-m-d');
- $pago2->uf = $uf->uf->value;
-
- $pago1->save();
- $pago2->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
- public static function pagar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $tipo = get('tipo');
- switch($tipo) {
- case 'subsidio':
- $pago = $venta->subsidio()->subsidio();
- break;
- case 'pago':
- $pago = $venta->subsidio()->pago();
- break;
- default:
- $pago = null;
- }
- echo view('ventas.subsidios.pagar', compact('venta', 'pago'));
- }
- public static function do_pagar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $tipo = post('tipo');
- switch($tipo) {
- case 'subsidio':
- $pago = $venta->subsidio()->subsidio();
- break;
- case 'pago':
- $pago = $venta->subsidio()->pago();
- break;
- default:
- $pago = null;
- }
- $pago->valor = post('valor');
- $tipo = model(TipoEstadoPago::class)->where('descripcion', 'depositado')->findOne();
- $data = [
- 'pago' => $pago->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => $tipo->id
- ];
- $estado = model(EstadoPago::class)->create($data);
- $pago->save();
- $estado->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
- public static function abonar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $tipo = get('tipo');
- switch($tipo) {
- case 'subsidio':
- $pago = $venta->subsidio()->subsidio();
- break;
- case 'pago':
- $pago = $venta->subsidio()->pago();
- break;
- default:
- $pago = null;
- }
- echo view('ventas.subsidios.abonar', compact('venta', 'pago'));
- }
- public static function do_abonar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $tipo = post('tipo');
- switch($tipo) {
- case 'subsidio':
- $pago = $venta->subsidio()->subsidio();
- break;
- case 'pago':
- $pago = $venta->subsidio()->pago();
- break;
- default:
- $pago = null;
- }
- $pago->valor = post('valor');
- $tipo = model(TipoEstadoPago::class)->where('descripcion', 'abonado')->findOne();
- $data = [
- 'pago' => $pago->id,
- 'fecha' => $f->format('Y-m-d'),
- 'estado' => $tipo->id
- ];
- $estado = model(EstadoPago::class)->create($data);
- $pago->save();
- $estado->save();
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
-}
diff --git a/app/Controller/Temas.php b/app/Controller/Temas.php
deleted file mode 100644
index 24b121a..0000000
--- a/app/Controller/Temas.php
+++ /dev/null
@@ -1,111 +0,0 @@
-orderByAsc('descripcion')->findMany();
- return view('temas.add', compact('proyectos'));
- }
- public static function agregar()
- {
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $data = [
- "proyecto_id" => post('proyecto'),
- "inicio" => $f->format('Y-m-d'),
- "texto" => post('texto')
- ];
- $tema = model(Tema::class)->create($data);
-
- $tema->save();
- header('Location: ' . url('', ['p' => 'temas', 'a' => 'list']));
- }
- public static function list()
- {
- $temas = model(Tema::class)->findMany();
- $t = Carbon::today(config('app.timezone'));
- foreach ($temas as $i => $tema) {
- if ($tema->cierre()->year != -1 and $t->diff($tema->cierre())->days > 10) {
- unset($temas[$i]);
- }
- }
- $temas = array_values($temas);
- usort($temas, function($a, $b) {
- $p = strcmp($a->proyecto()->descripcion, $b->proyecto()->descripcion);
- if ($p == 0) {
- $f = $b->inicio()->diff($a->inicio())->format('%r%a');
- if ($f == 0) {
- return $a->id - $b->id;
- }
- return $f;
- }
- return $p;
- });
-
- return view('temas.list', compact('temas'));
- }
- public static function edit()
- {
- $id = get('tema');
- $tema = model(Tema::class)->findOne($id);
- $proyectos = model(Proyecto::class)->orderByAsc('descripcion')->findMany();
- return view('temas.edit', compact('tema', 'proyectos'));
- }
- public static function editar()
- {
- $id = get('tema');
- $tema = model(Tema::class)->findOne($id);
-
- $proyecto = post('proyecto');
- $changed = false;
- if ($tema->proyecto_id != $proyecto) {
- $tema->proyecto_id = $proyecto;
- $changed = true;
- }
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- if ($tema->inicio() != $f) {
- $tema->inicio = $f->format('Y-m-d');
- $changed = true;
- }
- $texto = post('texto');
- if ($tema->texto != $texto) {
- $tema->texto = $texto;
- $changed = true;
- }
-
- if ($changed) {
- $tema->save();
- }
- header('Location: ' . url('', ['p' => 'temas', 'a' => 'list']));
- }
- public static function cerrar()
- {
- $id = get('tema');
- $tema = model(Tema::class)->findOne($id);
- $f = Carbon::today(config('app.timezone'));
- $tema->cierre = $f->format('Y-m-d');
-
- $tema->save();
- header('Location: ' . url('', ['p' => 'temas', 'a' => 'list']));
- }
- public static function abrir()
- {
- $id = get('tema');
- $tema = model(Tema::class)->findOne($id)->as_array();
- unset($tema['id'], $tema['cierre'], $tema['created_at'], $tema['updated_at']);
-
- $tema = model(Tema::class)->create($tema);
-
- $tema->save();
- header('Location: ' . url('', ['p' => 'temas', 'a' => 'list']));
- }
-}
-?>
diff --git a/app/Controller/Unidades.php b/app/Controller/Unidades.php
deleted file mode 100644
index 9f0da01..0000000
--- a/app/Controller/Unidades.php
+++ /dev/null
@@ -1,126 +0,0 @@
-findOne($id);
- $len = strlen(post('total'));
-
- $unis = json_decode(post('unidades'));
- $data = [];
- foreach ($unis as $n_unidad) {
- if ($tipo->tipo()->descripcion == 'departamento') {
- $ini = post('piso_ini' . $n_unidad);
- $end = post('piso_end' . $n_unidad);
- $subtipo = post('linea' . $n_unidad);
- $orientacion = post('orientacion' . $n_unidad);
- for ($piso = $ini; $piso <= $end; $piso ++) {
- $descripcion = $piso . str_pad(post('linea' . $n_unidad), $len, '0', \STR_PAD_LEFT);
-
- $data []= [
- 'proyecto' => $tipo->proyecto()->id,
- 'tipo' => $tipo->tipo()->id,
- 'subtipo' => $subtipo,
- 'piso' => $piso,
- 'descripcion' => $descripcion,
- 'abreviacion' => $tipo->abreviacion,
- 'm2' => $tipo->m2,
- 'terraza' => $tipo->terraza,
- 'logia' => $tipo->logia,
- 'orientacion' => $orientacion,
- 'pt' => $tipo->id
- ];
- }
- } else {
- $descripcion = post('descripcion' . $n_unidad);
- $piso = post('piso' . $n_unidad);
- $data []= [
- 'proyecto' => $tipo->proyecto()->id,
- 'tipo' => $tipo->tipo()->id,
- 'piso' => $piso,
- 'descripcion' => $descripcion,
- 'abreviacion' => $tipo->abreviacion,
- 'm2' => $tipo->m2,
- 'terraza' => $tipo->terraza,
- 'logia' => $tipo->logia,
- 'pt' => $tipo->id
- ];
- }
- }
-
- foreach ($data as $uni) {
- $unidad = model(Unidad::class)
- ->where('descripcion', $uni['descripcion'])
- ->where('proyecto', $uni['proyecto'])
- ->where('tipo', $uni['tipo'])
- ->findOne();
- if ($unidad) {
- continue;
- }
- $unidad = model(Unidad::class)->create($uni);
- $unidad->save();
- }
- header('Location: ' . url('', ['p' => 'proyectos', 'a' => 'list_unidades', 'proyecto' => $tipo->proyecto()->id]));
- }
- public static function edit()
- {
- $id = get('unidad');
- $unidad = model(Unidad::class)->findOne($id);
- $tipos = model(ProyectoTipoUnidad::class)->where('proyecto', $unidad->proyecto()->id)->findMany();
- $abreviaciones = ['N', 'NE', 'E', 'SE', 'S', 'SO', 'O', 'NO'];
- $descripciones = ['Norte', 'Noreste', 'Este', 'Sureste', 'Sur', 'Suroeste', 'Oeste', 'Noroeste'];
- $orientaciones = [];
- foreach ($abreviaciones as $i => $ab) {
- $orientaciones []= (object) ['abreviacion' => $ab, 'descripcion' => $descripciones[$i]];
- }
-
- return view('proyectos.unidades.edit', compact('unidad', 'tipos', 'orientaciones'));
- }
- public static function editar()
- {
- $id = get('unidad');
- $unidad = model(Unidad::class)->findOne($id);
-
- $change = false;
- $fields = ['descripcion', 'tipo', 'piso', 'linea', 'orientacion'];
- foreach ($fields as $field) {
- $f = $field;
- if ($f == 'tipo') {
- $f = 'pt';
- }
- if ($f == 'linea') {
- $f = 'subtipo';
- }
- if ($unidad->{$f} != post($field)) {
- $unidad->{$f} = post($field);
- $change = true;
- }
- }
-
- if ($change) {
- $unidad->save();
- }
- header('Location: ' . nUrl('proyectos', 'list_unidades', ['proyecto' => $unidad->proyecto()->id]));
- }
- public static function remove()
- {
- $id = get('unidad');
- $unidad = model(Unidad::class)->findOne($id);
- $unidad->delete();
-
- $id = get('proyecto');
- header('Location: ' . nUrl('proyectos', 'list_unidades', ['proyecto' => $id]));
- }
-}
-?>
diff --git a/app/Controller/UnidadesBloqueadas.php b/app/Controller/UnidadesBloqueadas.php
deleted file mode 100644
index 9bd4107..0000000
--- a/app/Controller/UnidadesBloqueadas.php
+++ /dev/null
@@ -1,83 +0,0 @@
-findMany();
- echo view('ventas.operadores.unidades.list', compact('proyectos'));
- }
- public static function add()
- {
- $proyectos = model(Proyecto::class)->findMany();
- echo view('ventas.operadores.unidades.add', compact('proyectos'));
- }
- public static function bloquear()
- {
- $operador = model(ProyectoAgente::class)->findOne(get('operador'));
- echo view('ventas.operadores.unidades.bloquear', compact('operador'));
- }
- public static function do_bloquear()
- {
- $operador = model(ProyectoAgente::class)->findOne(get('operador'));
- $fecha = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $unidades = self::getUnidades([], 'departamentos', 1);
- $unidades = self::getUnidades($unidades, 'estacionamientos', 2);
- $unidades = self::getUnidades($unidades, 'bodegas', 3);
- if (post('unidad') != null) {
- foreach (post('unidad') as $u) {
- $unidad = model(Unidad::class)->findOne($u);
- if (array_search($unidad, $unidades) === false) {
- $unidades []= $unidad;
- }
- }
- }
-
- foreach ($unidades as $unidad) {
- $data = [
- 'agente' => $operador->id,
- 'unidad' => $unidad->id
- ];
- $ub = model(UnidadBloqueada::class)->create($data);
- $ub->new($fecha);
- }
- header('Location: ' . nUrl('unidades_bloqueadas', 'list'));
- }
- protected static function getUnidades(array $unidades, string $name, int $tipo): array
- {
- if (trim(post($name)) == '') {
- return $unidades;
- }
- $unis = [];
- $separators = [PHP_EOL, ';', ',', '-'];
- foreach ($separators as $separator) {
- if (strpos(post($name), $separator) !== false) {
- $unis = explode($separator, post($name));
- break;
- }
- }
- if (count($unis) == 0) {
- return $unidades;
- }
- array_walk($unis, function(&$item) {
- $item = trim($item);
- $item = model(Unidad::class)->where('descripcion', $item)->where('tipo', 1)->findOne();
- });
- foreach ($unis as $uni) {
- if (array_search($uni, $unidades) === false) {
- $unidades []= $uni;
- }
- }
- return $unidades;
- }
-}
diff --git a/app/Controller/Ventas.php b/app/Controller/Ventas.php
deleted file mode 100644
index 31f1e61..0000000
--- a/app/Controller/Ventas.php
+++ /dev/null
@@ -1,605 +0,0 @@
-findOne($proyecto);
- $ventas = $proyecto->ventas();
- self::sort($ventas);
- return view('ventas.list', compact('proyecto', 'ventas'));
- }
- protected static function sort(&$ventas)
- {
- $sort = get('sort');
- if ($sort == null) {
- $sort = 'departamento';
- }
- $direction = get('sort_dir');
- if ($direction == null) {
- $direction = 1;
- }
- switch ($sort) {
- case 'departamento':
- usort($ventas, function($a, $b) use ($direction) {
- return ($a->propiedad()->unidad()->descripcion - $b->propiedad()->unidad()->descripcion) * $direction;
- });
- break;
- case 'propietario':
- usort($ventas, function($a, $b) use ($direction) {
- $pa = trim($a->propietario()->nombreCompleto(true), ', ');
- $pb = trim($b->propietario()->nombreCompleto(true), ', ');
- return $direction * strcasecmp($pa, $pb);
- });
- break;
- case 'valor_uf':
- usort($ventas, function($a, $b) use ($direction) {
- return $direction * ($a->valor_uf - $b->valor_uf);
- });
- break;
- case 'uf_m2':
- usort($ventas, function($a, $b) use ($direction) {
- return $direction * ($a->uf_m2() - $b->uf_m2());
- });
- break;
- case 'fecha_venta':
- usort($ventas, function($a, $b) use ($direction) {
- return ($a->fecha()->timestamp - $b->fecha()->timestamp) * $direction;
- });
- break;
- }
- if ($direction == 'desc') {
- $ventas = array_reverse($ventas);
- }
- }
- public static function listProyectos()
- {
- $proyectos = model(Proyecto::class)
- ->select('proyecto.*')
- ->join('estado_proyecto', ['estado.proyecto', '=', 'proyecto.id'], 'estado')
- ->join('tipo_estado_proyecto', ['tipo.id', '=', 'estado.estado'], 'tipo')
- ->join('etapa_proyecto', ['etapa.id', '=', 'tipo.etapa'], 'etapa')
- ->whereGte('etapa.orden', 4)
- ->orderByAsc('proyecto.descripcion')
- ->groupBy('proyecto.id')
- ->findMany();
- echo view('ventas.proyectos', compact('proyectos'));
- }
- public static function show()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.show', compact('venta'));
- }
- public static function new()
- {
- $proyectos = model(Proyecto::class)
- ->select('proyecto.*')
- ->join('estado_proyecto', ['estado.proyecto', '=', 'proyecto.id'], 'estado')
- ->join('tipo_estado_proyecto', ['tipo.id', '=', 'estado.estado'], 'tipo')
- ->join('etapa_proyecto', ['etapa.id', '=', 'tipo.etapa'], 'etapa')
- ->whereGte('etapa.orden', 3)
- ->orderByAsc('proyecto.descripcion')
- ->groupBy('proyecto.id')
- ->findMany();
- $regiones = model(Region::class)->order_by_asc('numeracion')->findMany();
- return view('ventas.add', compact('proyectos', 'regiones'));
- }
- public static function agregar()
- {
- error_log(var_export(post(), true));
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $t = Carbon::today(config('app.timezone'));
- $uf = uf($f);
- error_log(var_export($uf, true));
-
- $calle = trim(post('calle'));
- $numero = post('numero');
- $extra = trim(post('extra'));
- $comuna = post('comuna');
- $direccion = model(Direccion::class)
- ->where('calle', $calle)
- ->where('numero', $numero)
- ->where('extra', $extra)
- ->where('comuna', $comuna)
- ->findOne();
- if (!$direccion) {
- $direccion = model(Direccion::class)->create();
- $direccion->calle = $calle;
- $direccion->numero = $numero;
- $direccion->extra = $extra;
- $direccion->comuna = $comuna;
- $direccion->save();
- }
-
- list($rut, $dv) = explode('-', str_replace('.', '', post('rut')));
- $propietario = model(Propietario::class)->where('rut', $rut)->findOne();
- if (!$propietario) {
- $propietario = model(Propietario::class)->create();
- $propietario->rut = $rut;
- $propietario->dv = $dv;
- $propietario->nombres = trim(post('nombres'));
- $propietario->apellido_paterno = trim(post('paterno'));
- $propietario->apellido_materno = trim(post('materno'));
- $propietario->direccion = $direccion->id;
- if (post('otro') != null) {
- $propietario->otro = 1;
- }
-
- $propietario->save();
- }
-
- $unis = json_decode(post('unidades'));
- $id_principal = array_shift($unis);
- $principal = model(Unidad::class)->findOne(post('unidad' . $id_principal));
- // Revisar si existe la propiedad y si está vigente.
- $propiedad = model(Propiedad::class)->create();
- $propiedad->unidad_principal = $principal->id;
- $propiedad->save();
- $data = [
- 'propiedad' => $propiedad->id,
- 'unidad' => $principal->id,
- 'principal' => 1
- ];
- $pu = model(PropiedadUnidad::class)->create($data);
- $pu->save();
- foreach ($unis as $id_unidad) {
- $data = [
- 'propiedad' => $propiedad->id,
- 'unidad' => post('unidad' . $id_unidad),
- 'principal' => 0
- ];
- $pu = model(PropiedadUnidad::class)->create($data);
- $pu->save();
- }
-
- $venta = model(Venta::class)->create();
- $venta->propietario = $propietario->rut;
- $venta->propiedad = $propiedad->id;
- if (post('pie')) {
- $pie = model(Pie::class)->create();
- $pie->valor = post('pie');
- $pie->fecha = $f->format('Y-m-d');
- $pie->cuotas = post('cuotas');
- if ($uf->total > 0) {
- $pie->uf = $uf->uf->value;
- }
- $pie->save();
-
- $venta->pie = $pie->id;
- }
- if (post('bono_pie')) {
- $bono = model(BonoPie::class)->create();
- $bono->valor = post('bono_pie');
-
- $pago = model(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- if ($uf->total > 0) {
- $pago->uf = $uf->uf->value;
- }
- $pago->valor = $bono->valor * $uf->uf->value;
- $pago->tipo = 8;
- $pago->new();
-
- $bono->pago = $pago->id;
- $bono->save();
-
- $venta->bono_pie = $bono->id;
- }
- if (post('credito')) {
- $pago = model(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- if ($uf->total > 0) {
- $pago->uf = $uf->uf->value;
- }
- $pago->valor = post('credito') * $uf->uf->value;
- $pago->tipo = 2;
- $pago->new();
-
- $credito = model(Credito::class)->create();
- $credito->pago = $pago->id;
- $credito->save();
-
- $venta->credito = $credito->id;
- }
-
- $venta->fecha = $f->format('Y-m-d');
- $venta->valor_uf = str_replace(',', '.', post('valor'));
- $venta->fecha_ingreso = $t->format('Y-m-d');
- if (post('operador') != 0) {
- $venta->agente = post('operador');
- }
- if ($uf->total > 0) {
- $venta->uf = $uf->uf->value;
- }
- $venta->new();
-
- if (post('promociones') != 0) {
- $promos = json_decode(post('promociones'));
- foreach ($promos as $id_promo) {
- $promocion = model(Promocion::class)->findOne(post('promocion' . $id_promo));
- $promo = model(PromocionVenta::class)->create();
- $promo->promocion = $promocion->id;
- $promo->venta = $venta->id;
- $promo->valor = post('promo' . $id_promo);
- $promo->save();
- }
- }
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function edit()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->findMany();
- $regiones = model(Region::class)->order_by_asc('numeracion')->findMany();
- return view('ventas.edit', compact('venta', 'proyectos', 'regiones'));
- }
- public static function editar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
-
- $valor = correctNumber(post('valor'));
- $change = false;
- if ($venta->fecha != $f->format('Y-m-d')) {
- $venta->fecha = $f->format('Y-m-d');
- $venta->uf = $uf->uf->value;
- $change = true;
- }
- if ($venta->valor_uf != $valor) {
- $venta->valor_uf = $valor;
- $change = true;
- }
- if ($change) {
- $venta->save();
- }
-
- $direccion = $venta->propietario()->direccion();
- $calle = post('calle');
- $numero = post('numero');
- $extra = post('extra');
- $comuna = post('comuna');
- $change = false;
- if ($direccion->calle != $calle) {
- $direccion->calle = $calle;
- $change = true;
- }
- if ($direccion->numero != $numero) {
- $direccion->numero = $numero;
- $change = true;
- }
- if ($direccion->extra != $extra) {
- $direccion->extra = $extra;
- $change = true;
- }
- if ($direccion->comuna != $comuna) {
- $direccion->comuna = $comuna;
- $change = true;
- }
- if ($change) {
- $direccion->save();
- }
-
- $propietario = $venta->propietario();
- list($rut, $dv) = explode('-', str_replace('.', '', post('rut')));
- $nombres = post('nombres');
- $paterno = post('paterno');
- $materno = post('materno');
- $change = false;
- if ($propietario->rut != $rut) {
- $propietario->rut = $rut;
- $propietario->dv = $dv;
- $venta->propietario = $rut;
- $venta->save();
- $change = true;
- }
- if ($propietario->nombres != $nombres) {
- $propietario->nombres = $nombres;
- $change = true;
- }
- if ($propietario->apellido_paterno != $paterno) {
- $propietario->apellido_paterno = $paterno;
- $change = true;
- }
- if ($propietario->apellido_materno != $materno) {
- $propietario->apellido_materno = $materno;
- $change = true;
- }
- if ($change) {
- $propietario->save();
- }
-
- $unidades = json_decode(post('unidades'));
- if (count($unidades) > 0) {
- $propiedad = $venta->propiedad();
- $ests = explode(';', $propiedad->estacionamientos);
- $bods = explode(';', $propiedad->bodegas);
- $change = false;
- foreach ($unidades as $n) {
- $id = post('unidad' . $n);
- $unidad = model(Unidad::class)->findOne($id);
- if ($unidad->tipo == 1 and $propiedad->unidad_principal != $unidad->id) {
- $propiedad->unidad_principal = $unidad->id;
- $change = true;
- }
- if ($unidad->tipo == 2 and array_search($unidad->id, $ests) === false) {
- $ests []= $unidad->id;
- }
- if ($unidad->tipo == 3 and array_search($unidad->id, $bods) === false) {
- $bods []= $unidad->id;
- }
- }
- $ests = implode(';', $ests);
- $bods = implode(';', $bods);
- if ($propiedad->estacionamientos != $ests) {
- $propiedad->estacionamientos = $ests;
- $change = true;
- }
- if ($propiedad->bodegas != $bods) {
- $propiedad->bodegas = $bods;
- $change = true;
- }
- if ($change) {
- $propiedad->save();
- }
- }
-
- if (post('pie')) {
- $pie = $venta->pie();
- $valor = correctNumber(post('pie'));
- $cuotas = post('cuotas');
- $change = false;
- if ($pie->valor != $valor) {
- $pie->valor = $valor;
- $change = true;
- }
- if ($pie->cuotas != $cuotas) {
- $pie->cuotas = $cuotas;
- $change = true;
- }
- if ($change) {
- $pie->save();
- }
- }
-
- $credito = $venta->credito();
- $valor = post('credito');
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function desistir()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.desist', compact('venta'));
- }
- public static function desistiendo()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $valor = correctNumber(post('pago'));
- $uf = uf($f);
-
- $venta->estado = 0;
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'desistida')->findOne();
- $data = [
- 'venta' => $venta->id,
- 'estado' => $tipo->id,
- 'fecha' => $f->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data);
- $propiedad = $venta->propiedad();
- $propiedad->estado = 0;
- $pago = model(Pago::class)->create();
- $pago->fecha = $f->format('Y-m-d');
- $pago->valor = (double) $valor;
- $pago->uf = $uf->uf->value;
- $pago->tipo = 1;
-
- $pago->new();
- $propiedad->save();
- $estado->save();
- $venta->resciliacion = $pago->id;
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function ceder()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.ceder', compact('venta'));
- }
- public static function cediendo()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $nueva_venta = model(Venta::class)->create();
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
-
- list($rut, $dv) = explode('-', str_replace('.', '', post('rut')));
- $propietario = model(Propietario::class)->where('rut', $rut)->findOne();
- if (!$propietario) {
- $propietario = model(Propietario::class)->create();
- $propietario->rut = $rut;
- $propietario->dv = $dv;
- $propietario->nombres = trim(post('nombres'));
- $propietario->apellido_paterno = trim(post('paterno'));
- $propietario->apellido_materno = trim(post('materno'));
- $propietario->direccion = $direccion->id;
- if (post('otro') != null) {
- $propietario->otro = 1;
- }
-
- $propietario->save();
- }
-
- $nueva_venta->fecha_ingreso = $f->format();
- $nueva_venta->estado = 1;
- $cols = [
- 'propiedad',
- 'pie',
- 'bono_pie',
- 'credito',
- 'escritura',
- 'subsidio',
- 'fecha',
- 'valor_uf',
- 'agente',
- 'uf'
- ];
- foreach ($cols as $col) {
- $nueva_venta->{$col} = $venta->{$col};
- }
- $nueva_venta->new();
-
- $venta->estado = -1;
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'cedida')->findOne();
- $data = [
- 'venta' => $venta->id,
- 'estado' => $tipo->id,
- 'fecha' => $f->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data);
- $estado->save();
-
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function entregar()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- return view('ventas.entregar', compact('venta'));
- }
- public static function consolidacion()
- {
- if (get('proyecto')) {
- $id_proyecto = get('proyecto');
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
-
- $ventas = $proyecto->ventas();
- set_time_limit(count($ventas));
-
- $f = Carbon::today(config('app.timezone'));
- setlocale(LC_TIME, 'es');
-
- return view('ventas.consolidacion.show', compact('ventas', 'f'));
- } else {
- $proyectos = model(Proyecto::class)->order_by_asc('descripcion')->find_many();
- return view('ventas.consolidacion.proyectos', compact('proyectos'));
- }
- }
- public static function devolucion()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
- $uf = uf(Carbon::now(config('app.config')))->uf->value;
- $valor = round($venta->saldo() * $uf);
-
- return view('ventas.devolucion', compact('venta', 'valor', 'uf'));
- }
- public static function devolver()
- {
- $id = get('venta');
- $venta = model(Venta::class)->findOne($id);
-
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $uf = uf($f);
- $valor = correctNumber(post('valor'));
-
- $data = [
- 'fecha' => $f->format('Y-m-d'),
- 'valor' => $valor,
- 'tipo' => 1,
- 'uf' => $uf->uf->value,
- 'identificador' => post('identificador'),
- 'banco' => 0
- ];
-
- $banco = model(Banco::class)->where('nombre', post('banco'))->findOne();
- if ($banco) {
- $data['banco'] = $banco->id;
- }
-
- $pago = model(Pago::class)->create($data);
- $pago->newPagado();
-
- $venta->devolucion = $pago->id;
- $venta->save();
- header('Location: ' . url('', ['p' => 'ventas', 'a' => 'show', 'venta' => $venta->id]));
- }
- public static function resciliaciones()
- {
- $resciliaciones = model(Venta::class)->where('estado', 0)->findMany();
-
- return view('ventas.resciliaciones', compact('resciliaciones'));
- }
- public static function firmar()
- {
- $venta = \model(Venta::class)->findOne(get('venta'));
- return view('ventas.firmar', compact('venta'));
- }
- public static function firmando()
- {
- $venta = \model(Venta::class)->findOne(get('venta'));
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $venta->firmar($f);
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
-
- }
- public static function archivar()
- {
- $venta = \model(Venta::class)->findOne(get('venta'));
- return view('ventas.archivar', compact('venta'));
- }
- public static function archivando()
- {
- $venta = \model(Venta::class)->findOne(get('venta'));
- $f = Carbon::createFromDate(post('year'), post('month'), post('day'), config('app.timezone'));
- $venta->archivar($f);
- header('Location: ' . nUrl('ventas', 'show', ['venta' => $venta->id]));
- }
-}
-?>
diff --git a/app/Definition/Controller.php b/app/Definition/Controller.php
deleted file mode 100644
index c0e3dae..0000000
--- a/app/Definition/Controller.php
+++ /dev/null
@@ -1,31 +0,0 @@
-isPublic()) {
-
- return self::{$action}();
- }
- }
- if (self::$default == null and \method_exists(self::class, 'setDefault')) {
- self::setDefault();
- }
- if (self::$default == null) {
- header('Location: .');
- return;
- }
- return self::$default;
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Definition/hasEstado.php b/app/Definition/hasEstado.php
deleted file mode 100644
index 014fe8a..0000000
--- a/app/Definition/hasEstado.php
+++ /dev/null
@@ -1,38 +0,0 @@
-getTable();
- $self = Stringy::create(get_class($this));
- $ns = $self->substr(0, $self->indexOfLast('\\'));
- $self = $self->substr($self->indexOfLast('\\') + 1);
- $column = $self->underscored();
- $class = $ns . '\\Estado' . $self;
- if (substr($table, -1, 1) == 's') {
- $column .= '_id';
- }
-
- return $this->has_many($class, $column)->findMany();
- }
- public function estado()
- {
- $table = $this->getTable();
- $self = Stringy::create(get_class($this));
- $ns = $self->substr(0, $self->indexOfLast('\\'));
- $self = $self->substr($self->indexOfLast('\\') + 1);
- $column = $self->underscored();
- $class = $ns . '\\Estado' . $self;
- if (substr($table, -1, 1) == 's') {
- $column .= '_id';
- }
-
- $id = $this->has_many($class, $column)->max('id');
- return $this->has_many($class, $column)->findOne($id);
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Definition/hasRUT.php b/app/Definition/hasRUT.php
deleted file mode 100644
index 8ba3d80..0000000
--- a/app/Definition/hasRUT.php
+++ /dev/null
@@ -1,20 +0,0 @@
-rut) . '-' . $this->dv;
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Exception/PropertyNotFound.php b/app/Exception/PropertyNotFound.php
deleted file mode 100644
index a35e537..0000000
--- a/app/Exception/PropertyNotFound.php
+++ /dev/null
@@ -1,16 +0,0 @@
-class = $class;
- $this->property = $property;
- $msg = "Property '" . $property . "' for class '" . $class . "' not found.";
- parent::__construct($msg);
- }
-}
\ No newline at end of file
diff --git a/app/Helper/Color.php b/app/Helper/Color.php
deleted file mode 100644
index 68c3199..0000000
--- a/app/Helper/Color.php
+++ /dev/null
@@ -1,169 +0,0 @@
-color = $args[0];
- break;
- }
- $this->color = $this->hex2dec($this->hex2array($args[0]));
- break;
- case 2:
- if (is_array($args[0])) {
- $this->color = $args[0];
- $this->color []= $args[1];
- break;
- }
- $color = $this->hex2array($args[0]);
- $color []= $args[1];
- $this->color = $this->hex2dec($color);
- break;
- case 3:
- case 4:
- if (is_numeric($args[0])) {
- $this->color = $args;
- break;
- }
- $this->color = $this->hex2dec($args);
- break;
- }
- }
- protected function hex2dec(array $hex)
- {
- return array_map('hexdec', $hex);
- }
- protected function dec2hex(array $bin)
- {
- return array_map('dechex', $bin);
- }
- protected function hex2array(string $hex)
- {
- switch (strlen($hex)) {
- case 3:
- case 4:
- case 6:
- case 7:
- return str_split($hex, 2);
- default:
- throw new OutOfBoundsException('The string ' . $hex . ' is not a correct color code.');
- }
- }
- protected function array2hex(array $arr)
- {
- return implode('', $arr);
- }
-
- public function convertTo($type)
- {
- switch (strtolower($type)) {
- case 'hex':
- if (is_numeric($this->color[0])) {
- $this->color = $this->dec2hex($this->color);
- }
- break;
- case 'dec':
- if (!is_numeric($this->color[0])) {
- $this->color = $this->hex2dec($this->color);
- }
- break;
- default:
- throw new InvalidArgumentException($type . ' is not a valid argument.');
- }
- }
- public function add($base_color, $amount)
- {
- $changed = false;
- if (!is_numeric($this->color)) {
- $this->convertTo('dec');
- $changed = true;
- }
- switch (strtolower($base_color)) {
- case 'r':
- $base_color = 0;
- break;
- case 'g':
- $base_color = 1;
- break;
- case 'b':
- $base_color = 2;
- break;
- case 'a':
- $base_color = 3;
- break;
- default:
- throw new OutOfBoundsException("Base color '" . $base_color . "' does not exist.");
- }
- $this->color[$base_color] += $amount;
- if ($changed) {
- $this->convertTo('hex');
- }
- }
- public function print()
- {
- $this->convertTo('hex');
- return implode('', $this->color);
- }
- public function toRGB()
- {
- $changed = false;
- $this->convertTo('dec');
- $str = 'rgb(' . implode(', ', array_map(function($a) {
- return round($a, 2);
- }, $this->color)) . ')';
- if ($changed) {
- $this->convertTo('hex');
- }
- return $str;
- }
- public function __toString()
- {
- return $this->print();
- }
- public function toArray()
- {
- return $this->color;
- }
- public function toVector()
- {
- $changed = false;
- $this->convertTo('dec');
- $arr = $this->toArray();
- if ($changed) {
- $this->convertTo('hex');
- }
- return $arr;
- }
- public function luminosity()
- {
- $changed = false;
- $this->convertTo('dec');
- //sqrt( 0.299*R^2 + 0.587*G^2 + 0.114*B^2 )
- $str = sqrt(0.299 * pow($this->color[0], 2) + 0.587 * pow($this->color[1], 2) + 0.114 * pow($this->color[2], 2)) / 255 * 100;
- if ($changed) {
- $this->convertTo('hex');
- }
- return $str;
- }
- public function isDark()
- {
- if ($this->luminosity() < 50) {
- return true;
- }
- return false;
- }
- public function isBright()
- {
- if ($this->luminosity() > 75) {
- return true;
- }
- return false;
- }
-}
diff --git a/app/Helper/Line.php b/app/Helper/Line.php
deleted file mode 100644
index 02cc0d9..0000000
--- a/app/Helper/Line.php
+++ /dev/null
@@ -1,61 +0,0 @@
-origin = $point_a;
- $this->length = $this->distance($point_a, $point_b);
- $this->direction = $this->gradient($point_a, $point_b);
- }
- public function origin()
- {
- return $this->origin;
- }
- public function length()
- {
- return $this->length;
- }
- public function direction()
- {
- return $this->direction;
- }
- /**
- * Calculate the gradient to move from point a to point b
- * @param array $point_a [Vector]
- * @param array $point_b [Vector]
- * @return array [Vector]
- */
- public function gradient($point_a, $point_b)
- {
- $distance = $this->distance($point_a, $point_b);
- return array_map(function($a, $b) use ($distance) {
- return ($a - $b) / $distance;
- }, $point_b, $point_a);
- }
- // sqrt((a0-b0)²+(a1-b1)²+(a2-b2)²)
- public function distance($point_a, $point_b)
- {
- return sqrt(array_sum(array_map(function($a, $b) {
- return pow($a - $b, 2);
- }, $point_a, $point_b)));
- }
- /**
- * Move from point in the direction of the gradient acording to step_size
- * @param array $point [Vector]
- * @param int $step_size [step size]
- * @return array [Vector]
- */
- public function move($point, $step_size)
- {
- $gradient = $this->direction;
- return array_map(function($a, $b) use ($step_size) {
- return $a + $b * $step_size;
- }, $point, $gradient);
- }
-}
diff --git a/app/Helper/functions.php b/app/Helper/functions.php
deleted file mode 100644
index 7c55e14..0000000
--- a/app/Helper/functions.php
+++ /dev/null
@@ -1,128 +0,0 @@
- "http://{$remote->getIP()}:8080",
- 'headers' => [
- 'Accept' => 'application/json'
- ]
- ])))->getUF($date);
-}
-function format($tipo, $valor, $format = null, $print = false) {
- if ($valor === null) {
- $valor = 0;
- }
- if (strtolower($tipo) == 'localdate') {
- $d = \Carbon\Carbon::parse($valor);
- $d->locale('es_ES');
- if ($format == null) {
- $format = 'DD [de] MMMM [de] YYYY';
- }
- return $d->isoFormat($format);
- }
- if (method_exists('\App\Helper\Format', $tipo)) {
- if ($print) {
- return \App\Helper\Format::$tipo($valor, $print);
- } else {
- return \App\Helper\Format::$tipo($valor);
- }
- } else {
- switch ($tipo) {
- case 'localDate':
- if (isset($format)) {
- $intl = new IntlDateFormatter('es_ES', IntlDateFormatter::SHORT, IntlDateFormatter::SHORT, 'America/Santiago');
- $intl->setPattern($format);
- return ucwords($intl->format($valor));
- }
- case 'percent':
- return \App\Helper\Format::number($valor, 2);
- case 'rut':
- return \App\Helper\Format::number($valor, 0);
- }
- }
-}
-function model(string $class_name) {
- return \Model::factory($class_name);
-}
-function correctNumber($number) {
- if (strpos($number, ',') !== false) {
- return str_replace(',', '.', str_replace('.', '', $number));
- } elseif (substr_count($number, '.') > 1) {
- return str_replace('.', '', $number);
- }
- return $number;
-}
-function parseRanges($range, $numeric = true, $negatives = true) {
- $rns = preg_split('/[,;]+/', $range);
- $data = [];
- foreach ($rns as $p) {
- if (!$negatives) {
- if (strpos($p, '-') !== false) {
- list($ini, $end) = explode('-', $p);
- $data = array_merge($data, range($ini, $end));
- continue;
- }
- }
- if ($numeric) {
- $data []= (float) $p;
- continue;
- }
- $data []= $p;
- }
- return $data;
-}
-function nUrl($p, $a = null, $data = null) {
- $query = ['p' => $p];
- if ($a != null) {
- $query['a'] = $a;
- if ($data != null) {
- $query = array_merge($query, $data);
- }
- }
- return url('', $query);
-}
-function api($p, $a, $data = null) {
- $url = baseUrl() . '/' . 'api';
- $url .= '?' . 'p=' . $p . '&a=' . $a . '&API_KEY=1';
- if ($data != null) {
- $url .= '&' . implode('&', array_map(function($val, $k) {
- return $k . '=' . $val;
- }, $data));
- }
- return $url;
-}
-function doLog($user, $action, $variables) {
- App\Service\Register::log($user, $action, $variables);
-}
-?>
diff --git a/app/Service/Auth.php b/app/Service/Auth.php
deleted file mode 100644
index 7af1f48..0000000
--- a/app/Service/Auth.php
+++ /dev/null
@@ -1,163 +0,0 @@
-getCookie();
- }
- protected function getCookie()
- {
- if (isset($_COOKIE['rememberMe'])) {
- list($s, $t) = \explode(':', $_COOKIE['rememberMe']);
- $this->selector = $s;
- $this->token = $t;
- }
- }
- protected function saveCookie()
- {
- $now = \Carbon\Carbon::now(config('app.timezone'));
- $exp = $now->addHours(config('app.login_hours'));
- \setcookie('rememberMe', $this->selector . ':' . $this->token, $exp->timestamp);
- }
- protected function clearCookie()
- {
- \setcookie('rememberMe', '', \Carbon\Carbon::now(config('app.timezone'))->timestamp);
- }
- protected function generateToken()
- {
- $this->selector = bin2hex(\random_bytes(12));
- $this->token = bin2hex(\random_bytes(20));
- }
- public function login($username, $password)
- {
- $user = \Model::factory(\Incoviba\common\User::class)->where('name', $username)->where('enabled', 1)->findOne();
- if ($user !== false) {
- if (\password_verify($password, $user->password) === false) {
- $this->clearCookie();
- return false;
- }
-
- $this->generateToken();
- $now = \Carbon\Carbon::now(config('app.timezone'));
- $exp = $now->addHours(-config('app.login_hours'));
- $auth = \Model::factory(\Incoviba\common\Auth::class)->where('user_id', $user->id)->whereGt('time', $exp->timestamp)->where('status', 1)->findOne();
- if ($auth !== false) {
- $auth->time('now');
- $auth->selector = $this->selector;
- $auth->token($this->token);
- $auth->save();
- $this->saveCookie();
- return true;
- }
-
- $auth = \Model::factory(\Incoviba\common\Auth::class)->create();
- $auth->user_id = $user->id;
- $auth->time('now');
- $auth->selector = $this->selector;
- $auth->token($this->token);
-
- try {
- $auth->save();
- $this->saveCookie();
- return true;
- } catch (\Exception $e) {
- $this->clearCookie();
- return false;
- }
- }
- return false;
- }
- public function isIn()
- {
- if ($this->selector == null) {
- return false;
- }
- $auths = \Model::factory(\Incoviba\common\Auth::class)->where('selector', $this->selector)->findMany();
- if ($auths === false) {
- $this->clearCookie();
- return false;
- }
- foreach ($auths as $auth) {
- if (\password_verify($this->token, $auth->token)) {
- return $auth->isIn();
- }
- }
- return false;
- }
- public function User()
- {
- if ($this->selector == null) {
- return false;
- }
- $auths = \Model::factory(\Incoviba\common\Auth::class)->where('selector', $this->selector)->findMany();
- if ($auths === false) {
- return false;
- }
- foreach ($auths as $auth) {
- if (\password_verify($this->token, $auth->token)) {
- return $auth->user();
- }
- }
- return false;
- }
- public function hasAccess()
- {
- if ($this->selector == null) {
- return false;
- }
- $auths = \Model::factory(\Incoviba\common\Auth::class)->where('selector', $this->selector)->findMany();
- if ($auths === false) {
- return false;
- }
- foreach ($auths as $auth) {
- if (\password_verify($this->token, $auth->token)) {
- return $auth->user()->hasAccess();
- }
- }
- return false;
- }
- public function checkAccess($controller, $action = null)
- {
- if ($this->selector == null) {
- return false;
- }
- $auths = \Model::factory(\Incoviba\common\Auth::class)->where('selector', $this->selector)->findMany();
- if ($auths === false) {
- return false;
- }
- foreach ($auths as $auth) {
- if (\password_verify($this->token, $auth->token)) {
- return $auth->user()->checkAccess($controller, $action);
- }
- }
- return false;
- }
- public function logout()
- {
- $this->clearCookie();
- if ($this->selector == null) {
- return true;
- }
- $auths = \Model::factory(\Incoviba\common\Auth::class)->where('selector', $this->selector)->findMany();
- if ($auths === false) {
- return true;
- }
- foreach ($auths as $auth) {
- if (\password_verify($this->token, $auth->token)) {
- $auth->status = 0;
- try {
- $auth->save();
- return true;
- } catch (\Exception $e) {
- return false;
- }
- }
- }
- return true;
- }
-}
diff --git a/app/Service/Borrador.php b/app/Service/Borrador.php
deleted file mode 100644
index 4f4b3af..0000000
--- a/app/Service/Borrador.php
+++ /dev/null
@@ -1,118 +0,0 @@
-cierre = $cierre;
- $this->lineas = [];
- }
- protected function add(string $str, int $new_line = 0)
- {
- $this->lineas []= $str;
- if ($new_line > 0) {
- $this->newLine($new_line);
- }
- }
- protected function newLine($n = 1)
- {
- for ($i = 0; $i < $n; $i ++) {
- $this->lineas []= '';
- }
- }
- protected function load()
- {
- $this->word = IOFactory::load('borrador-' . $this->cierre->proyecto()->nombre . '.docx');
- }
- protected function extract()
- {
- $this->load();
- $data = [];
- foreach ($this->word->getSections() as $section) {
- foreach ($section->getElements() as $element) {
- $r = $this->elementGet($element);
- $data []= $r;
- }
- }
- if (count($data) > 0) {
- $this->text = $data;
- }
- }
- protected function elementGet($element)
- {
- if ($element instanceof TextBreak) {
- return PHP_EOL;
- }
- if ($element instanceof TextRun) {
- $data = [];
- foreach ($element->getElements() as $e) {
- $data []= $this->elementGet($e);
- }
- return implode('', $data);
- }
- if (!method_exists($element, 'getText')) {
- d($element);
- }
- return $element->getText();
- }
- protected function build()
- {
- if ($this->text == null) {
- $this->extract();
- }
- foreach ($this->text as $line) {
- if ($line == PHP_EOL) {
- $this->newLine();
- continue;
- }
- if (strpos($line, '[[') !== false) {
- $replacer = new Replacer();
- $this->add($replacer->replace($line, $this->cierre));
- continue;
- }
- $this->add($line);
- }
- }
- public function create()
- {
- $output = new PhpWord();
-
- $output->getSettings()->setDecimalSymbol(',');
- $output->getSettings()->setThemeFontLang(new Language(Language::ES_ES));
-
- $section = $output->addSection();
- foreach ($this->lineas as $linea) {
- if ($linea == '') {
- $section->addTextBreak();
- continue;
- }
- $section->addText($linea);
- }
-
- $output->getSettings()->setTrackRevisions(true);
-
- $writer = IOFactory::createWriter($output);
- $filename = 'Borrador ' . $this->cierre->propietario()->nombreCompleto() . ' con ' . $this->cierre->proyecto()->inmobiliaria()->razon_social . '.docx';
- $writer->save($filename);
- }
- public function show()
- {
- $this->build();
- return implode(PHP_EOL, $this->lineas);
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Service/DBToModel.php b/app/Service/DBToModel.php
deleted file mode 100644
index 158e85c..0000000
--- a/app/Service/DBToModel.php
+++ /dev/null
@@ -1,158 +0,0 @@
-name = $name;
- $this->db = \ORM::get_db($name);
- }
-
- public function run()
- {
- $this->getTables();
- foreach ($this->tables as $table) {
- if ($this->createClass($table)) {
- echo 'ok
', PHP_EOL;
- }
- }
- }
- protected function getType($type)
- {
- if (strpos($type, '(') !== false) {
- $type = substr($type, 0, strpos($type, '('));
- }
- if (strpos($type, ' ') !== false) {
- $type = substr($type, 0, strpos($type, ' '));
- }
- switch ($type) {
- case 'int':
- case 'float':
- case 'double':
- case 'char':
- return trim($type);
- case 'date':
- case 'datetime':
- return trim(strtolower($type));
- case 'varchar':
- case 'text':
- case 'blob':
- return 'string';
- case 'bigint':
- case 'tinyint':
- case 'enum':
- return 'int';
- default:
- d($type);
- }
- }
- protected function getTables()
- {
- $q = "SHOW TABLES";
- $st = $this->db->query($q);
- $results = $st->fetchAll(\PDO::FETCH_COLUMN);
- $this->tables = [];
- foreach ($results as $result) {
- $this->tables []= $result;
- }
- }
- protected function getColumns($table)
- {
- $q = "SHOW COLUMNS FROM `" . $table . "`";
- $st = $this->db->query($q);
- $results = $st->fetchAll(\PDO::FETCH_OBJ);
- return $results;
- }
- protected function phpDoc($columns)
- {
- $str = ['/**'];
- $str []= ' *';
- foreach ($columns as $column) {
- $str []= ' * @property ' . $this->getType($column->Type) . ' ' . $column->Field;
- }
- $str []= ' *';
- $str []= ' */';
-
- return implode(PHP_EOL, $str);
- }
- protected function className($table)
- {
- $name = Stringy::create($table)->upperCamelize();
- return $name;
- }
- protected function createClass($table)
- {
- $class = '' . $this->className($table);
- $columns = $this->getColumns($table);
- $docs = $this->phpDoc($columns);
-
- $output = ['name}';";
- $output []= '}';
- $output []= '?>';
-
- //d(implode(PHP_EOL, $output));
-
- $filename = realpath(root() . '/src') . DIRECTORY_SEPARATOR . $class . '.php';
- return file_put_contents($filename, implode(PHP_EOL, $output));
- }
- public function create($namespace, $table)
- {
- $class = '' . $this->className($table);
- $columns = $this->getColumns($table);
- $docs = $this->phpDoc($columns);
-
- $namespace = trim($namespace, '\\');
-
- $output = ['name}';";
- $output []= '}';
- $output []= '?>';
- $output = implode(PHP_EOL, $output);
-
- $namespace = explode('\\', $namespace);
- array_shift($namespace);
- $namespace = implode('/', $namespace);
-
- $filename = realpath(root() . '/src/' . $namespace) . DIRECTORY_SEPARATOR . $class . '.php';
-
- $result = [
- 'result' => false,
- 'filename' => $filename,
- 'output' => $output
- ];
- if (!file_exists($filename)) {
- $result['result'] = file_put_contents($filename, $output);
- } else {
- $result['result'] = true;
- }
- return json_encode($result);
- }
- public function list()
- {
- $this->getTables();
- $output = [];
- foreach ($this->tables as $table) {
- $output []= ['table' => $table, 'model' => '' . $this->className($table)];
- }
-
- return json_encode(['models' => $output]);
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Service/Factory.php b/app/Service/Factory.php
deleted file mode 100644
index ac7386a..0000000
--- a/app/Service/Factory.php
+++ /dev/null
@@ -1,204 +0,0 @@
-class = $class;
- $this->is_aggregator = true;
- if (is_subclass_of($class, 'Model')) {
- $this->is_aggregator = false;
- }
- }
- public function new()
- {
- $class = $this->class;
- if ($this->is_aggregator) {
- return new $class();
- }
- return model($class)->create();
- }
- public function create($data)
- {
- $class = $this->class;
- if ($this->is_aggregator) {
- $obj = new $class();
- $obj->create($data);
- return $obj;
- }
- return model($class)->create($data);
- }
- /**
- * [column => value, column => [value, operator]]
- * @var array
- */
- protected $conditions;
- public function where(array $data)
- {
- if ($this->conditions == null) {
- $this->conditions = $data;
- return $this;
- }
- $this->conditions = array_merge($this->conditions, $data);
- return $this;
- }
- /**
- * [column, column => order]
- * @var array
- */
- protected $order;
- public function order(array $data)
- {
- if ($this->order == null) {
- $this->order = $data;
- return $this;
- }
- $this->order = array_merge($this->order, $data);
- return $this;
- }
- protected $limit;
- public function limit(array $data)
- {
- if (!isset($data['limit'])) {
- $data['limit'] = $data[0];
- }
- if (!isset($data['offset'])) {
- $data['offset'] = 0;
- if (isset($data[1])) {
- $data['offset'] = $data[1];
- }
- }
- $this->limit = (object) ['limit' => $data['limit'], 'offset' => $data['offset']];
- return $this;
- }
- protected $many;
- public function find($many = false)
- {
- $this->many = $many;
- if ($this->is_aggregator) {
- return $this->findAggregator();
- }
- return $this->findModel();
- }
-
- protected function findModel()
- {
- $objs = model($this->class);
- $objs = $this->parseLimit($this->parseOrder($this->parseConditions($objs)));
-
- if ($this->many) {
- return $objs->findMany();
- }
- return $objs->findOne();
- }
- protected function parseConditions($orm)
- {
- if ($this->conditions == null) {
- return $orm;
- }
- foreach ($this->conditions as $column => $value) {
- if (is_array($value)) {
- list($value, $op) = $value;
- switch ($op) {
- case '>':
- case 'gt':
- $orm = $orm->whereGt($column, $value);
- break;
- }
- } else {
- $orm = $orm->where($column, $value);
- }
- }
- return $orm;
- }
- protected function parseOrder($orm)
- {
- if ($this->order == null) {
- return $orm;
- }
- foreach ($this->order as $column => $order) {
- if (is_numeric($column)) {
- $column = $order;
- $order = 'asc';
- }
- switch (strtolower($order)) {
- case 'asc':
- default:
- $orm = $orm->orderByAsc($column);
- break;
- case 'desc':
- $orm = $orm->orderByDesc($column);
- break;
- case 'expr':
- $orm = $orm->orderByExpr($column);
- break;
- }
- }
- return $orm;
- }
- protected function parseLimit($orm)
- {
- if ($this->limit == null) {
- return $orm;
- }
- $orm = $orm->limit($this->limit->limit);
- if (isset($this->limit->offset)) {
- $orm = $orm->offset($this->limit->offset);
- }
- return $orm;
- }
- protected function findAggregator()
- {
- $model = $this->modelName($this->class);
- $ids = $this->getIds($model);
- $class = $this->class;
- if (count($ids) == 0) {
- return false;
- }
- if ($this->many) {
- $objs = [];
- foreach ($ids as $id) {
- $objs []= new $class($id);
- }
- } else {
- $objs = new $class($ids[0]);
- }
- return $objs;
- }
- protected function getIds($model)
- {
- $id = $this->getModelId($model);
- $table = $this->getTable($model);
- $st = \ORM::forTable($table)->select($id);
- $st = $this->parseConditions($st);
- $results = $st->findArray();
- $output = array_map(function($a) use($id) {
- return $a[$id];
- }, $results);
- return $output;
- }
- protected function modelName($class)
- {
- $arr = explode("\\", $class);
- \array_push($arr, end($arr));
- return implode("\\", $arr);
- }
- protected function getModelId($model)
- {
- $table = $this->getTable($model);
- $query = "SHOW KEYS FROM {$table} WHERE Key_name = 'PRIMARY'";
- $st = \ORM::getDb()->query($query);
- $results = $st->fetchAll(\PDO::FETCH_OBJ);
- return $results[0]->Column_name;
- }
- protected function getTable($model)
- {
- $arr = explode("\\", $model);
- return Stringy::create(end($arr))->toLowerCase() . '';
- }
-}
diff --git a/app/Service/Informador.php b/app/Service/Informador.php
deleted file mode 100644
index c64db26..0000000
--- a/app/Service/Informador.php
+++ /dev/null
@@ -1,463 +0,0 @@
-title = $title;
- } else {
- $this->title = 'Informe';
- }
- }
-
- public function addColumn(string $title, $col = '')
- {
- if ($col == '') {
- if ($this->columns == null) {
- $i = 0;
- } else{
- $i = count($this->columns);
- }
- $col = $this->mapColumn($i);
- }
-
- if (isset($this->columns[$col])) {
- $columns = [];
- foreach ($this->columns as $c => $data) {
- if (ord($c) < ord($col)) {
- $columns[$c] = $data;
- } elseif (ord($c) == ord($col)) {
- $columns[$col] = $title;
- } else {
- $columns[chr(ord($c) + 1)] = $data;
- }
- }
- $this->columns = $columns;
- } else {
- $this->columns[$col] = $title;
- }
- }
- public function mapColumn($n)
- {
- $letters = range('A', 'Z');
- $max = count($letters);
- $r = $n / $max + 1;
- $p = floor($r - 1) - 1;
- $i = $n % $max;
- if ($r >= 2) {
- return $letters[$p] . $letters[$i];
- }
- return $letters[$i];
- }
- public function getColumn($col_title)
- {
- return array_search($col_title, $this->columns);
- }
- public function getColumnNumber($col)
- {
- $letters = range('A', 'Z');
- if (strlen($col) > 1) {
- $ls = str_split($col);
- $n = 0;
- foreach ($ls as $i => $l) {
- $n += array_search($l, $letters) + $i * count($letters) + 1;
- }
- return $n;
- }
- return array_search($col, $letters);
- }
- public function addColumns(array $columns)
- {
- foreach ($columns as $column) {
- $this->addColumn($column);
- }
- }
- public function addData(int $row, $data, $col = '')
- {
- if (!isset($this->data[$row])) {
- $this->data[$row] = [];
- }
- if ($col == '') {
- $i = count($this->data[$row]);
- $col = $this->mapColumn($i);
- } elseif (ctype_print($col)) {
- $col = $this->getColumn($col);
- } else {
- $col = $this->mapColumn($col);
- }
-
- if (isset($this->data[$row][$col])) {
- $data_array = [];
- foreach ($this->data[$row] as $c => $d) {
- if (ord($c) < ord($col)) {
- $data_array[$c] = $d;
- } elseif (ord($c) == ord($col)) {
- $data_array[$col] = $this->parseData($data);
- } else {
- $data_array[chr(ord($c) + 1)] = $d;
- }
- }
- $this->data[$row] = $data_array;
- } else {
- $this->data[$row][$col] = $this->parseData($data);
- }
- }
- protected function parseData($data)
- {
- if ($this->isDate($data)) {
- // Date
- return Date::PHPToExcel($data);
- }
- return $data;
- }
- protected function isDate($data)
- {
- try {
- if (strpos($data, '-') === false) {
- return false;
- }
- $fecha = explode('-', $data);
- if (count($fecha) != 3) {
- return false;
- }
- list($year, $month, $day) = $fecha;
- if (strlen($year) == 4 and strlen($month) <= 2 and strlen($day) <= 2) {
- return true;
- }
- if (ctype_digit($year) and ctype_digit($month) and ctype_digit($day)) {
- $f = Carbon::parse($data, config('app.timezone'));
- return true;
- }
- return false;
- } catch(\Exception $e) {
- return false;
- }
- return false;
- }
- public function addDataRow(int $row, array $data_array)
- {
- foreach ($data_array as $data) {
- $this->addData($row, $data);
- }
- }
- public function addDatas(array $data_matrix)
- {
- foreach ($data_matrix as $row => $data_array) {
- $this->addDataRow($row, $data_array);
- }
- }
- protected function findTitleColumn($title)
- {
- return array_search($title, $this->columns);
- }
- public function addFormat($format, $title = '')
- {
- $col = 'A';
- if ($title == '') {
- $i = count($this->col_formats);
- $col = $this->mapColumn($i);
- } else {
- $col = $this->findTitleColumn($title);
- }
-
- if (isset($this->col_formats[$col])) {
- $columns = [];
- foreach ($this->col_formats as $c => $data) {
- if (ord($c) < ord($col)) {
- $columns[$c] = $data;
- } elseif (ord($c) == ord($col)) {
- $columns[$col] = $this->translateFormat($format);
- } else {
- $columns[chr(ord($c) + 1)] = $data;
- }
- }
- $this->col_formats = $columns;
- } else {
- $this->col_formats[$col] = $this->translateFormat($format);
- }
-
- uksort($this->col_formats, function($ak, $bk) {
- return strcmp($ak, $bk);
- });
- }
- protected function translateFormat(array $format)
- {
- $translated = [];
- foreach ($format as $category => $values) {
- switch ($category) {
- case 'numberFormat':
- $data = $this->translateNumberFormat($values);
- break;
- case 'alignment':
- $data = $this->translateAlignment($values);
- break;
- case 'font':
- $data = $this->translateFont($values);
- break;
- case 'fill':
- $data = $this->translateFill($values);
- break;
- case 'borders':
- $data = $this->translateBorders($values);
- break;
- }
- $translated[$category] = $data;
- }
- return $translated;
- }
- protected function translateNumberFormat(array $values)
- {
- $translated = [];
- foreach ($values as $value) {
- switch ($value) {
- case 'short-date':
- $translated['formatCode'] = 'dd-mm-yyyy';
- break;
- case 'date':
- $translated['formatCode'] = 'dd mmmm, yyyy';
- break;
- case 'thousands':
- $translated['formatCode'] = NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1;
- break;
- case 'pesos':
- $translated['formatCode'] = '$ #.###';
- break;
- default:
- $translated['formatCode'] = $value;
- }
- }
- return $translated;
- }
- protected function translateAlignment(array $values)
- {
- $translated = [];
- foreach ($values as $type => $value) {
- switch ($type) {
- case 'horizontal':
- switch ($value) {
- case 'center':
- $new = Alignment::HORIZONTAL_CENTER;
- break;
- }
- break;
- case 'vertical':
- switch ($value) {
- case 'middle':
- case 'center':
- $new = Alignment::VERTICAL_CENTER;
- }
- default:
- $new = $value;
- break;
- }
- $translated[$type] = $new;
- }
- return $translated;
- }
- protected function translateFont(array $values)
- {
- $translated = [];
- foreach ($values as $type => $value) {
- switch ($type) {
- case 'color':
- $new = $this->translateColor($value);
- break;
- default:
- $new = $value;
- break;
- }
- $translated[$type] = $new;
- }
- return $translated;
- }
- protected function translateFill(array $values)
- {
- $translated = [];
- foreach ($values as $type => $value) {
- switch ($type) {
- case 'fillType':
- switch ($value) {
- case 'solid':
- $new = Fill::FILL_SOLID;
- break;
- default:
- $new = $value;
- break;
- }
- break;
- case 'color':
- $new = $this->translateColor($value);
- break;
- default:
- $new = $value;
- break;
- }
- $translated[$type] = $new;
- }
- return $translated;
- }
- protected function translateBorders(array $values)
- {
- $translated = [];
- foreach ($format as $category => $value) {
- switch ($category) {
- case 'allBorders':
- case 'left':
- case 'right':
- case 'top':
- case 'bottom':
- case 'diagonal':
- case 'vertical':
- case 'horizontal':
- $data = $this->translateBorder($value);
- break;
- default:
- $data = $value;
- }
- $translated[$category] = $data;
- }
- return $translated;
- }
- protected function translateBorder(array $values)
- {
- $translated = [];
- foreach ($values as $type => $value) {
- switch ($type) {
- case 'color':
- $new = $this->translateColor($value);
- break;
- default:
- $new = $value;
- break;
- }
- $translated[$type] = $new;
- }
- return $translated;
- }
- protected function translateColor($color)
- {
- $color_definitions = [
- 'red' => 'ff0000',
- 'light-red' => 'ffcccc',
- 'dark-red' => 'a00000'
- ];
- if (is_array($color)) {
- $t = dechex(255 * $color['transparency'] / 100);
- $c = $color_definitions[$color['color']];
- $hex = $t . $c;
- return ['argb' => $hex];
- }
- return ['rgb' => $color_definitions[$color]];
- }
- public function addFormats(array $formats)
- {
- foreach ($formats as $title => $format) {
- $this->addFormat($format, $title);
- }
- }
- public function addTotal(string $col)
- {
- if (isset($this->columns[$col])) {
- $sum = 0;
- foreach ($this->data as $row => $data) {
- $sum += $data[$col];
- }
- $this->totals[$col] = $sum;
- }
- }
- public function addAverage(string $col)
- {
- $this->addTotal($col);
- $this->totals[$col] /= count($this->data);
- }
-
- protected function fillData()
- {
- foreach ($this->data as $row => $data) {
- $this->data[$row] = $this->fillAndSort($data);
- }
- if (count($this->totals) > 0) {
- $this->totals = $this->fillAndSort($this->totals);
- }
- }
- protected function fillAndSort(array $row)
- {
- foreach ($this->columns as $val) {
- if (!isset($row[$val])) {
- $row[$val] = '';
- }
- }
- function sortArrayByArray(Array $array, Array $orderArray) {
- $ordered = array();
- foreach($orderArray as $key) {
- if(array_key_exists($key, $array)) {
- $ordered[$key] = $array[$key];
- unset($array[$key]);
- }
- }
- return $ordered + $array;
- }
- $row = sortArrayByArray($row, $this->columns);
-
- return $row;
- }
-
- public function informe()
- {
- $ea = new Spreadsheet();
- $ea->getProperties()->setCreator('Juan Pablo Vial B.');
- $ea->getProperties()->setTitle($this->title);
- $ea->getProperties()->setCompany('Incoviba S.A.');
-
- $ews = $ea->getActiveSheet();
-
- $ews->fromArray(array($this->columns), '', 'A1');
- $ews->fromArray($this->data, '', 'A2');
- $end = 2;
- if ($this->totals != null and count($this->totals) > 0) {
- $ews->fromArray($this->totals, '', 'A' . count($data) + 2);
- $end = 3;
- }
-
- if ($this->col_formats != null and count($this->col_formats) > 0) {
- foreach ($this->col_formats as $col => $format) {
- $ews->getStyleByColumnAndRow($this->getColumnNumber($col), 2, $this->getColumnNumber($col), count($this->data) + $end)->applyFromArray($format);
- }
- }
-
- for ($col = 0; $col < count($this->columns); $col ++) {
- $ews->getColumnDimensionByColumn($col)->setAutoSize(true);
- }
-
- $ews->setAutoFilterByColumnAndRow(0, 1, count($this->columns) - 1, count($this->data));
-
- $hoy = Carbon::now(config('app.timezone'));
- $filename = str_replace('ñ', 'n', $this->title . ' - ' . $hoy->format('Y-m-d') . '.xlsx');
-
- $writer = IOFactory::createWriter($ea, "Xlsx");
-
- header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8");
- header('Content-Transfer-Encoding: binary');
- header('Content-Disposition: attachment; filename="' . $filename . '"');
- header('Cache-Control: max-age=0');
-
- $writer->save('php://output');
- }
-}
-?>
diff --git a/app/Service/Informe/Contabilidad/Resumen.php b/app/Service/Informe/Contabilidad/Resumen.php
deleted file mode 100644
index e20266a..0000000
--- a/app/Service/Informe/Contabilidad/Resumen.php
+++ /dev/null
@@ -1,190 +0,0 @@
-separator = $separator;
- }
-
- protected function getVentas($id_proyecto)
- {
- $proyecto = model(Proyecto::class)->findOne($id_proyecto);
- $ventas = $proyecto->ventas();
- $output = [];
- foreach ($ventas as $venta) {
- $found = false;
- foreach ($output as $v) {
- if ($v->unidad()->descripcion == $venta->unidad()->descripcion) {
- $found = true;
- break;
- }
- }
- if (!$found) {
- $output []= $venta;
- }
- }
- return $output;
- }
- protected function startOfYear(DateTimeInterface $up_to)
- {
- return new DateTimeImmutable((clone $up_to)->sub(new DateInterval('P1Y'))->format('31-12-Y'));
- }
- protected function defaultValueDate(DateTimeInterface $up_to, $glosa = '')
- {
- return (object) ['fecha' => $this->startOfYear($up_to), 'valor' => 0, 'glosa' => $glosa, 'estado' => ''];
- }
- protected function extractValueDate(Pago $pago, $glosa = '')
- {
- return (object) ['fecha' => $pago->fecha(), 'valor' => $pago->valor, 'glosa' => $glosa, 'estado' => $pago->estado()->tipo()->descripcion];
- }
- protected function getAnticipos(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->pie == 0) {
- return [$this->defaultValueDate($up_to)];
- }
- $cuotas = $venta->pie()->cuotas('fecha', $up_to);
- $ly = $this->startOfYear($up_to);
- $older = array_reduce($cuotas, function($sum, $item) use ($ly) {
- if ($item->pago()->estado()->tipo()->active != 1 or strtolower($item->pago()->estado()->tipo()->descripcion) == 'no pagado') {
- return $sum;
- }
- if ($item->pago()->fecha() >= $ly) {
- return $sum;
- }
- return $sum + $item->pago()->valor;
- });
- $current = array_filter($cuotas, function($item) use ($ly) {
- return $item->pago()->fecha() >= $ly;
- });
- foreach ($current as &$item) {
- $item = $this->extractValueDate($item->pago(), "Cuota {$item->numero}");
- }
- return array_merge([(object) ['fecha' => $ly, 'valor' => $older, 'glosa' => 'Anticipo acumulado', 'estado' => 'Pagado']], $current);
- }
- protected function getReajuste(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->pie == 0 or $venta->pie()->reajuste == null) {
- return $this->defaultValueDate($up_to, 'Reajuste');
- }
- return $this->extractValueDate($venta->pie()->reajuste(), 'Reajuste');
- }
- protected function getAbono(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->escritura == 0) {
- return $this->defaultValueDate($up_to, 'Abono');
- }
- return $this->extractValueDate($venta->escritura()->pago(), 'Abono');
- }
- protected function getBono(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->bono_pie == 0) {
- return $this->defaultValueDate($up_to, 'Bono Pie');
- }
- return $this->extractValueDate($venta->bonoPie()->pago(), 'Bono Pie');
- }
- protected function getCredito(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->credito == 0) {
- return $this->defaultValueDate($up_to, 'Credito');
- }
- return $this->extractValueDate($venta->credito()->pago(), 'Credito');
- }
- protected function getSubsidio(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->subsidio == 0) {
- return [$this->defaultValueDate($up_to, 'Ahorro'), $this->defaultValueDate($up_to, 'Subsidio')];
- }
- return [$this->extractValueDate($venta->subsidio()->pago(), 'Ahorro'), $this->extractValueDate($venta->subsidio()->subsidio(), 'Subsidio')];
- }
- protected function getResciliacion(Venta $venta, DateTimeInterface $up_to)
- {
- if ($venta->resciliacion == null) {
- return $this->defaultValueDate($up_to, 'Resciliacion');
- }
- return $this->extractValueDate($venta->resciliacion()->pago(), 'Resciliacion');
- }
- protected function getPagos(Venta $venta, DateTimeInterface $up_to)
- {
- $pagos = [];
- $pagos = array_merge($pagos, $this->getAnticipos($venta, $up_to));
- $pagos []= $this->getReajuste($venta, $up_to);
- $pagos []= $this->getAbono($venta, $up_to);
- $pagos []= $this->getBono($venta, $up_to);
- $pagos []= $this->getCredito($venta, $up_to);
- $pagos = array_merge($pagos, $this->getSubsidio($venta, $up_to));
- return array_filter($pagos, function($item) {
- return $item->valor != 0;
- });
- }
-
- protected function buildLine(Venta $venta, $pago)
- {
- if ($pago->valor > 0) {
- return ['', $venta->unidad()->descripcion, $pago->fecha->format('d/m/Y'), $pago->glosa, '', $pago->valor, $pago->estado];
- }
- return ['', $venta->unidad()->descripcion, $pago->fecha->format('d/m/Y'), $pago->glosa, -$pago->valor, '', $pago->estado];
- }
- protected function buildLibro(Venta $venta, DateTimeInterface $up_to)
- {
- $pagos = $this->getPagos($venta, $up_to);
- $output = [
- ['', "Cuenta: Anticipos Dpto {$venta->unidad()->descripcion}"],
- ['', 'Fecha', 'Glosa', 'Haber', 'Debe', 'Estado']
- ];
- $debe = 0;
- $haber = 0;
- foreach ($pagos as $pago) {
- $output []= $this->buildLine($venta, $pago);
- if ($pago->valor > 0) {
- $debe += $pago->valor;
- }
- else {
- $haber -= $pago->valor;
- }
- }
- $output []= ['', '', '', 'Total', $haber, $debe];
- return $output;
- }
-
- public function build(int $id_proyecto, DateTimeInterface $up_to)
- {
- ini_set('max_execution_time', 60 * 60);
- $ventas = $this->getVentas($id_proyecto);
-
- $output = ["Libro Mayor {$ventas[0]->proyecto()->descripcion}", ''];
- foreach ($ventas as $venta) {
- $output = array_merge($output, $this->buildLibro($venta, $up_to));
- }
-
- $filename = "Contabilidad - Resumen - {$ventas[0]->proyecto()->descripcion} - {$up_to->format('Y-m-d')}.xlsx";
- $informe = new Informe();
- $informe->createSpreadsheet()
- ->addArray($output)
- ->formatColumn('E')
- ->formatColumn('F')
- ->send($filename);
- }
-}
diff --git a/app/Service/Informe/Informe.php b/app/Service/Informe/Informe.php
deleted file mode 100644
index 8254a10..0000000
--- a/app/Service/Informe/Informe.php
+++ /dev/null
@@ -1,55 +0,0 @@
-spreadsheet = new Spreadsheet();
- return $this;
- }
- protected function formatArray(array $data)
- {
- $maxCols = 0;
- foreach ($data as $row) {
- if (!is_array($row)) {
- continue;
- }
- if (count($row) > $maxCols) {
- $maxCols = count($row);
- }
- }
- foreach ($data as &$row) {
- if (!is_array($row)) {
- $row = [$row];
- }
- if (count($row) < $maxCols) {
- $row = array_merge($row, array_fill(0, $maxCols - count($row), ''));
- }
- }
- return $data;
- }
- public function addArray(array $data, string $start = 'A1')
- {
- $this->spreadsheet->getActiveSheet()->fromArray($this->formatArray($data), null, $start);
- return $this;
- }
- public function formatColumn(string $column)
- {
- $this->spreadsheet->getActiveSheet()->getStyle("{$column}:{$column}")->getNumberFormat()->setFormatCode('#,##0');
- return $this;
- }
- public function send(string $filename)
- {
- header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
- header("Content-Disposition: attachment;filename=\"{$filename}\"");
- header('Cache-Control: max-age=0');
-
- $writer = IOFactory::createWriter($this->spreadsheet, 'Xlsx');
- $writer->save('php://output');
- }
-}
diff --git a/app/Service/Money.php b/app/Service/Money.php
deleted file mode 100644
index 2472e62..0000000
--- a/app/Service/Money.php
+++ /dev/null
@@ -1,55 +0,0 @@
-parseDate($date);
- if (!$this->checkNextMonthValueCalculationByDate($date)) {
- return $this->emptyResult();
- }
-
- $response = $this->client->get('api/uf/value/' . $date->format('Y-m-d'));
-
- if (!$this->isOk($response)) {
- return $this->emptyResult();
- }
-
- $body = $response->getBody()->getContents();
- if (trim($response->getBody()) === '') {
- return $this->emptyResult();
- }
- return json_decode($body);
- }
-
- protected function parseDate(string|DateTimeInterface $date): DateTimeInterface
- {
- if (is_string($date)) {
- $date = Carbon::parse($date, config('app.timezone'));
- }
- return $date;
- }
- protected function checkNextMonthValueCalculationByDate(DateTimeInterface $date): bool
- {
- $next_m_9 = Carbon::today(config('app.timezone'))->copy()->endOfMonth()->addDays(9);
- $date = Carbon::parse($date);
- return $date->lessThan($next_m_9);
- }
- protected function isOk(ResponseInterface $response): bool
- {
- $statusCode = $response->getStatusCode();
- return $statusCode >= 200 and $statusCode < 300;
- }
- protected function emptyResult(): object
- {
- return (object) ['total' => 0];
- }
-}
diff --git a/app/Service/Register.php b/app/Service/Register.php
deleted file mode 100644
index 03f96e0..0000000
--- a/app/Service/Register.php
+++ /dev/null
@@ -1,34 +0,0 @@
- $user,
- 'action' => $action,
- 'time' => Carbon::now(config('app.timezone'))->toDateTimeString()//->format('Y-m-d HH:mm:ss')
- ];
- $registry = model(RModel::class)
- ->where('user', $user)
- ->where('action', $action)
- ->where('time', $data['time'])
- ->findOne();
- if (!$registry) {
- $registry = model(RModel::class)->create($data);
- $registry->save();
- }
- foreach ($variables as $data) {
- $data['registry'] = $registry->id;
- $log = (new Factory(RegistryData::class))->where($data)->find();
- if (!$log) {
- $log = model(RegistryData::class)->create($data);
- $log->save();
- }
- }
- }
-}
diff --git a/app/Service/Remote.php b/app/Service/Remote.php
deleted file mode 100644
index 2e6e69e..0000000
--- a/app/Service/Remote.php
+++ /dev/null
@@ -1,19 +0,0 @@
-connection->connect();
- $statement = $connection->query($query);
- $result = $statement->fetch(PDO::FETCH_ASSOC);
- return $result['ip'];
- }
-}
diff --git a/app/Service/Replacer.php b/app/Service/Replacer.php
deleted file mode 100644
index bf61513..0000000
--- a/app/Service/Replacer.php
+++ /dev/null
@@ -1,127 +0,0 @@
-parseLine($line);
-
- $output = $line;
- foreach ($instructions as $instruction) {
- $output = str_replace($instruction['original'], $this->buildLine($instruction['instruction'], $data), $output);
- }
- return $output;
- }
- protected function parseLine($line)
- {
- $ini_el = '[[';
- $end_el = ']]';
-
- $instructions = [];
- $offset = 0;
- while (strpos($line, $ini_el, $offset) !== false) {
- $ini = strpos($line, $ini_el, $offset) + strlen($ini_el);
- $end = strpos($line, $end_el, $offset);
- $find = substr($line, $ini, $end - $ini);
- $instructions []= ['original' => $ini_el . $find . $end_el, 'instruction' => $find];
- $offset = $end + 1;
- }
- return $instructions;
- }
- protected function buildLine($instructions, $data)
- {
- if (strpos($instructions, '|') !== false) {
- $instructions = explode('|', $instructions);
- } else {
- $instructions = [$instructions];
- }
- $output = '';
- foreach ($instructions as $instruction) {
- $output = $this->buildReplace($instruction, $data, $output);
- }
- return $output;
- }
- protected function buildReplace($instruction, $data, $output = null)
- {
- if (strpos($instruction, '(') !== false) {
- $ini = strpos($instruction, '(') + 1;
- $end = strpos($instruction, ')');
- $mod = substr($instruction, $ini, $end - $ini);
- $instruction = substr($instruction, 0, $ini - 1);
- }
- switch ($instruction) {
- case 'UPPER':
- return strtoupper($output);
- case 'LOWER':
- return strtolower($output);
- case 'ISSET':
- if ($output != '') {
- return ', ' . $output;
- }
- return '';
- case 'UFS':
- return format('ufs', $output);
- case 'PESOS':
- return format('pesos', $output);
- }
-
- if (isset($mod)) {
- $obj = $this->find($instruction . '(' . $mod .')', $data);
- } else {
- $obj = $this->find($instruction, $data);
- }
- if ($obj) {
- return $obj;
- }
- if (is_object($output) and method_exists($output, $instruction)) {
- if (isset($mod)) {
- return $output->$instruction($mod);
- }
- return $output->$instruction();
- }
- if (is_object($output) and isset($output->$instruction)) {
- return $output->$instruction;
- }
- if ($instruction == 'strftime') {
- setlocale(LC_TIME, 'es-CL', 'es');
- $f = Carbon::parse($output, config('app.timezone'));
- $output = strftime($mod, $f->timestamp);
- return $output;
- }
-
- d($output, $instruction, function_exists($instruction), is_object($output), is_object($output) and isset($output->$instruction));
- }
- protected function find($instruction, $data)
- {
- if (strpos($instruction, '(') !== false) {
- $ini = strpos($instruction, '(') + 1;
- $end = strpos($instruction, ')');
- $mod = substr($instruction, $ini, $end - $ini);
- $instruction = substr($instruction, 0, $ini - 1);
- }
- if (method_exists($data, $instruction)) {
- if (isset($mod)) {
- return $data->$instruction($mod);
- }
- return $data->$instruction();
- }
- if (isset($data->$instruction)) {
- return $data->$instruction;
- }
- switch ($instruction) {
- case 'Unidades':
- $str = 'Departamento ' . $data->reserva()->unidad()->numeracion;
- foreach ($data->reserva()->unidades() as $unidad) {
- $str .= ', ' . ucwords($unidad->unidadProyecto()->tipo()->descripcion) . ' ' . $unidad->numeracion;
- }
- return $str;
- case 'inmobiliaria':
- return $data->proyecto()->inmobiliaria();
- }
- return false;
- }
-}
-?>
\ No newline at end of file
diff --git a/app/Service/Route.php b/app/Service/Route.php
deleted file mode 100644
index f910f87..0000000
--- a/app/Service/Route.php
+++ /dev/null
@@ -1,131 +0,0 @@
-add($t, $query, $callback);
- }
- } else {
- switch (strtoupper($type)) {
- case 'GET':
- $this->get($query, $callback);
- break;
- case 'POST':
- $this->post($query, $callback);
- break;
- }
- }
- }
- public function get($query, $callback)
- {
- if ($this->exists('get', $query)) {
- return;
- }
- $this->routes['get'][$query] = (object) ['query' => $query, 'callback' => $this->parseCallback($callback)];
- }
- public function post($query, $callback)
- {
- if ($this->exists('post', $query)) {
- return;
- }
- $this->routes['post'][$query] = (object) ['query' => $query, 'callback' => $this->parseCallback($callback)];
- }
- protected function exists($type, $query)
- {
- return isset($this->routes['post'][$query]);
- }
- protected function parseCallback($callback)
- {
- if (is_callable($callback)) {
- return $callback;
- }
- elseif (is_object($callback)) {
- return [$callback, 'index'];
- }
- elseif (is_string($callback) and strpos($callback, '@') !== false) {
- list($class, $method) = explode('@', $callback);
- $class = '\\App\\Controller\\' . $class;
- if (method_exists($class, $method)) {
- return [$class, $method];
- }
- }
- elseif (is_string($callback)) {
- $class = '\\App\\Controller\\' . $callback;
- return [$class, 'index'];
- }
- }
- public function route()
- {
- $url = $_SERVER['SCRIPT_NAME'];
- $query = $_SERVER['QUERY_STRING'];
- $method = $_SERVER['REQUEST_METHOD'];
- $route = null;
- switch (strtoupper($method)) {
- case 'GET':
- $route = $this->getGet($url, $query);
- break;
- case 'POST':
- $route = $this->getPost($url, $query);
- break;
- }
- if ($route) {
- return $this->run($route->callback);
- }
- return false;
- }
- protected function getGet($url, $query)
- {
- if (isset($this->routes['get'][$url])) {
- return $this->routes['get'][$url];
- }
- $p = get('p');
- if ($p == null) {
- $p = get('page');
- if ($p == null) {
- $p = get('m');
- if ($p == null) {
- $p = get('module');
- }
- }
- }
- if (isset($this->routes['get'][$p])) {
- return $this->routes['get'][$p];
- }
- return false;
- }
- protected function getPost($url, $query)
- {
- if (isset($this->routes['post'][$url])) {
- return $this->routes['post'][$url];
- }
- $p = get('p');
- if ($p == null) {
- $p = get('page');
- if ($p == null) {
- $p = get('m');
- if ($p == null) {
- $p = get('module');
- }
- }
- }
- if (isset($this->routes['post'][$p])) {
- return $this->routes['post'][$p];
- }
- return false;
- }
- protected function run($callback)
- {
- return call_user_func($callback);
- }
-}
-?>
\ No newline at end of file
diff --git a/app/common/Alias/View.php b/app/common/Alias/View.php
new file mode 100644
index 0000000..80df0a9
--- /dev/null
+++ b/app/common/Alias/View.php
@@ -0,0 +1,9 @@
+parseFile($file);
+ $temp = [];
+ $columns = $this->columnMap();
+ foreach ($data as $row) {
+ $r = [];
+ foreach ($columns as $old => $new) {
+ if (!isset($row[$old])) {
+ continue;
+ }
+ $r[$new] = $row[$old];
+ }
+ $temp []= $r;
+ }
+ return $temp;
+ }
+ public function processMovimientosDiarios(array $movimientos): array
+ {
+ return $movimientos;
+ }
+
+ abstract protected function columnMap(): array;
+ abstract protected function parseFile(UploadedFileInterface $uploadedFile): array;
+}
diff --git a/app/common/Ideal/Controller.php b/app/common/Ideal/Controller.php
new file mode 100644
index 0000000..1d00c9e
--- /dev/null
+++ b/app/common/Ideal/Controller.php
@@ -0,0 +1,9 @@
+factories[$property] = $factory;
+ return $this;
+ }
+
+ protected function runFactory(string $property): mixed
+ {
+ if (isset($this->factories[$property])) {
+ return $this->factories[$property]->run();
+ }
+ return null;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'id' => $this->id
+ ];
+ }
+}
diff --git a/app/common/Ideal/Query.php b/app/common/Ideal/Query.php
new file mode 100644
index 0000000..8eb2a24
--- /dev/null
+++ b/app/common/Ideal/Query.php
@@ -0,0 +1,12 @@
+build();
+ }
+}
diff --git a/app/common/Ideal/Repository.php b/app/common/Ideal/Repository.php
new file mode 100644
index 0000000..18a4237
--- /dev/null
+++ b/app/common/Ideal/Repository.php
@@ -0,0 +1,164 @@
+table;
+ }
+ public function setTable(string $table): Repository
+ {
+ $this->table = $table;
+ return $this;
+ }
+
+ public function load(array $data_row): Define\Model
+ {
+ $model = $this->create($data_row);
+ $model->{$this->getKey()} = $data_row[$this->getKey()];
+ return $model;
+ }
+
+ public function remove(Define\Model $model): void
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->delete()->from($this->getTable())
+ ->where("{$this->getKey()} = ?");
+ $this->connection->execute($query, [$model->id]);
+ }
+
+ public function fetchById(int $id): Define\Model
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where("{$this->getKey()} = ?");
+ return $this->fetchOne($query, [$id]);
+ }
+ public function fetchAll(null|string|array $ordering = null): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable());
+ if ($ordering !== null) {
+ $query->order($ordering);
+ }
+ return $this->fetchMany($query);
+ }
+
+ protected function getKey(): string
+ {
+ return 'id';
+ }
+ protected function parseData(Define\Model $model, ?array $data, Implement\Repository\MapperParser $data_map): Define\Model
+ {
+ if ($data === null) {
+ return $model;
+ }
+ foreach ($data_map->getColumns() as $column) {
+ if (!$data_map->hasMapper($column)) {
+ $this->parsePlainColumn($model, $column, $data);
+ continue;
+ }
+
+ $settings = $data_map->getMapper($column);
+ if ($settings->parse($model, $column, $data)) {
+ continue;
+ }
+ $property = $column;
+ if ($settings->hasProperty()) {
+ $property = $settings->property;
+ }
+ $this->setDefault($model, $property);
+ }
+ return $model;
+ }
+ protected function parsePlainColumn(Define\Model &$model, string $column, ?array $data): void
+ {
+ $property = $column;
+ if (isset($data[$column])) {
+ $model->{$property} = $data[$column];
+ return;
+ }
+ $this->setDefault($model, $property);
+ }
+ protected function setDefault(Define\Model &$model, string $property): void
+ {
+ $prop = new ReflectionProperty($model, $property);
+ $type = $prop->getType()->getName();
+ $value = match ($type) {
+ 'int' => 0,
+ 'float' => 0.0,
+ 'string' => '',
+ default => null,
+ };
+ $model->{$property} = $value;
+ }
+ protected function saveNew(array $columns, array $values): int
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->insert()
+ ->into($this->getTable())
+ ->columns($columns)
+ ->values(array_fill(0, count($columns), '?'));
+ $this->connection->execute($query, $values);
+ return $this->connection->getPDO()->lastInsertId();
+ }
+ protected function update(Define\Model $model, array $columns, array $data): Define\Model
+ {
+ $changes = [];
+ $values = [];
+ foreach ($columns as $column) {
+ if (in_array($column, array_keys($data))) {
+ $changes []= $column;
+ $values []= $data[$column];
+ }
+ }
+
+ if (count($changes) === 0) {
+ return $model;
+ }
+ $columns_string = implode(', ', array_map(function($property) {return "`{$property}` = ?";}, $changes));
+ $query = $this->connection->getQueryBuilder()
+ ->update($this->getTable())
+ ->set($columns_string)
+ ->where("{$this->getKey()} = ?");
+ $values []= $model->{$this->getKey()};
+ $this->connection->execute($query, $values);
+ return $this->fetchById($model->{$this->getKey()});
+ }
+ protected function fetchOne(string $query, ?array $data = null): Define\Model
+ {
+ $result = $this->connection->execute($query, $data)->fetch(PDO::FETCH_ASSOC);
+ if ($result === false) {
+ throw new EmptyResult($query);
+ }
+ return $this->load($result);
+ }
+ protected function fetchMany(string $query, ?array $data = null): array
+ {
+ $results = $this->connection->execute($query, $data)->fetchAll(PDO::FETCH_ASSOC);
+ if ($results === false) {
+ throw new EmptyResult($query);
+ }
+ return array_map([$this, 'load'], $results);
+ }
+ protected function fetchAsArray(string $query, ?array $data = null): array
+ {
+ $results = $this->connection->execute($query, $data)->fetchAll(PDO::FETCH_ASSOC);
+ if ($results === false) {
+ throw new EmptyResult($query);
+ }
+ return $results;
+ }
+}
diff --git a/app/common/Ideal/Service.php b/app/common/Ideal/Service.php
new file mode 100644
index 0000000..fd7dfe2
--- /dev/null
+++ b/app/common/Ideal/Service.php
@@ -0,0 +1,9 @@
+connection)) {
+ if ($this->database->needsUser()) {
+ $this->connection = new PDO($this->database->getDSN(), $this->database->user, $this->database->password);
+ } else {
+ $this->connection = new PDO($this->database->getDSN());
+ }
+ }
+ return $this;
+ }
+ public function getPDO(): PDO
+ {
+ $this->connect();
+ return $this->connection;
+ }
+ public function getQueryBuilder(): Database\Query\Builder
+ {
+ return $this->queryBuilder;
+ }
+
+ public function query(string $query): PDOStatement
+ {
+ $this->connect();
+ $statement = $this->connection->query($query);
+ if ($statement === false) {
+ throw new PDOException("Query failed: '{$query}'");
+ }
+ return $statement;
+ }
+ public function prepare(string $query): PDOStatement
+ {
+ $this->connect();
+ $statement = $this->connection->prepare($query);
+ if ($statement === false) {
+ throw new PDOException("Query failed: '{$query}'");
+ }
+ return $statement;
+ }
+ public function execute(string $query, ?array $data = null): PDOStatement
+ {
+ if ($data === null) {
+ return $this->query($query);
+ }
+ $statement = $this->prepare($query);
+ $status = $statement->execute($data);
+ if ($status === false) {
+ throw new PDOException("Query could not be executed: '{$query}'");
+ }
+ return $statement;
+ }
+}
diff --git a/app/common/Implement/Database/MySQL.php b/app/common/Implement/Database/MySQL.php
new file mode 100644
index 0000000..b2bca28
--- /dev/null
+++ b/app/common/Implement/Database/MySQL.php
@@ -0,0 +1,24 @@
+host};dbname={$this->name}";
+ if ($this->port !== 3306) {
+ $dsn .= ";port={$this->port}";
+ }
+ return $dsn;
+ }
+ public function needsUser(): bool
+ {
+ return true;
+ }
+}
diff --git a/app/common/Implement/Database/Query/Builder.php b/app/common/Implement/Database/Query/Builder.php
new file mode 100644
index 0000000..82a3c5f
--- /dev/null
+++ b/app/common/Implement/Database/Query/Builder.php
@@ -0,0 +1,29 @@
+table($table_name);
+ }
+
+ public function select(array|string $columns = '*'): Select
+ {
+ return (new Select())->columns($columns);
+ }
+ public function insert(): Insert
+ {
+ return new Insert();
+ }
+ public function update(string $table): Update
+ {
+ return (new Update())->table($table);
+ }
+ public function delete(): Delete
+ {
+ return new Delete();
+ }
+}
diff --git a/app/common/Implement/Database/Query/Create.php b/app/common/Implement/Database/Query/Create.php
new file mode 100644
index 0000000..2c21bfe
--- /dev/null
+++ b/app/common/Implement/Database/Query/Create.php
@@ -0,0 +1,102 @@
+name = $name;
+ return $this;
+ }
+ public function definitions(Define\Query\Create\CreateDefinition|array|string $create_definitions): Define\Query\Create
+ {
+ if (is_array($create_definitions)) {
+ foreach ($create_definitions as $definition) {
+ $this->addDefinition($definition);
+ }
+ return $this;
+ }
+ return $this->addDefinition($create_definitions);
+ }
+ public function options(array|string $table_options): Define\Query\Create
+ {
+ if (is_string($table_options)) {
+ return $this->addOption($table_options);
+ }
+ foreach ($table_options as $option) {
+ $this->addOption($option);
+ }
+ return $this;
+ }
+ public function partition(array|string $partition_options): Define\Query\Create
+ {
+ if (is_string($partition_options)) {
+ return $this->addPartition($partition_options);
+ }
+ foreach ($partition_options as $option) {
+ $this->addPartition($option);
+ }
+ return $this;
+ }
+ public function build(): string
+ {
+ $query = [
+ "CREATE TABLE {$this->name}",
+ $this->getDefinitions(),
+ $this->getOptions(),
+ $this->getPartitions()
+ ];
+ return implode('', $query);
+ }
+
+ protected function addDefinition(string $definition): Create
+ {
+ if (!isset($this->definitions)) {
+ $this->definitions = [];
+ }
+ $this->definitions []= $definition;
+ return $this;
+ }
+ protected function addOption(string $option): Create
+ {
+ if (!isset($this->options)) {
+ $this->options = [];
+ }
+ $this->options []= $option;
+ return $this;
+ }
+ protected function addPartition(string $partition): Create
+ {
+ if (!isset($this->partitions)) {
+ $this->partitions = [];
+ }
+ $this->partitions []= $partition;
+ return $this;
+ }
+ protected function getDefinitions(): string
+ {
+ return ' (' . implode(', ', $this->definitions) . ')';
+ }
+ protected function getOptions(): string
+ {
+ if (!isset($this->options) or count($this->options) <= 0) {
+ return '';
+ }
+ return ' ' . implode(' ', $this->options);
+ }
+ protected function getPartitions(): string
+ {
+ if (!isset($this->partitions) or count($this->partitions) <= 0) {
+ return '';
+ }
+ return ' PARTITION BY (' . implode(', ', $this->partitions) . ')';
+ }
+}
diff --git a/app/common/Implement/Database/Query/Create/Definition.php b/app/common/Implement/Database/Query/Create/Definition.php
new file mode 100644
index 0000000..a81680c
--- /dev/null
+++ b/app/common/Implement/Database/Query/Create/Definition.php
@@ -0,0 +1,104 @@
+name = $name;
+ return $this;
+ }
+ public function type(string $type, ?int $size = null): CreateDefinition
+ {
+ $this->type = $type;
+ if ($size !== null) {
+ $this->size = $size;
+ }
+ return $this;
+ }
+ public function primary(): CreateDefinition
+ {
+ $this->primary = true;
+ return $this;
+ }
+ public function autoIncrement(): CreateDefinition
+ {
+ $this->auto_increment = true;
+ return $this;
+ }
+ public function unsigned(): CreateDefinition
+ {
+ $this->unsigned = true;
+ return $this;
+ }
+ public function default(mixed $value): CreateDefinition
+ {
+ $this->default = $value;
+ return $this;
+ }
+ public function foreign(string $reference_table, string $reference_column = 'id', int $on_delete = CreateDefinition::CASCADE, int $on_update = CreateDefinition::CASCADE): CreateDefinition
+ {
+ $this->foreign_table = $reference_table;
+ $this->foreign_key = $reference_column;
+ $this->foreign_delete = $on_delete;
+ $this->foreign_update = $on_update;
+ return $this;
+ }
+
+ public function __toString(): string
+ {
+ $type = $this->type ?? 'int';
+ if (isset($this->size)) {
+ $type = "{$type}({$this->size})";
+ } elseif (in_array($type, ['varchar'])) {
+ $type = "{$type}(255)";
+ }
+ $output = [
+ "`{$this->name}`",
+ $type
+ ];
+ if (isset($this->unsigned)) {
+ $output []= 'UNSIGNED';
+ }
+ if (isset($this->default)) {
+ $default = $this->default;
+ if (in_array($this->type, ['varchar', 'text', 'char'])) {
+ $default = "'{$default}'";
+ }
+ $output []= "DEFAULT {$default}";
+ }
+ if (isset($this->auto_increment)) {
+ $output []= 'AUTO_INCREMENT';
+ }
+ if (isset($this->primary)) {
+ $output []= 'PRIMARY KEY';
+ }
+ if (isset($this->foreign_table)) {
+ $output []= "REFERENCES `{$this->foreign_table}` (`{$this->foreign_key}`)";
+ $on = [
+ 'RESTRICT',
+ 'CASCADE',
+ 'SET_NULL',
+ 'NO_ACTION',
+ 'SET_DEFAULT'
+ ];
+ $output []= "ON DELETE {$on[$this->foreign_delete]}";
+ $output []= "ON UPDATE {$on[$this->foreign_update]}";
+ }
+ return implode(' ', $output);
+ }
+}
diff --git a/app/common/Implement/Database/Query/Delete.php b/app/common/Implement/Database/Query/Delete.php
new file mode 100644
index 0000000..c193d98
--- /dev/null
+++ b/app/common/Implement/Database/Query/Delete.php
@@ -0,0 +1,89 @@
+table = $table;
+ return $this;
+ }
+ public function where(array|string $conditions): Delete
+ {
+ if (is_string($conditions)) {
+ return $this->addCondition($conditions);
+ }
+ foreach ($conditions as $condition) {
+ $this->addCondition($condition);
+ }
+ return $this;
+ }
+ public function order(array|string $sorting): Delete
+ {
+ if (is_string($sorting)) {
+ return $this->addOrder($sorting);
+ }
+ foreach ($sorting as $order) {
+ $this->addOrder($order);
+ }
+ return $this;
+ }
+ public function limit(int $limit): Delete
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+ public function build(): string
+ {
+ $query = [
+ "DELETE FROM {$this->table}",
+ $this->getConditions(),
+ $this->getSorting(),
+ $this->getLimit()
+ ];
+ return implode('', $query);
+ }
+
+ protected function addCondition(string $condition): Delete
+ {
+ if (!isset($this->conditions)) {
+ $this->conditions = [];
+ }
+ $this->conditions []= $condition;
+ return $this;
+ }
+ protected function getConditions(): string
+ {
+ return ' WHERE ' . implode(' AND ', $this->conditions);
+ }
+ protected function addOrder(string $order): Delete
+ {
+ if (!isset($this->sorts)) {
+ $this->sorts = [];
+ }
+ $this->sorts []= $order;
+ return $this;
+ }
+ protected function getSorting(): string
+ {
+ if (!isset($this->sorts) or count($this->sorts) === 0) {
+ return '';
+ }
+ return ' ORDER BY ' . implode(', ', $this->sorts);
+ }
+ protected function getLimit(): string
+ {
+ if (!isset($this->limit) or $this->limit <= 0) {
+ return '';
+ }
+ return " LIMIT {$this->limit}";
+ }
+}
diff --git a/app/common/Implement/Database/Query/Insert.php b/app/common/Implement/Database/Query/Insert.php
new file mode 100644
index 0000000..6c9b7cf
--- /dev/null
+++ b/app/common/Implement/Database/Query/Insert.php
@@ -0,0 +1,87 @@
+table = $table;
+ if ($columns !== null) {
+ return $this->columns($columns);
+ }
+ return $this;
+ }
+ public function columns(array $columns): Insert
+ {
+ foreach ($columns as $column) {
+ $this->addColumn($column);
+ }
+ return $this;
+ }
+ public function values(array $values): Insert
+ {
+ foreach ($values as $value) {
+ $this->addValue($value);
+ }
+ return $this;
+ }
+ public function select(Define\Query\Select $select): Insert
+ {
+ $this->select = $select;
+ return $this;
+ }
+ public function build(): string
+ {
+ $query = [
+ "INSERT INTO {$this->table}"
+ ];
+ if (isset($this->select)) {
+ $query []= " {$this->select}";
+ return implode('', $query);
+ }
+ $query []= $this->getColumns();
+ $query []= $this->getValues();
+ return implode('', $query);
+ }
+
+ protected function addColumn(string $column): Insert
+ {
+ if (!isset($this->columns)) {
+ $this->columns = [];
+ }
+ $this->columns []= $column;
+ return $this;
+ }
+ protected function addValue(mixed $value): Insert
+ {
+ if (!isset($this->values)) {
+ $this->values = [];
+ }
+ $this->values []= $value;
+ return $this;
+ }
+ protected function getColumns(): string
+ {
+ return ' (' . implode(', ', array_map(function(string $column) {return "`{$column}`";}, $this->columns)) . ')';
+ }
+ protected function getValues(): string
+ {
+ return ' VALUES (' . implode(', ', array_map(function($value) {
+ if ($value === '?') {
+ return $value;
+ }
+ if ($value === (int) $value) {
+ return $value;
+ }
+ return "'{$value}'";
+ }, $this->values)) . ')';
+ }
+}
diff --git a/app/common/Implement/Database/Query/Select.php b/app/common/Implement/Database/Query/Select.php
new file mode 100644
index 0000000..0f7a88b
--- /dev/null
+++ b/app/common/Implement/Database/Query/Select.php
@@ -0,0 +1,215 @@
+addColumn($expressions);
+ }
+ foreach ($expressions as $expression) {
+ $this->addColumn($expression);
+ }
+ return $this;
+ }
+ public function from(string $table): Select
+ {
+ $this->table = $table;
+ return $this;
+ }
+ public function joined(array|string $joins): Select
+ {
+ if (is_string($joins)) {
+ return $this->addJoin($joins);
+ }
+ foreach ($joins as $join) {
+ $this->addJoin($join);
+ }
+ return $this;
+ }
+ public function where(array|string $conditions): Select
+ {
+ if (is_string($conditions)) {
+ return $this->addCondition($conditions);
+ }
+ foreach ($conditions as $condition) {
+ $this->addCondition($condition);
+ }
+ return $this;
+ }
+ public function group(array|string $grouping): Select
+ {
+ if (is_string($grouping)) {
+ return $this->addGroup($grouping);
+ }
+ foreach ($grouping as $group) {
+ $this->addGroup($group);
+ }
+ return $this;
+ }
+ public function having(array|string $conditions): Select
+ {
+ if (is_string($conditions)) {
+ return $this->addCondition($conditions);
+ }
+ foreach ($conditions as $condition) {
+ $this->addCondition($condition);
+ }
+ return $this;
+ }
+ public function order(array|string $sorting): Select
+ {
+ if (is_string($sorting)) {
+ return $this->addOrder($sorting);
+ }
+ foreach ($sorting as $order) {
+ $this->addOrder($order);
+ }
+ return $this;
+ }
+ public function limit(int $limit, ?int $offset = null): Select
+ {
+ $this->limit = $limit;
+ if ($offset !== null) {
+ return $this->offset($offset);
+ }
+ return $this;
+ }
+ public function offset(int $offset): Select
+ {
+ $this->offset = $offset;
+ return $this;
+ }
+ public function build(): string
+ {
+ $query = [
+ "SELECT {$this->getColumns()} FROM {$this->table}",
+ $this->getJoins(),
+ $this->getConditions(),
+ $this->getGroups(),
+ $this->getHaving(),
+ $this->getOrder(),
+ $this->getLimit()
+ ];
+ return implode('', $query);
+ }
+
+ protected function addColumn(string $expression): Select
+ {
+ if (!isset($this->columns)) {
+ $this->columns = [];
+ }
+ $this->columns []= $expression;
+ return $this;
+ }
+ protected function addJoin(string $join): Select
+ {
+ if (!isset($this->joins)) {
+ $this->joins = [];
+ }
+ $this->joins []= $join;
+ return $this;
+ }
+ protected function addCondition(string $condition): Select
+ {
+ if (!isset($this->coditions)) {
+ $this->conditions = [];
+ }
+ $this->conditions []= $condition;
+ return $this;
+ }
+ protected function addGroup(string $group): Select
+ {
+ if (!isset($this->groups)) {
+ $this->groups = [];
+ }
+ $this->groups []= $group;
+ return $this;
+ }
+ protected function addHaving(string $having): Select
+ {
+ if (!isset($this->haves)) {
+ $this->haves = [];
+ }
+ $this->haves []= $having;
+ return $this;
+ }
+ protected function addOrder(string $order): Select
+ {
+ if (!isset($this->orders)) {
+ $this->orders = [];
+ }
+ $this->orders []= $order;
+ return $this;
+ }
+ protected function getColumns(): string
+ {
+ if (!isset($this->columns) or count($this->columns) === 0) {
+ return '*';
+ }
+ return implode(', ', $this->columns);
+ }
+ protected function getJoins(): string
+ {
+ if (!isset($this->joins) or count($this->joins) === 0) {
+ return '';
+ }
+ return ' ' . implode(' ', $this->joins);
+ }
+ protected function getConditions(): string
+ {
+ if (!isset($this->conditions) or count($this->conditions) === 0) {
+ return '';
+ }
+ return ' WHERE ' . implode(' AND ', $this->conditions);
+ }
+ protected function getGroups(): string
+ {
+ if (!isset($this->groups) or count($this->groups) === 0) {
+ return '';
+ }
+ return ' GROUP BY ' . implode(', ', $this->groups);
+ }
+ protected function getHaving(): string
+ {
+ if (!isset($this->haves) or count($this->haves) === 0) {
+ return '';
+ }
+ return ' HAVING ' . implode(' AND ', $this->haves);
+ }
+ protected function getOrder(): string
+ {
+ if (!isset($this->orders) or count($this->orders) === 0) {
+ return '';
+ }
+ return ' ORDER BY ' . implode(', ', $this->orders);
+ }
+ protected function getLimit(): string
+ {
+ if (!isset($this->limit) or $this->limit <= 0) {
+ return '';
+ }
+ return " LIMIT {$this->limit}{$this->getOffset()}";
+ }
+ protected function getOffset(): string
+ {
+ if (!isset($this->offset) or $this->offset <= 0) {
+ return '';
+ }
+ return " OFFSET {$this->offset}";
+ }
+}
diff --git a/app/common/Implement/Database/Query/Update.php b/app/common/Implement/Database/Query/Update.php
new file mode 100644
index 0000000..f671363
--- /dev/null
+++ b/app/common/Implement/Database/Query/Update.php
@@ -0,0 +1,113 @@
+table = $table;
+ return $this;
+ }
+ public function set(array|string $column_pairs): Define\Query\Update
+ {
+ if (is_string($column_pairs)) {
+ return $this->addSet($column_pairs);
+ }
+ foreach ($column_pairs as $pair) {
+ $this->addSet($pair);
+ }
+ return $this;
+ }
+ public function where(array|string $conditions): Define\Query\Update
+ {
+ if (is_string($conditions)) {
+ return $this->addCondition($conditions);
+ }
+ foreach ($conditions as $condition) {
+ $this->addCondition($condition);
+ }
+ return $this;
+ }
+ public function order(array|string $ordering): Define\Query\Update
+ {
+ if (is_string($ordering)) {
+ return $this->addOrder($ordering);
+ }
+ foreach ($ordering as $order) {
+ $this->addOrder($order);
+ }
+ return $this;
+ }
+ public function limit(int $limit): Define\Query\Update
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+ public function build(): string
+ {
+ $query = [
+ "UPDATE {$this->table}",
+ $this->getSet(),
+ $this->getConditions(),
+ $this->getOrder(),
+ $this->getLimit()
+ ];
+ return implode('', $query);
+ }
+
+ protected function addSet(string $pair): Update
+ {
+ if (!isset($this->setPairs)) {
+ $this->setPairs = [];
+ }
+ $this->setPairs []= $pair;
+ return $this;
+ }
+ protected function addCondition(string $condition): Update
+ {
+ if (!isset($this->conditions)) {
+ $this->conditions = [];
+ }
+ $this->conditions []= $condition;
+ return $this;
+ }
+ protected function addOrder(string $order): Update
+ {
+ if (!isset($this->orders)) {
+ $this->orders = [];
+ }
+ $this->orders []= $order;
+ return $this;
+ }
+ protected function getSet(): string
+ {
+ return ' SET ' . implode(', ', $this->setPairs);
+ }
+ protected function getConditions(): string
+ {
+ return ' WHERE ' . implode(' AND ', $this->conditions);
+ }
+ protected function getOrder(): string
+ {
+ if (!isset($this->orders) or count($this->orders) === 0) {
+ return '';
+ }
+ return ' ORDER BY ' . implode(', ', $this->orders);
+ }
+ protected function getLimit(): string
+ {
+ if (!isset($this->limit) or $this->limit <= 0) {
+ return '';
+ }
+ return " LIMIT {$this->limit}";
+ }
+}
diff --git a/app/common/Implement/Exception/EmptyRedis.php b/app/common/Implement/Exception/EmptyRedis.php
new file mode 100644
index 0000000..cc6ac45
--- /dev/null
+++ b/app/common/Implement/Exception/EmptyRedis.php
@@ -0,0 +1,15 @@
+callable = $callable(...);
+ return $this;
+ }
+ public function setArgs(array $args): Define\Repository\Factory
+ {
+ $this->args = $args;
+ return $this;
+ }
+
+ public function run(): mixed
+ {
+ return call_user_func_array($this->callable, $this->args);
+ }
+}
diff --git a/app/common/Implement/Repository/Mapper.php b/app/common/Implement/Repository/Mapper.php
new file mode 100644
index 0000000..0a15a6e
--- /dev/null
+++ b/app/common/Implement/Repository/Mapper.php
@@ -0,0 +1,80 @@
+property = $property;
+ return $this;
+ }
+ public function setFunction(callable $function): Define\Repository\Mapper
+ {
+ $this->function = $function(...);
+ return $this;
+ }
+ public function setFactory(Define\Repository\Factory $factory): Define\Repository\Mapper
+ {
+ $this->factory = $factory;
+ return $this;
+ }
+ public function setDefault(mixed $value): Define\Repository\Mapper
+ {
+ $this->default = $value;
+ return $this;
+ }
+
+ public function hasProperty(): bool
+ {
+ return isset($this->property);
+ }
+ public function hasFunction(): bool
+ {
+ return isset($this->function);
+ }
+ public function hasFactory(): bool
+ {
+ return isset($this->factory);
+ }
+ public function hasDefault(): bool
+ {
+ return isset($this->default);
+ }
+
+ public function parse(Define\Model &$model, string $column, ?array $data): bool
+ {
+ $property = $column;
+ if ($this->hasProperty()) {
+ $property = $this->property;
+ }
+ if (in_array($column, array_keys($data))) {
+ if ($this->hasFactory()) {
+ $model->addFactory($property, $this->factory);
+ return true;
+ }
+ $value = $data[$column];
+ if ($this->hasFunction()) {
+ if ($value !== null) {
+ $value = ($this->function)($data);
+ } elseif ($this->hasDefault()) {
+ $value = $this->default;
+ }
+ }
+ $model->{$property} = $value;
+ return true;
+ }
+ if ($this->hasDefault()) {
+ $model->{$property} = $this->default;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/app/common/Implement/Repository/Mapper/Boolean.php b/app/common/Implement/Repository/Mapper/Boolean.php
new file mode 100644
index 0000000..4037e6c
--- /dev/null
+++ b/app/common/Implement/Repository/Mapper/Boolean.php
@@ -0,0 +1,18 @@
+setFunction(function($data) use ($column) {
+ return $data[$column] !== 0;
+ });
+ $this->setDefault($default);
+ if ($property !== null) {
+ $this->setProperty($property);
+ }
+ }
+}
diff --git a/app/common/Implement/Repository/Mapper/DateTime.php b/app/common/Implement/Repository/Mapper/DateTime.php
new file mode 100644
index 0000000..bbeb388
--- /dev/null
+++ b/app/common/Implement/Repository/Mapper/DateTime.php
@@ -0,0 +1,18 @@
+setFunction(function($data) use ($column) {
+ return new DateTimeImmutable($data[$column] ?? '');
+ });
+ if ($property !== null) {
+ $this->setProperty($property);
+ }
+ }
+}
diff --git a/app/common/Implement/Repository/MapperParser.php b/app/common/Implement/Repository/MapperParser.php
new file mode 100644
index 0000000..d93e078
--- /dev/null
+++ b/app/common/Implement/Repository/MapperParser.php
@@ -0,0 +1,41 @@
+register($column);
+ }
+ }
+ }
+
+ protected array $maps;
+
+ public function register(string $column, ?Mapper $mapper = null): Define\Repository\MapperParser
+ {
+ if ($mapper !== null) {
+ $this->maps[$column] = $mapper;
+ return $this;
+ }
+ $this->maps[$column] = [];
+ return $this;
+ }
+ public function getColumns(): array
+ {
+ return array_keys($this->maps);
+ }
+ public function hasMapper(string $column): bool
+ {
+ return is_a($this->maps[$column], Define\Repository\Mapper::class);
+ }
+ public function getMapper(string $column): Mapper
+ {
+ return $this->maps[$column];
+ }
+}
diff --git a/app/composer.json b/app/composer.json
new file mode 100644
index 0000000..d503569
--- /dev/null
+++ b/app/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "incoviba/web",
+ "type": "project",
+ "require": {
+ "berrnd/slim-blade-view": "^1.0",
+ "guzzlehttp/guzzle": "^7.8",
+ "monolog/monolog": "^3.4",
+ "nyholm/psr7": "^1.8",
+ "nyholm/psr7-server": "^1.0",
+ "php-di/php-di": "^7.0",
+ "php-di/slim-bridge": "^3.4",
+ "phpoffice/phpspreadsheet": "^1.29",
+ "predis/predis": "^2.2",
+ "slim/slim": "^4.11"
+ },
+ "require-dev": {
+ "kint-php/kint": "^5.1",
+ "phpunit/phpunit": "^10.2"
+ },
+ "authors": [
+ {
+ "name": "Aldarien",
+ "email": "aldarien85@gmail.com"
+ }
+ ],
+ "autoload": {
+ "psr-4": {
+ "Incoviba\\Common\\": "common/",
+ "Incoviba\\": "src/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ }
+}
diff --git a/public/images/Isotipo 16.png b/app/public/assets/images/Isotipo 16.png
similarity index 100%
rename from public/images/Isotipo 16.png
rename to app/public/assets/images/Isotipo 16.png
diff --git a/public/images/Isotipo 32.png b/app/public/assets/images/Isotipo 32.png
similarity index 100%
rename from public/images/Isotipo 32.png
rename to app/public/assets/images/Isotipo 32.png
diff --git a/public/images/Isotipo 64.png b/app/public/assets/images/Isotipo 64.png
similarity index 100%
rename from public/images/Isotipo 64.png
rename to app/public/assets/images/Isotipo 64.png
diff --git a/public/images/logo_cabezal.png b/app/public/assets/images/logo_cabezal.png
similarity index 100%
rename from public/images/logo_cabezal.png
rename to app/public/assets/images/logo_cabezal.png
diff --git a/app/public/index.php b/app/public/index.php
new file mode 100644
index 0000000..a7bedad
--- /dev/null
+++ b/app/public/index.php
@@ -0,0 +1,15 @@
+run();
+} catch (Error $error) {
+ $app->getContainer()->get(Psr\Log\LoggerInterface::class)->error($error);
+ header('Location: /construccion');
+} catch (Exception $exception) {
+ $app->getContainer()->get(Psr\Log\LoggerInterface::class)->notice($exception);
+ header('Location: /construccion');
+}
diff --git a/app/public/informes/.gitkeep b/app/public/informes/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/public/robots.txt b/app/public/robots.txt
new file mode 100644
index 0000000..1f53798
--- /dev/null
+++ b/app/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/app/resources/routes/01_api.php b/app/resources/routes/01_api.php
new file mode 100644
index 0000000..73fb159
--- /dev/null
+++ b/app/resources/routes/01_api.php
@@ -0,0 +1,13 @@
+group('/api', function($app) {
+ $folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'api']);
+ if (file_exists($folder)) {
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+ }
+})->add($app->getContainer()->get(Incoviba\Middleware\API::class));
diff --git a/app/resources/routes/02_inmobiliarias.php b/app/resources/routes/02_inmobiliarias.php
new file mode 100644
index 0000000..8991df7
--- /dev/null
+++ b/app/resources/routes/02_inmobiliarias.php
@@ -0,0 +1,6 @@
+group('/inmobiliarias', function($app) {
+ $app->get('[/]', Inmobiliarias::class);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/03_proyectos.php b/app/resources/routes/03_proyectos.php
new file mode 100644
index 0000000..332e7e7
--- /dev/null
+++ b/app/resources/routes/03_proyectos.php
@@ -0,0 +1,10 @@
+group('/proyectos', function($app) {
+ $app->get('/unidades[/]', [Proyectos::class, 'unidades']);
+ $app->get('[/]', Proyectos::class);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
+$app->group('/proyecto/{proyecto_id}', function($app) {
+ $app->get('[/]', [Proyectos::class, 'show']);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/04_ventas.php b/app/resources/routes/04_ventas.php
new file mode 100644
index 0000000..e094508
--- /dev/null
+++ b/app/resources/routes/04_ventas.php
@@ -0,0 +1,42 @@
+group('/ventas', function($app) {
+ $files = new FilesystemIterator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'ventas']));
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+ $app->get('/add[/]', [Ventas::class, 'add']);
+ $app->get('[/]', Ventas::class);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
+$app->group('/venta/{proyecto_nombre:[A-za-zÑñ\+\ %0-9]+}/{unidad_descripcion:[0-9]+}', function($app) {
+ $app->get('[/]', [Ventas::class, 'showUnidad']);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
+$app->group('/venta/{venta_id:[0-9]+}', function($app) {
+ $app->group('/propietario', function($app) {
+ $app->get('[/]', [Ventas::class, 'propietario']);
+ });
+ $app->group('/propiedad', function($app) {
+ $app->get('[/]', [Ventas::class, 'propiedad']);
+ });
+ $app->group('/pie', function($app) {
+ $app->group('/cuotas', function($app) {
+ $app->get('[/]', [Ventas::class, 'cuotas']);
+ });
+ $app->get('[/]', [Ventas::class, 'pie']);
+ });
+ $app->group('/escritura', function($app) {
+ $app->get('/add[/]', [Ventas\Escrituras::class, 'add']);
+ });
+ $app->group('/credito', function($app) {
+ $app->get('[/]', [Ventas\Creditos::class, 'show']);
+ });
+ $app->get('/escriturar[/]', [Ventas::class, 'escriturar']);
+ $app->get('/desistir[/]', [Ventas::class, 'desistir']);
+ $app->get('/desistida[/]', [Ventas::class, 'desistida']);
+ $app->get('/edit[/]', [Ventas::class, 'edit']);
+ $app->get('[/]', [Ventas::class, 'show']);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/05_contabilidad.php b/app/resources/routes/05_contabilidad.php
new file mode 100644
index 0000000..08de783
--- /dev/null
+++ b/app/resources/routes/05_contabilidad.php
@@ -0,0 +1,10 @@
+group('/contabilidad', function($app) {
+ $files = new FilesystemIterator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'contabilidad']));
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+});
diff --git a/app/resources/routes/97_search.php b/app/resources/routes/97_search.php
new file mode 100644
index 0000000..79cd977
--- /dev/null
+++ b/app/resources/routes/97_search.php
@@ -0,0 +1,7 @@
+group('/search', function($app) {
+ $app->get('[/{query}[/{tipo}[/]]]', Search::class);
+ $app->post('[/]', Search::class);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/98_login.php b/app/resources/routes/98_login.php
new file mode 100644
index 0000000..0623659
--- /dev/null
+++ b/app/resources/routes/98_login.php
@@ -0,0 +1,8 @@
+group('/login', function($app) {
+ $app->post('[/]', [Login::class, 'login']);
+ $app->get('[/]', [Login::class, 'form']);
+})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
+$app->get('/logout', [Login::class, 'logout'])->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/99_base.php b/app/resources/routes/99_base.php
new file mode 100644
index 0000000..12e7eb1
--- /dev/null
+++ b/app/resources/routes/99_base.php
@@ -0,0 +1,5 @@
+get('/construccion', [Base::class, 'construccion'])->setName('construccion');
+$app->get('[/]', Base::class)->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/api/contabilidad.php b/app/resources/routes/api/contabilidad.php
new file mode 100644
index 0000000..08de783
--- /dev/null
+++ b/app/resources/routes/api/contabilidad.php
@@ -0,0 +1,10 @@
+group('/contabilidad', function($app) {
+ $files = new FilesystemIterator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'contabilidad']));
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+});
diff --git a/app/resources/routes/api/contabilidad/cartolas.php b/app/resources/routes/api/contabilidad/cartolas.php
new file mode 100644
index 0000000..52cdf3c
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/cartolas.php
@@ -0,0 +1,13 @@
+group('/cartolas', function($app) {
+ $app->post('/procesar[/]', [Cartolas::class, 'procesar']);
+});
+$app->group('/cartola', function($app) {
+ $app->group('/diaria', function($app) {
+ $app->post('/ayer[/]', [Cartolas::class, 'ayer']);
+ $app->post('/procesar[/]', [Cartolas::class, 'diaria']);
+ });
+ $app->post('/exportar[/]', [Cartolas::class, 'exportar']);
+});
diff --git a/app/resources/routes/api/contabilidad/centros_costos.php b/app/resources/routes/api/contabilidad/centros_costos.php
new file mode 100644
index 0000000..877052b
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/centros_costos.php
@@ -0,0 +1,10 @@
+group('/centros_costos', function($app) {
+ $app->post('/add[/]', [CentrosCostos::class, 'add']);
+});
+$app->group('/centro_costo/{centro_costo_id}', function($app) {
+ $app->post('/edit[/]', [CentrosCostos::class, 'edit']);
+ $app->delete('[/]', [CentrosCostos::class, 'remove']);
+});
diff --git a/app/resources/routes/api/contabilidad/daps.php b/app/resources/routes/api/contabilidad/daps.php
new file mode 100644
index 0000000..037781e
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/daps.php
@@ -0,0 +1,7 @@
+group('/depositos', function($app) {
+ $app->post('/add[/]', [Depositos::class, 'add']);
+ $app->get('/inmobiliaria/{inmobiliaria_rut}[/]', [Depositos::class, 'inmobiliaria']);
+});
diff --git a/app/resources/routes/api/contabilidad/movimientos.php b/app/resources/routes/api/contabilidad/movimientos.php
new file mode 100644
index 0000000..545dd98
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/movimientos.php
@@ -0,0 +1,6 @@
+group('/movimiento/{movimiento_id}', function($app) {
+ $app->post('/detalles', [Movimientos::class, 'detalles']);
+});
diff --git a/app/resources/routes/api/contabilidad/nubox.php b/app/resources/routes/api/contabilidad/nubox.php
new file mode 100644
index 0000000..e1acbf9
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/nubox.php
@@ -0,0 +1,11 @@
+group('/nubox/{inmobiliaria_rut}', function($app) {
+ $app->get('/token[/]', [Nubox::class, 'token']);
+ $app->get('/sistemas[/]', [Nubox::class, 'sistemas']);
+ $app->group('/libro', function($app) {
+ $app->post('/mayor[/]', [Nubox::class, 'libroMayor']);
+ $app->post('/diario[/]', [Nubox::class, 'libroDiario']);
+ });
+});
diff --git a/app/resources/routes/api/direcciones.php b/app/resources/routes/api/direcciones.php
new file mode 100644
index 0000000..61ea957
--- /dev/null
+++ b/app/resources/routes/api/direcciones.php
@@ -0,0 +1,11 @@
+group('/direcciones', function($app) {
+ $app->group('/region/{region_id:[0-9]+}', function($app) {
+ $app->get('/comunas[/]', [Direcciones::class, 'comunas']);
+ });
+ $app->group('/comunas', function($app) {
+ $app->post('/find[/]', [Direcciones::class, 'findComunas']);
+ });
+});
diff --git a/app/resources/routes/api/inmobiliarias.php b/app/resources/routes/api/inmobiliarias.php
new file mode 100644
index 0000000..55c61fb
--- /dev/null
+++ b/app/resources/routes/api/inmobiliarias.php
@@ -0,0 +1,10 @@
+group('/inmobiliarias', function($app) {
+ $app->get('[/]', Inmobiliarias::class);
+});
+$app->group('/inmobiliaria/{inmobiliaria_rut}', function($app) {
+ $app->get('/cuentas[/]', [Inmobiliarias::class, 'cuentas']);
+ $app->get('/proyectos[/]', [Inmobiliarias::class, 'proyectos']);
+});
diff --git a/app/resources/routes/api/money.php b/app/resources/routes/api/money.php
new file mode 100644
index 0000000..6442dd4
--- /dev/null
+++ b/app/resources/routes/api/money.php
@@ -0,0 +1,8 @@
+group('/money', function($app) {
+ $app->post('/ipc[/]', [Money::class, 'ipc']);
+ $app->post('/uf[/]', [Money::class, 'uf']);
+ $app->post('[/]', [Money::class, 'get']);
+});
diff --git a/app/resources/routes/api/provincias.php b/app/resources/routes/api/provincias.php
new file mode 100644
index 0000000..f7bccb7
--- /dev/null
+++ b/app/resources/routes/api/provincias.php
@@ -0,0 +1,6 @@
+group('/provincia/{provincia_id}', function($app) {
+ $app->get('/comunas', [Provincias::class, 'comunas']);
+});
diff --git a/app/resources/routes/api/proyectos.php b/app/resources/routes/api/proyectos.php
new file mode 100644
index 0000000..0dd2495
--- /dev/null
+++ b/app/resources/routes/api/proyectos.php
@@ -0,0 +1,23 @@
+group('/proyectos', function($app) {
+ $app->get('/escriturando[/]', [Proyectos::class, 'escriturando']);
+ $app->get('[/]', [Proyectos::class, 'list']);
+});
+$app->group('/proyecto/{proyecto_id}', function($app) {
+ $app->get('/estados[/]', [Proyectos\EstadosProyectos::class, 'byProyecto']);
+ $app->get('/estado[/]', [Proyectos\EstadosProyectos::class, 'currentByProyecto']);
+ $app->get('/inicio[/]', [Proyectos\EstadosProyectos::class, 'firstByProyecto']);
+ $app->get('/recepcion[/]', [Proyectos\EstadosProyectos::class, 'recepcionByProyecto']);
+ $app->group('/superficies', function($app) {
+ $app->get('/vendible[/]', [Proyectos::class, 'superficies']);
+ });
+ $app->group('/unidades', function($app) {
+ $app->get('/disponibles[/]', [Proyectos::class, 'disponibles']);
+ $app->get('[/]', [Proyectos::class, 'unidades']);
+ });
+ $app->group('/terreno', function($app) {
+ $app->post('/edit[/]', [Proyectos::class, 'terreno']);
+ });
+});
diff --git a/app/resources/routes/api/proyectos/estados.php b/app/resources/routes/api/proyectos/estados.php
new file mode 100644
index 0000000..4dfb6a3
--- /dev/null
+++ b/app/resources/routes/api/proyectos/estados.php
@@ -0,0 +1,4 @@
+group('/estados');
diff --git a/app/resources/routes/api/regiones.php b/app/resources/routes/api/regiones.php
new file mode 100644
index 0000000..3f48645
--- /dev/null
+++ b/app/resources/routes/api/regiones.php
@@ -0,0 +1,8 @@
+group('/regiones', function($app) {});
+$app->group('/region/{region_id}', function($app) {
+ $app->get('/provincias[/]', [Regiones::class, 'provincias']);
+});
diff --git a/app/resources/routes/api/search.php b/app/resources/routes/api/search.php
new file mode 100644
index 0000000..9a7890b
--- /dev/null
+++ b/app/resources/routes/api/search.php
@@ -0,0 +1,12 @@
+group('/search', function($app) {
+ $app->group('/ventas', function($app) {
+ $app->post('/unidades', [Search::class, 'unidades']);
+ $app->get('/unidad/{unidad_id}', [Search::class, 'unidad']);
+ $app->post('[/]', [Search::class, 'ventas']);
+ });
+ $app->get('/venta/{venta_id}', [Search::class, 'venta']);
+ $app->post('[/]', [Search::class, 'query']);
+});
diff --git a/app/resources/routes/api/ventas.php b/app/resources/routes/api/ventas.php
new file mode 100644
index 0000000..9ff578f
--- /dev/null
+++ b/app/resources/routes/api/ventas.php
@@ -0,0 +1,44 @@
+group('/ventas', function($app) {
+ $folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'ventas']);
+ if (file_exists($folder)) {
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+ }
+ $app->post('/add[/]', [Ventas::class, 'add']);
+ $app->group('/estados', function($app) {
+ $app->post('/firmar[/]', [Ventas::class, 'porFirmar']);
+ });
+ $app->group('/escrituras', function($app) {
+ $app->post('/estados[/]', [Ventas::class, 'escrituras']);
+ });
+ $app->group('/by', function($app) {
+ $app->get('/unidad/{unidad_id}', [Ventas::class, 'unidad']);
+ });
+ $app->post('/get[/]', [Ventas::class, 'getMany']);
+ $app->post('[/]', [Ventas::class, 'proyecto']);
+});
+$app->group('/venta/{venta_id}', function($app) {
+ $app->get('/unidades[/]', [Ventas::class, 'unidades']);
+ $app->get('/comentarios[/]', [Ventas::class, 'comentarios']);
+ $app->group('/escritura', function($app) {
+ $app->post('/add[/]', [Ventas\Escrituras::class, 'add']);
+ });
+ $app->group('/credito', function($app) {
+ $app->post('[/]', [Ventas\Creditos::class, 'edit']);
+ });
+ $app->post('/escriturar[/]', [Ventas::class, 'escriturar']);
+ $app->group('/desistir', function($app) {
+ $app->get('/eliminar[/]', [Ventas::class, 'insistir']);
+ $app->post('[/]', [Ventas::class, 'desistir']);
+ });
+ $app->post('[/]', [Ventas::class, 'edit']);
+ $app->get('[/]', [Ventas::class, 'get']);
+});
diff --git a/app/resources/routes/api/ventas/cierres.php b/app/resources/routes/api/ventas/cierres.php
new file mode 100644
index 0000000..414df64
--- /dev/null
+++ b/app/resources/routes/api/ventas/cierres.php
@@ -0,0 +1,7 @@
+group('/cierres', function($app) {
+ $app->get('/vigentes[/]', [Cierres::class, 'vigentes']);
+ $app->post('[/]', [Cierres::class, 'proyecto']);
+});
diff --git a/app/resources/routes/api/ventas/cuotas.php b/app/resources/routes/api/ventas/cuotas.php
new file mode 100644
index 0000000..b895829
--- /dev/null
+++ b/app/resources/routes/api/ventas/cuotas.php
@@ -0,0 +1,8 @@
+group('/cuotas', function($app) {
+ $app->get('/hoy[/]', [Cuotas::class, 'hoy']);
+ $app->get('/pendiente[/]', [Cuotas::class, 'pendiente']);
+ $app->get('/vencer[/]', [Cuotas::class, 'porVencer']);
+});
diff --git a/app/resources/routes/api/ventas/escrituras.php b/app/resources/routes/api/ventas/escrituras.php
new file mode 100644
index 0000000..e2a65f4
--- /dev/null
+++ b/app/resources/routes/api/ventas/escrituras.php
@@ -0,0 +1,6 @@
+group('/escritura/{venta_id}', function($app) {
+ $app->post('/edit[/]', [Escrituras::class, 'edit']);
+});
diff --git a/app/resources/routes/api/ventas/facturacion.php b/app/resources/routes/api/ventas/facturacion.php
new file mode 100644
index 0000000..cae92a8
--- /dev/null
+++ b/app/resources/routes/api/ventas/facturacion.php
@@ -0,0 +1,6 @@
+group('/facturacion', function($app) {
+ $app->get('/proyecto/{proyecto_id}[/]', [Facturacion::class, 'proyecto']);
+});
diff --git a/app/resources/routes/api/ventas/pagos.php b/app/resources/routes/api/ventas/pagos.php
new file mode 100644
index 0000000..784f146
--- /dev/null
+++ b/app/resources/routes/api/ventas/pagos.php
@@ -0,0 +1,15 @@
+group('/pagos', function($app) {
+ $app->get('/pendientes', [Pagos::class, 'para_pendientes']);
+ $app->get('/abonar', [Pagos::class, 'para_abonar']);
+ $app->get('/rebotes', [Pagos::class, 'rebotes']);
+});
+$app->group('/pago/{pago_id:[0-9]+}', function($app) {
+ $app->post('/depositar[/]', [Pagos::class, 'depositar']);
+ $app->post('/abonar[/]', [Pagos::class, 'abonar']);
+ $app->post('/devolver[/]', [Pagos::class, 'devolver']);
+ $app->get('/anular[/]', [Pagos::class, 'anular']);
+ $app->post('[/]', [Pagos::class, 'edit']);
+});
diff --git a/app/resources/routes/api/ventas/pies.php b/app/resources/routes/api/ventas/pies.php
new file mode 100644
index 0000000..7b5abea
--- /dev/null
+++ b/app/resources/routes/api/ventas/pies.php
@@ -0,0 +1,6 @@
+group('/pie/{pie_id}', function($app) {
+ $app->post('/edit[/]', [Pies::class, 'edit']);
+});
diff --git a/app/resources/routes/api/ventas/precios.php b/app/resources/routes/api/ventas/precios.php
new file mode 100644
index 0000000..6546f48
--- /dev/null
+++ b/app/resources/routes/api/ventas/precios.php
@@ -0,0 +1,11 @@
+group('/precios', function($app) {
+ $app->post('[/]', [Precios::class, 'proyecto']);
+});
+$app->group('/precio', function($app) {
+ $app->group('/unidad/{unidad_id}', function($app) {
+ $app->get('[/]', [Precios::class, 'unidad']);
+ });
+});
diff --git a/app/resources/routes/api/ventas/propiedades.php b/app/resources/routes/api/ventas/propiedades.php
new file mode 100644
index 0000000..da542fa
--- /dev/null
+++ b/app/resources/routes/api/ventas/propiedades.php
@@ -0,0 +1,10 @@
+group('/propiedades', function($app) {
+ $files = new FilesystemIterator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'propiedades']));
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+});
diff --git a/app/resources/routes/api/ventas/propiedades/unidades.php b/app/resources/routes/api/ventas/propiedades/unidades.php
new file mode 100644
index 0000000..6cb7871
--- /dev/null
+++ b/app/resources/routes/api/ventas/propiedades/unidades.php
@@ -0,0 +1,10 @@
+group('/unidades', function($app) {
+ $app->post('/add[/]', [PropiedadesUnidades::class, 'add']);
+});
+$app->group('/unidad/{pu_id}', function($app) {
+ $app->post('/edit[/]', [PropiedadesUnidades::class, 'edit']);
+ $app->delete('[/]', [PropiedadesUnidades::class, 'remove']);
+});
diff --git a/app/resources/routes/api/ventas/propietarios.php b/app/resources/routes/api/ventas/propietarios.php
new file mode 100644
index 0000000..d76be63
--- /dev/null
+++ b/app/resources/routes/api/ventas/propietarios.php
@@ -0,0 +1,6 @@
+group('/propietario/{propietario_rut}', function($app) {
+ $app->get('[/]', [Propietarios::class, 'get']);
+});
diff --git a/app/resources/routes/api/ventas/unidades.php b/app/resources/routes/api/ventas/unidades.php
new file mode 100644
index 0000000..79ae108
--- /dev/null
+++ b/app/resources/routes/api/ventas/unidades.php
@@ -0,0 +1,12 @@
+group('/unidades', function($app) {
+ $app->post('/disponibles', [Unidades::class, 'disponibles']);
+});
+$app->group('/unidad/{unidad_id}', function($app) {
+ $app->group('/prorrateo', function($app) {
+ $app->post('[/]', [Unidades::class, 'prorrateo']);
+ });
+ $app->get('[/]', [Unidades::class, 'get']);
+});
diff --git a/app/resources/routes/contabilidad/cartolas.php b/app/resources/routes/contabilidad/cartolas.php
new file mode 100644
index 0000000..7bd0058
--- /dev/null
+++ b/app/resources/routes/contabilidad/cartolas.php
@@ -0,0 +1,6 @@
+group('/cartolas', function($app) {
+ $app->get('/diaria[/]', [Contabilidad::class, 'diaria']);
+});
diff --git a/app/resources/routes/contabilidad/centros_costos.php b/app/resources/routes/contabilidad/centros_costos.php
new file mode 100644
index 0000000..d1089a4
--- /dev/null
+++ b/app/resources/routes/contabilidad/centros_costos.php
@@ -0,0 +1,7 @@
+group('/centros_costos', function($app) {
+ $app->get('/asignar[/]', [CentrosCostos::class, 'asignar']);
+ $app->get('[/]', CentrosCostos::class);
+});
diff --git a/app/resources/routes/contabilidad/daps.php b/app/resources/routes/contabilidad/daps.php
new file mode 100644
index 0000000..312c207
--- /dev/null
+++ b/app/resources/routes/contabilidad/daps.php
@@ -0,0 +1,6 @@
+group('/depositos', function($app) {
+ $app->get('[/]', [Contabilidad::class, 'depositos']);
+});
diff --git a/app/resources/routes/contabilidad/informes.php b/app/resources/routes/contabilidad/informes.php
new file mode 100644
index 0000000..66bad08
--- /dev/null
+++ b/app/resources/routes/contabilidad/informes.php
@@ -0,0 +1,10 @@
+group('/informes', function($app) {
+ $files = new FilesystemIterator(implode(DIRECTORY_SEPARATOR, [__DIR__, 'informes']));
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+});
diff --git a/app/resources/routes/contabilidad/informes/tesoreria.php b/app/resources/routes/contabilidad/informes/tesoreria.php
new file mode 100644
index 0000000..9cbca00
--- /dev/null
+++ b/app/resources/routes/contabilidad/informes/tesoreria.php
@@ -0,0 +1,6 @@
+group('/tesoreria', function($app) {
+ $app->get('[/[{fecha}[/]]]', [Contabilidad::class, 'tesoreria']);
+});
diff --git a/app/resources/routes/contabilidad/informes/xlsx.php b/app/resources/routes/contabilidad/informes/xlsx.php
new file mode 100644
index 0000000..1514621
--- /dev/null
+++ b/app/resources/routes/contabilidad/informes/xlsx.php
@@ -0,0 +1,6 @@
+group('/xlsx', function($app) {
+ $app->get('/tesoreria/{fecha}[/]', [Informes::class, 'tesoreria']);
+});
diff --git a/app/resources/routes/ventas/cierres.php b/app/resources/routes/ventas/cierres.php
new file mode 100644
index 0000000..62e3084
--- /dev/null
+++ b/app/resources/routes/ventas/cierres.php
@@ -0,0 +1,9 @@
+group('/cierres', function($app) {
+ $app->get('[/]', Cierres::class);
+});
+$app->group('/cierre/{cierre_id}', function($app) {
+ $app->get('[/]', [Cierres::class, 'show']);
+});
diff --git a/app/resources/routes/ventas/cuotas.php b/app/resources/routes/ventas/cuotas.php
new file mode 100644
index 0000000..8960481
--- /dev/null
+++ b/app/resources/routes/ventas/cuotas.php
@@ -0,0 +1,12 @@
+group('/cuotas', function($app) {
+ $app->get('/pendientes[/]', [Cuotas::class, 'pendientes']);
+ $app->get('/abonar[/]', [Cuotas::class, 'depositadas']);
+});
+$app->group('/cuota', function($app) {
+ $app->post('/depositar[/]', [Cuotas::class, 'depositar']);
+ $app->post('/abonar[/]', [Cuotas::class, 'abonar']);
+ $app->post('/devolver[/]', [Cuotas::class, 'devolver']);
+});
diff --git a/app/resources/routes/ventas/escrituras.php b/app/resources/routes/ventas/escrituras.php
new file mode 100644
index 0000000..a9ecd40
--- /dev/null
+++ b/app/resources/routes/ventas/escrituras.php
@@ -0,0 +1,7 @@
+group('/escritura/{venta_id}', function($app) {
+ $app->get('/informe[/]', [Escrituras::class, 'informe']);
+ $app->get('[/]', [Escrituras::class, 'show']);
+});
diff --git a/app/resources/routes/ventas/facturacion.php b/app/resources/routes/ventas/facturacion.php
new file mode 100644
index 0000000..c43e7de
--- /dev/null
+++ b/app/resources/routes/ventas/facturacion.php
@@ -0,0 +1,9 @@
+group('/facturacion', function($app) {
+ $app->get('[/]', Facturacion::class);
+});
+$app->group('/factura/{venta_id}', function($app) {
+ $app->get('[/]', [Facturacion::class, 'show']);
+});
diff --git a/app/resources/routes/ventas/pagos.php b/app/resources/routes/ventas/pagos.php
new file mode 100644
index 0000000..9fad5b0
--- /dev/null
+++ b/app/resources/routes/ventas/pagos.php
@@ -0,0 +1,6 @@
+group('/pagos', function($app) {
+ $app->get('/pendientes', [Pagos::class, 'pendientes']);
+});
diff --git a/app/resources/routes/ventas/pies.php b/app/resources/routes/ventas/pies.php
new file mode 100644
index 0000000..25bb08a
--- /dev/null
+++ b/app/resources/routes/ventas/pies.php
@@ -0,0 +1,13 @@
+group('/pie/{pie_id}', function($app) {
+ $app->group('/cuotas', function($app) {
+ $app->group('/add', function($app) {
+ $app->get('[/]', [Cuotas::class, 'add']);
+ $app->post('[/]', [Cuotas::class, 'doAdd']);
+ });
+ $app->get('[/]', [Pies::class, 'cuotas']);
+ });
+});
diff --git a/app/resources/routes/ventas/precios.php b/app/resources/routes/ventas/precios.php
new file mode 100644
index 0000000..c035216
--- /dev/null
+++ b/app/resources/routes/ventas/precios.php
@@ -0,0 +1,6 @@
+group('/precios', function($app) {
+ $app->get('[/]', Precios::class);
+});
diff --git a/app/resources/routes/ventas/propietarios.php b/app/resources/routes/ventas/propietarios.php
new file mode 100644
index 0000000..bd0929f
--- /dev/null
+++ b/app/resources/routes/ventas/propietarios.php
@@ -0,0 +1,6 @@
+group('/propietario/{propietario_rut:[0-9]+}', function($app) {
+ $app->get('[/]', [Propietarios::class, 'show']);
+});
\ No newline at end of file
diff --git a/app/resources/views/construccion.blade.php b/app/resources/views/construccion.blade.php
new file mode 100644
index 0000000..3b1d313
--- /dev/null
+++ b/app/resources/views/construccion.blade.php
@@ -0,0 +1,14 @@
+@extends('layout.base')
+
+@section('page_title')
+ Construcción
+@endsection
+
+@section('page_content')
+
+
+
+ Esta parte del sitio está en construcción.
+
+
+@endsection
diff --git a/app/resources/views/contabilidad/cartolas/diaria.blade.php b/app/resources/views/contabilidad/cartolas/diaria.blade.php
new file mode 100644
index 0000000..316246b
--- /dev/null
+++ b/app/resources/views/contabilidad/cartolas/diaria.blade.php
@@ -0,0 +1,823 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+
+
+
+ Sociedad |
+ Banco - Cuenta |
+ Hoy |
+ Último Saldo |
+ Saldo Actual |
+ Diferencia |
+
+
+
+
+
+
+
+
+
+ Sociedad |
+ Banco - Cuenta |
+ Fecha |
+ Glosa |
+ Cargo |
+ Abono |
+ Saldo |
+ Centro de Costo |
+ Detalle |
+ Orden |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/contabilidad/centros_costos.blade.php b/app/resources/views/contabilidad/centros_costos.blade.php
new file mode 100644
index 0000000..9e75e7a
--- /dev/null
+++ b/app/resources/views/contabilidad/centros_costos.blade.php
@@ -0,0 +1,330 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+ {{--
+
+
--}}
+
+
+
+ Tipo de Centro |
+ Categoría |
+ Tipo de Cuenta |
+ Cuenta Contable |
+ Centro de Costo |
+ Descripción |
+ {{--
+ | --}}
+
+
+
+ @foreach ($centrosCostos as $centroCosto)
+
+ {{$centroCosto->tipoCentro->descripcion}} |
+ {{$centroCosto->categoria->descripcion}} |
+ {{$centroCosto->tipoCuenta?->descripcion}} |
+ {{$centroCosto->cuentaContable}} |
+ {{$centroCosto->id}} |
+ {{$centroCosto->descripcion}} |
+ {{--
+
+
+
+
+ | --}}
+
+ @endforeach
+
+
+
+
+
+
+
+
+
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/contabilidad/centros_costos/asignar.blade.php b/app/resources/views/contabilidad/centros_costos/asignar.blade.php
new file mode 100644
index 0000000..80fd04f
--- /dev/null
+++ b/app/resources/views/contabilidad/centros_costos/asignar.blade.php
@@ -0,0 +1,399 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+
+
+
+
+ Fecha |
+ Glosa |
+ Documento |
+ Cargo |
+ Abono |
+ Centro de Costo |
+ Detalle |
+ Orden |
+
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/contabilidad/depositos.blade.php b/app/resources/views/contabilidad/depositos.blade.php
new file mode 100644
index 0000000..9d2b0f9
--- /dev/null
+++ b/app/resources/views/contabilidad/depositos.blade.php
@@ -0,0 +1,263 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+
+
+
+
+ Inmobiliaria |
+ Banco |
+ N° Depósito |
+ Capital |
+ Inicio |
+ Plazo |
+ Vencimiento |
+ Vencimiento ISO |
+ Monto al Vencimiento |
+ Tasa |
+
+
+ |
+
+
+
+ @foreach ($activos as $deposito)
+
+ {{$deposito->cuenta->inmobiliaria->razon}} |
+ {{$deposito->cuenta->banco->nombre}} |
+ {{$deposito->id}} |
+ {{$format->pesos($deposito->capital)}} |
+ {{$deposito->inicio->format('d-m-Y')}} |
+ {{$deposito->plazo()}} |
+ {{$deposito->termino->format('d-m-Y')}} |
+ {{$deposito->termino->format('Y-m-d')}} |
+ {{$format->pesos($deposito->futuro)}} |
+ {{$format->percent($deposito->tasa() * 100, 4)}} |
+
+
+ |
+
+ @endforeach
+ @foreach ($vencidos as $deposito)
+
+ {{$deposito->cuenta->inmobiliaria->razon}} |
+ {{$deposito->cuenta->banco->nombre}} |
+ {{$deposito->id}} |
+ {{$format->pesos($deposito->capital)}} |
+ {{$deposito->inicio->format('d-m-Y')}} |
+ {{$deposito->plazo()}} |
+ {{$deposito->termino->format('d-m-Y')}} |
+ {{$deposito->termino->format('Y-m-d')}} |
+ {{$format->pesos($deposito->futuro)}} |
+ {{$format->percent($deposito->tasa() * 100, 4)}} |
+
+
+ |
+
+ @endforeach
+
+
+
+
+
+
+
+
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/contabilidad/informes/tesoreria.blade.php b/app/resources/views/contabilidad/informes/tesoreria.blade.php
new file mode 100644
index 0000000..18f3f82
--- /dev/null
+++ b/app/resources/views/contabilidad/informes/tesoreria.blade.php
@@ -0,0 +1,156 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+ Informe anterior |
+ {{$anterior->format('d/m/Y')}} |
+
+
+ Informe actual |
+ {{$fecha->format('d/m/Y')}} |
+
+
+
+
+
+
+
+ Valor UF |
+ {{$format->pesos($UF->get($fecha), 2)}} |
+
+
+ Valor Dólar |
+ {{$format->pesos($USD->get($fecha), 2)}} |
+
+
+
+
+
+
+
+ EMPRESA |
+ Banco |
+ Cuenta |
+ Saldo Anterior |
+ Saldo Actual |
+ Diferencia |
+ FFMM |
+ DAP |
+ Saldo Empresa |
+ Total Cuentas |
+ Total FFMM |
+ Total DAP |
+ Caja Total |
+
+
+
+ @foreach ($informes['inmobiliarias'] as $inmobiliaria_rut => $informe)
+ @foreach ($informe->cuentas as $i => $cuenta)
+
+ @if ($i === 0)
+ {{$informe->inmobiliaria->razon}} |
+ @endif
+ {{$cuenta->banco}} |
+ {{$cuenta->numero}} |
+ {{$format->pesos($cuenta->anterior)}} |
+ {{$format->pesos($cuenta->actual)}} |
+ {{$format->pesos($cuenta->diferencia())}} |
+ {{$format->pesos($cuenta->ffmm)}} |
+ {{$format->pesos($cuenta->deposito)}} |
+ {{$format->pesos($cuenta->saldo())}} |
+ @if ($i === 0)
+ {{$format->pesos($informe->total())}} |
+ {{$format->pesos($informe->ffmm())}} |
+ {{$format->pesos($informe->deposito())}} |
+ {{$format->pesos($informe->caja())}} |
+ @endif
+
+ @endforeach
+ @endforeach
+
+
+
+ TOTAL |
+ {{$format->pesos($informes['totales']->anterior)}} |
+ {{$format->pesos($informes['totales']->actual)}} |
+ {{$format->pesos($informes['totales']->diferencia())}} |
+ {{$format->pesos($informes['totales']->ffmm)}} |
+ {{$format->pesos($informes['totales']->deposito)}} |
+ {{$format->pesos($informes['totales']->saldo())}} |
+ {{$format->pesos($informes['totales']->cuentas())}} |
+ {{$format->pesos($informes['totales']->ffmms())}} |
+ {{$format->pesos($informes['totales']->depositos())}} |
+ {{$format->pesos($informes['totales']->caja())}} |
+
+
+
+
+
+
+ EMPRESA |
+ INGRESOS |
+ EGRESOS |
+ FECHA |
+ BANCO |
+ DESCRIPCIÓN |
+
+
+
+ @foreach ($informes['movimientos'] as $tipo => $movimientos)
+ @if ($tipo === 'capital dap')
+ @if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0)
+ @continue
+ @endif
+
+ {{strtoupper($tipo)}} |
+
+ @foreach ($movimientos as $ms)
+ @foreach ($ms as $movimiento)
+
+ {{$movimiento->cuenta->inmobiliaria->razon}} |
+ {{$format->pesos($movimiento->abono)}} |
+ {{$format->pesos($movimiento->cargo)}} |
+ {{$movimiento->fecha->format('d/m/Y')}} |
+ {{$movimiento->cuenta->banco->nombre}} |
+ {{$movimiento->glosa}} |
+
+ @endforeach
+ @endforeach
+ @continue
+ @endif
+ @if (count($movimientos) === 0)
+ @continue
+ @endif
+
+ {{strtoupper($tipo)}} |
+
+ @foreach ($movimientos as $movimiento)
+
+ {{$movimiento->cuenta->inmobiliaria->razon}} |
+ {{$format->pesos($movimiento->abono)}} |
+ {{$format->pesos($movimiento->cargo)}} |
+ {{$movimiento->fecha->format('d/m/Y')}} |
+ {{$movimiento->cuenta->banco->nombre}} |
+ {{$movimiento->glosa}} |
+
+ @endforeach
+ @endforeach
+
+
+@endsection
diff --git a/app/resources/views/guest.blade.php b/app/resources/views/guest.blade.php
new file mode 100644
index 0000000..8acdfe6
--- /dev/null
+++ b/app/resources/views/guest.blade.php
@@ -0,0 +1,7 @@
+@extends('layout.base')
+
+@section('page_content')
+
+ Bienvenid@ a Incoviba
+
+@endsection
diff --git a/app/resources/views/home.blade.php b/app/resources/views/home.blade.php
new file mode 100644
index 0000000..63180f0
--- /dev/null
+++ b/app/resources/views/home.blade.php
@@ -0,0 +1,86 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+
+
+
+ @include('home.cuotas_por_vencer')
+
+
+ @include('home.alertas')
+
+
+ @include('home.cierres_vigentes')
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/home/alertas.blade.php b/app/resources/views/home/alertas.blade.php
new file mode 100644
index 0000000..a1f9378
--- /dev/null
+++ b/app/resources/views/home/alertas.blade.php
@@ -0,0 +1,191 @@
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/home/cierres_vigentes.blade.php b/app/resources/views/home/cierres_vigentes.blade.php
new file mode 100644
index 0000000..0cf75f2
--- /dev/null
+++ b/app/resources/views/home/cierres_vigentes.blade.php
@@ -0,0 +1,59 @@
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/home/cuotas_por_vencer.blade.php b/app/resources/views/home/cuotas_por_vencer.blade.php
new file mode 100644
index 0000000..b8a01a0
--- /dev/null
+++ b/app/resources/views/home/cuotas_por_vencer.blade.php
@@ -0,0 +1,52 @@
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/inmobiliarias/list.blade.php b/app/resources/views/inmobiliarias/list.blade.php
new file mode 100644
index 0000000..1a4e173
--- /dev/null
+++ b/app/resources/views/inmobiliarias/list.blade.php
@@ -0,0 +1,36 @@
+@extends('layout.base')
+
+@section('page_title')
+ Inmobiliarias
+@endsection
+
+@section('page_content')
+
+
+
+ Inmobiliarias
+
+ {{--
+
+
--}}
+
+
+
+ @foreach($inmobiliarias as $inmobiliaria)
+
+
+
+
{{$inmobiliaria->razon}} {{$inmobiliaria->tipoSociedad->descripcion}}
+
{{$inmobiliaria->rut()}}
+
+
+ @endforeach
+
+
+@endsection
diff --git a/app/resources/views/layout/base.blade.php b/app/resources/views/layout/base.blade.php
new file mode 100644
index 0000000..9deb8c1
--- /dev/null
+++ b/app/resources/views/layout/base.blade.php
@@ -0,0 +1,5 @@
+
+
+@include('layout.head')
+@include('layout.body')
+
diff --git a/app/resources/views/layout/body.blade.php b/app/resources/views/layout/body.blade.php
new file mode 100644
index 0000000..fb0cc48
--- /dev/null
+++ b/app/resources/views/layout/body.blade.php
@@ -0,0 +1,5 @@
+
+ @include('layout.body.header')
+ @yield('page_content')
+ @include('layout.body.footer')
+
diff --git a/app/resources/views/layout/body/footer.blade.php b/app/resources/views/layout/body/footer.blade.php
new file mode 100644
index 0000000..c3b1007
--- /dev/null
+++ b/app/resources/views/layout/body/footer.blade.php
@@ -0,0 +1,4 @@
+
+@include('layout.body.scripts')
diff --git a/app/resources/views/layout/body/header.blade.php b/app/resources/views/layout/body/header.blade.php
new file mode 100644
index 0000000..258a1a8
--- /dev/null
+++ b/app/resources/views/layout/body/header.blade.php
@@ -0,0 +1,8 @@
+
+
+
+
+
+ @include('layout.body.header.menu')
+
+
diff --git a/app/resources/views/layout/body/header/menu.blade.php b/app/resources/views/layout/body/header/menu.blade.php
new file mode 100644
index 0000000..a68f999
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu.blade.php
@@ -0,0 +1,17 @@
+
diff --git a/app/resources/views/layout/body/header/menu/contabilidad.blade.php b/app/resources/views/layout/body/header/menu/contabilidad.blade.php
new file mode 100644
index 0000000..3f5233f
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/contabilidad.blade.php
@@ -0,0 +1,22 @@
+
+ Contabilidad
+
+
+
diff --git a/app/resources/views/layout/body/header/menu/guest.blade.php b/app/resources/views/layout/body/header/menu/guest.blade.php
new file mode 100644
index 0000000..8c7399b
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/guest.blade.php
@@ -0,0 +1 @@
+Ingresar
diff --git a/app/resources/views/layout/body/header/menu/herramientas.blade.php b/app/resources/views/layout/body/header/menu/herramientas.blade.php
new file mode 100644
index 0000000..45b0b52
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/herramientas.blade.php
@@ -0,0 +1,7 @@
+
+ Herramientas
+
+
+
diff --git a/app/resources/views/layout/body/header/menu/inmobiliarias.blade.php b/app/resources/views/layout/body/header/menu/inmobiliarias.blade.php
new file mode 100644
index 0000000..9aa161c
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/inmobiliarias.blade.php
@@ -0,0 +1 @@
+Inmobiliarias
diff --git a/app/resources/views/layout/body/header/menu/operadores.blade.php b/app/resources/views/layout/body/header/menu/operadores.blade.php
new file mode 100644
index 0000000..c30b9c0
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/operadores.blade.php
@@ -0,0 +1,9 @@
+
+ Operadores
+
+
+
diff --git a/app/resources/views/layout/body/header/menu/proyectos.blade.php b/app/resources/views/layout/body/header/menu/proyectos.blade.php
new file mode 100644
index 0000000..86e5bc2
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/proyectos.blade.php
@@ -0,0 +1,8 @@
+
+ Proyectos
+
+
+
diff --git a/app/resources/views/layout/body/header/menu/search.blade.php b/app/resources/views/layout/body/header/menu/search.blade.php
new file mode 100644
index 0000000..cd4315e
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/search.blade.php
@@ -0,0 +1 @@
+
diff --git a/app/resources/views/layout/body/header/menu/user.blade.php b/app/resources/views/layout/body/header/menu/user.blade.php
new file mode 100644
index 0000000..e2bd013
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/user.blade.php
@@ -0,0 +1,31 @@
+
+ {{$user->name}}
+
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/layout/body/header/menu/ventas.blade.php b/app/resources/views/layout/body/header/menu/ventas.blade.php
new file mode 100644
index 0000000..2cea6c4
--- /dev/null
+++ b/app/resources/views/layout/body/header/menu/ventas.blade.php
@@ -0,0 +1,41 @@
+
+ Ventas
+
+
+
diff --git a/app/resources/views/layout/body/scripts.blade.php b/app/resources/views/layout/body/scripts.blade.php
new file mode 100644
index 0000000..049a3d0
--- /dev/null
+++ b/app/resources/views/layout/body/scripts.blade.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+@stack('page_scripts')
diff --git a/app/resources/views/layout/body/scripts/chartjs.blade.php b/app/resources/views/layout/body/scripts/chartjs.blade.php
new file mode 100644
index 0000000..c11cb71
--- /dev/null
+++ b/app/resources/views/layout/body/scripts/chartjs.blade.php
@@ -0,0 +1,3 @@
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/layout/body/scripts/datatables.blade.php b/app/resources/views/layout/body/scripts/datatables.blade.php
new file mode 100644
index 0000000..d33c940
--- /dev/null
+++ b/app/resources/views/layout/body/scripts/datatables.blade.php
@@ -0,0 +1,5 @@
+@push('page_scripts')
+ {{----}}
+
+
+@endpush
diff --git a/app/resources/views/layout/body/scripts/datatables/buttons.blade.php b/app/resources/views/layout/body/scripts/datatables/buttons.blade.php
new file mode 100644
index 0000000..95b744e
--- /dev/null
+++ b/app/resources/views/layout/body/scripts/datatables/buttons.blade.php
@@ -0,0 +1,9 @@
+@push('page_scripts')
+
+
+
+
+
+
+
+@endpush
diff --git a/app/resources/views/layout/body/scripts/dayjs.blade.php b/app/resources/views/layout/body/scripts/dayjs.blade.php
new file mode 100644
index 0000000..00d8045
--- /dev/null
+++ b/app/resources/views/layout/body/scripts/dayjs.blade.php
@@ -0,0 +1 @@
+
diff --git a/app/resources/views/layout/head.blade.php b/app/resources/views/layout/head.blade.php
new file mode 100644
index 0000000..98233b9
--- /dev/null
+++ b/app/resources/views/layout/head.blade.php
@@ -0,0 +1,10 @@
+
+
+ @hasSection('page_title')
+ Incoviba - @yield('page_title')
+ @else
+ Incoviba
+ @endif
+
+ @include('layout.head.styles')
+
diff --git a/app/resources/views/layout/head/styles.blade.php b/app/resources/views/layout/head/styles.blade.php
new file mode 100644
index 0000000..22dbdc6
--- /dev/null
+++ b/app/resources/views/layout/head/styles.blade.php
@@ -0,0 +1,3 @@
+
+
+@stack('page_styles')
diff --git a/app/resources/views/layout/head/styles/datatables.blade.php b/app/resources/views/layout/head/styles/datatables.blade.php
new file mode 100644
index 0000000..f46671d
--- /dev/null
+++ b/app/resources/views/layout/head/styles/datatables.blade.php
@@ -0,0 +1,3 @@
+@push('page_styles')
+
+@endpush
diff --git a/app/resources/views/layout/head/styles/datatables/buttons.blade.php b/app/resources/views/layout/head/styles/datatables/buttons.blade.php
new file mode 100644
index 0000000..d8e6547
--- /dev/null
+++ b/app/resources/views/layout/head/styles/datatables/buttons.blade.php
@@ -0,0 +1,3 @@
+@push('page_styles')
+
+@endpush
diff --git a/app/resources/views/login/form.blade.php b/app/resources/views/login/form.blade.php
new file mode 100644
index 0000000..8a20b1f
--- /dev/null
+++ b/app/resources/views/login/form.blade.php
@@ -0,0 +1,60 @@
+@extends('layout.base')
+
+@section('page_content')
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/not_found.blade.php b/app/resources/views/not_found.blade.php
new file mode 100644
index 0000000..9169f01
--- /dev/null
+++ b/app/resources/views/not_found.blade.php
@@ -0,0 +1,14 @@
+@extends('layout.base')
+
+@section('page_title')
+ 404 - No Encontrado
+@endsection
+
+@section('page_content')
+
+
+
+ No se ha encontrado la página solicitada
+
+
+@endsection
diff --git a/app/resources/views/proyectos/list.blade.php b/app/resources/views/proyectos/list.blade.php
new file mode 100644
index 0000000..c01ac85
--- /dev/null
+++ b/app/resources/views/proyectos/list.blade.php
@@ -0,0 +1,188 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+ Proyecto |
+ Inmobiliaria |
+ Etapa |
+ Estado |
+ Tiempo Total |
+ Tiempo RF |
+
+
+
+ @foreach ($proyectos as $proyecto)
+
+
+
+ {{$proyecto->descripcion}}
+
+ |
+ {{$proyecto->inmobiliaria()->nombreCompleto()}} |
+ |
+ |
+ |
+ |
+
+ @endforeach
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/proyectos/show.blade.php b/app/resources/views/proyectos/show.blade.php
new file mode 100644
index 0000000..568c0ca
--- /dev/null
+++ b/app/resources/views/proyectos/show.blade.php
@@ -0,0 +1,490 @@
+@extends('layout.base')
+
+@section('page_title')
+ Proyecto {{$proyecto->descripcion}}
+@endsection
+
+@section('page_content')
+
+
+ @php
+ $today = new DateTimeImmutable();
+ @endphp
+
+
+ Dirección |
+ {{$proyecto->direccion()}} |
+
+
+ Inmobiliaria |
+ {{$proyecto->inmobiliaria()->nombreCompleto()}} |
+
+
+ Inicio |
+
+ {{$proyecto->estados()[0]->tipoEstadoProyecto->descripcion}}
+ [{{$proyecto->estados()[0]->tipoEstadoProyecto->etapa->descripcion}}]
+ ({{$proyecto->estados()[0]->fecha->format('d-m-Y')}})
+ ({{$today->diff($proyecto->estados()[0]->fecha)->format('%y años antes')}})
+ |
+
+
+ Estado |
+
+ {{$proyecto->currentEstado()->tipoEstadoProyecto->descripcion}}
+ [{{$proyecto->currentEstado()->tipoEstadoProyecto->etapa->descripcion}}]
+ ({{$proyecto->currentEstado()->fecha->format('d-m-Y')}})
+ ({{$today->diff($proyecto->currentEstado()->fecha)->format('%y años antes')}})
+
+
+
+ |
+
+
+ Terreno |
+
+
+
+
+ {{$format->number($proyecto->terreno->superficie, 2)}}m²
+ |
+
+ {{$format->pesos($proyecto->terreno->valor)}} ({{$proyecto->terreno->fecha?->format('d-m-Y')}})
+ |
+
+
+
+
+ |
+
+
+ |
+
+
+ Superficies |
+
+
+
+
+
+ Total
+
+ |
+
+
+ {{$format->number($proyecto->superficie->total(), 2)}}m²
+
+ |
+ |
+
+
+ Bajo Nivel |
+ {{$format->number($proyecto->superficie->bajo_nivel, 2)}}m² |
+
+
+ Sobre Nivel |
+ {{$format->number($proyecto->superficie->sobre_nivel, 2)}}m² |
+
+
+
+
+ Vendible
+
+ |
+
+
+ |
+
+
+ Vendido |
+ |
+
+
+ Por Vender |
+ |
+
+
+ |
+
+
+ Unidades |
+ |
+
+
+ Ventas |
+ |
+
+
+ Stock |
+ |
+
+
+ Proyección |
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+@endsection
+
+@include('layout.body.scripts.chartjs')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/proyectos/terreno/edit.blade.php b/app/resources/views/proyectos/terreno/edit.blade.php
new file mode 100644
index 0000000..d1164c2
--- /dev/null
+++ b/app/resources/views/proyectos/terreno/edit.blade.php
@@ -0,0 +1,5 @@
+@extends('layout.base')
+
+@push('page_content')
+
+@endpush
diff --git a/app/resources/views/proyectos/unidades.blade.php b/app/resources/views/proyectos/unidades.blade.php
new file mode 100644
index 0000000..759ae75
--- /dev/null
+++ b/app/resources/views/proyectos/unidades.blade.php
@@ -0,0 +1,234 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+ @foreach ($proyectos as $proyecto)
+
{{$proyecto->descripcion}}
+ @endforeach
+
+
+
+@endsection
+
+@push('page_styles')
+
+@endpush
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/search.blade.php b/app/resources/views/search.blade.php
new file mode 100644
index 0000000..9464141
--- /dev/null
+++ b/app/resources/views/search.blade.php
@@ -0,0 +1,370 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
Búsqueda
+
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/add.blade.php b/app/resources/views/ventas/add.blade.php
new file mode 100644
index 0000000..c02b147
--- /dev/null
+++ b/app/resources/views/ventas/add.blade.php
@@ -0,0 +1,810 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/base.blade.php b/app/resources/views/ventas/base.blade.php
new file mode 100644
index 0000000..1a75b85
--- /dev/null
+++ b/app/resources/views/ventas/base.blade.php
@@ -0,0 +1,36 @@
+@extends('layout.base')
+
+@section('page_title')
+ Venta {{$venta->proyecto()->descripcion}} {{$venta->propiedad()->summary()}}
+@endsection
+
+@section('page_content')
+
+
+
+
+ @if (isset($showPropietario) and $showPropietario)
+
+ @include('ventas.show.propietario')
+
+ @endif
+
+ @hasSection('venta_subtitle')
+
+
+ @yield('venta_subtitle')
+
+
+ @endif
+
+
+ @yield('venta_content')
+
+@endsection
diff --git a/app/resources/views/ventas/cierres/list.blade.php b/app/resources/views/ventas/cierres/list.blade.php
new file mode 100644
index 0000000..be09dff
--- /dev/null
+++ b/app/resources/views/ventas/cierres/list.blade.php
@@ -0,0 +1,293 @@
+@extends('layout.base')
+
+
+@section('page_title')
+ Cierres - Listado
+@endsection
+
+@section('page_content')
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_styles')
+
+@endpush
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/cierres/show.blade.php b/app/resources/views/ventas/cierres/show.blade.php
new file mode 100644
index 0000000..d778fad
--- /dev/null
+++ b/app/resources/views/ventas/cierres/show.blade.php
@@ -0,0 +1,141 @@
+@extends('layout.base')
+
+@section('page_title')
+ Cierre - Detalle
+@endsection
+
+@section('page_content')
+
+
+
+
+
+
+ Fecha
+
+
+ {{$cierre->dateTime->format('d-m-Y')}}
+
+
+
PROPIETARIO
+
+
+
+ {{$cierre->propietario->rut()}}
+
+
+ {{$cierre->propietario->nombreCompleto()}}
+
+
+
+
+
+ {{$cierre->propietario->datos->direccion}}
+
+
+
+
PROPIEDAD
+
+
+
+ @foreach ($cierre->unidades as $unidad)
+
+ {{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}} |
+ {{$unidad->descripcion}} |
+ {{$unidad->proyectoTipoUnidad->nombre}} |
+ {{$unidad->proyectoTipoUnidad->abreviacion}} |
+ {{number_format($unidad->proyectoTipoUnidad->vendible(), 2, ',', '.')}} m² |
+ {{number_format($unidad->currentPrecio->valor, 2, ',', '.')}} UF |
+ {{number_format($unidad->currentPrecio->valor / $unidad->proyectoTipoUnidad->vendible(), 2, ',', '.')}} UF/m² |
+
+ @endforeach
+
+
+
+
OFERTA
+
+
+ Precio
+
+
+ {{number_format($cierre->precio, 2, ',', '.')}} UF
+
+
+
+
+ Neto
+
+
+ {{number_format($cierre->neto(), 2, ',', '.')}} UF
+
+
+ {{number_format($cierre->neto() / $cierre->principal()->vendible, 2, ',', '.')}} UF/m²
+
+
+ @if ($cierre->neto() / $cierre->principal()->vendible > $cierre->principal()->precio / $cierre->principal()->vendible)
+
+ @else
+
+ @endif
+
+
+ @foreach($cierre->valoresCierre as $valorCierre)
+
+
{{ucwords($valorCierre->tipoValorCierre->descripcion)}}
+
{{number_format($valorCierre->valor, 2, ',', '.')}} UF
+
{{number_format($valorCierre->valor / $cierre->precio * 100, 2, ',', '.')}}%
+
+ @endforeach
+
DIFERENCIA
+
+
Neto
+
+ {{number_format($cierre->neto() - $cierre->principal()->precio, 2, ',', '.')}} UF
+
+
+
ESTADO
+
+
+
+ {{ucwords($cierre->current->tipoEstadoCierre->descripcion)}}
+
+
+ {{$cierre->current->fecha->format('d-m-Y')}}
+
+
+ @if ($cierre->current->tipoEstadoCierre->descripcion === 'aprobado')
+
+
+ @endif
+
+
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/creditos.blade.php b/app/resources/views/ventas/creditos.blade.php
new file mode 100644
index 0000000..54d8fe3
--- /dev/null
+++ b/app/resources/views/ventas/creditos.blade.php
@@ -0,0 +1,294 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Crédito
+@endsection
+
+@section('venta_content')
+ @php($credito = $venta->formaPago()->credito)
+
+
+
Fecha
+
+
+ {{$credito->pago->fecha->format('d-m-Y')}}
+
+
+
+
+
+
+
+
+
Banco
+
+
+ @if (isset($credito->pago->banco))
+ {{$credito->pago->banco->nombre}}
+ @else
+ No definido
+ @endif
+
+
+
+
+
+
+
+
+
Valor
+
+
+ {{$format->ufs($credito->pago->valor())}}
+
+
+
+
+
+
+
+
+@endsection
+
+@push('page_styles')
+
+@endpush
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/cuotas/abonar.blade.php b/app/resources/views/ventas/cuotas/abonar.blade.php
new file mode 100644
index 0000000..e6bf045
--- /dev/null
+++ b/app/resources/views/ventas/cuotas/abonar.blade.php
@@ -0,0 +1,145 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
Total
+
{{count($cuotas_depositadas)}}
+
{{$format->pesos(array_reduce($cuotas_depositadas, function($sum, $cuota) {return $sum + $cuota['Valor'];}, 0))}}
+
+
+
+
+ Proyecto |
+ Departamento |
+ Departamento Sort |
+ Propietario |
+ Valor Cuota |
+ Fecha Cuota |
+ Fecha ISO |
+ Fecha Depositada |
+ Fecha Abono / Devolución |
+ Acción |
+
+
+
+ @foreach($cuotas_depositadas as $cuota)
+
+ {{$cuota['Proyecto']}} |
+
+ {{$cuota['Departamento']}}
+ |
+ {{str_pad($cuota['Departamento'], 4, 0, STR_PAD_LEFT)}} |
+ {{$cuota['Propietario']}} |
+ {{$format->pesos($cuota['Valor'])}} |
+ {{$cuota['Fecha Cheque']}} |
+ {{$cuota['Fecha ISO']}} |
+ {{$cuota['Fecha Depositada']}} |
+
+
+ |
+
+
+
+
+
+ |
+
+ @endforeach
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/cuotas/pendientes.blade.php b/app/resources/views/ventas/cuotas/pendientes.blade.php
new file mode 100644
index 0000000..eae188e
--- /dev/null
+++ b/app/resources/views/ventas/cuotas/pendientes.blade.php
@@ -0,0 +1,125 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
Total
+
{{count($cuotas_pendientes)}}
+
{{$format->pesos(array_reduce($cuotas_pendientes, function($sum, $cuota) {return $sum + $cuota['Valor'];}, 0))}}
+
+
+
+
+ Proyecto |
+ Departamento |
+ Departamento Sort |
+ Propietario |
+ Cuota |
+ Banco |
+ Valor |
+ Día |
+ Fecha Cheque (Días) |
+ Fecha ISO |
+ Fecha Deposito |
+ Depositar |
+
+
+
+ @foreach($cuotas_pendientes as $cuota)
+
+ {{$cuota['Proyecto']}} |
+
+
+ {{$cuota['Departamento']}}
+
+ |
+ {{str_pad($cuota['Departamento'], 4, '0', STR_PAD_LEFT)}} |
+ {{$cuota['Propietario']}} |
+ {{$cuota['Numero']}} |
+ {{$cuota['Banco']}} |
+ {{$format->pesos($cuota['Valor'])}} |
+ {{$cuota['Dia']}} |
+ {{$cuota['Fecha Cheque']}} ({{$cuota['Vencida']}}) |
+ {{$cuota['Fecha ISO']}} |
+
+
+ |
+
+
+ |
+
+ @endforeach
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/desistida.blade.php b/app/resources/views/ventas/desistida.blade.php
new file mode 100644
index 0000000..530d572
--- /dev/null
+++ b/app/resources/views/ventas/desistida.blade.php
@@ -0,0 +1,110 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Desistida
+@endsection
+
+@section('venta_content')
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/desistir.blade.php b/app/resources/views/ventas/desistir.blade.php
new file mode 100644
index 0000000..d853777
--- /dev/null
+++ b/app/resources/views/ventas/desistir.blade.php
@@ -0,0 +1,73 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Desistir
+@endsection
+
+@section('venta_content')
+
+
+
+
+ {{$format->pesos($venta->formaPago()->pie->pagado('pesos'))}}
+
+ {{$format->number($venta->formaPago()->pie->pagado() / $venta->valor * 100)}}% de la venta
+
+
+
+
+
+
+ {{$format->pesos($venta->valor * 0.05 * $UF->get())}}
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/edit.blade.php b/app/resources/views/ventas/edit.blade.php
new file mode 100644
index 0000000..9bf3237
--- /dev/null
+++ b/app/resources/views/ventas/edit.blade.php
@@ -0,0 +1,82 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Editar Venta
+@endsection
+
+@section('venta_content')
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/escriturar.blade.php b/app/resources/views/ventas/escriturar.blade.php
new file mode 100644
index 0000000..23445e2
--- /dev/null
+++ b/app/resources/views/ventas/escriturar.blade.php
@@ -0,0 +1,276 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Escriturar
+@endsection
+
+@section('venta_content')
+
+
+
Faltante
+
{{$format->pesos($venta->saldo('pesos'))}}
+
{{$format->ufs($venta->saldo())}}
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/escrituras/add.blade.php b/app/resources/views/ventas/escrituras/add.blade.php
new file mode 100644
index 0000000..24234a4
--- /dev/null
+++ b/app/resources/views/ventas/escrituras/add.blade.php
@@ -0,0 +1,153 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Agregar Abono en Escritura
+@endsection
+
+@section('venta_content')
+
+
Valor Promesa {{$format->ufs($venta->valor)}}
+ @if (isset($venta->formaPago()->pie))
+
Valor Anticipo {{$format->ufs($venta->formaPago()->pie->valor)}}
+ @endif
+ @if (isset($venta->formaPago()->credito))
+
Crédito {{$format->ufs($venta->formaPago()->credito->pago->valor())}}
+ @endif
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/escrituras/informe.blade.php b/app/resources/views/ventas/escrituras/informe.blade.php
new file mode 100644
index 0000000..648192c
--- /dev/null
+++ b/app/resources/views/ventas/escrituras/informe.blade.php
@@ -0,0 +1,88 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Resumen Escritura
+@endsection
+
+@section('venta_content')
+
+ El departamento {{$venta->propiedad()->departamentos()[0]->descripcion}}:
+ @php
+ $estacionamientos = $venta->propiedad()->estacionamientos();
+ @endphp
+ @if (count($estacionamientos) === 0)
+ no tiene estacionamientos
+ @else
+ tiene
+ {{count($estacionamientos) === 1 ? 'el' : 'los'}}
+ estacionamiento{{count($estacionamientos) === 1 ? '': 's'}}
+ {{implode(', ', array_map(function(Incoviba\Model\Venta\Unidad $unidad) {
+ return $unidad->descripcion;
+ }, $estacionamientos))}}
+ @endif
+ y
+ @php
+ $bodegas = $venta->propiedad()->bodegas();
+ @endphp
+ @if (count($bodegas) === 0)
+ no tiene bodegas
+ @else
+ tiene
+ {{count($bodegas) === 1 ? 'la' : 'las'}}
+ bodega{{count($bodegas) === 1 ? '' : 's'}}
+ {{implode(', ', array_map(function(Incoviba\Model\Venta\Unidad $unidad) {
+ return $unidad->descripcion;
+ }, $bodegas))}}
+ @endif
+
+
+
PRECIO
+ {{$format->ufs($venta->valor)}}
+
+
+ @if (isset($venta->formaPago()->pie))
+ @php($pie = $venta->formaPago()->pie)
+
PIE
+ {{$pie->cuotas}} cuotas que suman
+ {{$format->pesos($pie->pagado('pesos'))}}
+ equivalente a
+ {{$format->ufs($pie->pagado())}}.
+
+ @endif
+ @if (isset($venta->formaPago()->escritura))
+ @php($escritura = $venta->formaPago()->escritura)
+
ESCRITURA
+ {{$format->pesos($escritura->pago->valor)}}
+ el
+ {{$escritura->fecha->format('d-m-Y')}}
+ equivalente a
+ {{$format->ufs($escritura->pago->valor())}}
+
+ @endif
+
+
TOTAL ANTICIPO
+ {{$format->ufs($venta->formaPago()->anticipo())}}
+
+ @if (isset($venta->formaPago()->bonoPie))
+ @php($bono = $venta->formaPago()->bonoPie)
+
BONO PIE
+ {{$format->ufs($bono->pago->valor())}}
+
+ @endif
+ @if (isset($venta->formaPago()->credito))
+ @php($credito = $venta->formaPago()->credito)
+
CRÉDITO
+ {{$format->ufs($credito->pago->valor())}}
+ en Banco {{$credito->pago->banco->nombre}}
+
+ @endif
+
+
TOTAL
+ {{$format->ufs($venta->formaPago()->total())}}
+ @if (($venta->formaPago()->total() - $venta->valor) !== 0)
+
+
+ Diferencia {{$format->ufs($venta->formaPago()->total() - $venta->valor)}}. ({{$format->percent(($venta->formaPago()->total() - $venta->valor) / $venta->valor * 100)}})
+ @endif
+
+@endsection
diff --git a/app/resources/views/ventas/escrituras/show.blade.php b/app/resources/views/ventas/escrituras/show.blade.php
new file mode 100644
index 0000000..5be5aab
--- /dev/null
+++ b/app/resources/views/ventas/escrituras/show.blade.php
@@ -0,0 +1,51 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Escritura
+@endsection
+
+@section('venta_content')
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/estado/edit.blade.php b/app/resources/views/ventas/estado/edit.blade.php
new file mode 100644
index 0000000..194ebfc
--- /dev/null
+++ b/app/resources/views/ventas/estado/edit.blade.php
@@ -0,0 +1,16 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+@endsection
diff --git a/app/resources/views/ventas/facturacion.blade.php b/app/resources/views/ventas/facturacion.blade.php
new file mode 100644
index 0000000..d0a09d4
--- /dev/null
+++ b/app/resources/views/ventas/facturacion.blade.php
@@ -0,0 +1,382 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+ @foreach ($proyectos as $proyecto)
+
{{$proyecto->descripcion}}
+ @endforeach
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/facturacion/show.blade.php b/app/resources/views/ventas/facturacion/show.blade.php
new file mode 100644
index 0000000..e8f7c03
--- /dev/null
+++ b/app/resources/views/ventas/facturacion/show.blade.php
@@ -0,0 +1,451 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+ Valor Venta: {{$format->ufs($venta->valor)}}
+
+
+ @if ($venta->currentEstado()->fecha->sub(new DateInterval('P1M')) > $venta->proyecto()->terreno->fecha
+ and $IPC->get($venta->proyecto()->terreno->fecha, $venta->currentEstado()->fecha->sub(new DateInterval('P1M'))) === 0.0)
+
+
+
+ IPC no disponible para este mes.
+
+
+ @endif
+
+
+
+
+
+
+ {{mb_strtoupper($venta->proyecto()->inmobiliaria()->nombreCompleto())}}
+
+ GIRO:
+ Dirección: {{$venta->proyecto()->direccion()->simple()}}
+
+
+
+
+ RUT: {{$venta->proyecto()->inmobiliaria()->rut()}}
+ FACTURA ELECTRÓNICA
+ N° #
+
+
+
+
+
+
+
+ Señor(es) |
+ {{$venta->propietario()->nombreCompleto()}} |
+ RUT |
+ {{$venta->propietario()->rut()}} |
+
+
+ Giro |
+ Otras Actividades Profesionales |
+ Fecha Emisión |
+ {{(new IntlDateFormatter('es-CL', IntlDateFormatter::LONG, IntlDateFormatter::NONE))->format($venta->currentEstado()->fecha)}} |
+
+
+ Dirección |
+ {{$venta->propietario()->datos->direccion->simple()}} |
+ Comuna |
+ {{mb_strtoupper($venta->propietario()->datos->direccion->comuna->descripcion)}} |
+
+
+
+
+
+
+
+ DETALLES |
+
+
+ N° |
+ Descripción |
+ Cant/Unidad |
+ Prec. Unit. |
+ Ind |
+ Total |
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+ TOTALES |
+
+
+
+
+ Monto Neto |
+ |
+
+
+ Monto Exento |
+ |
+
+
+ 19% IVA |
+ |
+
+
+ Monto Total |
+ |
+
+
+
+
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/list.blade.php b/app/resources/views/ventas/list.blade.php
new file mode 100644
index 0000000..bf6bfa0
--- /dev/null
+++ b/app/resources/views/ventas/list.blade.php
@@ -0,0 +1,333 @@
+@extends('layout.base')
+
+@section('page_title')
+ Ventas
+@endsection
+
+@section('page_content')
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/pagos/pendientes.blade.php b/app/resources/views/ventas/pagos/pendientes.blade.php
new file mode 100644
index 0000000..4bf89a1
--- /dev/null
+++ b/app/resources/views/ventas/pagos/pendientes.blade.php
@@ -0,0 +1,257 @@
+@extends('layout.base')
+
+@section('page_title')
+ Pagos Pendientes
+@endsection
+
+@section('page_content')
+
+@endsection
+
+@include('layout.body.scripts.chartjs')
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/pies/cuotas.blade.php b/app/resources/views/ventas/pies/cuotas.blade.php
new file mode 100644
index 0000000..64ebb57
--- /dev/null
+++ b/app/resources/views/ventas/pies/cuotas.blade.php
@@ -0,0 +1,317 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Cuotas - Pie
+@endsection
+
+@section('venta_content')
+
+
+
+ # |
+ Fecha |
+ Fecha ISO |
+ Banco |
+ Identificador |
+ Valor |
+ Valor UF |
+ Estado |
+ Fecha Estado |
+ Fecha Estado ISO |
+ |
+
+
+ @php
+ $now = new DateTimeImmutable();
+ $uf_venta = $venta->uf === 0.0 ? $UF->get($venta->currentEstado()->fecha) : $venta->uf;
+ @endphp
+ @foreach ($venta->formaPago()->pie->cuotas() as $cuota)
+ pago->currentEstado->tipoEstadoPago->descripcion, ['anulado', 'reemplazado']))
+ class="disabled"
+ @endif >
+ {{$cuota->numero}} |
+ {{$cuota->pago->fecha->format('d-m-Y')}} |
+ {{$cuota->pago->fecha->format('Y-m-d')}} |
+ {{$cuota->pago->banco->nombre}} |
+ {{$cuota->pago->identificador}} |
+ {{$format->pesos($cuota->pago->valor)}} |
+
+ @if ($cuota->pago->currentEstado->tipoEstadoPago->descripcion === 'abonado' and $cuota->pago->currentEstado->fecha <= $now)
+ {{$format->ufs($cuota->pago->valor())}}
+ @endif
+ |
+ pago->currentEstado->tipoEstadoPago->descripcion === 'abonado')
+ class="green"
+ @elseif ($cuota->pago->currentEstado->tipoEstadoPago->descripcion === 'depositado')
+ class="yellow"
+ @elseif ($cuota->pago->currentEstado->tipoEstadoPago->activo !== 1)
+ class="red"
+ @endif
+ >{{ucwords($cuota->pago->currentEstado->tipoEstadoPago->descripcion)}} |
+
+ @if (in_array($cuota->pago->currentEstado->tipoEstadoPago->descripcion, ['abonado', 'anulado', 'reemplazado']))
+ {{$cuota->pago->currentEstado->fecha->format('d-m-Y')}}
+ @elseif (!in_array($cuota->pago->currentEstado->tipoEstadoPago->descripcion, ['anulado', 'reemplazado']))
+
+
+
+
+
+ @if ($cuota->pago->currentEstado->tipoEstadoPago->descripcion === 'depositado')
+
+ @endif
+
+
+ @endif
+ |
+ {{$cuota->pago->currentEstado->fecha->format('Y-m-d')}} |
+
+ @if ($cuota->pago->currentEstado->tipoEstadoPago->descripcion !== 'anulado')
+
+ @endif
+ |
+
+ @endforeach
+
+
+
+ TOTAL |
+
+ {{$format->pesos($total_pesos = array_reduce($venta->formaPago()->pie->cuotas(),
+ function(float $sum, Incoviba\Model\Venta\Cuota $cuota) {
+ return $sum + $cuota->pago->valor;
+ }, 0))}}
+ |
+
+ {{$format->ufs($total = array_reduce($venta->formaPago()->pie->cuotas(),
+ function(float $sum, Incoviba\Model\Venta\Cuota $cuota) use ($now, $uf_venta) {
+ return $sum + (($cuota->pago->fecha > $now or $cuota->pago->uf === null) ?
+ $cuota->pago->valor / $uf_venta :
+ $cuota->pago->valor());
+ }, 0.0))}}
+ |
+ |
+
+
+ TOTAL PAGADO |
+
+ {{$format->pesos($pagado_pesos = array_reduce($venta->formaPago()->pie->cuotas(true),
+ function(int $sum, Incoviba\Model\Venta\Cuota $cuota) {
+ return $sum + $cuota->pago->valor;
+ }, 0))}}
+ |
+
+ {{$format->ufs($pagado = array_reduce($venta->formaPago()->pie->cuotas(true),
+ function(float $sum, Incoviba\Model\Venta\Cuota $cuota) {
+ return $sum + $cuota->pago->valor();
+ }, 0.0))}}
+ |
+
+ {{$format->number($pagado / $total * 100, 2)}}%
+ |
+ |
+
+
+ POR PAGAR |
+
+ {{$format->pesos($total_pesos - $pagado_pesos)}}
+ |
+
+ {{$format->ufs($total - $pagado)}}
+ |
+
+ {{$format->number(($total - $pagado) / $total * 100, 2)}}%
+ |
+ |
+
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.head.styles.datatables.buttons')
+@include('layout.body.scripts.datatables')
+@include('layout.body.scripts.datatables.buttons')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/pies/cuotas/add.blade.php b/app/resources/views/ventas/pies/cuotas/add.blade.php
new file mode 100644
index 0000000..2cffa1a
--- /dev/null
+++ b/app/resources/views/ventas/pies/cuotas/add.blade.php
@@ -0,0 +1,135 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Agregar Cuotas - Pie
+@endsection
+
+@section('venta_content')
+
+@endsection
+
+@include('layout.body.scripts.dayjs')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/pies/edit.blade.php b/app/resources/views/ventas/pies/edit.blade.php
new file mode 100644
index 0000000..db5d4ce
--- /dev/null
+++ b/app/resources/views/ventas/pies/edit.blade.php
@@ -0,0 +1,43 @@
+@extends('ventas.base')
+
+@section('venta_subtitle')
+ Pie
+@endsection
+
+@section('venta_content')
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/precios/list.blade.php b/app/resources/views/ventas/precios/list.blade.php
new file mode 100644
index 0000000..a55a892
--- /dev/null
+++ b/app/resources/views/ventas/precios/list.blade.php
@@ -0,0 +1,697 @@
+@extends('layout.base')
+
+
+@section('page_title')
+ Precios - Listado
+@endsection
+
+@section('page_content')
+
+
+@endsection
+
+@push('page_styles')
+
+@endpush
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/propiedades/edit.blade.php b/app/resources/views/ventas/propiedades/edit.blade.php
new file mode 100644
index 0000000..e54d5d9
--- /dev/null
+++ b/app/resources/views/ventas/propiedades/edit.blade.php
@@ -0,0 +1,252 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+
+
+
+ Tipo |
+ Unidad |
+ Valor |
+
+
+ |
+
+
+
+ @foreach($propiedad->unidades as $unidad)
+
+ {{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}} |
+ {{$unidad->descripcion}} |
+
+
+ |
+
+
+ |
+
+ @endforeach
+
+
+
+
+
+
+
+
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/propietarios/edit.blade.php b/app/resources/views/ventas/propietarios/edit.blade.php
new file mode 100644
index 0000000..24dad58
--- /dev/null
+++ b/app/resources/views/ventas/propietarios/edit.blade.php
@@ -0,0 +1,226 @@
+@extends('layout.base')
+
+@section('page_title')
+Editar Propietario
+@endsection
+
+@section('page_content')
+
+
+
+
+@endsection
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/propietarios/show.blade.php b/app/resources/views/ventas/propietarios/show.blade.php
new file mode 100644
index 0000000..db1ce61
--- /dev/null
+++ b/app/resources/views/ventas/propietarios/show.blade.php
@@ -0,0 +1,7 @@
+@extends('layout.base')
+
+@section('page_content')
+
+ {{$propietario->nombreCompleto()}}
+
+@endsection
\ No newline at end of file
diff --git a/app/resources/views/ventas/show.blade.php b/app/resources/views/ventas/show.blade.php
new file mode 100644
index 0000000..0260d2e
--- /dev/null
+++ b/app/resources/views/ventas/show.blade.php
@@ -0,0 +1,34 @@
+@extends('ventas.base')
+
+@php
+$showPropietario = true;
+@endphp
+
+@section('venta_content')
+
+
+ @include('ventas.show.propiedad')
+ @include('ventas.show.detalle')
+ @include('ventas.show.forma_pago', ['formaPago' => $venta->formaPago()])
+ @include('ventas.show.escritura')
+ @include('ventas.show.entrega')
+ @include('ventas.show.comentarios')
+
+@endsection
diff --git a/app/resources/views/ventas/show/comentarios.blade.php b/app/resources/views/ventas/show/comentarios.blade.php
new file mode 100644
index 0000000..8c5d735
--- /dev/null
+++ b/app/resources/views/ventas/show/comentarios.blade.php
@@ -0,0 +1,88 @@
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/show/detalle.blade.php b/app/resources/views/ventas/show/detalle.blade.php
new file mode 100644
index 0000000..e928812
--- /dev/null
+++ b/app/resources/views/ventas/show/detalle.blade.php
@@ -0,0 +1,38 @@
+
+
+
+
+
+ Valor Promesa |
+ Valor Util |
+ UF/m² |
+ Comisión |
+
+ Fecha Promesa
+ Fecha Ingreso
+ |
+
+
+
+
+ {{$format->ufs($venta->valor)}} |
+ {{$format->ufs($venta->util())}} |
+ {{$format->number($venta->util() / $venta->propiedad()->vendible(), 2)}} UF/m² |
+ 0,00 UF (0,00%) |
+
+ {{$venta->fecha->format('d-m-Y')}}
+ {{$venta->fechaIngreso->format('d-m-Y')}}
+ |
+
+
+
+
diff --git a/app/resources/views/ventas/show/entrega.blade.php b/app/resources/views/ventas/show/entrega.blade.php
new file mode 100644
index 0000000..ce51587
--- /dev/null
+++ b/app/resources/views/ventas/show/entrega.blade.php
@@ -0,0 +1,11 @@
+
+ ENTREGA
+
+
+ @if ($venta->entrega() !== null)
+ @else
+
+ No
+
+ @endif
+
diff --git a/app/resources/views/ventas/show/escritura.blade.php b/app/resources/views/ventas/show/escritura.blade.php
new file mode 100644
index 0000000..7e2aade
--- /dev/null
+++ b/app/resources/views/ventas/show/escritura.blade.php
@@ -0,0 +1,31 @@
+
+ ESCRITURA
+
+@if (in_array($venta->currentEstado()->tipoEstadoVenta->descripcion, ['escriturando', 'firmado por inmobiliaria', 'archivado']))
+
+@else
+
+@endif
diff --git a/app/resources/views/ventas/show/forma_pago.blade.php b/app/resources/views/ventas/show/forma_pago.blade.php
new file mode 100644
index 0000000..2f2a264
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago.blade.php
@@ -0,0 +1,229 @@
+
+ FORMA DE PAGO
+
+
+
+ @include('ventas.show.forma_pago.pie', ['pie' => $formaPago?->pie])
+ @include('ventas.show.forma_pago.escritura', ['escritura' => $formaPago?->escritura])
+ @include('ventas.show.forma_pago.anticipo', ['anticipo' => ['uf' => $formaPago?->anticipo(), 'pesos' => $formaPago?->anticipo('pesos')]])
+ @include('ventas.show.forma_pago.bono_pie', ['bonoPie' => $formaPago?->bonoPie])
+ @include('ventas.show.forma_pago.subsidio', ['subsidio' => $formaPago?->subsidio])
+ @include('ventas.show.forma_pago.credito', ['credito' => $formaPago?->credito])
+ @include('ventas.show.forma_pago.total')
+ @include('ventas.show.forma_pago.devolucion', ['devolucion' => $formaPago?->devolucion])
+
+
+
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/ventas/show/forma_pago/anticipo.blade.php b/app/resources/views/ventas/show/forma_pago/anticipo.blade.php
new file mode 100644
index 0000000..d9f3095
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/anticipo.blade.php
@@ -0,0 +1,7 @@
+
+ Anticipo |
+ |
+ {{$format->ufs($anticipo['uf'])}} |
+ {{$format->pesos($anticipo['pesos'])}} |
+ |
+
diff --git a/app/resources/views/ventas/show/forma_pago/bono_pie.blade.php b/app/resources/views/ventas/show/forma_pago/bono_pie.blade.php
new file mode 100644
index 0000000..adae804
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/bono_pie.blade.php
@@ -0,0 +1,24 @@
+
+
+ Bono Pie
+ @if ($bonoPie !== null)
+
+
+
+
+
+ @else
+
+
+
+ @endif
+ |
+ @if ($bonoPie !== null)
+ |
+ {{$format->ufs($bonoPie->pago->valor())}} |
+ {{$format->pesos($bonoPie->pago->valor)}} |
+ |
+ @else
+ |
+ @endif
+
diff --git a/app/resources/views/ventas/show/forma_pago/credito.blade.php b/app/resources/views/ventas/show/forma_pago/credito.blade.php
new file mode 100644
index 0000000..0310043
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/credito.blade.php
@@ -0,0 +1,42 @@
+
+
+ Crédito
+ @if ($credito !== null)
+
+
+
+
+
+ @else
+
+
+
+ @endif
+ |
+ @if ($credito !== null)
+ |
+
+ {{$format->ufs($credito->pago->valor())}}
+ |
+
+ {{$format->pesos($credito->pago->valor)}}
+ |
+
+ {{$credito->pago->currentEstado->fecha->format('d-m-Y')}}
+ @if ($credito->pago->currentEstado->tipoEstadoPago->descripcion === 'no pagado')
+
+
+
+ @elseif($credito->pago->currentEstado->tipoEstadoPago->descripcion === 'depositado')
+
+
+
+ @endif
+ |
+
+ Banco: {{$credito->pago->banco?->nombre}}
+ |
+ @else
+ |
+ @endif
+
diff --git a/app/resources/views/ventas/show/forma_pago/devolucion.blade.php b/app/resources/views/ventas/show/forma_pago/devolucion.blade.php
new file mode 100644
index 0000000..e69de29
diff --git a/app/resources/views/ventas/show/forma_pago/escritura.blade.php b/app/resources/views/ventas/show/forma_pago/escritura.blade.php
new file mode 100644
index 0000000..25be00c
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/escritura.blade.php
@@ -0,0 +1,36 @@
+
+
+ Escritura
+ @if ($escritura !== null)
+
+
+
+
+
+ @else
+
+
+
+ @endif
+ |
+ @if ($escritura !== null)
+ |
+ {{$format->ufs($escritura->pago->valor())}} |
+ {{$format->pesos($escritura->pago->valor)}} |
+
+ {{$escritura->pago->currentEstado->fecha->format('d-m-Y')}}
+ @if ($escritura->pago->currentEstado->tipoEstadoPago->descripcion === 'no pagado')
+
+
+
+ @elseif ($escritura->pago->currentEstado->tipoEstadoPago->descripcion === 'depositado')
+
+
+
+ @endif
+ |
+ |
+ @else
+ |
+ @endif
+
diff --git a/app/resources/views/ventas/show/forma_pago/pie.blade.php b/app/resources/views/ventas/show/forma_pago/pie.blade.php
new file mode 100644
index 0000000..bb5e032
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/pie.blade.php
@@ -0,0 +1,42 @@
+@if ($pie !== null)
+
+
+ Pie
+
+
+
+
+
+ |
+ |
+ {{$format->ufs($pie->valor)}} |
+ {{$format->pesos($pie->valor * $pie->uf)}} |
+ Cuotas |
+
+
+ {{count($pie->cuotas(true))}}/{{$pie->cuotas}}
+
+ @if (count($pie->cuotas(false, true)) < $pie->cuotas)
+
+
+
+ @endif
+ |
+
+
+ Pagado |
+ |
+ {{$format->ufs($pie->pagado())}} |
+ {{$format->pesos($pie->pagado('pesos'))}} |
+ |
+
+@if ($pie->reajuste)
+
+ Reajuste |
+ |
+ {{$format->ufs($pie->reajuste->valor())}} |
+ {{$format->pesos($pie->reajuste->valor)}} |
+ |
+
+@endif
+@endif
diff --git a/app/resources/views/ventas/show/forma_pago/subsidio.blade.php b/app/resources/views/ventas/show/forma_pago/subsidio.blade.php
new file mode 100644
index 0000000..c090946
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/subsidio.blade.php
@@ -0,0 +1,34 @@
+
+
+ Subsidio
+ @if ($subsidio !== null)
+
+
+
+
+
+ @else
+
+
+
+ @endif
+ |
+ @if ($subsidio !== null)
+ Ahorro |
+ {{$format->ufs($subsidio->ahorro->valor())}} |
+ {{$format->pesos($subsidio->ahorro->valor)}} |
+ |
+
+
+ Subsidio |
+ {{$format->ufs($subsidio->ahorro->valor())}} |
+ {{$format->pesos($subsidio->ahorro->valor)}} |
+ |
+ @else
+ |
+ @endif
+
diff --git a/app/resources/views/ventas/show/forma_pago/total.blade.php b/app/resources/views/ventas/show/forma_pago/total.blade.php
new file mode 100644
index 0000000..251e5fa
--- /dev/null
+++ b/app/resources/views/ventas/show/forma_pago/total.blade.php
@@ -0,0 +1,41 @@
+
+
+
+ Total
+
+ |
+ |
+
+
+ {{$format->ufs($formaPago->total())}}
+
+ |
+
+
+ {{$format->pesos($formaPago->total('pesos') - (($formaPago->bonoPie) ? $formaPago->bonoPie->pago->valor : 0))}}
+
+ @if ($formaPago->bonoPie)
+ *
+ @endif
+ |
+
+ @if (abs($venta->saldo() / $venta->valor) > 0.01)
+
+ Δ
+ {{$format->ufs($venta->saldo())}}
+ ({{$format->number($venta->saldo() / $venta->valor * 100, 2)}} %)
+
+ @endif
+ |
+ |
+
+@if ($formaPago->bonoPie)
+
+
+
+ *
+ Total en pesos no incluye Promociones como Bono Pie
+
+ |
+
+@endif
diff --git a/app/resources/views/ventas/show/propiedad.blade.php b/app/resources/views/ventas/show/propiedad.blade.php
new file mode 100644
index 0000000..5bba106
--- /dev/null
+++ b/app/resources/views/ventas/show/propiedad.blade.php
@@ -0,0 +1,63 @@
+
+
+
+
+
+ Unidad |
+ Piso |
+ Metros vendibles |
+ Precio |
+ Valor Venta |
+ UF/m² |
+ Orientacion |
+
+
+
+ @foreach($venta->propiedad()->unidades as $unidad)
+ @php
+ $precio = $unidad->precio($venta->fecha) ? $unidad->precio($venta->fecha)->valor : 0;
+ @endphp
+
+
+ {{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}}
+ @if ($unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento')
+ {{$unidad->proyectoTipoUnidad->abreviacion}}
+ @endif
+ |
+
+ {{$unidad->descripcion}}
+ |
+
+ {{$unidad->piso}}
+ |
+
+ {{$format->number($unidad->proyectoTipoUnidad->vendible(), 2)}} m²
+ |
+
+ {{$format->ufs($precio)}}
+ |
+
+ {{$format->ufs($unidad->valor)}}
+ |
+
+ @if ($unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento')
+ {{$format->number(($unidad->valor ?? $precio) / $unidad->proyectoTipoUnidad->vendible(), 2)}} UF/m²
+ @endif
+ |
+
+ {{$unidad->orientacion}}
+ |
+
+ @endforeach
+
+
+
diff --git a/app/resources/views/ventas/show/propietario.blade.php b/app/resources/views/ventas/show/propietario.blade.php
new file mode 100644
index 0000000..62f564f
--- /dev/null
+++ b/app/resources/views/ventas/show/propietario.blade.php
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ {{$venta->propietario()->rut()}}
+
+ {{$venta->propietario()->datos->direccion ?? ''}}
+
+
+
diff --git a/app/setup/app.php b/app/setup/app.php
new file mode 100644
index 0000000..a17667e
--- /dev/null
+++ b/app/setup/app.php
@@ -0,0 +1,45 @@
+isDir()) {
+ continue;
+ }
+ $builder->addDefinitions($file->getRealPath());
+ }
+ }
+ $app = Bridge::create($builder->build());
+ $folder = implode(DIRECTORY_SEPARATOR, [
+ __DIR__,
+ 'middlewares'
+ ]);
+ if (file_exists($folder)) {
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ require_once $file->getRealPath();
+ }
+ }
+ return $app;
+}
+return buildApp();
diff --git a/app/setup/composer.php b/app/setup/composer.php
new file mode 100644
index 0000000..b451f96
--- /dev/null
+++ b/app/setup/composer.php
@@ -0,0 +1,6 @@
+add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/setup/middlewares/97_not_found.php b/app/setup/middlewares/97_not_found.php
new file mode 100644
index 0000000..14d5c25
--- /dev/null
+++ b/app/setup/middlewares/97_not_found.php
@@ -0,0 +1,3 @@
+add($app->getContainer()->get(Incoviba\Middleware\NotFound::class));
+$app->add($app->getContainer()->get(Incoviba\Middleware\Errors::class));
diff --git a/app/setup/middlewares/98_logs.php b/app/setup/middlewares/98_logs.php
new file mode 100644
index 0000000..b81e521
--- /dev/null
+++ b/app/setup/middlewares/98_logs.php
@@ -0,0 +1,2 @@
+getContainer()->get(Psr\Log\LoggerInterface::class));
diff --git a/app/setup/middlewares/99_routes.php b/app/setup/middlewares/99_routes.php
new file mode 100644
index 0000000..a08c17c
--- /dev/null
+++ b/app/setup/middlewares/99_routes.php
@@ -0,0 +1,12 @@
+getContainer()->get('folders')->get('routes');
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+}
+loadRoutes($app);
diff --git a/app/setup/settings/env.php b/app/setup/settings/env.php
new file mode 100644
index 0000000..580b775
--- /dev/null
+++ b/app/setup/settings/env.php
@@ -0,0 +1,2 @@
+ function() {
+ return new DI\Container([
+ 'base' => dirname(__FILE__, 3),
+ 'resources' => DI\String('{base}/resources'),
+ 'routes' => DI\String('{resources}/routes'),
+ 'cache' => DI\String('{base}/cache'),
+ 'templates' => DI\String('{resources}/views'),
+ 'public' => DI\String('{base}/public'),
+ 'uploads' => DI\String('{public}/uploads'),
+ 'informes' => DI\String('{public}/informes')
+ ]);
+ }
+];
diff --git a/app/setup/settings/nubox.php b/app/setup/settings/nubox.php
new file mode 100644
index 0000000..382f46b
--- /dev/null
+++ b/app/setup/settings/nubox.php
@@ -0,0 +1,8 @@
+ function() {
+ return new DI\Container([
+ 'url' => 'https://api.nubox.com/Nubox.API'
+ ]);
+ }
+];
diff --git a/app/setup/settings/urls.php b/app/setup/settings/urls.php
new file mode 100644
index 0000000..d07f846
--- /dev/null
+++ b/app/setup/settings/urls.php
@@ -0,0 +1,21 @@
+ function() {
+ $urls = [
+ 'base' => $_ENV['APP_URL'] ?? '',
+ ];
+ $urls['api'] = implode('/', [
+ $urls['base'],
+ 'api'
+ ]);
+ $urls['assets'] = implode('/', [
+ $urls['base'],
+ 'assets'
+ ]);
+ $urls['images'] = implode('/', [
+ $urls['assets'],
+ 'images'
+ ]);
+ return (object) $urls;
+ }
+];
diff --git a/app/setup/setups/database.php b/app/setup/setups/database.php
new file mode 100644
index 0000000..cdea0d2
--- /dev/null
+++ b/app/setup/setups/database.php
@@ -0,0 +1,19 @@
+ function(ContainerInterface $container) {
+ return new Incoviba\Common\Implement\Database\MySQL(
+ $container->has('DB_HOST') ? $container->get('DB_HOST') : 'db',
+ $container->get('DB_DATABASE'),
+ $container->get('DB_USER'),
+ $container->get('DB_PASSWORD')
+ );
+ },
+ Incoviba\Common\Define\Connection::class => function(ContainerInterface $container) {
+ return new Incoviba\Common\Implement\Connection(
+ $container->get(Incoviba\Common\Define\Database::class),
+ $container->get(Incoviba\Common\Implement\Database\Query\Builder::class)
+ );
+ }
+];
diff --git a/app/setup/setups/logs.php b/app/setup/setups/logs.php
new file mode 100644
index 0000000..cb17296
--- /dev/null
+++ b/app/setup/setups/logs.php
@@ -0,0 +1,38 @@
+ function(ContainerInterface $container) {
+ return new Monolog\Logger('incoviba', [
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/debug.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Debug,
+ Monolog\Level::Debug
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/info.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Info,
+ Monolog\Level::Warning,
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/error.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Error,
+ Monolog\Level::Error
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/critical.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Critical
+ )
+ ], [
+ $container->get(Monolog\Processor\PsrLogMessageProcessor::class),
+ $container->get(Monolog\Processor\WebProcessor::class),
+ $container->get(Monolog\Processor\IntrospectionProcessor::class),
+ $container->get(Monolog\Processor\MemoryUsageProcessor::class),
+ $container->get(Monolog\Processor\MemoryPeakUsageProcessor::class)
+ ]);
+ }
+];
diff --git a/app/setup/setups/middlewares.php b/app/setup/setups/middlewares.php
new file mode 100644
index 0000000..567b36e
--- /dev/null
+++ b/app/setup/setups/middlewares.php
@@ -0,0 +1,20 @@
+ function(ContainerInterface $container) {
+ return new Incoviba\Middleware\Authentication(
+ $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+ $container->get(Incoviba\Service\Login::class),
+ $container->get(Psr\Log\LoggerInterface::class),
+ $container->get(Incoviba\Common\Alias\View::class),
+ implode('/', [$container->get('APP_URL'), 'login'])
+ );
+ },
+ Incoviba\Middleware\API::class => function(ContainerInterface $container) {
+ return new Incoviba\Middleware\API(
+ $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+ $container->get('API_KEY')
+ );
+ }
+];
diff --git a/app/setup/setups/psr7.php b/app/setup/setups/psr7.php
new file mode 100644
index 0000000..7e86808
--- /dev/null
+++ b/app/setup/setups/psr7.php
@@ -0,0 +1,14 @@
+ function(ContainerInterface $container) {
+ return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class);
+ },
+ Psr\Http\Message\RequestFactoryInterface::class => function(ContainerInterface $container) {
+ return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class);
+ },
+ Psr\Http\Message\ResponseFactoryInterface::class => function(ContainerInterface $container) {
+ return $container->get(Nyholm\Psr7\Factory\Psr17Factory::class);
+ },
+];
diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php
new file mode 100644
index 0000000..01dd83e
--- /dev/null
+++ b/app/setup/setups/services.php
@@ -0,0 +1,81 @@
+ function(ContainerInterface $container) {
+ return new Incoviba\Service\Login(
+ $container->get(Incoviba\Repository\Login::class),
+ $container->get('COOKIE_NAME'),
+ $container->get('MAX_LOGIN_HOURS'),
+ $container->has('COOKIE_DOMAIN') ? $container->get('COOKIE_DOMAIN') : '',
+ $container->has('COOKIE_PATH') ? $container->get('COOKIE_PATH') : ''
+ );
+ },
+ Incoviba\Service\Money::class => function(ContainerInterface $container) {
+ $mindicador = new Incoviba\Service\Money\MiIndicador(new GuzzleHttp\Client([
+ 'base_uri' => 'https://mindicador.cl/api/',
+ 'headers' => ['Accept' => 'application/json']
+ ]));
+ $ine = new Incoviba\Service\Money\Ine(new GuzzleHttp\Client([
+ 'base_uri' => 'https://api-calculadora.ine.cl/ServiciosCalculadoraVariacion'
+ ]));
+ return (new Incoviba\Service\Money($container->get(Psr\Log\LoggerInterface::class)))
+ ->register('uf', $mindicador)
+ ->register('usd', $mindicador)
+ ->register('ipc', $ine);
+ },
+ Predis\Client::class => function(ContainerInterface $container) {
+ return new Predis\Client([
+ 'scheme' => 'tcp',
+ 'host' => $container->get('REDIS_HOST'),
+ 'port' => $container->get('REDIS_PORT')
+ ]);
+ },
+ Incoviba\Service\Cartola::class => function(ContainerInterface $container) {
+ return (new Incoviba\Service\Cartola(
+ $container->get(Psr\Log\LoggerInterface::class),
+ $container->get(Psr\Http\Message\StreamFactoryInterface::class),
+ $container->get(Incoviba\Common\Define\Contabilidad\Exporter::class),
+ $container->get(Incoviba\Repository\Inmobiliaria::class),
+ $container->get(Incoviba\Repository\Inmobiliaria\Cuenta::class),
+ $container->get(Incoviba\Repository\Movimiento::class),
+ $container->get(Incoviba\Service\Movimiento::class),
+ $container->get(Incoviba\Repository\Cartola::class)
+ ))
+ ->register('security', $container->get(Incoviba\Service\Cartola\Security::class))
+ ->register('itau', $container->get(Incoviba\Service\Cartola\Itau::class))
+ ->register('santander', $container->get(Incoviba\Service\Cartola\Santander::class));
+ },
+ Incoviba\Common\Define\Contabilidad\Exporter::class => function(ContainerInterface $container) {
+ return $container->get(Incoviba\Service\Contabilidad\Exporter\Nubox::class);
+ },
+ Incoviba\Service\Contabilidad\Exporter\Nubox::class => function(ContainerInterface $container) {
+ return new Incoviba\Service\Contabilidad\Exporter\Nubox($container->get(Incoviba\Repository\CentroCosto::class),
+ $container->get('folders')->get('uploads'));
+ },
+ Incoviba\Service\Contabilidad\Nubox::class => function(ContainerInterface $container) {
+ return new Incoviba\Service\Contabilidad\Nubox(
+ $container->get(Psr\Log\LoggerInterface::class),
+ $container->get(Incoviba\Repository\Nubox::class),
+ $container->get(Incoviba\Service\Redis::class),
+ new GuzzleHttp\Client(),
+ $container->get(Psr\Http\Message\RequestFactoryInterface::class),
+ $container->get('nubox')->get('url'));
+ },
+ Incoviba\Service\Informe::class => function(ContainerInterface $container) {
+ return (new Incoviba\Service\Informe(
+ $container->get(Psr\Log\LoggerInterface::class),
+ $container->get('folders')->get('informes'))
+ )
+ ->register('xlsx', Incoviba\Service\Informe\Excel::class);
+ },
+ Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel::class => function(ContainerInterface $container) {
+ return new Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel(
+ $container->get(Psr\Log\LoggerInterface::class),
+ $container->get('folders')->get('informes'),
+ $container->get(Incoviba\Service\UF::class),
+ $container->get(Incoviba\Service\USD::class)
+ );
+ }
+];
diff --git a/app/setup/setups/views.php b/app/setup/setups/views.php
new file mode 100644
index 0000000..816bf80
--- /dev/null
+++ b/app/setup/setups/views.php
@@ -0,0 +1,28 @@
+ function(ContainerInterface $container) {
+ $folders = $container->get('folders');
+ $global_variables = [
+ 'urls' => $container->get('urls'),
+ 'money_url' => '',
+ 'login' => $container->get(Incoviba\Service\Login::class),
+ 'format' => $container->get(Incoviba\Service\Format::class),
+ 'API_KEY' => $container->get('API_KEY'),
+ 'UF' => $container->get(Incoviba\Service\UF::class),
+ 'USD' => $container->get(Incoviba\Service\USD::class),
+ 'IPC' => $container->get(Incoviba\Service\IPC::class),
+ 'hoy' => new DateTimeImmutable()
+ ];
+ if ($global_variables['login']->isIn()) {
+ $global_variables['user'] = $global_variables['login']->getUser();
+ }
+ return new Incoviba\Common\Alias\View(
+ $folders->get('templates'),
+ $folders->get('cache'),
+ null,
+ $global_variables
+ );
+ }
+];
diff --git a/app/src/Controller/API/CentrosCostos.php b/app/src/Controller/API/CentrosCostos.php
new file mode 100644
index 0000000..f1466b5
--- /dev/null
+++ b/app/src/Controller/API/CentrosCostos.php
@@ -0,0 +1,62 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'added' => false
+ ];
+ try {
+ $centroCosto = $centroCostoRepository->create($body);
+ $centroCosto->id = $body['id'];
+ $centroCostoRepository->save($centroCosto);
+ $output['added'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\CentroCosto $centroCostoRepository, int $centro_costo_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'centro_costo_id' => $centro_costo_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $centroCosto = $centroCostoRepository->fetchById($centro_costo_id);
+ if ($body['tipo_cuenta_id'] === '') {
+ $body['tipo_cuenta_id'] = null;
+ }
+ $centroCostoRepository->edit($centroCosto, $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function remove(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\CentroCosto $centroCostoRepository, int $centro_costo_id): ResponseInterface
+ {
+ $output = [
+ 'centro_costo_id' => $centro_costo_id,
+ 'removed' => false
+ ];
+ try {
+ $centroCosto = $centroCostoRepository->fetchById($centro_costo_id);
+ $centroCostoRepository->remove($centroCosto);
+ $output['removed'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Contabilidad.php b/app/src/Controller/API/Contabilidad.php
new file mode 100644
index 0000000..c99ce31
--- /dev/null
+++ b/app/src/Controller/API/Contabilidad.php
@@ -0,0 +1,17 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'movimientos' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
+ $banco = $bancoRepository->fetchById($body['banco']);
+ $mes = new DateTimeImmutable($body['mes']);
+ $file = $request->getUploadedFiles()['file'];
+ $output['movimientos'] = $cartolaService->process($inmobiliaria, $banco, $mes, $file);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function exportar(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Banco $bancoRepository,
+ Service\Cartola $cartolaService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'filename' => ''
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria']);
+ $banco = $bancoRepository->fetchById($body['banco']);
+ $mes = new DateTimeImmutable($body['mes']);
+ $output['filename'] = $cartolaService->export($inmobiliaria, $banco, $mes, json_decode($body['movimientos']));
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function diaria(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ Service\Cartola $cartolaService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'cartolas' => []
+ ];
+ $fields = json_decode($body['fields']);
+ foreach ($fields as $field) {
+ try {
+ $cuenta = $cuentaRepository->fetchById($body["cuenta_id{$field}"]);
+ $fecha = new DateTimeImmutable($body["fecha{$field}"]);
+ if (array_key_exists("manual{$field}", $body)) {
+ $file = json_decode($body["file{$field}"], JSON_OBJECT_AS_ARRAY);
+ $output['cartolas'][$field] = $cartolaService->diariaManual($cuenta, $fecha, $file);
+ continue;
+ }
+ $file = $request->getUploadedFiles()["file{$field}"];
+
+ $output['cartolas'][$field] = $cartolaService->diaria($cuenta, $fecha, $file);
+ } catch (EmptyResult $exception) {
+ $this->logger->debug($exception);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function ayer(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ Repository\Cartola $cartolaRepository): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'cartola' => []
+ ];
+ try {
+ $cuenta = $cuentaRepository->fetchById($body['cuenta_id']);
+ $fecha = new DateTimeImmutable($body['fecha']);
+ $output['cartola'] = $cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Contabilidad/Depositos.php b/app/src/Controller/API/Contabilidad/Depositos.php
new file mode 100644
index 0000000..26cb074
--- /dev/null
+++ b/app/src/Controller/API/Contabilidad/Depositos.php
@@ -0,0 +1,68 @@
+ $inmobiliaria_rut,
+ 'depositos' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut);
+ $cuentas = $cuentaRepository->fetchByInmobiliaria($inmobiliaria->rut);
+ foreach ($cuentas as $cuenta) {
+ $output['depositos'] = $dapRepository->fetchByCuenta($cuenta->id);
+ }
+ } catch (Implement\Exception\EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository, Repository\Banco $bancoRepository,
+ Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ Repository\Deposito $dapRepository): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'status' => false
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['inmobiliaria_rut']);
+ $banco = $bancoRepository->fetchById($body['banco_id']);
+ $cuenta = $cuentaRepository->fetchByInmobiliariaAndBanco($inmobiliaria->rut, $banco->id);
+ $data = [
+ 'id' => $body['id'],
+ 'cuenta_id' => $cuenta->id,
+ 'capital' => $body['capital'],
+ 'futuro' => $body['futuro'],
+ 'inicio' => (new DateTimeImmutable($body['inicio']))->format('Y-m-d'),
+ 'termino' => (new DateTimeImmutable($body['termino']))->format('Y-m-d')
+ ];
+ try {
+ $dapRepository->fetchById($body['id']);
+ } catch (Implement\Exception\EmptyResult) {
+ $dap = $dapRepository->create($data);
+ $dapRepository->save($dap);
+ }
+ $output['status'] = true;
+ } catch (Implement\Exception\EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Contabilidad/Movimientos.php b/app/src/Controller/API/Contabilidad/Movimientos.php
new file mode 100644
index 0000000..e792b86
--- /dev/null
+++ b/app/src/Controller/API/Contabilidad/Movimientos.php
@@ -0,0 +1,50 @@
+getParsedBody();
+ $output = [
+ 'movimiento_id' => $movimiento_id,
+ 'input' => $body,
+ 'status' => false,
+ 'movimiento' => null,
+ 'centro' => null,
+ 'detalle' => ''
+ ];
+ try {
+ $movimiento = $movimientoService->getById($movimiento_id);
+ $output['movimiento'] = $movimiento;
+ $data = [];
+ if (isset($body['centro_id'])) {
+ $centro = $centroCostoRepository->fetchById($body['centro_id']);
+ $data['centro_costo_id'] = $centro->id;
+ }
+ if (isset($body['detalle'])) {
+ $data['detalle'] = $body['detalle'];
+ }
+ $movimientoService->setDetalles($movimiento, $data);
+ if (isset($body['centro_id'])) {
+ $output['centro'] = $centro;
+ }
+ if (isset($body['detalle'])) {
+ $output['detalle'] = $body['detalle'];
+ }
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Direcciones.php b/app/src/Controller/API/Direcciones.php
new file mode 100644
index 0000000..f7527c9
--- /dev/null
+++ b/app/src/Controller/API/Direcciones.php
@@ -0,0 +1,65 @@
+ 0, 'comunas' => []];
+ $redisKey = 'comunas';
+ try {
+ $output['comunas'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['comunas']);
+ } catch (EmptyRedis) {
+ $provinciaKey = 'provincias';
+ try {
+ $temp_provincias = $this->fetchRedis($redisService, $provinciaKey);
+ } catch (EmptyRedis) {
+ $temp_provincias = $provinciaRepository->fetchByRegion($region_id);
+ $this->saveRedis($redisService, $provinciaKey, $temp_provincias, 60 * 60 * 24 * 30);
+ }
+ $comunas = [];
+ foreach($temp_provincias as $provincia) {
+ $temp_comunas = $comunaRepository->fetchByProvincia($provincia->id);
+ $comunas = array_merge($comunas, $temp_comunas);
+ }
+ usort($comunas, function(Model\Comuna $a, Model\Comuna $b) {
+ return strcoll($a->descripcion, $b->descripcion);
+ });
+ $output = ['comunas' => $comunas, 'total' => count($comunas)];
+ $this->saveRedis($redisService, $redisKey, $comunas, 60 * 60 * 24 * 30);
+ }
+ return $this->withJson($response, $output);
+ }
+ public function findComunas(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Repository\Comuna $comunaRepository): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $output = ['input' => $json, 'total' => 0, 'comunas' => []];
+ $redisKey = "comunas:direccion:{$json->direccion}";
+ try {
+ $output['comunas'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $comunas = $comunaRepository->fetchByDireccion($json->direccion);
+ $output['comunas'] = $comunas;
+ $output['total'] = count($comunas);
+ $this->saveRedis($redisService, $redisKey, $comunas);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Informes.php b/app/src/Controller/API/Informes.php
new file mode 100644
index 0000000..5e06ea1
--- /dev/null
+++ b/app/src/Controller/API/Informes.php
@@ -0,0 +1,25 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'data' => []
+ ];
+ try {
+ $file = $request->getUploadedFiles()['file'];
+ $output['data'] = $diarioService->process($file);
+ } catch (\Error) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Inmobiliarias.php b/app/src/Controller/API/Inmobiliarias.php
new file mode 100644
index 0000000..273e49d
--- /dev/null
+++ b/app/src/Controller/API/Inmobiliarias.php
@@ -0,0 +1,48 @@
+ $inmobiliaria_rut,
+ 'cuentas' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut);
+ $output['cuentas'] = $cuentaRepository->fetchByInmobiliaria($inmobiliaria->rut);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function proyectos(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Service\Proyecto $proyectoService, int $inmobiliaria_rut): ResponseInterface
+ {
+ $output = [
+ 'inmobiliaria_rut' => $inmobiliaria_rut,
+ 'proyectos' => []
+ ];
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut);
+ $output['proyectos'] = array_map(function(Model\Proyecto $proyecto) {
+ $p = json_decode(json_encode($proyecto));
+ $p->current_estado = $proyecto->currentEstado();
+ $p->estados = $proyecto->estados();
+ return $p;
+ },$proyectoService->getByInmobiliaria($inmobiliaria->rut));
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Money.php b/app/src/Controller/API/Money.php
new file mode 100644
index 0000000..61a8ae0
--- /dev/null
+++ b/app/src/Controller/API/Money.php
@@ -0,0 +1,100 @@
+getParsedBody();
+ $output = [
+ 'input' => $data
+ ];
+ $output[$data['provider']] = 0;
+ $redisKey = $data['provider'];
+ $date = new DateTimeImmutable($data['fecha']);
+ if (isset($data['start'])) {
+ $start = new DateTimeImmutable($data['start']);
+ }
+ $value = $this->getValue($redisService, $redisKey, $moneyService, $date, $data['provider']);
+ if (isset($start)) {
+ $months = $date->diff($start)->m;
+ $current = clone $start;
+ $value = $this->getValue($redisService, $redisKey, $moneyService, $current, $data['provider']);
+ for ($i = 1; $i <= $months; $i ++) {
+ $current = $current->add(new DateInterval("P{$i}M"));
+ $value += $this->getValue($redisService, $redisKey, $moneyService, $current, $data['provider']);
+ }
+ }
+ $output[$data['provider']] = $value;
+ return $this->withJson($response, $output);
+ }
+
+ protected array $data;
+ protected function getValue(Service\Redis $redisService, string $redisKey, Service\Money $moneyService,
+ DateTimeInterface $date, string $provider): float
+ {
+ if (isset($this->data[$provider][$date->format('Y-m-d')])) {
+ return $this->data[$provider][$date->format('Y-m-d')];
+ }
+ try {
+ $this->data[$provider] = (array) $this->fetchRedis($redisService, $redisKey);
+ if (!isset($this->data[$provider][$date->format('Y-m-d')])) {
+ throw new EmptyRedis($redisKey);
+ }
+ } catch (EmptyRedis) {
+ $result = $moneyService->get($provider, $date);
+ $this->data[$provider][$date->format('Y-m-d')] = $result;
+ $this->saveRedis($redisService, $redisKey, $this->data[$provider], $this->time);
+ }
+ return $this->data[$provider][$date->format('Y-m-d')];
+ }
+ public function uf(ServerRequestInterface $request, ResponseInterface $response, Service\UF $ufService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'uf' => 0
+ ];
+ $date = new DateTimeImmutable($body['fecha']);
+ $now = new DateTimeImmutable();
+ if ($date > $now) {
+ return $this->withJson($response, $output);
+ }
+ $output['uf'] = $ufService->get($date);
+ return $this->withJson($response, $output);
+ }
+ public function ipc(ServerRequestInterface $request, ResponseInterface $response,
+ Service\IPC $ipcService): ResponseInterface
+ {
+ $data = $request->getParsedBody();
+ $output = [
+ 'input' => $data,
+ 'date_string' => '',
+ 'ipc' => 0
+ ];
+ $start = new DateTimeImmutable($data['start']);
+ $end = new DateTimeImmutable($data['end']);
+ $now = new DateTimeImmutable();
+ if ($end > $now) {
+ return $this->withJson($response, $output);
+ }
+ $dateKey = "{$start->format('Y-m')}|{$end->format('Y-m')}";
+ $output['date_string'] = $dateKey;
+ $output['ipc'] = $ipcService->get($start, $end);
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Nubox.php b/app/src/Controller/API/Nubox.php
new file mode 100644
index 0000000..cc1d323
--- /dev/null
+++ b/app/src/Controller/API/Nubox.php
@@ -0,0 +1,90 @@
+ $inmobiliaria_rut,
+ 'token' => ''
+ ];
+ try {
+ $output['token'] = $nuboxService->getToken($inmobiliaria_rut);
+ } catch (HttpResponse $exception) {
+ $output['error'] = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage()
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+ public function sistemas(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface
+ {
+ $output = [
+ 'inmobiliaria_rut' => $inmobiliaria_rut,
+ 'sistemas' => []
+ ];
+ try {
+ $output['sistemas'] = $nuboxService->getSistemas($inmobiliaria_rut);
+ } catch (HttpResponse $exception) {
+ $output['error'] = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage()
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+ public function libroMayor(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'inmobiliaria_rut' => $inmobiliaria_rut,
+ 'input' => $body,
+ 'libro_mayor' => []
+ ];
+ try {
+ $from = new DateTimeImmutable($body['inicio']);
+ $to = new DateTimeImmutable($body['termino']);
+ $output['libro_mayor'] = $nuboxService->getLibroMayor($inmobiliaria_rut, $from, $to);
+ } catch (HttpResponse $exception) {
+ $output['error'] = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage()
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+ public function libroDiario(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'inmobiliaria_rut' => $inmobiliaria_rut,
+ 'input' => $body,
+ 'libro_diario' => []
+ ];
+ try {
+ $from = new DateTimeImmutable($body['inicio']);
+ $to = new DateTimeImmutable($body['termino']);
+ $output['libro_diario'] = $nuboxService->getLibroDiario($inmobiliaria_rut, $from, $to);
+ } catch (HttpResponse $exception) {
+ $output['error'] = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage()
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Provincias.php b/app/src/Controller/API/Provincias.php
new file mode 100644
index 0000000..99c55b5
--- /dev/null
+++ b/app/src/Controller/API/Provincias.php
@@ -0,0 +1,39 @@
+ $provincia_id,
+ 'comunas' => []
+ ];
+ $redisKey = "comunas:provincia:{$provincia_id}";
+ try {
+ $output['comunas'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $comunas = $comunaRepository->fetchByProvincia($provincia_id);
+ usort($comunas, function(Model\Comuna $a, Model\Comuna $b) {
+ return strcmp($a->descripcion, $b->descripcion);
+ });
+ $output['comunas'] = $comunas;
+ $this->saveRedis($redisService, $redisKey, $comunas, 60 * 60 * 24 * 30);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Proyectos.php b/app/src/Controller/API/Proyectos.php
new file mode 100644
index 0000000..dc5e46f
--- /dev/null
+++ b/app/src/Controller/API/Proyectos.php
@@ -0,0 +1,173 @@
+ 0, 'proyectos' => []];
+ $redisKey = 'proyectos:activos';
+ try {
+ $output['proyectos'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['proyectos']);
+ } catch (EmptyRedis) {
+ try {
+ $output['proyectos'] = $proyectoRepository->fetchAllActive();
+ $output['total'] = count($output['proyectos']);
+ $this->saveRedis($redisService, $redisKey, $output['proyectos']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function escriturando(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Redis $redisService, Repository\Proyecto $proyectoRepository): ResponseInterface
+ {
+ $output = ['total' => 0, 'proyectos' => []];
+ $redisKey = 'proyectos:escriturando';
+ try {
+ $output['proyectos'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['proyectos']);
+ } catch (EmptyRedis) {
+ try {
+ $output['proyectos'] = $proyectoRepository->fetchAllEscriturando();
+ $output['total'] = count($output['proyectos']);
+ $this->saveRedis($redisService, $redisKey, $output['proyectos']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function unidades(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta\Unidad $unidadRepository, Service\Redis $redisService,
+ int $proyecto_id): ResponseInterface
+ {
+ $output = ['proyecto_id' => $proyecto_id, 'unidades' => [], 'total' => 0];
+ $redisKey = "unidades:proyecto:{$proyecto_id}";
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $unidades = $unidadRepository->fetchByProyecto($proyecto_id);
+ $tipos = [];
+ foreach ($unidades as $unidad) {
+ if (!isset($tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion])) {
+ $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] = [];
+ }
+ $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] []= $unidad;
+ }
+ foreach ($tipos as &$subtipo) {
+ usort($subtipo, function(Model\Venta\Unidad $a, Model\Venta\Unidad $b) {
+ return strcmp(str_pad($a->descripcion, 4, '0', STR_PAD_LEFT), str_pad($b->descripcion, 4, '0', STR_PAD_LEFT));
+ });
+ }
+ $output['unidades'] = $tipos;
+ $output['total'] = count($unidades);
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function disponibles(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Redis $redisService, Repository\Venta\Unidad $unidadRepository,
+ int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'unidades' => []
+ ];
+ $redisKey = "unidades:disponibles:proyecto:{$proyecto_id}";
+ try {
+ $output['unidades'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['unidades'] = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['unidades']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function superficies(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta $ventaRepository, Repository\Venta\Unidad $unidadRepository,
+ Service\Redis $redisService, Service\Format $formatService,
+ int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'superficies' => [
+ 'vendible' => 0,
+ 'vendido' => 0,
+ 'por_vender' => 0
+ ],
+ 'formatted' => [
+ 'vendible' => '0m²',
+ 'vendido' => '0m²',
+ 'por_vender' => '0m²'
+ ]
+ ];
+ $redisKey = "superficices:proyecto:{$proyecto_id}";
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $ventas = $ventaRepository->fetchActivaByProyecto($proyecto_id);
+ $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
+
+ $output['superficies']['vendido'] = array_reduce($ventas, function($sum, Model\Venta $venta) {
+ return $sum + array_reduce($venta->propiedad()->unidades, function($sum, Model\Venta\Unidad $unidad) {
+ return $sum + $unidad->proyectoTipoUnidad->vendible();
+ });
+ }, 0);
+ $output['formatted']['vendido'] = "{$formatService->number($output['superficies']['vendido'], 2)}m²";
+ $output['superficies']['por_vender'] = array_reduce($unidades, function($sum, Model\Venta\Unidad $unidad) {
+ return $sum + $unidad->proyectoTipoUnidad->vendible();
+ });
+ $output['formatted']['por_vender'] = "{$formatService->number($output['superficies']['por_vender'], 2)}m²";
+ $output['superficies']['vendible'] = $output['superficies']['vendido'] + $output['superficies']['por_vender'];
+ $output['formatted']['vendible'] = "{$formatService->number($output['superficies']['vendible'], 2)}m²";
+ $this->saveRedis($redisService, $redisKey, $output, 60 * 60);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function terreno(ServerRequestInterface $request, ResponseInterface $response, Repository\Proyecto $proyectoRepository, int $proyecto_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'proyecto_id' => $proyecto_id,
+ 'edited' => false
+ ];
+ try {
+ $proyecto = $proyectoRepository->fetchById($proyecto_id);
+ $proyectoRepository->editTerreno($proyecto, $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function tiposUnidades(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Proyecto $proyectoRepository,
+ Repository\Proyecto\TipoUnidad $tipoUnidadRepository,
+ int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'tipos' => []
+ ];
+ try {
+ $proyecto = $proyectoRepository->fetchById($proyecto_id);
+ $output['tipos'] = $tipoUnidadRepository->fetchByProyecto($proyecto->id);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Proyectos/EstadosProyectos.php b/app/src/Controller/API/Proyectos/EstadosProyectos.php
new file mode 100644
index 0000000..8634565
--- /dev/null
+++ b/app/src/Controller/API/Proyectos/EstadosProyectos.php
@@ -0,0 +1,99 @@
+ $proyecto_id,
+ 'estados' => []
+ ];
+ $redisKey = "estados:proyecto:{$proyecto_id}";
+ try {
+ $output['estados'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['estados'] = $estadoProyectoRepository->fetchByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['estados']);
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function currentByProyecto(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Repository\Proyecto\EstadoProyecto $estadoProyectoRepository, int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'estado' => null
+ ];
+ $redisKey = "estado:proyecto:{$proyecto_id}";
+ try {
+ $output['estado'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['estado'] = $estadoProyectoRepository->fetchCurrentByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['estado']);
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function firstByProyecto(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Repository\Proyecto\EstadoProyecto $estadoProyectoRepository, int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'estado' => null
+ ];
+ $redisKey = "estado:proyecto:{$proyecto_id}:first";
+ try {
+ $output['estado'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['estado'] = $estadoProyectoRepository->fetchFirstByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['estado']);
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function recepcionByProyecto(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Redis $redisService,
+ Repository\Proyecto\EstadoProyecto $estadoProyectoRepository,
+ int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'estado' => null
+ ];
+ $redisKey = "recepcion:proyecto:{$proyecto_id}";
+ try {
+ $output['estado'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['estado'] = $estadoProyectoRepository->fetchRecepcionByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['estado']);
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Regiones.php b/app/src/Controller/API/Regiones.php
new file mode 100644
index 0000000..75ac94f
--- /dev/null
+++ b/app/src/Controller/API/Regiones.php
@@ -0,0 +1,39 @@
+ $region_id,
+ 'provincias' => []
+ ];
+ $redisKey = "provincias:region:{$region_id}";
+ try {
+ $output['provincias'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $provincias = $provinciaRepository->fetchByRegion($region_id);
+ usort($provincias, function(Model\Provincia $a, Model\Provincia $b) {
+ return strcmp($a->descripcion, $b->descripcion);
+ });
+ $output['provincias'] = $provincias;
+ $this->saveRedis($redisService, $redisKey, $output['provincias'], 60 * 60 * 24 * 30);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Search.php b/app/src/Controller/API/Search.php
new file mode 100644
index 0000000..ae76f3b
--- /dev/null
+++ b/app/src/Controller/API/Search.php
@@ -0,0 +1,173 @@
+getParsedBody();
+ $results = $service->query($data['query'], $data['tipo']);
+ $output = compact('results');
+ return $this->withJson($response, $output);
+ }
+ public function unidad(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta\Unidad $unidadService, int $unidad_id): ResponseInterface
+ {
+ $output = [
+ 'unidad_id' => $unidad_id,
+ 'unidad' => null
+ ];
+ $redisKey = "search:unidad:{$unidad_id}";
+ try {
+ $output['unidad'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (Exception\EmptyRedis) {
+ try {
+ $unidad = $unidadService->getByIdForSearch($unidad_id);
+ $output['unidad'] = [
+ 'id' => $unidad['id'],
+ 'descripcion' => $unidad['descripcion'],
+ 'proyecto_tipo_unidad' => [
+ 'proyecto' => [
+ 'id' => $unidad['proyecto_id'],
+ 'descripcion' => $unidad['proyecto_descripcion']
+ ],
+ 'tipo_unidad' => [
+ 'descripcion' => $unidad['tipo_unidad_descripcion']
+ ],
+ 'superficie' => $unidad['superficie']
+ ],
+ 'current_precio' => [
+ 'valor' => $unidad['precio']
+ ]
+ ];
+ $this->saveRedis($redisService, $redisKey, $output['unidad']);
+ } catch (Exception\EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function unidades(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta\Unidad $unidadService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'unidades' => []
+ ];
+ $unidades = explode(',', $body['unidades']);
+ foreach ($unidades as $unidad_id) {
+ $redisKey = "search:unidad:{$unidad_id}";
+ try {
+ $output['unidades'] []= $this->fetchRedis($redisService, $redisKey);
+ } catch (Exception\EmptyRedis) {
+ try {
+ $unidad = $unidadService->getByIdForSearch($unidad_id);
+ $unidad = [
+ 'id' => $unidad['id'],
+ 'descripcion' => $unidad['descripcion'],
+ 'proyecto_tipo_unidad' => [
+ 'proyecto' => [
+ 'id' => $unidad['proyecto_id'],
+ 'descripcion' => $unidad['proyecto_descripcion']
+ ],
+ 'tipo_unidad' => [
+ 'descripcion' => $unidad['tipo_unidad_descripcion']
+ ],
+ 'superficie' => $unidad['superficie']
+ ],
+ 'current_precio' => [
+ 'valor' => $unidad['precio']
+ ]
+ ];
+ $output['unidades'] []= $unidad;
+ $this->saveRedis($redisService, $redisKey, $unidad);
+ } catch (Exception\EmptyResult) {}
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function venta(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $output = [
+ 'venta_id' => $venta_id,
+ 'venta' => null
+ ];
+ $redisKey = "search:venta:{$venta_id}";
+ try {
+ $output['venta'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (Exception\EmptyRedis) {
+ try {
+ $venta = $ventaService->getById($venta_id);
+ /*$output['venta'] = [
+ 'id' => $venta->id,
+ ''
+ ];*/
+ $output['venta'] = $venta;
+ $this->saveRedis($redisService, $redisKey, $output['venta']);
+ } catch (Exception\EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function ventas(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $ventaService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'ventas' => []
+ ];
+ $ventas = explode(',', $body['ventas']);
+ foreach ($ventas as $venta_id) {
+ $redisKey = "search:venta:{$venta_id}";
+ try {
+ $output['ventas'] []= $this->fetchRedis($redisService, $redisKey);
+ } catch (Exception\EmptyRedis) {
+ try {
+ $venta = $ventaService->getByIdForSearch($venta_id);
+ $venta = [
+ 'id' => $venta['id'],
+ 'proyecto' => [
+ 'id' => $venta['proyecto_id'],
+ 'descripcion' => $venta['proyecto_descripcion']
+ ],
+ 'propietario' => [
+ 'nombre_completo' => $venta['propietario']
+ ],
+ 'propiedad' => [
+ 'unidades' => [
+ [
+ 'descripcion' => $venta['unidad_descripcion'],
+ 'proyecto_tipo_unidad' => [
+ 'tipo_unidad' => [
+ 'descripcion' => $venta['tipo_unidad_descripcion']
+ ],
+ 'superficie' => $venta['superficie']
+ ]
+ ]
+ ]
+ ],
+ 'fecha' => $venta['fecha'],
+ 'current_estado' => [
+ 'tipo_estado_venta' => [
+ 'activa' => $venta['activa']
+ ]
+ ],
+ 'valor' => $venta['valor']
+ ];
+ $output['ventas'] []= $venta;
+ $this->saveRedis($redisService, $redisKey, json_encode($venta));
+ } catch (Exception\EmptyResult) {}
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas.php b/app/src/Controller/API/Ventas.php
new file mode 100644
index 0000000..94fc0c9
--- /dev/null
+++ b/app/src/Controller/API/Ventas.php
@@ -0,0 +1,305 @@
+getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $output = [
+ 'proyecto' => [
+ 'id' => $proyecto_id
+ ],
+ 'total' => 0
+ ];
+ $proyectosKey = "proyectos";
+ try {
+ $proyectos = $this->fetchRedis($redisService, $proyectosKey);
+ } catch (EmptyRedis) {
+ $proyectos = $proyectoRepository->fetchAllActive();
+ $this->saveRedis($redisService, $proyectosKey, $proyectos);
+ }
+ $proyecto = array_values(array_filter($proyectos, function($proyecto) use ($proyecto_id) {return $proyecto->id === $proyecto_id;}))[0];
+ $output['proyecto']['descripcion'] = $proyecto->descripcion;
+
+ $redisKey = "ventas:proyecto:{$proyecto_id}";
+ try {
+ $output['ventas'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['ventas']);
+ } catch (EmptyRedis) {
+ try {
+ $ventas = $ventaRepository->fetchActivaByProyecto($proyecto_id);
+ $output['ventas'] = array_map(function(Model\Venta $venta) {return $venta->id;}, $ventas);
+ $output['total'] = count($ventas);
+ $this->saveRedis($redisService, $redisKey, $output['ventas']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function get(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $service, int $venta_id): ResponseInterface
+ {
+ $redisKey = "venta:{$venta_id}";
+ $output = [
+ 'venta' => null
+ ];
+ try {
+ $venta = $this->fetchRedis($redisService, $redisKey);
+ $output = compact('venta');
+ } catch (EmptyRedis) {
+ try {
+ $venta = $service->getById($venta_id);
+ $output = compact('venta');
+ $this->saveRedis($redisService, $redisKey, $venta);
+ } catch (EmptyResult $exception) {
+ $this->logger->notice($exception);
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function getMany(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $service): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'ventas' => []
+ ];
+ $ventas = explode(',', $body['ventas']);
+ foreach ($ventas as $venta_id) {
+ $redisKey = "venta:{$venta_id}";
+ try {
+ $venta = $this->fetchRedis($redisService, $redisKey);
+ $output['ventas'] []= $venta;
+ } catch (EmptyRedis) {
+ try {
+ $venta = $service->getById($venta_id);
+ $output['ventas'] []= $venta;
+ $this->saveRedis($redisService, $redisKey, $venta);
+ } catch (EmptyResult $exception) {
+ $this->logger->notice($exception);
+ }
+ }
+ }
+ return $this->withJson($response, $output);
+ }
+ public function porFirmar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, Service\Redis $redisService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $today = new DateTimeImmutable();
+ $redisKey = "promesas:por_firmar:proyecto:{$proyecto_id}:{$today->format('Y-m-d')}";
+
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'promesas' => 0
+ ];
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $ventas = $ventaService->getByProyecto($proyecto_id);
+ $promesas = array_filter($ventas, function(Model\Venta $venta) {
+ return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'vigente';
+ });
+ $output['promesas'] = count($promesas);
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function escrituras(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, Service\Venta\Pago $pagoService, Service\Redis $redisService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $today = new DateTimeImmutable();
+ $redisKey = "escrituras:proyecto:{$proyecto_id}:{$today->format('Y-m-d')}";
+
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'escrituras' => [
+ 'firmar' => 0,
+ 'pagar' => 0,
+ 'abonar' => 0
+ ]
+ ];
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $ventas = $ventaService->getEscriturasByProyecto($proyecto_id);
+ $porFirmar = array_filter($ventas, function(Model\Venta $venta) {
+ return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'escriturando';
+ });
+ $output['escrituras']['firmar'] = count($porFirmar);
+ unset($porFirmar);
+ $escrituras = array_filter($ventas, function(Model\Venta $venta) {
+ return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'firmado por inmobiliaria';
+ });
+ unset($ventas);
+ $porPagar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) {
+ $pagos = $pagoService->getByVenta($venta->id);
+ $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) {
+ return $pago->currentEstado->tipoEstadoPago->descripcion === 'no pagado';
+ });
+ return count($porPagar) > 0;
+ });
+ $output['escrituras']['pagar'] = count($porPagar);
+ unset($porPagar);
+ $porAbonar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) {
+ $pagos = $pagoService->getByVenta($venta->id);
+ $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) {
+ return $pago->currentEstado->tipoEstadoPago->descripcion === 'depositado';
+ });
+ return count($porPagar) > 0;
+ });
+ $output['escrituras']['abonar'] = count($porAbonar);
+ unset($porAbonar);
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function comentarios(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $service, Repository\Venta\Comentario $comentarioRepository, int $venta_id): ResponseInterface
+ {
+ $venta = $service->getById($venta_id);
+ $output = ['total' => 0, 'comentarios' => []];
+ $redisKey = "comentarios:venta:{$venta_id}";
+ try {
+ $output['comentarios'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['comentarios']);
+ } catch (EmptyRedis) {
+ try {
+ $comentarios = $comentarioRepository->fetchByVenta($venta->id);
+ $output['total'] = count($comentarios);
+ $output['comentarios'] = $comentarios;
+ $this->saveRedis($redisService, $redisKey, $output['comentarios']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta $ventaService): ResponseInterface
+ {
+ $data = $request->getParsedBody();
+ $output = [
+ 'status' => false,
+ 'venta_id' => null,
+ 'errors' => []
+ ];
+ try {
+ $venta = $ventaService->add($data);
+ $this->saveRedis($redisService, "venta:{$venta->id}", $venta);
+ $output['venta_id'] = $venta->id;
+ $output['status'] = true;
+ } catch (EmptyResult | PDOException $exception) {
+ $output['errors'] = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage(),
+ 'stack' => $exception->getTraceAsString()
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta $ventaRepository, int $venta_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'venta_id' => $venta_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $venta = $ventaRepository->fetchById($venta_id);
+ $body['valor_uf'] = $body['valor'];
+ $body['fecha'] = (new DateTimeImmutable($body['fecha']))->format('Y-m-d');
+ $ventaRepository->edit($venta, $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function unidades(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta\Unidad $unidadService, int $venta_id): ResponseInterface
+ {
+ $output = [
+ 'venta_id' => $venta_id,
+ 'unidades' => []
+ ];
+ $redisKey = "unidades:venta:{$venta_id}";
+ try {
+ $output['unidades'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $unidades = $unidadService->getByVenta($venta_id);
+ $output['unidades'] = json_decode(json_encode($unidades));
+ array_walk($output['unidades'], function($unidad, $index, $unidades) {
+ $unidad->prorrateo = $unidades[$index]->prorrateo;
+ $unidad->precios = $unidades[$index]->precios;
+ $unidad->current_precio = $unidades[$index]->currentPrecio;
+ }, $unidades);
+ $this->saveRedis($redisService, $redisKey, $output['unidades']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function escriturar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $data = $request->getParsedBody();
+ $output = [
+ 'input' => $data,
+ 'venta_id' => $venta_id,
+ 'status' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ $output['status'] = $ventaService->escriturar($venta, $data);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function desistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $data = $request->getParsedBody();
+ $output = [
+ 'input' => $data,
+ 'venta_id' => $venta_id,
+ 'desistida' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ $output['desistida'] = $ventaService->desistir($venta, $data);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function insistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $output = [
+ 'venta_id' => $venta_id,
+ 'eliminado' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ $output['eliminado'] = $ventaService->insistir($venta);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Cierres.php b/app/src/Controller/API/Ventas/Cierres.php
new file mode 100644
index 0000000..7acf4d9
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Cierres.php
@@ -0,0 +1,74 @@
+getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $output = ['total' => 0, 'cierres' => []];
+ $redisKey = "cierres:proyecto:{$proyecto_id}";
+ try {
+ $output['cierres'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['cierres']);
+ } catch (EmptyRedis) {
+ try {
+ $cierres = $service->getByProyecto($proyecto_id);
+ $output['cierres'] = $cierres;
+ $this->saveRedis($redisService, $redisKey, $output['cierres']);
+ $output['total'] = count($cierres);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function vigentes(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Repository\Venta\Cierre $cierreRepository): ResponseInterface
+ {
+ $output = ['cierres' => []];
+ $redisKey = "cierres:vigentes";
+ try {
+ $output['cierres'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $cierres = $cierreRepository->fetchDatosVigentes();
+ $estados = [
+ 'revisado' => 'pendientes',
+ 'rechazado' => 'rechazados',
+ 'aprobado' => 'pendientes',
+ 'vendido' => 'promesados',
+ 'abandonado' => 'rechazados',
+ 'promesado' => 'promesados',
+ 'resciliado' => 'rechazados'
+ ];
+ foreach ($cierres as $row) {
+ if (!isset($output['cierres'][$row['Proyecto']])) {
+ $output['cierres'][$row['Proyecto']] = [
+ 'promesados' => 0,
+ 'pendientes' => 0,
+ 'rechazados' => 0,
+ 'total' => 0
+ ];
+ }
+ $estado = $estados[$row['Estado']];
+ $output['cierres'][$row['Proyecto']][$estado] += $row['Cantidad'];
+ $output['cierres'][$row['Proyecto']]['total'] += $row['Cantidad'];
+ }
+ $this->saveRedis($redisService, $redisKey, $output['cierres']);
+ } catch (EmptyRedis) {}
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Creditos.php b/app/src/Controller/API/Ventas/Creditos.php
new file mode 100644
index 0000000..6ba25c3
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Creditos.php
@@ -0,0 +1,31 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'credito' => null,
+ 'status' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ $output['credito'] = $creditoService->edit($venta->formaPago()->credito, $body);
+ $output['status'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Cuotas.php b/app/src/Controller/API/Ventas/Cuotas.php
new file mode 100644
index 0000000..102c324
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Cuotas.php
@@ -0,0 +1,94 @@
+format('Y-m-d')}";
+ $output = [
+ 'cuotas' => 0
+ ];
+ try {
+ $output['cuotas'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['cuotas'] = count($cuotaRepository->fetchHoy());
+ $this->saveRedis($redisService, $redisKey, $output['cuotas']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function pendiente(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta\Cuota $cuotaRepository, Service\Redis $redisService): ResponseInterface
+ {
+ $today = new DateTimeImmutable();
+ $redisKey = "cuotas:pendientes:{$today->format('Y-m-d')}";
+ $output = [
+ 'cuotas' => 0
+ ];
+ try {
+ $output['cuotas'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['cuotas'] = count($cuotaRepository->fetchPendientes());
+ $this->saveRedis($redisService, $redisKey, $output['cuotas']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function porVencer(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta\Cuota $cuotaRepository, Service\Redis $redisService,
+ Service\Format $formatService): ResponseInterface
+ {
+ $today = new DateTimeImmutable();
+ $redisKey = "cuotas:por_vencer:{$today->format('Y-m-d')}";
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ $output = [];
+ try {
+ $cuotas = $cuotaRepository->fetchDatosPorVencer();
+ foreach ($cuotas as $row) {
+ $fecha = $row['Fecha'];
+ $date = new DateTimeImmutable($fecha);
+ if (($weekday = $date->format('N')) > 5) {
+ $day_diff = 7 - $weekday + 1;
+ $date = $date->add(new DateInterval("P{$day_diff}D"));
+ $fecha = $date->format('Y-m-d');
+ }
+ $key = $formatService->localDate($fecha, "EEE. dd 'de' MMMM 'de' yyyy", true);
+ if (!isset($output[$key])) {
+ $output[$key] = [];
+ }
+ if (!isset($output[$key][$row['Proyecto']])) {
+ $output[$key][$row['Proyecto']] = 0;
+ }
+ $output[$key][$row['Proyecto']] += $row['Cantidad'];
+ }
+ foreach ($output as $key => $day) {
+ uksort($day, function($a, $b) {
+ return strcmp($a, $b);
+ });
+ $output[$key] = $day;
+ }
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, ['cuotas' => $output]);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Escrituras.php b/app/src/Controller/API/Ventas/Escrituras.php
new file mode 100644
index 0000000..ad7f1cc
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Escrituras.php
@@ -0,0 +1,82 @@
+getParsedBody();
+ $output = [
+ 'venta_id' => $venta_id,
+ 'input' => $body,
+ 'status' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ if (isset($venta->formaPago()->escritura)) {
+ throw new EmptyResult('');
+ }
+ $fecha = new DateTimeImmutable($body['fecha']);
+ $uf = $ufService->get($fecha);
+ $valor = $body['valor'];
+ if (str_contains($valor, ',')) {
+ $valor = str_replace(['.', ','], ['', '.'], $valor);
+ }
+ $valor = ((float) $valor) * (($body['uf']) ? $uf : 1);
+ $data = [
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'valor' => $valor,
+ 'banco' => $body['banco'],
+ 'tipo' => $body['tipo'],
+ 'uf' => $uf
+ ];
+ $pago = $pagoService->add($data);
+ $data = [
+ 'valor' => $valor,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'uf' => $uf,
+ 'pago' => $pago->id
+ ];
+ $escritura = $escrituraRepository->create($data);
+ $escrituraRepository->save($escritura);
+ $ventaRepository->edit($venta, ['escritura' => $escritura->id]);
+ $output['status'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Venta $ventaService, Repository\Venta\EstadoVenta $estadoVentaRepository,
+ int $venta_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'venta_id' => $venta_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $venta = $ventaService->getById($venta_id);
+ $estado = $venta->currentEstado();
+ if (!in_array($estado->tipoEstadoVenta->descripcion, ['escriturando', 'firmado por inmobiliaria'])) {
+ throw new EmptyResult('');
+ }
+ $body['fecha'] = (new DateTimeImmutable($body['fecha']))->format('Y-m-d');
+ $estadoVentaRepository->edit($estado, $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Facturacion.php b/app/src/Controller/API/Ventas/Facturacion.php
new file mode 100644
index 0000000..14477da
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Facturacion.php
@@ -0,0 +1,37 @@
+ $proyecto_id,
+ 'ventas' => []
+ ];
+ $today = new DateTimeImmutable();
+ $redisKey = "ventas:facturacion:proyecto:{$proyecto_id}:{$today->format('Y-m-d')}";
+ try {
+ $output['ventas'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['ventas'] = $ventaService->getActivaByProyecto($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $output['ventas']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Pagos.php b/app/src/Controller/API/Ventas/Pagos.php
new file mode 100644
index 0000000..ba1e2d5
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Pagos.php
@@ -0,0 +1,129 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'pago_id' => $pago_id,
+ 'pago' => null
+ ];
+ try {
+ $pago = $pagoRepository->fetchById($pago_id);
+ if (isset($body['fecha'])) {
+ $fecha = new DateTimeImmutable($body['fecha']);
+ $body['fecha'] = $fecha->format('Y-m-d');
+ }
+ $output['pago'] = $pagoRepository->edit($pago, $body);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function depositar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService, int $pago_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'pago_id' => $pago_id,
+ 'input' => $body,
+ 'depositado' => false
+ ];
+ try {
+ $pago = $pagoService->getById($pago_id);
+ $fecha = new DateTimeImmutable($body->fecha);
+ $output['depositado'] = $pagoService->depositar($pago, $fecha);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function abonar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService, int $pago_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'pago_id' => $pago_id,
+ 'input' => $body,
+ 'abonado' => false
+ ];
+ try {
+ $pago = $pagoService->getById($pago_id);
+ $fecha = new DateTimeImmutable($body->fecha);
+ $output['abonado'] = $pagoService->abonar($pago, $fecha);
+ $output['input']['fecha'] = $fecha->format('d-m-Y');
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function devolver(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService, int $pago_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'pago_id' => $pago_id,
+ 'input' => $body,
+ 'devuelto' => false
+ ];
+ try {
+ $pago = $pagoService->getById($pago_id);
+ $fecha = new DateTimeImmutable($body->fecha);
+ $output['devuelto'] = $pagoService->devolver($pago, $fecha);
+ $output['input']['fecha'] = $fecha->format('d-m-Y');
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function para_pendientes(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $pagos = $pagoService->getPendientes();
+ $pagos_pendientes = [];
+ foreach ($pagos as $pago) {
+ $pagos_pendientes []= [
+ 'id' => $pago->id
+ ];
+ }
+ return $this->withJson($response, ['pagos' => $pagos_pendientes, 'total' => count($pagos_pendientes)]);
+ }
+ public function para_abonar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $pagos = $pagoService->getDepositados();
+ $pagos_depositados = [];
+ foreach ($pagos as $pago) {
+ $pagos_depositados []= [
+ 'id' => $pago->id
+ ];
+ }
+ return $this->withJson($response, ['pagos' => $pagos_depositados, 'total' => count($pagos_depositados)]);
+ }
+ public function rebotes(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $pagos = $pagoService->getRebotes();
+ $rebotes = [];
+ foreach ($pagos as $pago) {
+ $rebotes []= [
+ 'id' => $pago->id
+ ];
+ }
+ return $this->withJson($response, ['pagos' => $rebotes, 'total' => count($rebotes)]);
+ }
+
+ public function anular(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pago $pagoService, int $pago_id): ResponseInterface
+ {
+ $fecha = new DateTimeImmutable();
+ $output = [
+ 'pago_id' => $pago_id,
+ 'fecha' => $fecha->format('d-m-Y'),
+ 'anulado' => false
+ ];
+ try {
+ $pago = $pagoService->getById($pago_id);
+ $output['anulado'] = $pagoService->anular($pago, $fecha);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Pies.php b/app/src/Controller/API/Ventas/Pies.php
new file mode 100644
index 0000000..9c90638
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Pies.php
@@ -0,0 +1,30 @@
+getParsedBody();
+ $output = [
+ 'pie_id' => $pie_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $pie = $pieService->getById($pie_id);
+ $pieService->edit($pie, (array) $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Precios.php b/app/src/Controller/API/Ventas/Precios.php
new file mode 100644
index 0000000..8f8dbe9
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Precios.php
@@ -0,0 +1,54 @@
+getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $output = ['total' => 0, 'precios' => []];
+ $redisKey = "precios:proyecto:{$proyecto_id}";
+ try {
+ $output['precios'] = $this->fetchRedis($redisService, $redisKey);
+ $output['total'] = count($output['precios']);
+ } catch (EmptyRedis) {
+ try {
+ $precios = $precioService->getByProyecto($proyecto_id);
+ $output['precios'] = $precios;
+ $output['total'] = count($precios);
+ $this->saveRedis($redisService, $redisKey, $output['precios']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function unidad(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
+ Service\Venta\Precio $precioService, int $unidad_id): ResponseInterface
+ {
+ $redisKey = "precio:unidad:{$unidad_id}";
+ try {
+ $precio = $this->fetchRedis($redisService, $redisKey);
+ return $this->withJson($response, compact('precio'));
+ } catch (EmptyRedis) {
+ try {
+ $precio = $precioService->getVigenteByUnidad($unidad_id);
+ $this->saveRedis($redisService, $redisKey, $precio);
+ return $this->withJson($response, compact('precio'));
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+ }
+}
diff --git a/app/src/Controller/API/Ventas/PropiedadesUnidades.php b/app/src/Controller/API/Ventas/PropiedadesUnidades.php
new file mode 100644
index 0000000..74ba123
--- /dev/null
+++ b/app/src/Controller/API/Ventas/PropiedadesUnidades.php
@@ -0,0 +1,64 @@
+getParsedBody();
+ $output = [
+ 'input' => $body,
+ 'propiedad_unidad' => null,
+ 'added' => false
+ ];
+ try {
+ $pu = $propiedadUnidadService->add($body);
+ $output['propiedad_unidad'] = $pu;
+ $output['added'] = true;
+ } catch (EmptyResult $exception) {
+ error_log($exception);
+ }
+ return $this->withJson($response, $output);
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response,
+ Service\Venta\PropiedadUnidad $propiedadUnidadService, int $pu_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'propiedad_unidad_id' => $pu_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $pu = $propiedadUnidadService->getById($pu_id);
+ $propiedadUnidadService->edit($pu, (array) $body);
+ $output['edited'] = true;
+ } catch (PDOException | EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function remove(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta\PropiedadUnidad $propiedadUnidadRepository, int $pu_id): ResponseInterface
+ {
+ $output = [
+ 'propiedad_unidad_id' => $pu_id,
+ 'removed' => false
+ ];
+ try {
+ $pu = $propiedadUnidadRepository->fetchById($pu_id);
+ $propiedadUnidadRepository->remove($pu);
+ $output['removed'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Unidades.php b/app/src/Controller/API/Ventas/Unidades.php
new file mode 100644
index 0000000..aa0ced4
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Unidades.php
@@ -0,0 +1,101 @@
+ $unidad_id,
+ 'unidad' => null
+ ];
+ $redisKey = "unidad:{$unidad_id}";
+ try {
+ $output['unidad'] = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $output['unidad'] = $unidadService->getById($unidad_id);
+ $this->saveRedis($redisService, $redisKey, $output['unidad']);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function disponibles(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Unidad $unidadRepository, Repository\Proyecto\TipoUnidad $tipoUnidadRepository, Service\Redis $redisService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $today = new DateTimeImmutable();
+ $redisKey = "unidades:disponibles:proyecto:{$proyecto_id}:{$today->format('Y-m-d')}";
+
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'unidades' => [
+ 'total' => [
+ 'departamentos' => 0,
+ 'estacionamientos' => 0,
+ 'bodegas' => 0,
+ ],
+ 'departamentos' => 0,
+ 'estacionamientos' => 0,
+ 'bodegas' => 0,
+ ]
+ ];
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $totalUnidades = $unidadRepository->fetchByProyecto($proyecto_id);
+ $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
+
+ $tiposUnidades = $tipoUnidadRepository->fetchAll();
+ foreach ($tiposUnidades as $tipoUnidad) {
+ $tempUnidades = array_filter($totalUnidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) {
+ return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id;
+ });
+ if (count($tempUnidades) > 0) {
+ $output['unidades']['total']["{$tipoUnidad->descripcion}s"] = count($tempUnidades);
+ }
+ $tempUnidades = array_filter($unidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) {
+ return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id;
+ });
+ if (count($tempUnidades) === 0) {
+ continue;
+ }
+ $output['unidades']["{$tipoUnidad->descripcion}s"] = count($tempUnidades);
+ }
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function prorrateo(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Unidad $unidadRepository, int $unidad_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $output = [
+ 'unidad_id' => $unidad_id,
+ 'input' => $body,
+ 'edited' => false
+ ];
+ try {
+ $unidad = $unidadRepository->fetchById($unidad_id);
+ $unidadRepository->editProrrateo($unidad, $body);
+ $output['edited'] = true;
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/emptyBody.php b/app/src/Controller/API/emptyBody.php
new file mode 100644
index 0000000..6392565
--- /dev/null
+++ b/app/src/Controller/API/emptyBody.php
@@ -0,0 +1,12 @@
+withStatus(204);
+ }
+}
diff --git a/app/src/Controller/API/withJson.php b/app/src/Controller/API/withJson.php
new file mode 100644
index 0000000..1a6e2f4
--- /dev/null
+++ b/app/src/Controller/API/withJson.php
@@ -0,0 +1,13 @@
+getBody()->write(json_encode($data));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
diff --git a/app/src/Controller/Base.php b/app/src/Controller/Base.php
new file mode 100644
index 0000000..15da3ec
--- /dev/null
+++ b/app/src/Controller/Base.php
@@ -0,0 +1,33 @@
+isIn()) {
+ return $this->home($response, $view);
+ }
+ return $this->login($response, $view);
+ }
+ public function construccion(ServerRequestInterface $request, ResponseInterface $response, View $view): ResponseInterface
+ {
+ return $view->render($response, 'construccion');
+ }
+ protected function home(ResponseInterface $response, View $view): ResponseInterface
+ {
+ return $view->render($response, 'home');
+ }
+ protected function login(ResponseInterface $response, View $view): ResponseInterface
+ {
+ return $view->render($response, 'guest');
+ }
+}
diff --git a/app/src/Controller/CentrosCostos.php b/app/src/Controller/CentrosCostos.php
new file mode 100644
index 0000000..6854b8b
--- /dev/null
+++ b/app/src/Controller/CentrosCostos.php
@@ -0,0 +1,32 @@
+fetchAll();
+ $tiposCentros = $tipoCentroRepository->fetchAll();
+ $categorias = $categoriaCentroRepository->fetchAll('descripcion');
+ $tiposCuentas = $tipoCuentaRepository->fetchAll();
+ return $view->render($response, 'contabilidad.centros_costos', compact('centrosCostos',
+ 'tiposCentros', 'categorias', 'tiposCuentas'));
+ }
+ public function asignar(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Repository\CentroCosto $centroCostoRepository,
+ Repository\Inmobiliaria $inmobiliariaRepository): ResponseInterface
+ {
+ $centrosCostos = $centroCostoRepository->fetchAll();
+ $inmobiliarias = $inmobiliariaRepository->fetchAllActive('razon');
+ return $view->render($response, 'contabilidad.centros_costos.asignar', compact('centrosCostos', 'inmobiliarias'));
+ }
+}
diff --git a/app/src/Controller/Contabilidad.php b/app/src/Controller/Contabilidad.php
new file mode 100644
index 0000000..4f9b618
--- /dev/null
+++ b/app/src/Controller/Contabilidad.php
@@ -0,0 +1,76 @@
+fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $inmobiliarias = $inmobiliariaRepository->fetchAll();
+ $this->saveRedis($redisService, $redisKey, $inmobiliarias, 30 * 24 * 60 * 60);
+ } catch (EmptyResult) {}
+ }
+ $centrosCostos = $centroCostoRepository->fetchAll();
+ return $view->render($response, 'contabilidad.cartolas.diaria', compact('inmobiliarias', 'centrosCostos'));
+ }
+ public function depositos(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Redis $redisService,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Deposito $dapRepository): ResponseInterface
+ {
+ $redisKey = 'inmobiliarias';
+ $inmobiliarias = [];
+ try {
+ $inmobiliarias = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $inmobiliarias = $inmobiliariaRepository->fetchAll();
+ $this->saveRedis($redisService, $redisKey, $inmobiliarias, 30 * 24 * 60 * 60);
+ } catch (EmptyResult) {}
+ }
+ $depositos = [];
+ try {
+ $depositos = $dapRepository->fetchAll();
+ } catch (EmptyResult) {}
+ $fecha = new DateTimeImmutable('today');
+ $activos = array_filter($depositos, function(Model\Deposito $deposito) use ($fecha) {
+ return $deposito->termino >= $fecha;
+ });
+ $mes = $fecha->sub(new DateInterval('P1M'));
+ $vencidos = array_filter($depositos, function(Model\Deposito $deposito) use ($fecha, $mes) {
+ return $deposito->termino < $fecha and $deposito->termino >= $mes;
+ });
+ return $view->render($response, 'contabilidad.depositos', compact('inmobiliarias', 'activos', 'vencidos'));
+ }
+ public function tesoreria(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Contabilidad\Informe\Tesoreria $contabilidadService,
+ string $fecha = 'today'): ResponseInterface
+ {
+ $fecha = new DateTimeImmutable($fecha);
+ $anterior = $contabilidadService->getAnterior($fecha);
+ $informes = $contabilidadService->build($fecha);
+ $filename = "Informe de Tesorería {$fecha->format('d.m.Y')}";
+ return $view->render($response, 'contabilidad.informes.tesoreria', compact('fecha', 'anterior', 'informes', 'filename'));
+ }
+}
diff --git a/app/src/Controller/Contabilidad/Informes.php b/app/src/Controller/Contabilidad/Informes.php
new file mode 100644
index 0000000..6f3dc14
--- /dev/null
+++ b/app/src/Controller/Contabilidad/Informes.php
@@ -0,0 +1,20 @@
+buildInforme($fecha, $tesoreriaService->build($fecha));
+ $response->getBody()->write(file_get_contents('php://output'));
+ return $response;
+ }
+}
diff --git a/app/src/Controller/Inmobiliarias.php b/app/src/Controller/Inmobiliarias.php
new file mode 100644
index 0000000..3387909
--- /dev/null
+++ b/app/src/Controller/Inmobiliarias.php
@@ -0,0 +1,45 @@
+load((array) $row);
+ }, $this->fetchRedis($redisService, $redisKey));
+ } catch (EmptyRedis) {
+ try {
+ $inmobiliarias = $inmobiliariaRepository->fetchAll();
+ $this->saveRedis($redisService, $redisKey, $inmobiliarias);
+ } catch (EmptyResult) {}
+ }
+ return $view->render($response, 'inmobiliarias.list', compact('inmobiliarias'));
+ }
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Redis $redisService, Repository\Inmobiliaria $inmobiliariaRepository, int $inmobiliaria_rut): ResponseInterface
+ {
+ $redisKey = "inmobiliaria:{$inmobiliaria_rut}";
+ try {
+ $inmobiliaria = $inmobiliariaRepository->load((array) $this->fetchRedis($redisService, $redisKey));
+ } catch (EmptyResult) {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut);
+ $this->saveRedis($redisService, $redisKey, $inmobiliaria);
+ }
+ return $view->render($response, 'inmobiliaria.show', compact('inmobiliaria'));
+ }
+}
diff --git a/app/src/Controller/Login.php b/app/src/Controller/Login.php
new file mode 100644
index 0000000..d018605
--- /dev/null
+++ b/app/src/Controller/Login.php
@@ -0,0 +1,50 @@
+isIn()) {
+ return $response->withStatus(302)->withHeader('Location', $view->get('urls')->base);
+ }
+ return $view->render($response, 'login.form');
+ }
+ public function login(ServerRequestInterface $request, ResponseInterface $response, Repository\User $userRepository, Service\Login $service): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $user = $userRepository->fetchByName($body['name']);
+ $output = [
+ 'name' => $user->name,
+ 'login' => false
+ ];
+ if ($user->validate($body['password'])) {
+ $output['login'] = $service->login($user);
+ }
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+ public function logout(ServerRequestInterface $request, ResponseInterface $response, Repository\Login $loginRepository, Service\Login $service): ResponseInterface
+ {
+ $output = [
+ 'name' => '',
+ 'logout' => false
+ ];
+ try {
+ $user = $service->getUser();
+ $output = [
+ 'name' => $user->name,
+ 'logout' => $service->logout($user)
+ ];
+ } catch (PDOException) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
diff --git a/app/src/Controller/Proyectos.php b/app/src/Controller/Proyectos.php
new file mode 100644
index 0000000..80e7bae
--- /dev/null
+++ b/app/src/Controller/Proyectos.php
@@ -0,0 +1,65 @@
+fetchAll();
+ usort($proyectos, function(Model\Proyecto $a, Model\Proyecto $b) {
+ return strcmp($a->descripcion, $b->descripcion);
+ });
+ } catch (EmptyResult) {}
+ return $view->render($response, 'proyectos.list', compact('proyectos'));
+ }
+ public function unidades(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Redis $redisService, Repository\Proyecto $proyectoRepository,
+ Repository\Venta\Unidad $unidadRepository): ResponseInterface
+ {
+ $proyectos = [];
+ $redisKey = "proyectos:con_unidades";
+ try {
+ $proyectos = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $proyectos = $proyectoRepository->fetchAll();
+ $proyectos = array_filter($proyectos, function(Model\Proyecto $proyecto) use ($unidadRepository) {
+ $unidades = $unidadRepository->fetchByProyecto($proyecto->id);
+ return count($unidades) > 0;
+ });
+ usort($proyectos, function(Model\Proyecto $a, Model\Proyecto $b) {
+ return strcmp($a->descripcion, $b->descripcion);
+ });
+ $this->saveRedis($redisService, $redisKey, $proyectos);
+ } catch (EmptyResult) {}
+ }
+ return $view->render($response, 'proyectos.unidades', compact('proyectos'));
+ }
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Redis $redisService, Service\Proyecto $proyectoService,
+ Repository\Proyecto $proyectoRepository, int $proyecto_id): ResponseInterface
+ {
+ $redisKey = "proyecto:{$proyecto_id}";
+ try {
+ $proyecto = $proyectoService->getById($this->fetchRedis($redisService, $redisKey)->id);
+ } catch (EmptyRedis) {
+ $proyecto = $proyectoService->getById($proyecto_id);
+ $this->saveRedis($redisService, $redisKey, $proyecto);
+ }
+ return $view->render($response, 'proyectos.show', compact('proyecto'));
+ }
+}
diff --git a/app/src/Controller/Search.php b/app/src/Controller/Search.php
new file mode 100644
index 0000000..082d713
--- /dev/null
+++ b/app/src/Controller/Search.php
@@ -0,0 +1,16 @@
+getParsedBody() ?? '';
+ return $view->render($response, 'search', compact('post', 'query', 'tipo'));
+ }
+}
diff --git a/app/src/Controller/Users.php b/app/src/Controller/Users.php
new file mode 100644
index 0000000..cfa82ff
--- /dev/null
+++ b/app/src/Controller/Users.php
@@ -0,0 +1,11 @@
+fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ $proyectos = array_map(function(Model\Proyecto $proyecto) {
+ return ['id' => $proyecto->id, 'descripcion' => $proyecto->descripcion];
+ }, $proyectoService->getVendibles());
+ $this->saveRedis($redisService, $redisKey, $proyectos);
+ }
+ return $view->render($response, 'ventas.list', compact('proyectos'));
+ }
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, int $venta_id): ResponseInterface
+ {
+ try {
+ $venta = $service->getById($venta_id);
+ return $view->render($response, 'ventas.show', compact('venta'));
+ } catch (EmptyResult) {
+ $response = $response->withStatus(404);
+ return $view->render($response, 'not_found');
+ }
+ }
+ public function showUnidad(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, string $proyecto_nombre, int $unidad_descripcion): ResponseInterface
+ {
+ $proyecto_nombre = urldecode($proyecto_nombre);
+ $venta = $service->getByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
+ return $view->render($response, 'ventas.show', compact('venta'));
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, int $venta_id): ResponseInterface
+ {
+ $venta = $service->getById($venta_id);
+ return $view->render($response, 'ventas.edit', compact('venta'));
+ }
+ public function propietario(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, Repository\Region $regionRepository, int $venta_id): ResponseInterface
+ {
+ $venta = $service->getById($venta_id);
+ $propietario = $venta->propietario();
+ $regiones = $regionRepository->fetchAll();
+ usort($regiones, function(Model\Region $a, Model\Region $b) {
+ return $a->numeracion - $b->numeracion;
+ });
+ return $view->render($response, 'ventas.propietarios.edit', compact('propietario',
+ 'venta_id', 'regiones'));
+ }
+ public function propiedad(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, Service\Venta\Unidad $unidadService, int $venta_id): ResponseInterface
+ {
+ $venta = $service->getById($venta_id);
+ $propiedad = $venta->propiedad();
+ $proyecto = $venta->proyecto();
+ $unidades = $unidadService->getDisponiblesByProyecto($proyecto->id);
+ $tiposUnidades = [];
+ foreach ($unidades as $unidad) {
+ if (!in_array($unidad->proyectoTipoUnidad->tipoUnidad, $tiposUnidades)) {
+ $tiposUnidades []= $unidad->proyectoTipoUnidad->tipoUnidad;
+ }
+ }
+ return $view->render($response, 'ventas.propiedades.edit', compact('propiedad',
+ 'proyecto', 'tiposUnidades', 'unidades', 'venta'));
+ }
+ public function pie(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $service, int $venta_id): ResponseInterface
+ {
+ $venta = $service->getById($venta_id);
+ return $view->render($response, 'ventas.pies.edit', compact('venta'));
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Repository\Region $regionRepository, Repository\Proyecto $proyectoRepository): ResponseInterface
+ {
+ $regiones = $regionRepository->fetchAll();
+ usort($regiones, function(Model\Region $a, Model\Region $b) {
+ return $a->numeracion - $b->numeracion;
+ });
+ $proyectos = $proyectoRepository->fetchAllActive();
+ return $view->render($response, 'ventas.add', compact('regiones', 'proyectos'));
+ }
+ public function cuotas(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
+ View $view, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ return $view->render($response, 'ventas.pies.cuotas', compact('venta'));
+ }
+ public function escriturar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
+ Repository\Banco $bancoRepository, View $view, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ $bancos = $bancoRepository->fetchAll();
+ usort($bancos, function(Model\Banco $a, Model\Banco $b) {
+ return strcmp($a->nombre, $b->nombre);
+ });
+ return $view->render($response, 'ventas.escriturar', compact('venta', 'bancos'));
+ }
+ public function desistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
+ View $view, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ return $view->render($response, 'ventas.desistir', compact('venta'));
+ }
+ public function desistida(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
+ View $view, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ return $view->render($response, 'ventas.desistida', compact('venta'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Cierres.php b/app/src/Controller/Ventas/Cierres.php
new file mode 100644
index 0000000..ed92eca
--- /dev/null
+++ b/app/src/Controller/Ventas/Cierres.php
@@ -0,0 +1,36 @@
+render($response, 'ventas.cierres.list');
+ }
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view, Service\Venta\Cierre $service, int $cierre_id): ResponseInterface
+ {
+ $cierre = $service->getById($cierre_id);
+ return $view->render($response, 'ventas.cierres.show', compact('cierre'));
+ }
+
+ public function proyecto(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Cierre $service): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $output = ['total' => 0];
+ try {
+ $cierres = $service->getByProyecto($proyecto_id);
+ $output['cierres'] = $cierres;
+ $output['total'] = count($cierres);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
diff --git a/app/src/Controller/Ventas/Comentarios.php b/app/src/Controller/Ventas/Comentarios.php
new file mode 100644
index 0000000..8d39525
--- /dev/null
+++ b/app/src/Controller/Ventas/Comentarios.php
@@ -0,0 +1,22 @@
+ 0];
+ try {
+ $comentarios = $comentarioRepository->fetchAll();
+ $output['comentarios'] = $comentarios;
+ $output['total'] = count($comentarios);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
diff --git a/app/src/Controller/Ventas/Creditos.php b/app/src/Controller/Ventas/Creditos.php
new file mode 100644
index 0000000..e04f9b1
--- /dev/null
+++ b/app/src/Controller/Ventas/Creditos.php
@@ -0,0 +1,20 @@
+fetchById($venta_id);
+ $bancos = $bancoRepository->fetchAll('nombre');
+ return $view->render($response, 'ventas.creditos', compact('venta', 'bancos'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Cuotas.php b/app/src/Controller/Ventas/Cuotas.php
new file mode 100644
index 0000000..0c03d72
--- /dev/null
+++ b/app/src/Controller/Ventas/Cuotas.php
@@ -0,0 +1,107 @@
+pendientes();
+ return $view->render($response, 'ventas.cuotas.pendientes', compact('cuotas_pendientes'));
+ }
+ public function depositadas(ServerRequestInterface $request, ResponseInterface $response, View $view, Service\Venta\Cuota $cuotaService): ResponseInterface
+ {
+ $cuotas_depositadas = $cuotaService->depositadas();
+ return $view->render($response, 'ventas.cuotas.abonar', compact('cuotas_depositadas'));
+ }
+ public function depositar(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $cuota_id = $json->cuota_id;
+ $fecha = new DateTimeImmutable($json->fecha);
+ $output = [
+ 'cuota_id' => $cuota_id,
+ 'depositada' => false
+ ];
+ try{
+ $cuota = $cuotaRepository->fetchById($cuota_id);
+ $output['depositada'] = $pagoService->depositar($cuota->pago, $fecha);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+ public function abonar(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $cuota_id = $json->cuota_id;
+ $fecha = new DateTimeImmutable($json->fecha);
+ $output = [
+ 'cuota_id' => $cuota_id,
+ 'abonada' => false
+ ];
+ try{
+ $cuota = $cuotaRepository->fetchById($cuota_id);
+ $output['abonada'] = $pagoService->abonar($cuota->pago, $fecha);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+ public function devolver(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Venta\Pago $pagoService): ResponseInterface
+ {
+ $body = $request->getBody();
+ $json = json_decode($body->getContents());
+ $cuota_id = $json->cuota_id;
+ $fecha = new DateTimeImmutable($json->fecha);
+ $output = [
+ 'cuota_id' => $cuota_id,
+ 'devuelta' => false
+ ];
+ try{
+ $cuota = $cuotaRepository->fetchById($cuota_id);
+ $output['devuelta'] = $pagoService->devolver($cuota->pago, $fecha);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pie $pieService, Repository\Venta $ventaRepository, Repository\Banco $bancoRepository, View $view, int $pie_id): ResponseInterface
+ {
+ $pie = $pieService->getById($pie_id);
+ $venta = $ventaRepository->fetchByPie($pie_id);
+ $bancos = $bancoRepository->fetchAll();
+ usort($bancos, function(Model\Banco $a, Model\Banco $b) {
+ return strcmp($a->nombre, $b->nombre);
+ });
+ return $view->render($response, 'ventas.pies.cuotas.add', compact('pie', 'venta', 'bancos'));
+ }
+ public function doAdd(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Pie $pieService,
+ Repository\Venta $ventaRepository, int $pie_id): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $pie = $pieService->getById($pie_id);
+ $venta = $ventaRepository->fetchByPie($pie_id);
+ $start = count($pie->cuotas(vigentes: true));
+ $total = $pie->cuotas;
+ for ($i = $start; $i < $total; $i ++) {
+ $data = [
+ 'pie' => $pie->id,
+ 'fecha' => $body["fecha{$i}"],
+ 'banco' => $body["banco{$i}"],
+ 'identificador' => $body["identificador{$i}"],
+ 'valor' => str_replace(['.', ','], ['', ''], $body["valor{$i}"]),
+ 'numero' => $i + 1,
+ ];
+ $pieService->addCuota($data);
+ }
+ return $response->withHeader('Location', "/venta/{$venta->id}");
+ }
+}
diff --git a/app/src/Controller/Ventas/Escrituras.php b/app/src/Controller/Ventas/Escrituras.php
new file mode 100644
index 0000000..86fcd62
--- /dev/null
+++ b/app/src/Controller/Ventas/Escrituras.php
@@ -0,0 +1,32 @@
+getById($venta_id);
+ return $view->render($response, 'ventas.escrituras.show', compact('venta'));
+ }
+ public function informe(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ return $view->render($response, 'ventas.escrituras.informe', compact('venta'));
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Venta $ventaService, Repository\Banco $bancoRepository,
+ int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ $bancos = $bancoRepository->fetchAll('nombre');
+ return $view->render($response, 'ventas.escrituras.add', compact('venta', 'bancos'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Estados.php b/app/src/Controller/Ventas/Estados.php
new file mode 100644
index 0000000..4e8782f
--- /dev/null
+++ b/app/src/Controller/Ventas/Estados.php
@@ -0,0 +1,17 @@
+getById($venta_id);
+ return $view->render($response, 'ventas.estado', compact('venta'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Facturacion.php b/app/src/Controller/Ventas/Facturacion.php
new file mode 100644
index 0000000..90581a9
--- /dev/null
+++ b/app/src/Controller/Ventas/Facturacion.php
@@ -0,0 +1,21 @@
+getEscriturando();
+ return $view->render($response, 'ventas.facturacion', compact('proyectos'));
+ }
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view, Service\Venta $ventaService, int $venta_id): ResponseInterface
+ {
+ $venta = $ventaService->getById($venta_id);
+ return $view->render($response, 'ventas.facturacion.show', compact('venta'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Pagos.php b/app/src/Controller/Ventas/Pagos.php
new file mode 100644
index 0000000..e8de649
--- /dev/null
+++ b/app/src/Controller/Ventas/Pagos.php
@@ -0,0 +1,16 @@
+render($response, 'ventas.pagos.pendientes');
+ }
+}
diff --git a/app/src/Controller/Ventas/Pies.php b/app/src/Controller/Ventas/Pies.php
new file mode 100644
index 0000000..21e5fcc
--- /dev/null
+++ b/app/src/Controller/Ventas/Pies.php
@@ -0,0 +1,23 @@
+getById($pie_id);
+ $venta = $ventaRepository->fetchByPie($pie_id);
+ $bancos = $bancoRepository->fetchAll();
+ usort($bancos, function(Model\Banco $a, Model\Banco $b) {
+ return strcmp($a->nombre, $b->nombre);
+ });
+ return $view->render($response, 'ventas.pies.cuotas', compact('pie', 'venta', 'bancos'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Precios.php b/app/src/Controller/Ventas/Precios.php
new file mode 100644
index 0000000..890d749
--- /dev/null
+++ b/app/src/Controller/Ventas/Precios.php
@@ -0,0 +1,17 @@
+ $proyecto->id, 'descripcion' => $proyecto->descripcion];}, $proyectoService->getVendibles());
+ return $view->render($response, 'ventas.precios.list', compact('proyectos'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Propietarios.php b/app/src/Controller/Ventas/Propietarios.php
new file mode 100644
index 0000000..aee848c
--- /dev/null
+++ b/app/src/Controller/Ventas/Propietarios.php
@@ -0,0 +1,28 @@
+fetchById($propietario_rut);
+ return $view->render($response, 'ventas.propietarios.show', compact('propietario'));
+ }
+ public function get(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Propietario $propietarioRepository, int $propietario_rut): ResponseInterface
+ {
+ $output = [
+ 'rut' => $propietario_rut,
+ 'propietario' => null
+ ];
+ try {
+ $output['propietario'] = $propietarioRepository->fetchById($propietario_rut);
+ } catch (EmptyResult) {}
+ $response->getBody()->write(json_encode($output));
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
diff --git a/app/src/Controller/withRedis.php b/app/src/Controller/withRedis.php
new file mode 100644
index 0000000..0cc5bab
--- /dev/null
+++ b/app/src/Controller/withRedis.php
@@ -0,0 +1,28 @@
+get($redisKey);
+ if ($jsonString === null) {
+ throw new EmptyRedis($redisKey);
+ }
+ return json_decode($jsonString);
+ }
+ public function saveRedis(Service\Redis $redisService, string $redisKey, mixed $value, ?int $expiration = null): void
+ {
+ if (is_array($value) or is_object($value)) {
+ $value = json_encode($value);
+ }
+ if ($expiration !== null) {
+ $redisService->set($redisKey, $value, $expiration);
+ return;
+ }
+ $redisService->set($redisKey, $value);
+ }
+}
diff --git a/app/src/Exception/MissingAuthorizationHeader.php b/app/src/Exception/MissingAuthorizationHeader.php
new file mode 100644
index 0000000..8999018
--- /dev/null
+++ b/app/src/Exception/MissingAuthorizationHeader.php
@@ -0,0 +1,13 @@
+getKey($request);
+ } catch (MissingAuthorizationHeader $exception) {
+ return $this->responseFactory->createResponse(401);
+ }
+ if ($this->validate($key)) {
+ return $handler->handle($request);
+ }
+ return $this->responseFactory->createResponse(403);
+ }
+ protected function getKey(ServerRequestInterface $request): string
+ {
+ $auth_headers = $request->getHeader('Authorization');
+ foreach ($auth_headers as $header) {
+ if (str_contains($header, 'Bearer')) {
+ return substr($header, strlen('Bearer '));
+ }
+ }
+ throw new MissingAuthorizationHeader();
+ }
+ protected function validate($incoming_key): bool
+ {
+ return $incoming_key === md5($this->key);
+ }
+}
diff --git a/app/src/Middleware/Authentication.php b/app/src/Middleware/Authentication.php
new file mode 100644
index 0000000..ca1a79b
--- /dev/null
+++ b/app/src/Middleware/Authentication.php
@@ -0,0 +1,61 @@
+service->isIn() or $this->isValid($request)) {
+ return $handler->handle($request);
+ }
+ $this->logger->notice("Not logged in.");
+ $response = $this->responseFactory->createResponse(301, 'Not logged in')
+ ->withHeader('Referer', (string) $request->getUri())
+ ->withHeader('X-Redirected-URI', (string) $request->getUri());
+ $url = "{$request->getUri()}";
+ if (str_ends_with($url, '/login')) {
+ $url = str_replace('/login', '', $url);
+ }
+ return $this->view->render($response, 'login.form', ['redirect_uri' => $url]);
+ }
+
+ protected function isValid(ServerRequestInterface $request): bool
+ {
+ $uri = $request->getUri();
+ $current_path = $uri->getPath();
+ $current_url = implode('', [
+ "{$uri->getScheme()}://",
+ $uri->getHost() . ($uri->getPort() !== null ? ":{$uri->getPort()}" : ''),
+ $uri->getPath()
+ ]);
+
+ $valid_paths = [
+ '/',
+ ];
+ if (in_array($current_path, $valid_paths, true)) {
+ return true;
+ }
+ $valid_uris = [
+ $this->login_url,
+ ];
+ if (in_array($current_url, $valid_uris, true)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/app/src/Middleware/Errors.php b/app/src/Middleware/Errors.php
new file mode 100644
index 0000000..f30df46
--- /dev/null
+++ b/app/src/Middleware/Errors.php
@@ -0,0 +1,31 @@
+handle($request);
+ } catch (Exception $exception) {
+ $this->logger->notice($exception);
+ } catch (Error $error) {
+ $this->logger->error($error);
+ }
+ $response = $this->responseFactory->createResponse(600, 'Internal Server Error');
+ if (str_contains($request->getUri()->getPath(), '/api')) {
+ return $response;
+ }
+ return $this->view->render($response, 'construccion');
+ }
+}
diff --git a/app/src/Middleware/NotFound.php b/app/src/Middleware/NotFound.php
new file mode 100644
index 0000000..abccf49
--- /dev/null
+++ b/app/src/Middleware/NotFound.php
@@ -0,0 +1,28 @@
+handle($request);
+ } catch (HttpNotFoundException $exception) {
+ $this->logger->notice($exception);
+ $response = $this->responseFactory->createResponse(404);
+ if (str_contains($request->getUri()->getPath(), '/api')) {
+ return $response;
+ }
+ return $this->view->render($response, 'not_found');
+ }
+ }
+}
diff --git a/app/src/Model/Banco.php b/app/src/Model/Banco.php
new file mode 100644
index 0000000..1852ff2
--- /dev/null
+++ b/app/src/Model/Banco.php
@@ -0,0 +1,16 @@
+ $this->nombre ?? ''
+ ]);
+ }
+}
diff --git a/app/src/Model/Cartola.php b/app/src/Model/Cartola.php
new file mode 100644
index 0000000..49363b6
--- /dev/null
+++ b/app/src/Model/Cartola.php
@@ -0,0 +1,26 @@
+ $this->cuenta->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'cargos' => $this->cargos,
+ 'abonos' => $this->abonos,
+ 'saldo' => $this->saldo
+ ]);
+ }
+}
diff --git a/app/src/Model/CategoriaCentro.php b/app/src/Model/CategoriaCentro.php
new file mode 100644
index 0000000..e131f86
--- /dev/null
+++ b/app/src/Model/CategoriaCentro.php
@@ -0,0 +1,5 @@
+ $this->tipoCentro,
+ 'categoria' => $this->categoria,
+ 'tipo_cuenta' => $this->tipoCuenta,
+ 'cuenta_contable' => $this->cuentaContable,
+ 'descripcion' => $this->descripcion
+ ]);
+ }
+}
diff --git a/app/src/Model/Comuna.php b/app/src/Model/Comuna.php
new file mode 100644
index 0000000..057bdf1
--- /dev/null
+++ b/app/src/Model/Comuna.php
@@ -0,0 +1,22 @@
+ $this->descripcion,
+ 'provincia' => $this->provincia
+ ]);
+ }
+ public function __toString(): string
+ {
+ return $this->descripcion;
+ }
+}
diff --git a/app/src/Model/Deposito.php b/app/src/Model/Deposito.php
new file mode 100644
index 0000000..da32727
--- /dev/null
+++ b/app/src/Model/Deposito.php
@@ -0,0 +1,36 @@
+termino->diff($this->inicio)->days;
+ }
+ public function tasa(): float
+ {
+ return ($this->futuro - $this->capital) / $this->capital;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'cuenta_id' => $this->cuenta->id,
+ 'capital' => $this->capital,
+ 'futuro' => $this->futuro,
+ 'inicio' => $this->inicio->format('Y-m-d'),
+ 'termino' => $this->termino->format('Y-m-d'),
+ 'plazo' => $this->plazo(),
+ 'tasa' => $this->tasa()
+ ]);
+ }
+}
diff --git a/app/src/Model/Direccion.php b/app/src/Model/Direccion.php
new file mode 100644
index 0000000..d27a4ff
--- /dev/null
+++ b/app/src/Model/Direccion.php
@@ -0,0 +1,58 @@
+calle,
+ $this->numero
+ ])
+ ];
+ if ($this->extra !== '') {
+ $arr []= $this->extra;
+ }
+ return implode(', ', $arr);
+ }
+
+ public function full(): string
+ {
+ return implode(', ', [
+ "{$this}",
+ $this->comuna->provincia
+ ]);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'calle' => $this->calle,
+ 'numero' => $this->numero,
+ 'extra' => $this->extra,
+ 'comuna' => $this->comuna
+ ]);
+ }
+ public function __toString(): string
+ {
+ $array = [
+ implode(' ', [
+ $this->calle,
+ $this->numero
+ ])
+ ];
+ if ($this->extra !== '') {
+ $array[]= $this->extra;
+ }
+ $array []= $this->comuna;
+ return implode(', ', $array);
+ }
+}
diff --git a/app/src/Model/Inmobiliaria.php b/app/src/Model/Inmobiliaria.php
new file mode 100644
index 0000000..83400ab
--- /dev/null
+++ b/app/src/Model/Inmobiliaria.php
@@ -0,0 +1,45 @@
+rut, 0, ',', '.'),
+ $this->dv
+ ]);
+ }
+ public function nombreCompleto(): string
+ {
+ return implode(' ', [
+ $this->razon,
+ $this->tipoSociedad->descripcion
+ ]);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'rut' => $this->rut,
+ 'dv' => $this->dv ?? '',
+ 'rut_formateado' => $this->rut(),
+ 'razon' => $this->razon ?? '',
+ 'abreviacion' => $this->abreviacion ?? '',
+ 'cuenta' => $this->cuenta ?? '',
+ 'banco' => $this->banco ?? '',
+ 'tipo_sociedad' => $this->tipoSociedad ?? ''
+ ];
+ }
+}
diff --git a/app/src/Model/Inmobiliaria/Cuenta.php b/app/src/Model/Inmobiliaria/Cuenta.php
new file mode 100644
index 0000000..33487ef
--- /dev/null
+++ b/app/src/Model/Inmobiliaria/Cuenta.php
@@ -0,0 +1,21 @@
+ $this->inmobiliaria->rut,
+ 'banco' => $this->banco,
+ 'cuenta' => $this->cuenta
+ ]);
+ }
+}
diff --git a/app/src/Model/Inmobiliaria/TipoSociedad.php b/app/src/Model/Inmobiliaria/TipoSociedad.php
new file mode 100644
index 0000000..dc71047
--- /dev/null
+++ b/app/src/Model/Inmobiliaria/TipoSociedad.php
@@ -0,0 +1,16 @@
+ $this->abreviacion
+ ]);
+ }
+}
diff --git a/app/src/Model/Login.php b/app/src/Model/Login.php
new file mode 100644
index 0000000..fb66590
--- /dev/null
+++ b/app/src/Model/Login.php
@@ -0,0 +1,25 @@
+ $this->user->id,
+ 'selector' => $this->selector,
+ 'token' => $this->token,
+ 'date_time' => $this->dateTime->format('Y-m-d H:i:s'),
+ 'status' => $this->status
+ ]);
+ }
+}
diff --git a/app/src/Model/Menu.php b/app/src/Model/Menu.php
new file mode 100644
index 0000000..7d45894
--- /dev/null
+++ b/app/src/Model/Menu.php
@@ -0,0 +1,7 @@
+detalles)) {
+ $this->detalles = $this->runFactory('detalles');
+ }
+ return $this->detalles;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'cuenta_id' => $this->cuenta->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'glosa' => $this->glosa,
+ 'documento' => $this->documento,
+ 'cargo' => $this->cargo,
+ 'abono' => $this->abono,
+ 'saldo' => $this->saldo,
+ 'detalles' => $this->getDetalles() ?? null
+ ]);
+ }
+}
diff --git a/app/src/Model/Movimiento/Detalle.php b/app/src/Model/Movimiento/Detalle.php
new file mode 100644
index 0000000..ec56449
--- /dev/null
+++ b/app/src/Model/Movimiento/Detalle.php
@@ -0,0 +1,21 @@
+ $this->movimiento->id,
+ 'centro_costo' => $this->centroCosto,
+ 'detalle' => $this->detalle
+ ];
+ }
+}
diff --git a/app/src/Model/Nubox.php b/app/src/Model/Nubox.php
new file mode 100644
index 0000000..05b223a
--- /dev/null
+++ b/app/src/Model/Nubox.php
@@ -0,0 +1,18 @@
+usuario, $this->password]));
+ }
+}
diff --git a/app/src/Model/PagoCentroCosto.php b/app/src/Model/PagoCentroCosto.php
new file mode 100644
index 0000000..5be8849
--- /dev/null
+++ b/app/src/Model/PagoCentroCosto.php
@@ -0,0 +1,18 @@
+ $this->pago,
+ 'centro_costo' => $this->centroCosto
+ ]);
+ }
+}
diff --git a/app/src/Model/Provincia.php b/app/src/Model/Provincia.php
new file mode 100644
index 0000000..652e3ce
--- /dev/null
+++ b/app/src/Model/Provincia.php
@@ -0,0 +1,22 @@
+ $this->descripcion,
+ 'region' => $this->region
+ ]);
+ }
+ public function __toString(): string
+ {
+ return implode(', ', [$this->descripcion, '' . $this->region]);
+ }
+}
diff --git a/app/src/Model/Proyecto.php b/app/src/Model/Proyecto.php
new file mode 100644
index 0000000..d4a2e69
--- /dev/null
+++ b/app/src/Model/Proyecto.php
@@ -0,0 +1,64 @@
+inmobiliaria)) {
+ $this->inmobiliaria = $this->runFactory('inmobiliaria');
+ }
+ return $this->inmobiliaria;
+ }
+ public function direccion(): Direccion
+ {
+ if (!isset($this->direccion)) {
+ $this->direccion = $this->runFactory('direccion');
+ }
+ return $this->direccion;
+ }
+ public function estados(): array
+ {
+ if (!isset($this->estados)) {
+ $this->estados = $this->runFactory('estados');
+ }
+ return $this->estados;
+ }
+ public function currentEstado(): Proyecto\EstadoProyecto
+ {
+ if (!isset($this->currentEstado)) {
+ $this->currentEstado = $this->runFactory('currentEstado');
+ }
+ return $this->currentEstado;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'inmobiliaria' => $this->inmobiliaria(),
+ 'descripcion' => $this->descripcion,
+ 'direccion' => $this->direccion(),
+ 'terreno' => $this->terreno,
+ 'superficie' => $this->superficie,
+ 'corredor' => $this->corredor,
+ 'pisos' => $this->pisos,
+ 'subterraneos' => $this->subterraneos
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/Elemento.php b/app/src/Model/Proyecto/Elemento.php
new file mode 100644
index 0000000..9a015ff
--- /dev/null
+++ b/app/src/Model/Proyecto/Elemento.php
@@ -0,0 +1,20 @@
+ $this->descripcion,
+ 'abreviacion' => $this->abreviacion,
+ 'orden' => $this->orden
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/EstadoProyecto.php b/app/src/Model/Proyecto/EstadoProyecto.php
new file mode 100644
index 0000000..061d0f0
--- /dev/null
+++ b/app/src/Model/Proyecto/EstadoProyecto.php
@@ -0,0 +1,30 @@
+proyecto)) {
+ $this->proyecto = $this->runFactory('proyecto');
+ }
+ return $this->proyecto;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'proyecto' => $this->proyecto(),
+ 'tipo_estado_proyecto' => $this->tipoEstadoProyecto,
+ 'fecha' => $this->fecha
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/Etapa.php b/app/src/Model/Proyecto/Etapa.php
new file mode 100644
index 0000000..10f7d97
--- /dev/null
+++ b/app/src/Model/Proyecto/Etapa.php
@@ -0,0 +1,18 @@
+ $this->descripcion,
+ 'orden' => $this->orden
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/ProyectoTipoUnidad.php b/app/src/Model/Proyecto/ProyectoTipoUnidad.php
new file mode 100644
index 0000000..8c7a6bf
--- /dev/null
+++ b/app/src/Model/Proyecto/ProyectoTipoUnidad.php
@@ -0,0 +1,62 @@
+util, $this->logia, $this->terraza], function($sum, $item) {return $sum + $item;}, 0);
+ }
+ public function vendible(): float
+ {
+ return array_reduce([$this->util, $this->logia, $this->terraza / 2], function($sum, $item) {return $sum + $item;}, 0);
+ }
+ public function tipologia(): string
+ {
+ if (isset($this->tipologias) and count($this->tipologias) > 0) {
+ $temp = [...$this->tipologias];
+ usort($temp, function(Tipologia $a, Tipologia $b) {
+ $el = $a->elemento->orden - $b->elemento->orden;
+ if ($el === 0) {
+ return strcmp($a->elemento->abreviacion, $b->elemento->abreviacion);
+ }
+ return $el;
+ });
+ return implode('/', array_map(function(Tipologia $tipologia) {
+ return $tipologia->cantidad . $tipologia->elemento->abreviacion;
+ }, $temp));
+ }
+ return $this->abreviacion;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'proyecto' => $this->proyecto,
+ 'tipo_unidad' => $this->tipoUnidad,
+ 'nombre' => $this->nombre,
+ 'abreviacion' => $this->abreviacion,
+ 'util' => $this->util,
+ 'logia' => $this->logia,
+ 'terraza' => $this->terraza,
+ 'superficie' => $this->superficie(),
+ 'vendible' => $this->vendible(),
+ 'descripcion' => $this->descripcion,
+ 'tipologia' => $this->tipologia()
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/Superficie.php b/app/src/Model/Proyecto/Superficie.php
new file mode 100644
index 0000000..5127e3d
--- /dev/null
+++ b/app/src/Model/Proyecto/Superficie.php
@@ -0,0 +1,24 @@
+bajo_nivel + $this->sobre_nivel;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'sobre_nivel' => $this->sobre_nivel,
+ 'bajo_nivel' => $this->bajo_nivel,
+ 'total' => $this->total()
+ ];
+ }
+}
diff --git a/app/src/Model/Proyecto/Terreno.php b/app/src/Model/Proyecto/Terreno.php
new file mode 100644
index 0000000..cdb1bd8
--- /dev/null
+++ b/app/src/Model/Proyecto/Terreno.php
@@ -0,0 +1,22 @@
+ $this->superficie,
+ 'valor' => $this->valor,
+ 'fecha' => $this->fecha?->format('Y-m-d')
+ ];
+ }
+}
diff --git a/app/src/Model/Proyecto/TipoEstadoProyecto.php b/app/src/Model/Proyecto/TipoEstadoProyecto.php
new file mode 100644
index 0000000..a6b0485
--- /dev/null
+++ b/app/src/Model/Proyecto/TipoEstadoProyecto.php
@@ -0,0 +1,18 @@
+ $this->orden,
+ 'etapa' => $this->etapa
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/TipoTipologia.php b/app/src/Model/Proyecto/TipoTipologia.php
new file mode 100644
index 0000000..39a3649
--- /dev/null
+++ b/app/src/Model/Proyecto/TipoTipologia.php
@@ -0,0 +1,8 @@
+ $this->orden
+ ]);
+ }
+}
diff --git a/app/src/Model/Proyecto/Tipologia.php b/app/src/Model/Proyecto/Tipologia.php
new file mode 100644
index 0000000..85eb36a
--- /dev/null
+++ b/app/src/Model/Proyecto/Tipologia.php
@@ -0,0 +1,20 @@
+ $this->cantidad,
+ 'elemento' => $this->elemento
+ ]);
+ }
+}
diff --git a/app/src/Model/Region.php b/app/src/Model/Region.php
new file mode 100644
index 0000000..3b1d801
--- /dev/null
+++ b/app/src/Model/Region.php
@@ -0,0 +1,24 @@
+ $this->descripcion,
+ 'numeral' => $this->numeral,
+ 'numeracion' => $this->numeracion ?? 0
+ ]);
+ }
+ public function __toString(): string
+ {
+ return $this->descripcion;
+ }
+}
diff --git a/app/src/Model/Role.php b/app/src/Model/Role.php
new file mode 100644
index 0000000..e27c6a9
--- /dev/null
+++ b/app/src/Model/Role.php
@@ -0,0 +1,7 @@
+ $this->descripcion
+ ]);
+ }
+}
diff --git a/app/src/Model/TipoCentro.php b/app/src/Model/TipoCentro.php
new file mode 100644
index 0000000..9c23000
--- /dev/null
+++ b/app/src/Model/TipoCentro.php
@@ -0,0 +1,5 @@
+password);
+ }
+ public function isAdmin(): bool
+ {
+ return false;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'name' => $this->name
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta.php b/app/src/Model/Venta.php
new file mode 100644
index 0000000..a49d36e
--- /dev/null
+++ b/app/src/Model/Venta.php
@@ -0,0 +1,118 @@
+propietario)) {
+ $this->propietario = $this->runFactory('propietario');
+ }
+ return $this->propietario;
+ }
+ public function propiedad(): Venta\Propiedad
+ {
+ if (!isset($this->propiedad)) {
+ $this->propiedad = $this->runFactory('propiedad');
+ }
+ return $this->propiedad;
+ }
+ public function formaPago(): ?Venta\FormaPago
+ {
+ if (!isset($this->formaPago)) {
+ $this->formaPago = $this->runFactory('formaPago');
+ }
+ return $this->formaPago;
+ }
+ public function entrega(): ?Venta\Entrega
+ {
+ if (!isset($this->entrega)) {
+ $this->entrega = $this->runFactory('entrega');
+ }
+ return $this->entrega;
+ }
+ public function resciliacion(): ?Venta\Pago
+ {
+ if (!isset($this->resciliacion)) {
+ $this->resciliacion = $this->runFactory('resciliacion');
+ }
+ return $this->resciliacion;
+ }
+
+ public function estados(): array
+ {
+ if (!isset($this->estados)) {
+ $this->estados = $this->runFactory('estados');
+ }
+ return $this->estados ?? [];
+ }
+ public function currentEstado(): ?Venta\EstadoVenta
+ {
+ if (!isset($this->currentEstado)) {
+ $this->currentEstado = $this->runFactory('currentEstado');
+ }
+ return $this->currentEstado;
+ }
+
+ public function proyecto(): Proyecto
+ {
+ return $this->propiedad()->proyecto();
+ }
+
+ protected float $valor_util;
+ public function util(): float
+ {
+ if (!isset($this->valor_util)) {
+ $sum = $this->valor;
+ $sum -= array_reduce($this->propiedad()->estacionamientos(), function(float $sum, Venta\Unidad $unidad) {
+ return $unidad->valor ?? $unidad->precio($this->fecha)->valor;
+ }, 0);
+ $sum -= array_reduce($this->propiedad()->bodegas(), function(float $sum, Venta\Unidad $unidad) {
+ return $unidad->valor ?? $unidad->precio($this->fecha)->valor;
+ }, 0);
+ $this->valor_util = $sum;
+ }
+ return $this->valor_util;
+ }
+ public function saldo(string $moneda = Pago::UF): float
+ {
+ $valor = $this->valor * (($moneda === Pago::UF) ? 1 : $this->uf);
+ return $valor - $this->formaPago()->total($moneda);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'propietario' => $this->propietario(),
+ 'propiedad' => $this->propiedad(),
+ 'forma_pago' => $this->formaPago()?->ids(),
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'fecha_ingreso' => $this->fechaIngreso->format('Y-m-d'),
+ 'valor' => $this->valor,
+ 'relacionado' => $this->relacionado,
+ 'proyecto' => $this->proyecto(),
+ 'estados' => array_map(function(Venta\EstadoVenta $estado) {return $estado->id;}, $this->estados()),
+ 'current_estado' => $this->currentEstado()
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/BonoPie.php b/app/src/Model/Venta/BonoPie.php
new file mode 100644
index 0000000..02f1666
--- /dev/null
+++ b/app/src/Model/Venta/BonoPie.php
@@ -0,0 +1,18 @@
+ $this->valor,
+ 'pago' => $this->pago
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Cierre.php b/app/src/Model/Venta/Cierre.php
new file mode 100644
index 0000000..a070cf1
--- /dev/null
+++ b/app/src/Model/Venta/Cierre.php
@@ -0,0 +1,58 @@
+precio;
+ $bonos = array_filter($this->valoresCierre, function(ValorCierre $valorCierre) {return $valorCierre->tipoValorCierre->descripcion === 'bono pie';});
+ $sum -= array_reduce($bonos, function($sum, ValorCierre $bono) {return $sum + $bono->valor;}, 0);
+ $unidades = array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion !== 'departamento';});
+ $sum -= array_reduce($unidades, function($sum, Unidad $unidad) {return $sum + ($unidad->currentPrecio->valor ?? 0);});
+ return $sum;
+ }
+
+ public function principal(): stdClass
+ {
+ $unidades = array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento';});
+ $output = [
+ 'descripcion' => implode(' - ', array_map(function(Unidad $unidad) {return $unidad->descripcion;}, $unidades)),
+ 'vendible' => array_reduce($unidades, function($sum, Unidad $unidad) {return $sum + $unidad->proyectoTipoUnidad->vendible();}, 0),
+ 'precio' => array_reduce($unidades, function($sum, Unidad $unidad) {return $sum + $unidad->currentPrecio->valor;}, 0)
+ ];
+ return (object) $output;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'proyecto' => $this->proyecto,
+ 'precio' => $this->precio,
+ 'date_time' => $this->dateTime->format('Y-m-d H:i:s'),
+ 'relacionado' => $this->relacionado,
+ 'propietario' => $this->propietario->rut,
+ 'estados' => $this->estados,
+ 'estado_cierre' => $this->current,
+ 'unidades' => $this->unidades,
+ 'valores_cierre' => $this->valoresCierre
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Comentario.php b/app/src/Model/Venta/Comentario.php
new file mode 100644
index 0000000..55910bb
--- /dev/null
+++ b/app/src/Model/Venta/Comentario.php
@@ -0,0 +1,21 @@
+ $this->fecha->format('Y-m-d'),
+ 'texto' => $this->texto,
+ 'activo' => $this->activo
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Credito.php b/app/src/Model/Venta/Credito.php
new file mode 100644
index 0000000..25b4fa3
--- /dev/null
+++ b/app/src/Model/Venta/Credito.php
@@ -0,0 +1,18 @@
+ $this->valor,
+ 'pago' => $this->pago
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Cuota.php b/app/src/Model/Venta/Cuota.php
new file mode 100644
index 0000000..05dfb41
--- /dev/null
+++ b/app/src/Model/Venta/Cuota.php
@@ -0,0 +1,38 @@
+ $this->pie->id,
+ 'fecha' => $this->fecha->format('Y-m-d H:i:s'),
+ 'valor' => $this->valor,
+ 'estado' => $this->estado ?? false,
+ 'banco' => $this->banco,
+ 'fecha_pago' => $this->fechaPago?->format('Y-m-d H:i:s') ?? '',
+ 'abonado' => $this->abonado ?? false,
+ 'fecha_abonado' => $this->fechaAbonado?->format('Y-m-d H:i:s') ?? '',
+ 'uf' => $this->uf ?? 1,
+ 'pago' => $this->pago ?? '',
+ 'numero' => $this->numero ?? ''
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Datos.php b/app/src/Model/Venta/Datos.php
new file mode 100644
index 0000000..b9a7ebd
--- /dev/null
+++ b/app/src/Model/Venta/Datos.php
@@ -0,0 +1,27 @@
+ $this->sexo ?? '',
+ 'estado_civil' => $this->estado_civil ?? '',
+ 'profesion' => $this->profesion ?? '',
+ 'direccion' => $this->direccion ?? '',
+ 'telefono' => $this->telefono ?? '',
+ 'email' => $this->email ?? ''
+ ];
+ }
+}
diff --git a/app/src/Model/Venta/Entrega.php b/app/src/Model/Venta/Entrega.php
new file mode 100644
index 0000000..cfce6e3
--- /dev/null
+++ b/app/src/Model/Venta/Entrega.php
@@ -0,0 +1,21 @@
+ $this->fecha->format('Y-m-d'),
+ 'operacion' => $this->operacion,
+ 'reserva' => $this->reserva
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Escritura.php b/app/src/Model/Venta/Escritura.php
new file mode 100644
index 0000000..035fe09
--- /dev/null
+++ b/app/src/Model/Venta/Escritura.php
@@ -0,0 +1,19 @@
+ $this->pago,
+ 'fecha' => $this->fecha->format('Y-m-d')
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/EstadoCierre.php b/app/src/Model/Venta/EstadoCierre.php
new file mode 100644
index 0000000..2a94606
--- /dev/null
+++ b/app/src/Model/Venta/EstadoCierre.php
@@ -0,0 +1,21 @@
+ $this->cierre->id,
+ 'tipo_estado_cierre' => $this->tipoEstadoCierre,
+ 'fecha' => $this->fecha->format('Y-m-d')
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/EstadoPago.php b/app/src/Model/Venta/EstadoPago.php
new file mode 100644
index 0000000..e94f8d8
--- /dev/null
+++ b/app/src/Model/Venta/EstadoPago.php
@@ -0,0 +1,22 @@
+ $this->pago->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'tipo_estado_pago_id' => $this->tipoEstadoPago->id
+ ]);
+ }
+
+}
diff --git a/app/src/Model/Venta/EstadoPrecio.php b/app/src/Model/Venta/EstadoPrecio.php
new file mode 100644
index 0000000..815793f
--- /dev/null
+++ b/app/src/Model/Venta/EstadoPrecio.php
@@ -0,0 +1,21 @@
+ $this->precio->id,
+ 'tipo_estado_precio' => $this->tipoEstadoPrecio,
+ 'fecha' => $this->fecha->format('Y-m-d')
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/EstadoVenta.php b/app/src/Model/Venta/EstadoVenta.php
new file mode 100644
index 0000000..c0df977
--- /dev/null
+++ b/app/src/Model/Venta/EstadoVenta.php
@@ -0,0 +1,22 @@
+ $this->venta->id,
+ 'tipo_estado_venta' => $this->tipoEstadoVenta,
+ 'fecha' => $this->fecha->format('Y-m-d')
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/FormaPago.php b/app/src/Model/Venta/FormaPago.php
new file mode 100644
index 0000000..ee06f0d
--- /dev/null
+++ b/app/src/Model/Venta/FormaPago.php
@@ -0,0 +1,78 @@
+pie !== null) {
+ $sum += $this->pie->pagado($moneda);
+ if (isset($this->pie->reajuste) and $this->pie->reajuste !== null) {
+ $sum += $this->pie->reajuste->valor($moneda);
+ }
+ }
+ if ($this->escritura !== null) {
+ $sum += $this->escritura->pago->valor($moneda);
+ }
+ return $sum;
+ }
+ public function prometido(string $moneda = Pago::UF): float
+ {
+ $sum = 0;
+ if (isset($this->pie)) {
+ $sum += $this->pie->valor($moneda);
+ }
+ if (isset($this->escritura)) {
+ $sum += $this->escritura->pago->valor($moneda);
+ }
+ return $sum;
+ }
+ public function total(string $moneda = Pago::UF): float
+ {
+ $sum = $this->anticipo($moneda);
+ if (isset($this->bonoPie)) {
+ $sum += $this->bonoPie->pago->valor($moneda);
+ }
+ if (isset($this->subsidio)) {
+ $sum += $this->subsidio->ahorro->valor($moneda);
+ $sum += $this->subsidio->subsidio->valor($moneda);
+ }
+ if (isset($this->credito)) {
+ $sum += $this->credito->pago->valor($moneda);
+ }
+ return $sum;
+ }
+ public function ids(): array
+ {
+ return [
+ 'pie_id' => $this->pie?->id,
+ 'escritura_id' => $this->escritura?->id,
+ 'bono_pie_id' => $this->bonoPie?->id,
+ 'credito_id' => $this->credito?->id,
+ 'subsidio_id' => $this->subsidio?->id,
+ 'devolucion_id' => $this->devolucion?->id
+ ];
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'pie' => $this->pie ?? null,
+ 'escritura' => $this->escritura ?? null,
+ 'bono_pie' => $this->bonoPie ?? null,
+ 'subsidio' => $this->subsidio ?? null,
+ 'credito' => $this->credito ?? null,
+ 'devolucion' => $this->devolucion ?? null
+ ];
+ }
+}
diff --git a/app/src/Model/Venta/Pago.php b/app/src/Model/Venta/Pago.php
new file mode 100644
index 0000000..c983b22
--- /dev/null
+++ b/app/src/Model/Venta/Pago.php
@@ -0,0 +1,44 @@
+uf ?? ($this->uf > 0.0 ? $this->uf : 1);
+ return $this->valor / (($moneda === Pago::UF) ? $uf : 1);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'valor' => $this->valor,
+ 'banco' => $this->banco ?? '',
+ 'tipo_pago' => $this->tipoPago ?? '',
+ 'identificador' => $this->identificador ?? '',
+ 'fecha' => $this->fecha->format('Y-m-d H:i:s') ?? '',
+ 'uf' => $this->uf ?? 1,
+ 'pagador' => $this->pagador ?? '',
+ 'asociado' => $this->asociado ?? ''
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Pie.php b/app/src/Model/Venta/Pie.php
new file mode 100644
index 0000000..adb5862
--- /dev/null
+++ b/app/src/Model/Venta/Pie.php
@@ -0,0 +1,91 @@
+asociado !== null) {
+ return $this->asociado->cuotas($pagadas, $vigentes);
+ }
+ if (!$pagadas and !$vigentes) {
+ return $this->cuotasArray;
+ }
+ if ($pagadas) {
+ return array_filter($this->cuotasArray, function(Cuota $cuota) {
+ return in_array($cuota->pago->currentEstado->tipoEstadoPago->descripcion, ['depositado', 'abonado']);
+ });
+ }
+ return array_filter($this->cuotasArray, function(Cuota $cuota) {
+ return $cuota->pago->currentEstado->tipoEstadoPago->activo or $cuota->pago->currentEstado->tipoEstadoPago->descripcion === 'devuelto';
+ });
+ }
+
+ public function valor(string $moneda = Pago::UF): float
+ {
+ $proporcion = $this->proporcion();
+ if ($this->asociado !== null) {
+ return $this->asociado->valor($moneda) * $proporcion;
+ }
+ return array_reduce($this->cuotas(), function(float $sum, Cuota $cuota) use ($moneda) {
+ return $sum + $cuota->pago->valor($moneda);
+ }, 0) * $proporcion;
+ }
+ public function pagado(string $moneda = Pago::UF): float
+ {
+ $proporcion = $this->proporcion();
+ if ($this->asociado !== null) {
+ return $this->asociado->pagado($moneda) * $proporcion;
+ }
+
+ return array_reduce($this->cuotas(true), function(float $sum, Cuota $cuota) use ($moneda) {
+ return $sum + $cuota->pago->valor($moneda);
+ }, 0) * $proporcion;
+ }
+ protected function proporcion(): float
+ {
+ $proporcion = 1;
+ if (count($this->asociados()) > 0) {
+ $proporcion = $this->valor / ((($this->asociado) ? $this->asociado->valor : $this->valor) + array_reduce($this->asociados(), function(float $sum, Pie $pie) {
+ return $sum + $pie->valor;
+ }, 0));
+ }
+ return $proporcion;
+ }
+
+ public ?array $asociados;
+ public function asociados(): array
+ {
+ if ($this->asociado !== null) {
+ return $this->asociado->asociados();
+ }
+ if (!isset($this->asociados) or $this->asociados === []) {
+ $this->asociados = $this->runFactory('asociados');
+ }
+ return $this->asociados ?? [];
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'fecha' => $this->fecha->format('Y-m-d H:i:s'),
+ 'valor' => $this->valor,
+ 'uf' => $this->uf ?? 1,
+ 'cuotas' => $this->cuotas,
+ 'asociado' => $this->asociado ?? '',
+ 'reajuste' => $this->reajuste ?? ''
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Precio.php b/app/src/Model/Venta/Precio.php
new file mode 100644
index 0000000..0b2094e
--- /dev/null
+++ b/app/src/Model/Venta/Precio.php
@@ -0,0 +1,23 @@
+ $this->unidad,
+ 'valor' => $this->valor,
+ 'estado_precio' => $this->current ?? [],
+ 'estados' => $this->estados ?? null
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Propiedad.php b/app/src/Model/Venta/Propiedad.php
new file mode 100644
index 0000000..47e8094
--- /dev/null
+++ b/app/src/Model/Venta/Propiedad.php
@@ -0,0 +1,74 @@
+departamentos)) {
+ $this->departamentos = array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento';}));
+ }
+ return $this->departamentos;
+ }
+ protected array $estacionamientos;
+ public function estacionamientos(): array
+ {
+ if (!isset($this->estacionamientos)) {
+ $this->estacionamientos = array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'estacionamiento';}));
+ }
+ return $this->estacionamientos;
+ }
+ protected array $bodegas;
+ public function bodegas(): array
+ {
+ if (!isset($this->bodegas)) {
+ $this->bodegas = array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'bodega';}));
+ }
+ return $this->bodegas;
+ }
+
+ public function proyecto(): Model\Proyecto
+ {
+ return $this->unidades[0]->proyectoTipoUnidad->proyecto;
+ }
+
+ protected float $vendible;
+ public function vendible(): float
+ {
+ return array_reduce($this->departamentos(), function(float $sum, Unidad $unidad) {
+ return $sum + $unidad->proyectoTipoUnidad->vendible();
+ }, 0);
+ }
+
+ public function summary(): string
+ {
+ return implode(' - ', array_merge(
+ array_map(function(Unidad $unidad) {
+ return $unidad->descripcion;
+ }, $this->departamentos()),
+ array_map(function(Unidad $unidad) {
+ return "E{$unidad->descripcion}";
+ }, $this->estacionamientos()),
+ array_map(function(Unidad $unidad) {
+ return "B{$unidad->descripcion}";
+ }, $this->bodegas())
+ ));
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'unidades' => $this->unidades,
+ 'departamentos' => $this->departamentos(),
+ 'estacionamientos' => $this->estacionamientos(),
+ 'bodegas' => $this->bodegas(),
+ 'summary' => $this->summary()
+ ];
+ }
+}
diff --git a/app/src/Model/Venta/PropiedadUnidad.php b/app/src/Model/Venta/PropiedadUnidad.php
new file mode 100644
index 0000000..9545477
--- /dev/null
+++ b/app/src/Model/Venta/PropiedadUnidad.php
@@ -0,0 +1,18 @@
+ $this->pu_id,
+ 'propiedad_id' => $this->propiedad_id,
+ 'valor' => $this->valor
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Propietario.php b/app/src/Model/Venta/Propietario.php
new file mode 100644
index 0000000..77300eb
--- /dev/null
+++ b/app/src/Model/Venta/Propietario.php
@@ -0,0 +1,46 @@
+rut, 0, ',', '.'),
+ $this->dv
+ ]);
+ }
+ public function nombreCompleto(): string
+ {
+ return implode(' ', [
+ $this->nombres,
+ implode(' ', $this->apellidos)
+ ]);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge([
+ 'rut' => $this->rut,
+ 'dv' => $this->dv,
+ 'rut_formateado' => $this->rut(),
+ 'nombres' => $this->nombres,
+ 'apellidos' => $this->apellidos,
+ 'nombre_completo' => $this->nombreCompleto(),
+ ], $this->datos->jsonSerialize(), [
+ 'representante' => $this->representante ?? '',
+ 'otro' => $this->otro ?? ''
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Subsidio.php b/app/src/Model/Venta/Subsidio.php
new file mode 100644
index 0000000..3fc384b
--- /dev/null
+++ b/app/src/Model/Venta/Subsidio.php
@@ -0,0 +1,18 @@
+ $this->ahorro,
+ 'subsidio' => $this->subsidio
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/TipoEstadoCierre.php b/app/src/Model/Venta/TipoEstadoCierre.php
new file mode 100644
index 0000000..58a6d5b
--- /dev/null
+++ b/app/src/Model/Venta/TipoEstadoCierre.php
@@ -0,0 +1,16 @@
+ $this->vigente
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/TipoEstadoPago.php b/app/src/Model/Venta/TipoEstadoPago.php
new file mode 100644
index 0000000..0281c65
--- /dev/null
+++ b/app/src/Model/Venta/TipoEstadoPago.php
@@ -0,0 +1,16 @@
+ $this->activo
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/TipoEstadoPrecio.php b/app/src/Model/Venta/TipoEstadoPrecio.php
new file mode 100644
index 0000000..bf9b008
--- /dev/null
+++ b/app/src/Model/Venta/TipoEstadoPrecio.php
@@ -0,0 +1,7 @@
+ $this->activa
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/TipoPago.php b/app/src/Model/Venta/TipoPago.php
new file mode 100644
index 0000000..186e5f8
--- /dev/null
+++ b/app/src/Model/Venta/TipoPago.php
@@ -0,0 +1,8 @@
+currentPrecio !== null and $dateTime > $this->currentPrecio->current->fecha) {
+ return $this->currentPrecio;
+ }
+ $precio = array_reduce(array_filter($this->precios, function(Precio $precio) use ($dateTime) {
+ return $dateTime > $precio->current->fecha;
+ }), function(?Precio $max, Precio $precio) {
+ if ($max === null) {
+ return $precio;
+ }
+ return $max->current->fecha > $precio->current->fecha ? $max : $precio;
+ });
+ if ($precio === null) {
+ $precio = array_reduce(array_filter($this->precios, function(Precio $precio) use ($dateTime) {
+ return $dateTime < $precio->current->fecha;
+ }), function(?Precio $min, Precio $precio) {
+ if ($min === null) {
+ return $precio;
+ }
+ return $min->current->fecha < $precio->current->fecha ? $min : $precio;
+ });
+ }
+
+ return $precio;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ $output = array_merge(parent::jsonSerialize(), [
+ 'subtipo' => $this->subtipo,
+ 'piso' => $this->piso,
+ 'descripcion' => $this->descripcion,
+ 'orientacion' => $this->orientacion,
+ 'proyecto_tipo_unidad' => $this->proyectoTipoUnidad,
+ 'prorrateo' => $this->prorrateo
+ ]);
+ if (isset($this->precios)) {
+ $output['precios'] = $this->precios;
+ $output['current_precio'] = $this->currentPrecio;
+ }
+ return $output;
+ }
+}
diff --git a/app/src/Model/Venta/ValorCierre.php b/app/src/Model/Venta/ValorCierre.php
new file mode 100644
index 0000000..023f1cc
--- /dev/null
+++ b/app/src/Model/Venta/ValorCierre.php
@@ -0,0 +1,20 @@
+ $this->cierre->id,
+ 'tipo_valor_cierre' => $this->tipoValorCierre,
+ 'valor' => $this->valor
+ ]);
+ }
+}
diff --git a/app/src/Repository/Banco.php b/app/src/Repository/Banco.php
new file mode 100644
index 0000000..00afc45
--- /dev/null
+++ b/app/src/Repository/Banco.php
@@ -0,0 +1,34 @@
+setTable('banco');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['nombre']);
+ return $this->parseData(new Model\Banco(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['nombre'],
+ [$model->nombre]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['nombre'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Cartola.php b/app/src/Repository/Cartola.php
new file mode 100644
index 0000000..23e9cc1
--- /dev/null
+++ b/app/src/Repository/Cartola.php
@@ -0,0 +1,68 @@
+setTable('cartolas');
+ }
+
+ public function create(?array $data = null): Model\Cartola
+ {
+ $map = (new Implement\Repository\MapperParser(['cargos', 'abonos', 'saldo']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('cuenta_id', (new Implement\Repository\Mapper())
+ ->setProperty('cuenta')
+ ->setFunction(function($data) {
+ return $this->cuentaRepository->fetchById($data['cuenta_id']);
+ }));
+ return $this->parseData(new Model\Cartola(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Cartola
+ {
+ $model->id = $this->saveNew([
+ 'cuenta_id',
+ 'fecha',
+ 'cargos',
+ 'abonos',
+ 'saldo'
+ ], [
+ $model->cuenta->id,
+ $model->fecha->format('Y-m-d'),
+ $model->cargos,
+ $model->abonos,
+ $model->saldo
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Cartola
+ {
+ return $this->update($model, ['cuenta_id', 'fecha', 'cargos', 'abonos', 'saldo'], $new_data);
+ }
+
+ public function fetchByFecha(DateTimeInterface $fecha): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('fecha = ?');
+ return $this->fetchMany($query, [$fecha->format('Y-m-d')]);
+ }
+ public function fetchByCuentaAndFecha(int $cuenta_id, DateTimeInterface $fecha): Model\Cartola
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ? AND fecha = ?');
+ return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d')]);
+ }
+}
diff --git a/app/src/Repository/CategoriaCentro.php b/app/src/Repository/CategoriaCentro.php
new file mode 100644
index 0000000..4ed43de
--- /dev/null
+++ b/app/src/Repository/CategoriaCentro.php
@@ -0,0 +1,19 @@
+setTable('categorias_centros_costos');
+ }
+
+ protected function getBlank(): Define\Model
+ {
+ return new Model\CategoriaCentro();
+ }
+}
diff --git a/app/src/Repository/CentroCosto.php b/app/src/Repository/CentroCosto.php
new file mode 100644
index 0000000..dbd41fb
--- /dev/null
+++ b/app/src/Repository/CentroCosto.php
@@ -0,0 +1,81 @@
+setTable('centros_costos');
+ }
+
+ public function create(?array $data = null): Model\CentroCosto
+ {
+ $map = (new MapperParser(['descripcion']))
+ ->register('tipo_centro_id', (new Mapper())
+ ->setProperty('tipoCentro')
+ ->setFunction(function(array $data) {
+ return $this->tipoCentroRepository->fetchById($data['tipo_centro_id']);
+ }))
+ ->register('categoria_id', (new Mapper())
+ ->setProperty('categoria')
+ ->setFunction(function(array $data) {
+ return $this->categoriaCentroRepository->fetchById($data['categoria_id']);
+ }))
+ ->register('tipo_cuenta_id', (new Mapper())
+ ->setProperty('tipoCuenta')
+ ->setFunction(function(array $data) {
+ return $this->tipoCuentaRepository->fetchById($data['tipo_cuenta_id']);
+ })
+ ->setDefault(null))
+ ->register('cuenta_contable', (new Mapper())
+ ->setProperty('cuentaContable'));
+ return $this->parseData(new Model\CentroCosto(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\CentroCosto
+ {
+ $this->saveNew(
+ ['id', 'tipo_centro_id', 'categoria_id', 'tipo_cuenta_id', 'cuenta_contable', 'descripcion'],
+ [$model->id, $model->tipoCentro->id, $model->categoria->id, $model->tipoCuenta?->id, $model->cuentaContable, $model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\CentroCosto
+ {
+ return $this->update($model, ['tipo_centro_id', 'categoria_id', 'tipo_cuenta_id', 'cuenta_contable', 'descripcion'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Model\CentroCosto
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('descripcion LIKE ?');
+ return $this->fetchOne($query, [$descripcion]);
+ }
+ public function fetchByTipoCuenta(string $tipo_cuenta): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('tipo_cuenta_id LIKE ?');
+ return $this->fetchMany($query, [$tipo_cuenta]);
+ }
+ public function fetchByCategoria(string $categoria): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('categoria_id LIKE ?');
+ return $this->fetchMany($query, [$categoria]);
+ }
+}
diff --git a/app/src/Repository/Comuna.php b/app/src/Repository/Comuna.php
new file mode 100644
index 0000000..c7567ec
--- /dev/null
+++ b/app/src/Repository/Comuna.php
@@ -0,0 +1,56 @@
+setTable('comuna');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']))
+ ->register('provincia', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $this->provinciaRepository->fetchById($data['provincia']);
+ }));
+ return $this->parseData(new Model\Comuna(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'provincia'],
+ [$model->descripcion, $model->provincia->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'provincia'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+ public function fetchByProvincia(int $provincia_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `provincia` = ?";
+ return $this->fetchMany($query, [$provincia_id]);
+ }
+ public function fetchByDireccion(string $direccion): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN `direccion` ON `direccion`.`comuna` = a.`id`
+WHERE TRIM(CONCAT_WS(' ', `direccion`.`calle`, `direccion`.`numero`, `direccion`.`extra`)) LIKE ?";
+ return $this->fetchMany($query, ["%{$direccion}%"]);
+ }
+}
diff --git a/app/src/Repository/Deposito.php b/app/src/Repository/Deposito.php
new file mode 100644
index 0000000..b006403
--- /dev/null
+++ b/app/src/Repository/Deposito.php
@@ -0,0 +1,64 @@
+setTable('depositos');
+ }
+
+ public function create(?array $data = null): Model\Deposito
+ {
+ $map = (new Implement\Repository\MapperParser(['id', 'capital', 'futuro']))
+ ->register('cuenta_id', (new Implement\Repository\Mapper())
+ ->setProperty('cuenta')
+ ->setFunction(function(array $data) {
+ return $this->cuentaRepository->fetchById($data['cuenta_id']);
+ }))
+ ->register('inicio', new Implement\Repository\Mapper\DateTime('inicio'))
+ ->register('termino', new Implement\Repository\Mapper\DateTime('termino'));
+ return $this->parseData(new Model\Deposito(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Deposito
+ {
+ $this->saveNew([
+ 'id', 'cuenta_id', 'capital', 'futuro', 'inicio', 'termino'
+ ], [
+ $model->id, $model->cuenta->id, $model->capital, $model->futuro,
+ $model->inicio->format('Y-m-d'), $model->termino->format('Y-m-d')
+ ]);
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Model\Deposito
+ {
+ return $this->update($model, ['cuenta_id', 'capital', 'futuro', 'inicio', 'termino'], $new_data);
+ }
+
+ public function fetchByCuenta(int $cuenta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ?');
+ return $this->fetchMany($query, [$cuenta_id]);
+ }
+ public function fetchAllActive(): array
+ {
+ $fecha = new DateTimeImmutable();
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inicio <= ? AND termino >= ?');
+ return $this->fetchMany($query, [$fecha->format('Y-m-d'), $fecha->format('Y-m-d')]);
+ }
+}
diff --git a/app/src/Repository/Direccion.php b/app/src/Repository/Direccion.php
new file mode 100644
index 0000000..e2396b4
--- /dev/null
+++ b/app/src/Repository/Direccion.php
@@ -0,0 +1,48 @@
+setTable('direccion');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['calle', 'numero', 'extra']))
+ ->register('comuna', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $this->comunaRepository->fetchById($data['comuna']);
+ }));
+ return $this->parseData(new Model\Direccion(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['calle', 'numero', 'extra', 'comuna'],
+ [$model->calle, $model->numero, $model->extra, $model->comuna->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['calle', 'numero', 'extra', 'comuna'], $new_data);
+ }
+
+ public function fetchByCalleAndNumero(string $calle, int $numero): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `calle` = ? AND `numero` = ?";
+ return $this->fetchMany($query, [$calle, $numero]);
+ }
+ public function fetchByCalleAndNumeroAndExtra(string $calle, int $numero, string $extra): Model\Direccion
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `calle` = ? AND `numero` = ? AND `extra` = ?";
+ return $this->fetchOne($query, [$calle, $numero, $extra]);
+ }
+}
diff --git a/app/src/Repository/Inmobiliaria.php b/app/src/Repository/Inmobiliaria.php
new file mode 100644
index 0000000..decedf3
--- /dev/null
+++ b/app/src/Repository/Inmobiliaria.php
@@ -0,0 +1,65 @@
+setTable('inmobiliaria');
+ }
+
+ protected function getKey(): string
+ {
+ return 'rut';
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['dv', 'razon', 'abreviacion', 'cuenta']))
+ ->register('banco', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->bancoRepository->fetchById($data['banco']);
+ }))
+ ->register('sociedad', (new Implement\Repository\Mapper())
+ ->setProperty('tipoSociedad')
+ ->setFunction(function($data) {
+ return $this->tipoSociedadRepository->fetchById($data['sociedad']);
+ }));
+ return $this->parseData(new Model\Inmobiliaria(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->rut = $this->saveNew(
+ ['dv', 'razon', 'abreviacion', 'cuenta', 'banco', 'sociedad'],
+ [$model->dv, $model->razon, $model->abreviacion, $model->cuenta, $model->banco->id, $model->tipoSociedad->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['dv', 'razon', 'abreviacion', 'cuenta', 'banco', 'sociedad'], $new_data);
+ }
+
+ public function fetchAllActive(null|string|array $sorting = null): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN proyecto ON a.rut = proyecto.inmobiliaria')
+ ->joined('JOIN (SELECT ep1.* FROM estado_proyecto ep1 JOIN (SELECT MAX(id) AS id, proyecto FROM estado_proyecto GROUP BY proyecto) ep0 ON ep0.id = ep1.id) ep ON ep.proyecto = proyecto.id')
+ ->joined('JOIN tipo_estado_proyecto tep ON tep.id = ep.estado')
+ ->joined('JOIN etapa_proyecto ON etapa_proyecto.id = tep.etapa')
+ ->where('etapa_proyecto.orden BETWEEN ? AND ?');
+ if ($sorting !== null) {
+ $query->order($sorting);
+ }
+ return $this->fetchMany($query, [1, 8]);
+ }
+}
diff --git a/app/src/Repository/Inmobiliaria/Cuenta.php b/app/src/Repository/Inmobiliaria/Cuenta.php
new file mode 100644
index 0000000..5005723
--- /dev/null
+++ b/app/src/Repository/Inmobiliaria/Cuenta.php
@@ -0,0 +1,61 @@
+setTable('cuenta');
+ }
+
+ public function create(?array $data = null): Model\Inmobiliaria\Cuenta
+ {
+ $map = (new Implement\Repository\MapperParser(['cuenta']))
+ ->register('inmobiliaria', (new Implement\Repository\Mapper())
+ ->setFunction(function(array $data) {
+ return $this->inmobiliariaRepository->fetchById($data['inmobiliaria']);
+ }))
+ ->register('banco', (new Implement\Repository\Mapper())
+ ->setFunction(function(array $data) {
+ return $this->bancoRepository->fetchById($data['banco']);
+ }));
+ return $this->parseData(new Model\Inmobiliaria\Cuenta(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Inmobiliaria\Cuenta
+ {
+ $model->id = $this->saveNew(['inmobiliaria', 'banco', 'cuenta'],
+ [$model->inmobiliaria->rut, $model->banco->id, $model->cuenta]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Inmobiliaria\Cuenta
+ {
+ return $this->update($model, ['inmobiliaria', 'banco', 'cuenta'], $new_data);
+ }
+
+ public function fetchByInmobiliaria(int $inmobiliaria_rut): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria = ?');
+ return $this->fetchMany($query, [$inmobiliaria_rut]);
+ }
+ public function fetchByInmobiliariaAndBanco(int $inmobiliaria_rut, int $banco_id): Model\Inmobiliaria\Cuenta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria = ? AND banco = ?');
+ return $this->fetchOne($query, [$inmobiliaria_rut, $banco_id]);
+ }
+}
diff --git a/app/src/Repository/Inmobiliaria/TipoSociedad.php b/app/src/Repository/Inmobiliaria/TipoSociedad.php
new file mode 100644
index 0000000..7fa573d
--- /dev/null
+++ b/app/src/Repository/Inmobiliaria/TipoSociedad.php
@@ -0,0 +1,34 @@
+setTable('tipo_sociedad');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion', 'abreviacion']));
+ return $this->parseData(new Model\Inmobiliaria\TipoSociedad(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'abreviacion'],
+ [$model->descripcion, $model->abreviacion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'abreviacion'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Login.php b/app/src/Repository/Login.php
new file mode 100644
index 0000000..e9e872b
--- /dev/null
+++ b/app/src/Repository/Login.php
@@ -0,0 +1,65 @@
+setTable('logins');
+ }
+
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['selector', 'token']))
+ ->register('user_id', (new Implement\Repository\Mapper())
+ ->setProperty('user')
+ ->setFunction(function($data) {
+ return $this->userRepository->fetchById($data['user_id']);
+ }))
+ ->register('time', new Implement\Repository\Mapper\DateTime('time', 'dateTime'))
+ ->register('status', new Implement\Repository\Mapper\Boolean('status'));
+ return $this->parseData(new Model\Login(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['user_id', 'selector', 'token', 'time', 'status'],
+ [$model->user->id, $model->selector, $model->token, $model->dateTime->format('Y-m-d H:i:s'), $model->status ? 1 : 0]);
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['user_id', 'selector', 'token', 'time', 'status'], $new_data);
+ }
+
+ public function fetchByUser(int $user_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `user_id` = ?";
+ return $this->fetchMany($query, [$user_id]);
+ }
+ public function fetchActiveByUser(int $user_id): Model\Login
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `user_id` = ? AND `status` = 1";
+ return $this->fetchOne($query, [$user_id]);
+ }
+ public function fetchBySelectorAndToken(string $selector, string $token): Model\Login
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `selector` = ? AND `token` = ?";
+ return $this->fetchOne($query, [$selector, $token]);
+ }
+ public function fetchActiveBySelector(string $selector): Model\Login
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `selector` = ? AND `status` = 1";
+ return $this->fetchOne($query, [$selector]);
+ }
+}
diff --git a/app/src/Repository/Menu.php b/app/src/Repository/Menu.php
new file mode 100644
index 0000000..c709285
--- /dev/null
+++ b/app/src/Repository/Menu.php
@@ -0,0 +1,62 @@
+setTable('menus');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['title']))
+ ->register('url', (new Implement\Repository\Mapper())
+ ->setDefault(''));
+ $model = $this->parseData(new Model\Menu(), $data, $map);
+ $model->children = $this->fetchChildren($model->id);
+ return $model;
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['title', 'url'],
+ [$model->title, $model->url]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['title', 'url'], $new_data);
+ }
+
+ public function fetchByUser(int $user_id): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN `menu_permissions` mp ON mp.`menu_id` = a.`id`
+ JOIN `permissions` ON `permissions`.`id` = mp.`permission_id`
+ LEFT JOIN `users` u1 ON u1.`id` = `permissions`.`'ext_id` AND `permissions`.`type` = 2
+ LEFT JOIN (SELECT u2.* FROM `roles` ON `roles`.`id` = `permissions`.`ext_id` AND `permissions`.`type` = 1
+ JOIN `user_roles` ur ON ur.`role` = `role`.`id`
+ JOIN `users` u2 ON u2.`id` = ur.`user`) us
+ LEFT JOIN `menu_relations` mr ON mr.`child_id` = a.`id`
+WHERE u1.`id` = ? OR us.`id` = ? AND mr.`id` IS NULL";
+ return $this->fetchMany($query, [$user_id, $user_id]);
+ }
+ public function fetchChildren(int $menu_id): array
+ {
+ $query = "SELECT sm.* FROM `menu_relations` mr WHERE mr.`parent_id` = ?";
+ try {
+ return $this->fetchMany($query, [$menu_id]);
+ } catch (Implement\Exception\EmptyResult) {
+ return [];
+ }
+ }
+}
diff --git a/app/src/Repository/Movimiento.php b/app/src/Repository/Movimiento.php
new file mode 100644
index 0000000..48a715c
--- /dev/null
+++ b/app/src/Repository/Movimiento.php
@@ -0,0 +1,72 @@
+setTable('movimientos');
+ }
+
+ public function create(?array $data = null): Model\Movimiento
+ {
+ $map = (new Implement\Repository\MapperParser(['cargo', 'abono', 'saldo', 'glosa', 'documento']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('cuenta_id', (new Implement\Repository\Mapper())
+ ->setProperty('cuenta')
+ ->setFunction(function($data) {
+ return $this->cuentaRepository->fetchById($data['cuenta_id']);
+ })
+ );
+ return $this->parseData(new Model\Movimiento(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Movimiento
+ {
+ $model->id = $this->saveNew([
+ 'cuenta_id',
+ 'fecha',
+ 'glosa',
+ 'documento',
+ 'cargo',
+ 'abono',
+ 'saldo'
+ ], [
+ $model->cuenta->id,
+ $model->fecha->format('Y-m-d'),
+ $model->glosa,
+ $model->documento,
+ $model->cargo,
+ $model->abono,
+ $model->saldo
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Movimiento
+ {
+ return $this->update($model, ['cuenta_id', 'fecha', 'glosa', 'documento', 'cargo', 'abono', 'saldo'], $new_data);
+ }
+
+ public function fetchByCuentaAndFecha(int $cuenta_id, DateTimeInterface $fecha): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ? AND fecha = ?');
+ return $this->fetchMany($query, [$cuenta_id, $fecha->format('Y-m-d')]);
+ }
+ public function fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo(int $cuenta_id, DateTimeInterface $fecha, int $cargo, int $abono, int $saldo): Model\Movimiento
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('cuenta_id = ? AND fecha = ? AND cargo = ? AND abono = ? AND saldo = ?');
+ return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d'), $cargo, $abono, $saldo]);
+ }
+}
diff --git a/app/src/Repository/Movimiento/Detalle.php b/app/src/Repository/Movimiento/Detalle.php
new file mode 100644
index 0000000..cdeed75
--- /dev/null
+++ b/app/src/Repository/Movimiento/Detalle.php
@@ -0,0 +1,60 @@
+setTable('movimientos_detalles');
+ }
+
+ public function create(?array $data = null): Model\Movimiento\Detalle
+ {
+ $map = (new Implement\Repository\MapperParser(['detalle']))
+ ->register('movimiento_id', (new Implement\Repository\Mapper())
+ ->setProperty('movimiento')
+ ->setFunction(function(array $data) {
+ return $this->movimientoRepository->fetchById($data['movimiento_id']);
+ }))
+ ->register('centro_costo_id', (new Implement\Repository\Mapper())
+ ->setProperty('centroCosto')
+ ->setFunction(function(array $data) {
+ return $this->centroCostoRepository->fetchById($data['centro_costo_id']);
+ }));
+ return $this->parseData(new Model\Movimiento\Detalle(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Movimiento\Detalle
+ {
+ $this->saveNew(
+ ['movimiento_id', 'centro_costo_id', 'detalle'],
+ [$model->movimiento->id, $model->centroCosto->id, $model->detalle]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Movimiento\Detalle
+ {
+ return $this->update($model, ['movimiento_id', 'centro_costo_id', 'detalle'], $new_data);
+ }
+
+ public function fetchByMovimiento(int $movimiento_id): Model\Movimiento\Detalle
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('movimiento_id = ?');
+ return $this->fetchOne($query, [$movimiento_id]);
+ }
+
+ protected function getKey(): string
+ {
+ return 'movimiento_id';
+ }
+}
diff --git a/app/src/Repository/Nubox.php b/app/src/Repository/Nubox.php
new file mode 100644
index 0000000..3f91268
--- /dev/null
+++ b/app/src/Repository/Nubox.php
@@ -0,0 +1,55 @@
+setTable('inmobiliarias_nubox');
+ }
+
+ public function create(?array $data = null): Model\Nubox
+ {
+ $map = (new Implement\Repository\MapperParser(['usuario', 'alias']))
+ ->register('inmobiliaria_rut', (new Implement\Repository\Mapper())
+ ->setProperty('inmobiliaria')
+ ->setFunction(function(array $data) {
+ return $this->inmobiliariaRepository->fetchById($data['inmobiliaria_rut']);
+ }))
+ ->register('contraseña', (new Implement\Repository\Mapper())
+ ->setProperty('password'));
+ return $this->parseData(new Model\Nubox(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Nubox
+ {
+ $this->saveNew(
+ ['inmobiliaria_rut', 'alias', 'usuario', 'contraseña'],
+ [$model->inmobiliaria->rut, $model->alias, $model->usuario, $model->password]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Nubox
+ {
+ return $this->update($model, ['inmobiliaria_rut', 'alias', 'usuario', 'contraseña'], $new_data);
+ }
+
+ public function fetchByInmobiliaria(int $inmobiliaria_rut): Model\Nubox
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria_rut = ?');
+ return $this->fetchOne($query, [$inmobiliaria_rut]);
+ }
+
+ protected function getKey(): string
+ {
+ return 'inmobiliaria_rut';
+ }
+}
diff --git a/app/src/Repository/PagoCentroCosto.php b/app/src/Repository/PagoCentroCosto.php
new file mode 100644
index 0000000..0e2e046
--- /dev/null
+++ b/app/src/Repository/PagoCentroCosto.php
@@ -0,0 +1,42 @@
+setTable('pagos_centros_costos');
+ }
+
+ public function create(?array $data = null): Model\PagoCentroCosto
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('pago_id', (new Implement\Repository\Mapper())
+ ->setProperty('pago')
+ ->setFunction(function(array $data) {
+ return $this->pagoRepository->fetchById($data['pago_id']);
+ }))
+ ->register('centro_costo_id', (new Implement\Repository\Mapper())
+ ->setProperty('centroCosto')
+ ->setFunction(function(array $data) {
+ return $this->centroCostoRepository->fetchById($data['centro_costo_id']);
+ }));
+ return $this->parseData(new Model\PagoCentroCosto(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\PagoCentroCosto
+ {
+ $model->id = $this->saveNew(['pago_id', 'centro_costo_id'], [$model->pago->id, $model->centroCosto->id]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\PagoCentroCosto
+ {
+ return $this->update($model, ['pago_id', 'centro_costo_id'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Permission.php b/app/src/Repository/Permission.php
new file mode 100644
index 0000000..9fc501e
--- /dev/null
+++ b/app/src/Repository/Permission.php
@@ -0,0 +1,15 @@
+setTable('permissions');
+ }
+}
diff --git a/app/src/Repository/Provincia.php b/app/src/Repository/Provincia.php
new file mode 100644
index 0000000..7f95a77
--- /dev/null
+++ b/app/src/Repository/Provincia.php
@@ -0,0 +1,49 @@
+setTable('provincia');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']))
+ ->register('region', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->regionRepository->fetchById($data['region']);
+ }));
+ return $this->parseData(new Model\Provincia(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'region'],
+ [$model->descripcion, $model->region->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'region'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $description): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$description]);
+ }
+ public function fetchByRegion(int $region_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `region` = ?";
+ return $this->fetchMany($query, [$region_id]);
+ }
+}
diff --git a/app/src/Repository/Proyecto.php b/app/src/Repository/Proyecto.php
new file mode 100644
index 0000000..561868c
--- /dev/null
+++ b/app/src/Repository/Proyecto.php
@@ -0,0 +1,201 @@
+setTable('proyecto');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion', 'corredor', 'pisos', 'subterraneos']))
+ ->register('inmobiliaria', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->inmobiliariaRepository, 'fetchById'])
+ ->setArgs([$data['inmobiliaria']])))
+ ->register('direccion', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->direccionRepository, 'fetchById'])
+ ->setArgs([$data['direccion']])))
+ ->register('superficie_terreno', (new Implement\Repository\Mapper())
+ ->setProperty('terreno')
+ ->setFunction(function($data) {
+ $terreno = new Model\Proyecto\Terreno();
+ $terreno->superficie = $data['superficie_terreno'];
+ $terreno->valorUnitario = $data['valor_unitario_terreno'] ?? 0;
+ $terreno->valor = 0;
+ $terreno->fecha = null;
+ if (isset($data['fecha_terreno']) and $data['fecha_terreno'] !== '') {
+ $terreno->valor = $data['valor_terreno'];
+ $terreno->fecha = new DateTimeImmutable($data['fecha_terreno']);
+ }
+ return $terreno;
+ }))
+ ->register('superficie_sobre_nivel', (new Implement\Repository\Mapper())
+ ->setProperty('superficie')
+ ->setFunction(function($data) {
+ $superficie = new Model\Proyecto\Superficie();
+ $superficie->sobre_nivel = $data['superficie_sobre_nivel'];
+ $superficie->bajo_nivel = $data['superficie_bajo_nivel'];
+ return $superficie;
+ }));
+ return $this->parseData(new Model\Proyecto(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['inmobiliaria', 'descripcion', 'direccion', 'superficie_terreno', 'valor_terreno', 'corredor',
+ 'superficie_sobre_nivel', 'superficie_bajo_nivel', 'pisos', 'subterraneos'],
+ [$model->inmobiliaria()->rut, $model->descripcion, $model->direccion()->id, $model->terreno->superficie,
+ $model->terreno->valorUnitario, $model->corredor, $model->superficie->sobre_nivel,
+ $model->superficie->bajo_nivel, $model->pisos, $model->subterraneos]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['inmobiliaria', 'descripcion', 'direccion', 'superficie_terreno',
+ 'valor_terreno', 'corredor', 'superficie_sobre_nivel', 'superficie_bajo_nivel', 'pisos',
+ 'subterraneos'], $new_data);
+ }
+
+ public function fetchById(int $id): Model\Proyecto
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select($this->columns())
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinTerreno())
+ ->where("a.id = ?");
+ return $this->fetchOne($query, [$id]);
+ }
+
+ public function fetchByName(string $name): Model\Proyecto
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select($this->columns())
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinTerreno())
+ ->where("a.descripcion LIKE ?");
+ return $this->fetchOne($query, ["%{$name}%"]);
+ }
+ public function fetchAllActive(): array
+ {
+ $etapaProyecto = $this->etapaRepository->fetchByDescripcion('Proyecto');
+ $etapaTerminado = $this->etapaRepository->fetchByDescripcion('Terminado');
+ $query = $this->connection->getQueryBuilder()
+ ->select($this->columns())
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinTerreno())
+ ->joined($this->joinEstado())
+ ->where("et.orden BETWEEN {$etapaProyecto->orden} AND ({$etapaTerminado->orden} - 1)")
+ ->order('a.descripcion');
+ return $this->fetchMany($query);
+ }
+ public function fetchAllEscriturando(): array
+ {
+ $etapaRecepcion = $this->etapaRepository->fetchByDescripcion('Recepción');
+ $etapaTerminado = $this->etapaRepository->fetchByDescripcion('Terminado');
+ $query = $this->connection->getQueryBuilder()
+ ->select($this->columns())
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinTerreno())
+ ->joined($this->joinEstado())
+ ->where("et.orden BETWEEN {$etapaRecepcion->orden} AND ({$etapaTerminado->orden} - 1)")
+ ->order('a.descripcion');
+ return $this->fetchMany($query);
+ }
+ public function editTerreno(Model\Proyecto $proyecto, array $data): Model\Proyecto
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ try {
+ $query = $this->connection->getQueryBuilder()
+ ->select('valor')
+ ->from('proyecto_terreno')
+ ->where('proyecto_id = ? AND fecha = ?');
+ $result = $this->connection->execute($query, [$proyecto->id, $fecha->format('Y-m-d')])->fetch(PDO::FETCH_ASSOC);
+ if ($result === false) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ if ($result['valor'] !== $data['valor']) {
+ $query = $this->connection->getQueryBuilder()
+ ->update('proyecto_terreno')
+ ->set('valor = ?')
+ ->where('proyecto_id = ? AND fecha = ?');
+ $this->connection->execute($query, [$data['valor'], $proyecto->id, $fecha->format('Y-m-d')]);
+ $proyecto->terreno->valor = $data['valor'];
+ }
+ } catch (PDOException | Implement\Exception\EmptyResult) {
+ $query = $this->connection->getQueryBuilder()
+ ->insert()
+ ->into('proyecto_terreno')
+ ->columns(['proyecto_id', 'fecha', 'valor', 'tipo_moneda_id'])
+ ->values(['?', '?', '?', '1']);
+ try {
+ $this->connection->execute($query, [$proyecto->id, $fecha->format('Y-m-d'), $data['valor']]);
+ $proyecto->terreno->fecha = $fecha;
+ $proyecto->terreno->valor = $data['valor'];
+ } catch (PDOException $exception) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ }
+ return $proyecto;
+ }
+ public function fetchByInmobiliaria(int $inmobiliaria_rut): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria = ?');
+ return $this->fetchMany($query, [$inmobiliaria_rut]);
+ }
+ /*public function fetchSuperficieVendido(int $proyecto_id): float
+ {
+
+ }*/
+
+ protected function columns(): string
+ {
+ return "a.id, a.inmobiliaria, a.descripcion, a.direccion, a.superficie_terreno, valor_terreno AS valor_unitario_terreno,
+ COALESCE(pt.valor, '') AS valor_terreno, COALESCE(pt.fecha, '') AS fecha_terreno, a.corredor,
+ a.superficie_sobre_nivel, a.superficie_bajo_nivel, a.pisos, a.subterraneos";
+ }
+ protected function joinTerreno(): string
+ {
+ return "LEFT OUTER JOIN (SELECT pt1.* FROM proyecto_terreno pt1 JOIN (SELECT MAX(id) AS id, proyecto_id FROM proyecto_terreno GROUP BY proyecto_id) pt0 ON pt0.id = pt1.id) pt ON pt.proyecto_id = a.id";
+ }
+ protected function joinEstado(): string
+ {
+ return "JOIN (
+ SELECT e2.*
+ FROM `estado_proyecto` e2
+ JOIN (
+ SELECT MAX(e1.`id`) AS 'id', e1.`proyecto`
+ FROM `estado_proyecto` e1
+ JOIN (
+ SELECT `id`, `proyecto`, MAX(`fecha`) as 'fecha'
+ FROM `estado_proyecto`
+ GROUP BY `proyecto`, `fecha`
+ ) e0 ON e1.`id` = e0.`id`
+ GROUP BY `proyecto`
+ ) e01 ON e01.`id` = e2.`id`
+ ) ep ON ep.`proyecto` = a.`id`
+ JOIN `tipo_estado_proyecto` tep ON tep.`id` = ep.`estado`
+ JOIN `etapa_proyecto` et ON et.`id` = tep.`etapa`";
+ }
+}
diff --git a/app/src/Repository/Proyecto/Elemento.php b/app/src/Repository/Proyecto/Elemento.php
new file mode 100644
index 0000000..5da5e99
--- /dev/null
+++ b/app/src/Repository/Proyecto/Elemento.php
@@ -0,0 +1,34 @@
+setTable('tipo_elemento');
+ }
+
+ public function create(?array $data = null): Model\Proyecto\Elemento
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion', 'abreviacion', 'orden']);
+ return $this->parseData(new Model\Proyecto\Elemento(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Proyecto\Elemento
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'abreviacion', 'orden'],
+ [$model->descripcion, $model->abreviacion, $model->orden]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Proyecto\Elemento
+ {
+ return $this->update($model, ['descripcion', 'abreviacion', 'orden'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Proyecto/EstadoProyecto.php b/app/src/Repository/Proyecto/EstadoProyecto.php
new file mode 100644
index 0000000..ff6ece5
--- /dev/null
+++ b/app/src/Repository/Proyecto/EstadoProyecto.php
@@ -0,0 +1,81 @@
+setTable('estado_proyecto');
+ }
+
+ public function create(?array $data = null): Model\Proyecto\EstadoProyecto
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('proyecto', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->proyectoRepository, 'fetchById'])
+ ->setArgs([$data['proyecto']])))
+ ->register('estado', (new Implement\Repository\Mapper())
+ ->setProperty('tipoEstadoProyecto')
+ ->setFunction(function($data) {
+ return $this->tipoEstadoProyectoRepository->fetchById($data['estado']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ;
+ return $this->parseData(new Model\Proyecto\EstadoProyecto(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Proyecto\EstadoProyecto
+ {
+ $model->id = $this->saveNew(['proyecto', 'estado', 'fecha'], [
+ $model->proyecto()->id,
+ $model->tipoEstadoProyecto()->id,
+ $model->fecha->format('Y-m-d')
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Proyecto\EstadoProyecto
+ {
+ return $this->update($model, ['proyecto', 'estado', 'fecha'], $new_data);
+ }
+
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `proyecto` = ?";
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchCurrentByProyecto(int $proyecto_id): Model\Proyecto\EstadoProyecto
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT MAX(`id`) AS 'id', `proyecto` FROM `{$this->getTable()}` GROUP BY `proyecto`) e0 ON e0.`id` = a.`id`
+WHERE a.`proyecto` = ?";
+ return $this->fetchOne($query, [$proyecto_id]);
+ }
+ public function fetchFirstByProyecto(int $proyecto_id): Model\Proyecto\EstadoProyecto
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT MIN(`id`) AS 'id', `proyecto` FROM `{$this->getTable()}` GROUP BY `proyecto`) e0 ON e0.`id` = a.`id`
+WHERE a.`proyecto` = ?";
+ return $this->fetchOne($query, [$proyecto_id]);
+ }
+ public function fetchRecepcionByProyecto(int $proyecto_id): Model\Proyecto\EstadoProyecto
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN `tipo_estado_proyecto` tep ON tep.`id` = a.`estado`
+WHERE a.`proyecto` = ? AND tep.`descripcion` = 'Recepción Final'";
+ return $this->fetchOne($query, [$proyecto_id]);
+ }
+}
diff --git a/app/src/Repository/Proyecto/Etapa.php b/app/src/Repository/Proyecto/Etapa.php
new file mode 100644
index 0000000..4ab3bbb
--- /dev/null
+++ b/app/src/Repository/Proyecto/Etapa.php
@@ -0,0 +1,37 @@
+setTable('etapa_proyecto');
+ }
+
+ public function create(?array $data = null): Model\Proyecto\Etapa
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion', 'orden']);
+ return $this->parseData(new Model\Proyecto\Etapa(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Proyecto\Etapa
+ {
+ $model->id = $this->saveNew(['descripcion', 'orden'], [$model->descripcion, $model->orden]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Proyecto\Etapa
+ {
+ return $this->update($model, ['descripcion', 'orden'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Model\Proyecto\Etapa
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+}
diff --git a/app/src/Repository/Proyecto/ProyectoTipoUnidad.php b/app/src/Repository/Proyecto/ProyectoTipoUnidad.php
new file mode 100644
index 0000000..737f767
--- /dev/null
+++ b/app/src/Repository/Proyecto/ProyectoTipoUnidad.php
@@ -0,0 +1,46 @@
+setTable('proyecto_tipo_unidad');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['nombre', 'abreviacion', 'logia', 'terraza', 'descripcion']))
+ ->register('proyecto', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->proyectoRepository->fetchById($data['proyecto']);
+ }))
+ ->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('tipoUnidad')
+ ->setFunction(function($data) {
+ return $this->tipoUnidadRepository->fetchById($data['tipo']);
+ }))
+ ->register('m2', (new Implement\Repository\Mapper())
+ ->setProperty('util'));
+ return $this->parseData(new Model\Proyecto\ProyectoTipoUnidad(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['proyecto', 'tipo', 'nombre', 'abreviacion', 'm2', 'logia', 'terraza', 'descripcion'],
+ [$model->proyecto->id, $model->tipoUnidad->id, $model->nombre, $model->abreviacion, $model->util, $model->logia, $model->terraza, $model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['proyecto', 'tipo', 'nombre', 'abreviacion', 'util', 'logia', 'terraza', 'descripcion'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Proyecto/TipoEstadoProyecto.php b/app/src/Repository/Proyecto/TipoEstadoProyecto.php
new file mode 100644
index 0000000..188cb63
--- /dev/null
+++ b/app/src/Repository/Proyecto/TipoEstadoProyecto.php
@@ -0,0 +1,36 @@
+setTable('tipo_estado_proyecto');
+ }
+
+ public function create(?array $data = null): Model\Proyecto\TipoEstadoProyecto
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion', 'orden']))
+ ->register('etapa', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->etapaRepository->fetchById($data['etapa']);
+ }));
+ return $this->parseData(new Model\Proyecto\TipoEstadoProyecto(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Proyecto\TipoEstadoProyecto
+ {
+ $model->id = $this->saveNew(['descripcion', 'orden', 'etapa'], [$model->descripcion, $model->orden, $model->etapa->id]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Proyecto\TipoEstadoProyecto
+ {
+ return $this->update($model, ['descripcion', 'orden', 'etapa'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Proyecto/TipoTipologia.php b/app/src/Repository/Proyecto/TipoTipologia.php
new file mode 100644
index 0000000..3bf1a9a
--- /dev/null
+++ b/app/src/Repository/Proyecto/TipoTipologia.php
@@ -0,0 +1,34 @@
+setTable('tipologia');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']));
+ return $this->parseData(new Model\Proyecto\TipoTipologia(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Proyecto/TipoUnidad.php b/app/src/Repository/Proyecto/TipoUnidad.php
new file mode 100644
index 0000000..8a2788a
--- /dev/null
+++ b/app/src/Repository/Proyecto/TipoUnidad.php
@@ -0,0 +1,48 @@
+setTable('tipo_unidad');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion', 'orden']);
+ return $this->parseData(new Model\Proyecto\TipoUnidad(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'orden'],
+ [$model->descripcion, $model->orden]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'orden'], $new_data);
+ }
+
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN proyecto_tipo_unidad b ON b.tipo = a.id')
+ ->where('b.proyecto = ?')
+ ->group('a.id')
+ ->order('a.orden');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+}
+
+
diff --git a/app/src/Repository/Proyecto/Tipologia.php b/app/src/Repository/Proyecto/Tipologia.php
new file mode 100644
index 0000000..3db6ed4
--- /dev/null
+++ b/app/src/Repository/Proyecto/Tipologia.php
@@ -0,0 +1,58 @@
+setTable('tipo_tipologia');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['cantidad']))
+ ->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('proyectoTipoUnidad')
+ ->setFunction(function($data) {
+ return $this->proyectoTipoUnidadRepository->fetchById($data['tipo']);
+ }))
+ ->register('tipologia', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->tipoTipologiaRepository->fetchById($data['tipologia']);
+ }))
+ ->register('elemento', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->elementoRepository->fetchById($data['elemento']);
+ }));
+ return $this->parseData(new Model\Proyecto\Tipologia(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['tipo', 'tipologia', 'cantidad', 'elemento'],
+ [$model->proyectoTipoUnidad->id, $model->tipoTipologia->id, $model->cantidad, $model->elemento->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['tipo', 'tipologia', 'cantidad', 'elemento'], $new_data);
+ }
+
+ public function fetchByProyectoTipoUnidad(int $proyecto_tipo_unidad_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `tipo` = ?";
+ return $this->fetchMany($query, [$proyecto_tipo_unidad_id]);
+ }
+}
diff --git a/app/src/Repository/Region.php b/app/src/Repository/Region.php
new file mode 100644
index 0000000..3932ea3
--- /dev/null
+++ b/app/src/Repository/Region.php
@@ -0,0 +1,50 @@
+setTable('region');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion', 'numeral', 'numeracion']);
+ return $this->parseData(new Model\Region(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'numeral', 'numeracion'],
+ [$model->descripcion, $model->numeral, $model->numeracion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'numeral', 'numeracion'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+ public function fetchByNumeral(string $numeral): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `numeral` = ?";
+ return $this->fetchOne($query, [$numeral]);
+ }
+ public function fetchByNumeracion(int $numeracion): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `numeracion` = ?";
+ return $this->fetchOne($query, [$numeracion]);
+ }
+}
diff --git a/app/src/Repository/Tipo.php b/app/src/Repository/Tipo.php
new file mode 100644
index 0000000..791d47c
--- /dev/null
+++ b/app/src/Repository/Tipo.php
@@ -0,0 +1,37 @@
+parseData($this->getBlank(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Define\Model
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('descripcion LIKE ?');
+ return $this->fetchOne($query, [$descripcion]);
+ }
+}
diff --git a/app/src/Repository/TipoCentro.php b/app/src/Repository/TipoCentro.php
new file mode 100644
index 0000000..db5bae9
--- /dev/null
+++ b/app/src/Repository/TipoCentro.php
@@ -0,0 +1,19 @@
+setTable('tipos_centros_costos');
+ }
+
+ protected function getBlank(): Define\Model
+ {
+ return new Model\TipoCentro();
+ }
+}
diff --git a/app/src/Repository/TipoCuenta.php b/app/src/Repository/TipoCuenta.php
new file mode 100644
index 0000000..2076a65
--- /dev/null
+++ b/app/src/Repository/TipoCuenta.php
@@ -0,0 +1,19 @@
+setTable('tipos_cuentas_costos');
+ }
+
+ protected function getBlank(): Define\Model
+ {
+ return new Model\TipoCuenta();
+ }
+}
diff --git a/app/src/Repository/User.php b/app/src/Repository/User.php
new file mode 100644
index 0000000..4211bc6
--- /dev/null
+++ b/app/src/Repository/User.php
@@ -0,0 +1,40 @@
+setTable('users');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['name', 'password']))
+ ->register('enabled', new Implement\Repository\Mapper\Boolean('enabled'));
+ return $this->parseData(new Model\User(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(['name', 'password', 'enabled'], [$model->name, $model->password, $model->enabled ? 1 : 0]);
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['name', 'password', 'enabled'], $new_data);
+ }
+
+ public function fetchByName(string $name): Model\User
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `name` = ?";
+ return $this->fetchOne($query, [$name]);
+ }
+}
diff --git a/app/src/Repository/Venta.php b/app/src/Repository/Venta.php
new file mode 100644
index 0000000..a6a7a0f
--- /dev/null
+++ b/app/src/Repository/Venta.php
@@ -0,0 +1,417 @@
+setTable('venta');
+ }
+
+ public function create(?array $data = null): Model\Venta
+ {
+ $map = (new Implement\Repository\MapperParser(['uf']))
+ ->register('propietario', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->propietarioRepository, 'fetchById'])
+ ->setArgs([$data['propietario']])))
+ ->register('propiedad', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->propiedadRepository, 'fetchById'])
+ ->setArgs([$data['propiedad']])))
+ /*->register('pie', (new Implement\Repository\Mapper())
+ ->setProperty('formaPago')
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable(function($repositories, $data) {
+ $fp = new Model\Venta\FormaPago();
+ $map = [
+ 'pie' => [
+ 'service' => $repositories->pieService
+ ],
+ 'bono_pie' => [
+ 'property' => 'bonoPie',
+ 'repository' => $repositories->bonoPieRepository
+ ],
+ 'credito' => [
+ 'repository' => $repositories->creditoRepository
+ ],
+ 'escritura' => [
+ 'repository' => $repositories->escrituraRepository
+ ],
+ 'subsidio' => [
+ 'repository' => $repositories->subsidioRepository
+ ],
+ 'devolucion' => [
+ 'service' => $repositories->pagoService
+ ]
+ ];
+ foreach ($map as $column => $settings) {
+ if (isset($data[$column]) and $data[$column] !== 0) {
+ if (isset($settings['repository'])) {
+ $fp->{$settings['property'] ?? $column} = $settings['repository']->fetchById($data[$column]);
+ continue;
+ }
+ $fp->{$settings['property'] ?? $column} = $settings['service']->getById($data[$column]);
+ continue;
+ }
+ $fp->{$settings['property'] ?? $column} = null;
+ }
+ return $fp;
+ })
+ ->setArgs([(object) [
+ 'pieService' => $this->pieService,
+ 'bonoPieRepository' => $this->bonoPieRepository,
+ 'creditoRepository' => $this->creditoRepository,
+ 'escrituraRepository' => $this->escrituraRepository,
+ 'subsidioRepository' => $this->subsidioRepository,
+ 'pagoService' => $this->pagoService
+ ], $data])))*/
+ /*->register('escriturado', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $data['escritura'] !== null;
+ }))*/
+ /*->register('entrega', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable(function($entrega_id) {
+ if ($entrega_id !== null and $entrega_id !== 0) {
+ return $this->entregaRepository->fetchById($entrega_id);
+ }
+ return null;
+ })
+ ->setArgs([$data['entrega']]))
+ ->setDefault(null))*/
+ /*->register('entregado', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable(function($entrega_id) {
+ if ($entrega_id !== null and $entrega_id !== 0) {
+ return $entrega_id != null;
+ }
+ return false;
+ })
+ ->setArgs([$data['entrega']])))*/
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('valor_uf', (new Implement\Repository\Mapper())
+ ->setProperty('valor'))
+ //->register('estado')
+ ->register('fecha_ingreso', new Implement\Repository\Mapper\DateTime('fecha_ingreso', 'fechaIngreso'))
+ //->register('avalchile')
+ //->register('agente')
+ ->register('relacionado', new Implement\Repository\Mapper\Boolean('relacionado'));
+ //->register('promocion')
+ //->register('devolucion');
+ if (array_key_exists('resciliacion', $data)) {
+ $map = $map->register('resciliacion', (new Implement\Repository\Mapper())
+ ->setFactory((new Implement\Repository\Factory())
+ ->setCallable([$this->pagoService, 'getById'])
+ ->setArgs(['pago_id' => $data['resciliacion']])));
+ }
+ return $this->parseData(new Model\Venta(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta
+ {
+ $model->id = $this->saveNew(
+ ['propietario', 'propiedad', 'pie', 'bono_pie', 'credito', 'escritura', 'subsidio', 'escriturado',
+ 'entrega', 'entregado', 'fecha', 'valor_uf', 'estado', 'fecha_ingreso', 'avalchile', 'agente', 'uf',
+ 'relacionado', 'promocion', 'resciliacion', 'devolucion'],
+ [$model->propietario()->rut, $model->propiedad()->id, $model->formaPago()->pie?->id, $model->formaPago()->bonoPie?->id,
+ $model->formaPago()->credito?->id, $model->formaPago()->escritura?->id, $model->formaPago()->subsidio?->id,
+ $model->formaPago()->escritura !== null ? $model->formaPago()->escritura->pago->fecha->format('Y-m-d') : null,
+ null, null, $model->fecha->format('Y-m-d'), $model->valor, 1, $model->fechaIngreso->format('Y-m-d'),
+ null, null, $model->uf, $model->relacionado ? 1 : 0, null, null, null]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta
+ {
+ return $this->update($model, ['propietario', 'propiedad', 'pie', 'bono_pie', 'credito', 'escritura', 'subsidio', 'escriturado',
+ 'entrega', 'entregado', 'fecha', 'valor_uf', 'estado', 'fecha_ingreso', 'avalchile', 'agente', 'uf',
+ 'relacionado', 'promocion', 'resciliacion', 'devolucion'], $new_data);
+ }
+
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
+ ->joined('JOIN unidad ON unidad.id = pu.unidad AND pu.principal = 1')
+ ->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
+ ->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
+ ->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
+ ->where('ptu.proyecto = ? AND tev.activa')
+ ->group('a.id');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchIdsByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.id')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
+ ->joined('JOIN unidad ON unidad.id = pu.unidad AND unidad.pt')
+ ->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
+ ->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = a.id')
+ ->joined('JOIN tipo_estado_venta tev ON tev.id = ev.estado')
+ ->where('ptu.proyecto = ? AND tev.activa')
+ ->group('a.id');
+ return $this->fetchIds($query, [$proyecto_id]);
+ }
+ public function fetchActivaByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
+ ->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1')
+ ->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
+ ->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
+ ->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
+ ->where('ptu.`proyecto` = ? AND tev.`activa`')
+ ->group('a.id');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select("a.*")
+ ->from("`{$this->getTable()}` a")
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
+ ->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1')
+ ->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
+ ->joined('JOIN `proyecto` ON `proyecto`.`id` = ptu.`proyecto`')
+ ->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
+ ->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
+ ->where('`proyecto`.`descripcion` = ? AND `unidad`.`descripcion` = ? AND tev.`activa`');
+ return $this->fetchOne($query, [$proyecto_nombre, $unidad_descripcion]);
+ }
+ public function fetchByPie(int $pie_id): Model\Venta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pie = ?');
+ return $this->fetchOne($query, [$pie_id]);
+ }
+ public function fetchIdByPie(int $pie_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('pie = ?');
+ return $this->fetchId($query, [$pie_id]);
+ }
+ public function fetchByUnidad(string $unidad, string $tipo): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
+ ->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
+ ->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
+ ->joined('JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`')
+ ->where('`unidad`.`descripcion` LIKE ? AND tu.`descripcion` = ?');
+ return $this->fetchMany($query, [$unidad, $tipo]);
+ }
+ public function fetchByUnidadId(int $unidad_id): Model\Venta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN propiedad_unidad pu ON pu.propiedad = a.propiedad')
+ ->where('pu.unidad = ?');
+ return $this->fetchOne($query, [$unidad_id]);
+ }
+ public function fetchIdsByUnidad(string $unidad, string $tipo): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.id')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
+ ->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
+ ->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`')
+ ->joined('JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`')
+ ->where('`unidad`.`descripcion` LIKE ? AND tu.`descripcion` = ?');
+ return $this->fetchIds($query, [$unidad, $tipo]);
+ }
+ public function fetchByPrecio(string $precio): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor_uf = ?');
+ return $this->fetchMany($query, [$precio]);
+ }
+ public function fetchIdsByPrecio(string $precio): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('valor_uf = ?');
+ return $this->fetchIds($query, [$precio]);
+ }
+ public function fetchByPropietarioAndPropiedad(int $propietario_rut, int $propiedad_id): Model\Venta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('propietario = ? AND propiedad = ?');
+ return $this->fetchOne($query, [$propietario_rut, $propiedad_id]);
+ }
+ public function fetchByPropietario(string $propietario): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
+ ->where("CONCAT_WS('-', `propietario`.`rut`, `propietario`.`dv`) LIKE :propietario OR `propietario`.`nombres` LIKE :propietario
+ OR `propietario`.`apellido_paterno` LIKE :propietario OR `propietario`.`apellido_materno` LIKE :propietario
+ OR CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE :propietario");
+ return $this->fetchMany($query, [':propietario' => "%{$propietario}%"]);
+ }
+ public function fetchIdsByPropietario(string $propietario): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.id')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
+ ->where("CONCAT_WS('-', `propietario`.`rut`, `propietario`.`dv`) LIKE :propietario OR `propietario`.`nombres` LIKE :propietario
+ OR `propietario`.`apellido_paterno` LIKE :propietario OR `propietario`.`apellido_materno` LIKE :propietario
+ OR CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE :propietario
+ OR rut = :rut
+ OR CONCAT_WS('-', rut, dv) = :rut");
+ return $this->fetchIds($query, [':propietario' => "%{$propietario}%", ':rut' => $propietario]);
+ }
+ public function fetchByPropietarioNombreCompleto(string $propietario): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propietario` ON `propietario`.`rut` = a.`propietario`')
+ ->where("CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) LIKE ?");
+ return $this->fetchMany($query, [$propietario]);
+ }
+ public function fetchEscriturasByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('DISTINCT a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`propiedad` = a.`propiedad`')
+ ->joined('JOIN `unidad` ON `unidad`.`id` = pu.`unidad`')
+ ->joined('JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`id`')
+ ->joined("JOIN (SELECT e1.* FROM `estado_venta` e1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) e0 ON e0.`id` = e1.`id`) ev ON ev.`venta` = a.`id`")
+ ->joined('JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`')
+ ->where("ptu.`proyecto` = ? AND tev.`descripcion` IN ('firmado por inmobiliaria', 'escriturando')")
+ ->group('a.id');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchIdByEscritura(int $escritura_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('escritura = ?');
+ return $this->fetchId($query, [$escritura_id]);
+ }
+ public function fetchIdBySubsidio(int $subsidio_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('subsidio = ?');
+ return $this->fetchId($query, [$subsidio_id]);
+ }
+ public function fetchIdByCredito(int $credito_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('credito = ?');
+ return $this->fetchId($query, [$credito_id]);
+ }
+ public function fetchIdByBono(int $bono_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('id')
+ ->from($this->getTable())
+ ->where('bono_pie = ?');
+ return $this->fetchId($query, [$bono_id]);
+ }
+ public function fetchByIdForSearch(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('venta.id AS id, venta.fecha AS fecha, venta.valor_uf AS valor')
+ ->columns('proyecto.id AS proyecto_id, proyecto.descripcion AS proyecto_descripcion')
+ ->columns('CONCAT_WS(" ", propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) AS propietario')
+ ->columns('unidad.descripcion AS unidad_descripcion, tu.descripcion AS tipo_unidad_descripcion, ptu.m2 + ptu.logia + ptu.terraza AS superficie')
+ ->columns('tev.activa')
+ ->from($this->getTable())
+ ->joined('JOIN propietario ON propietario.rut = venta.propietario')
+ ->joined('JOIN propiedad_unidad pu ON pu.propiedad = venta.propiedad')
+ ->joined('JOIN unidad ON unidad.id = pu.unidad')
+ ->joined('JOIN proyecto_tipo_unidad ptu ON unidad.pt = ptu.id')
+ ->joined('JOIN proyecto ON proyecto.id = ptu.proyecto')
+ ->joined('JOIN tipo_unidad tu ON tu.id = ptu.tipo')
+ ->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = venta.id')
+ ->joined('JOIN tipo_estado_venta tev ON ev.estado = tev.id')
+ ->where('venta.id = ? AND tu.descripcion = "departamento"')
+ ->group('venta.id');
+ return $this->connection->execute($query, [$venta_id])->fetch(PDO::FETCH_ASSOC);
+ }
+ public function fetchByIdForList(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('venta.id AS id, venta.fecha AS fecha, venta.valor_uf AS valor')
+ ->columns('proyecto.id AS proyecto_id, proyecto.descripcion AS proyecto_descripcion')
+ ->columns('CONCAT_WS(" ", propietario.nombres, propietario.apellido_paterno, propietario.apellido_materno) AS propietario')
+ ->columns("GROUP_CONCAT(unidad.descripcion SEPARATOR ' - ') AS unidad_descripcion, tu.descripcion AS tipo_unidad_descripcion, ptu.m2 + ptu.logia + ptu.terraza AS superficie")
+ ->columns('tev.activa')
+ ->from($this->getTable())
+ ->joined('JOIN propietario ON propietario.rut = venta.propietario')
+ ->joined('JOIN propiedad_unidad pu ON pu.propiedad = venta.propiedad')
+ ->joined('JOIN unidad ON unidad.id = pu.unidad')
+ ->joined('JOIN proyecto_tipo_unidad ptu ON unidad.pt = ptu.id')
+ ->joined('JOIN proyecto ON proyecto.id = ptu.proyecto')
+ ->joined('JOIN tipo_unidad tu ON tu.id = ptu.tipo')
+ ->joined('JOIN (SELECT ev1.* FROM estado_venta ev1 JOIN (SELECT MAX(id) AS id, venta FROM estado_venta GROUP BY venta) ev0 ON ev0.id = ev1.id) ev ON ev.venta = venta.id')
+ ->joined('JOIN tipo_estado_venta tev ON ev.estado = tev.id')
+ ->where('venta.id = ?')
+ ->group('venta.id');
+ return $this->connection->execute($query, [$venta_id])->fetch(PDO::FETCH_ASSOC);
+ }
+
+ protected function fetchIds(string $query, ?array $data = null): array
+ {
+ $results = $this->connection->execute($query, $data)->fetchAll(PDO::FETCH_ASSOC);
+ if ($results === false) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ return $results;
+ }
+ protected function fetchId(string $query, ?array $data = null): array
+ {
+ $results = $this->connection->execute($query, $data)->fetch(PDO::FETCH_ASSOC);
+ if ($results === false) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ return $results;
+ }
+}
diff --git a/app/src/Repository/Venta/BonoPie.php b/app/src/Repository/Venta/BonoPie.php
new file mode 100644
index 0000000..eb1cb3a
--- /dev/null
+++ b/app/src/Repository/Venta/BonoPie.php
@@ -0,0 +1,64 @@
+setTable('bono_pie');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pagoRepository->fetchById($data['pago']);
+ }));
+ return $this->parseData(new Model\Venta\BonoPie(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['valor', 'pago'],
+ [$model->pago->valor, $model->pago->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['valor', 'pago'], $new_data);
+ }
+
+ public function fetchByValue(float $value): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor = ?');
+ return $this->fetchMany($query, [$value]);
+ }
+ public function fetchByPago(int $pago_id): Model\Venta\BonoPie
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pago = ?');
+ return $this->fetchOne($query, [$pago_id]);
+ }
+ public function fetchByVenta(int $venta_id): Model\Venta\BonoPie
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.bono_pie = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Cierre.php b/app/src/Repository/Venta/Cierre.php
new file mode 100644
index 0000000..02dba77
--- /dev/null
+++ b/app/src/Repository/Venta/Cierre.php
@@ -0,0 +1,81 @@
+setTable('cierre');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['precio']))
+ ->register('proyecto', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->proyectoRepository->fetchById($data['proyecto']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha', 'dateTime'))
+ ->register('relacionado', new Implement\Repository\Mapper\Boolean('relacionado'))
+ ->register('propietario', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->propietarioRepository->fetchById($data['propietario']);
+ }));
+ return $this->parseData(new Model\Venta\Cierre(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['proyecto', 'precio', 'fecha', 'relacionado', 'propietario'],
+ [$model->proyecto->id, $model->precio, $model->fecha->format('Y-m-d H:i:s'), $model->relacionado ? 1 : 0, $model->propietario->rut]
+ );
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['proyecto', 'precio', 'fecha', 'relacionado', 'propietario'], $new_data);
+ }
+
+ public function fetchDatosVigentes(): array
+ {
+ $query = "
+SELECT `proyecto`.`descripcion` AS 'Proyecto', tec.`descripcion` AS 'Estado', COUNT(a.`id`) AS 'Cantidad'
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.*
+ FROM `estado_cierre` e1
+ JOIN (SELECT MAX(`id`) AS id, `cierre` FROM `estado_cierre` GROUP BY `cierre`) e0 ON e0.`id` = e1.`id`) ec ON ec.`cierre` = a.`id`
+ JOIN `tipo_estado_cierre` tec ON tec.`id` = ec.`tipo`
+ JOIN `proyecto` ON `proyecto`.`id` = a.`proyecto` AND tec.`descripcion` NOT IN ('revisado')
+GROUP BY `proyecto`.`descripcion`, tec.`descripcion`";
+ $results = $this->connection->execute($query)->fetchAll(PDO::FETCH_ASSOC);
+ if ($results === false) {
+ throw new EmptyResult($query);
+ }
+ return $results;
+ }
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.*
+ FROM `estado_cierre` e1
+ JOIN (SELECT MAX(`id`) AS id, `cierre` FROM `estado_cierre` GROUP BY `cierre`) e0 ON e0.`id` = e1.`id`) ec ON ec.`cierre` = a.`id`
+ JOIN `tipo_estado_cierre` tec ON tec.`id` = ec.`tipo`
+WHERE `proyecto` = ? AND tec.`descripcion` NOT IN ('revisado')";
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Comentario.php b/app/src/Repository/Venta/Comentario.php
new file mode 100644
index 0000000..9197264
--- /dev/null
+++ b/app/src/Repository/Venta/Comentario.php
@@ -0,0 +1,43 @@
+setTable('comentario');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['texto']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('estado', new Implement\Repository\Mapper\Boolean('estado', 'activo'));
+ return $this->parseData(new Model\Venta\Comentario(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['fecha', 'texto', 'estado'],
+ [$model->fecha->format('Y-m-d'), $model->texto, $model->activo ? 1 : 0]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['fecha', 'texto', 'estado'], $new_data);
+ }
+
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `venta` = ? AND `estado` = 1 ORDER BY `fecha` DESC";
+ return $this->fetchMany($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Credito.php b/app/src/Repository/Venta/Credito.php
new file mode 100644
index 0000000..6abe902
--- /dev/null
+++ b/app/src/Repository/Venta/Credito.php
@@ -0,0 +1,65 @@
+setTable('credito');
+ }
+
+ public function create(?array $data = null): Model\Venta\Credito
+ {
+ $map = (new Implement\Repository\MapperParser(['valor']))
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pagoService->getById($data['pago']);
+ }));
+ return $this->parseData(new Model\Venta\Credito(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Credito
+ {
+ $model->id = $this->saveNew(
+ ['banco', 'valor', 'fecha', 'uf', 'abonado', 'fecha_abono', 'pago'],
+ [$model->pago->banco?->id, $model->valor ?? (($model->pago->uf > 0) ? $model->pago->valor / $model->pago->uf : null), $model->pago->fecha->format('Y-m-d'), $model->pago->uf, null, null, $model->pago->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Credito
+ {
+ return $this->update($model, ['banco', 'valor', 'fecha', 'uf', 'abonado', 'fecha_abono', 'pago'], $new_data);
+ }
+
+ public function fetchByValue(int $value): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor = ?');
+ return $this->fetchMany($query, [$value]);
+ }
+ public function fetchByPago(int $pago_id): Model\Venta\Credito
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pago = ?');
+ return $this->fetchOne($query, [$pago_id]);
+ }
+ public function fetchByVenta(int $venta_id): Model\Venta\Credito
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.credito = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Cuota.php b/app/src/Repository/Venta/Cuota.php
new file mode 100644
index 0000000..2a204f1
--- /dev/null
+++ b/app/src/Repository/Venta/Cuota.php
@@ -0,0 +1,208 @@
+setTable('cuota');
+ }
+
+ public function create(?array $data = null): Model\Venta\Cuota
+ {
+ $map = (new Implement\Repository\MapperParser(['uf', 'numero']))
+ ->register('pie', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pieRepository->fetchById($data['pie']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('valor_$', (new Implement\Repository\Mapper())
+ ->setProperty('valor')
+ )
+ ->register('estado', new Implement\Repository\Mapper\Boolean('estado'))
+ ->register('banco', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['banco'] === null or $data['banco'] === '') {
+ return null;
+ }
+ return $this->bancoRepository->fetchById($data['banco']);
+ }))
+ ->register('fecha_pago', (new Implement\Repository\Mapper\DateTime('fecha_pago', 'fechaPago'))
+ ->setDefault(null))
+ ->register('abonado', (new Implement\Repository\Mapper\Boolean('abonado'))
+ ->setDefault(null))
+ ->register('fecha_abonado', (new Implement\Repository\Mapper\DateTime('fecha_abonado', 'fechaAbonado'))
+ ->setDefault(null))
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['pago'] === null) {
+ return null;
+ }
+ return $this->pagoService->getById($data['pago']);
+ }));
+ return $this->parseData(new Model\Venta\Cuota(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Model\Venta\Cuota
+ {
+ $model->id = $this->saveNew(
+ ['pie', 'fecha', 'valor_$', 'estado', 'banco', 'fecha_pago', 'abonado', 'fecha_abono', 'uf', 'pago', 'numero'],
+ [$model->pie->id, $model->fecha->format('Y-m-d H:i:s'), $model->valor, $model->estado ? 1 : 0, $model->banco?->id,
+ null, null, null,
+ $model->uf, $model->pago->id, $model->numero]
+ );
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Cuota
+ {
+ return $this->update($model, ['pie', 'fecha', 'valor', 'estado', 'banco', 'fecha_pago', 'abonado', 'fecha_abonado', 'uf', 'pago', 'numero'], $new_data);
+ }
+
+ public function fetchHoy(): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN `pago` ON `pago`.`id` = a.`pago`
+ JOIN (SELECT e1.* FROM `estado_pago` e1 JOIN (SELECT MAX(`id`) AS `id`, `pago` FROM `estado_pago` GROUP BY `pago`) e0 ON e0.`id` = e1.`id`) ep ON ep.`pago` = `pago`.`id`
+ JOIN `tipo_estado_pago` tep ON tep.`id` = ep.`estado`
+ JOIN `venta` ON `venta`.`pie` = a.`pie`
+ JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`
+WHERE tep.`descripcion` = 'no pagado' AND `pago`.`fecha` = CURDATE()
+ AND tev.`descripcion` IN ('vigente', 'escriturando', 'firmado por inmobiliaria')";
+ return $this->fetchMany($query);
+ }
+ public function fetchPendientes(): array
+ {
+ $query = "SELECT a.`id` AS 'cuota_id', `venta`.`id` AS 'venta_id', `proyecto`.`descripcion` AS 'Proyecto', `unidad`.`descripcion` AS 'Departamento',
+ `pago`.`valor` AS 'Valor', `pago`.`fecha`, CONCAT_WS(' - ', a.`numero`, `pie`.`cuotas`) AS 'Numero', `banco`.`nombre` AS 'Banco',
+ CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) AS 'Propietario'
+FROM `{$this->getTable()}` a
+ JOIN `pago` ON `pago`.`id` = a.`pago`
+ JOIN (SELECT e1.* FROM `estado_pago` e1 JOIN (SELECT MAX(`id`) AS 'id', `pago` FROM `estado_pago` GROUP BY `pago`) e0 ON e0.`id` = e1.`id`) ep ON ep.`pago` = `pago`.`id`
+ JOIN `tipo_estado_pago` tep ON tep.`id` = ep.`estado`
+ JOIN `pie` ON `pie`.`id` = a.`pie`
+ JOIN `venta` ON `venta`.`pie` = a.`pie`
+ JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`
+ JOIN `propietario` ON `propietario`.`rut` = `venta`.`propietario`
+ JOIN `propiedad_unidad` pu ON pu.`propiedad` = `venta`.`propiedad`
+ JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1
+ JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`
+ JOIN `proyecto` ON `proyecto`.`id` = ptu.`proyecto`
+ JOIN `banco` ON `banco`.`id` = `pago`.`banco`
+WHERE tep.`descripcion` = 'no pagado' AND `pago`.`fecha` < CURDATE()
+ AND tev.`descripcion` IN ('vigente', 'escriturando', 'firmado por inmobiliaria')
+ORDER BY `pago`.`fecha` DESC";
+ return $this->fetchAsArray($query);
+ }
+ public function fetchDepositadas(): array
+ {
+ $query = "SELECT a.`id` AS 'cuota_id', `venta`.`id` AS 'venta_id', `proyecto`.`descripcion` AS 'Proyecto', `unidad`.`descripcion` AS 'Departamento',
+ `pago`.`valor` AS 'Valor', `pago`.`fecha`, CONCAT_WS(' - ', a.`numero`, `pie`.`cuotas`) AS 'Numero', `banco`.`nombre` AS 'Banco', ep.`fecha` AS 'Fecha Depositada',
+ CONCAT_WS(' ', `propietario`.`nombres`, `propietario`.`apellido_paterno`, `propietario`.`apellido_materno`) AS 'Propietario'
+FROM `{$this->getTable()}` a
+ JOIN `pago` ON `pago`.`id` = a.`pago`
+ JOIN (SELECT e1.* FROM `estado_pago` e1 JOIN (SELECT MAX(`id`) AS 'id', `pago` FROM `estado_pago` GROUP BY `pago`) e0 ON e0.`id` = e1.`id`) ep ON ep.`pago` = `pago`.`id`
+ JOIN `tipo_estado_pago` tep ON tep.`id` = ep.`estado`
+ JOIN `pie` ON `pie`.`id` = a.`pie`
+ JOIN `venta` ON `venta`.`pie` = a.`pie`
+ JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) AS 'id', `venta` FROM `estado_venta` GROUP BY `venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`
+ JOIN `propietario` ON `propietario`.`rut` = `venta`.`propietario`
+ JOIN `propiedad_unidad` pu ON pu.`propiedad` = `venta`.`propiedad`
+ JOIN `unidad` ON `unidad`.`id` = pu.`unidad` AND pu.`principal` = 1
+ JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`
+ JOIN `proyecto` ON `proyecto`.`id` = ptu.`proyecto`
+ JOIN `banco` ON `banco`.`id` = `pago`.`banco`
+WHERE tep.`descripcion` = 'depositado' AND `pago`.`fecha` < CURDATE()
+ AND tev.`descripcion` IN ('vigente', 'escriturando', 'firmado por inmobiliaria')
+ORDER BY `pago`.`fecha` DESC";
+ return $this->fetchAsArray($query);
+ }
+ public function fetchDatosPorVencer(): array
+ {
+ $query = "SELECT p1.`fecha` AS 'Fecha', v1.`descripcion` AS 'Proyecto', COUNT(a.`id`) AS 'Cantidad'
+FROM `{$this->getTable()}` a
+ JOIN (
+ SELECT `pago`.`id`, `pago`.`fecha`
+ FROM `pago`
+ JOIN (
+ SELECT e1.*
+ FROM `estado_pago` e1
+ JOIN (
+ SELECT MAX(`id`) AS 'id', `pago`
+ FROM `estado_pago`
+ GROUP BY `pago`
+ ) e0 ON e0.`id` = e1.`id`
+ ) ep ON ep.`pago` = `pago`.`id`
+ JOIN `tipo_estado_pago` tep ON tep.`id` = ep.`estado` AND tep.`descripcion` = 'no pagado'
+ ) p1 ON p1.id = a.`pago`
+ JOIN (
+ SELECT `venta`.`pie`, `venta`.`propiedad`, `proyecto`.`descripcion`
+ FROM `venta`
+ JOIN (
+ SELECT ev1.*
+ FROM `estado_venta` ev1
+ JOIN (
+ SELECT MAX(`id`) AS 'id', `venta`
+ FROM `estado_venta`
+ GROUP BY `venta`
+ ) ev0 ON ev0.`id` = ev1.`id`
+ ) ev ON ev.`venta` = `venta`.`id`
+ JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado` AND tev.`descripcion` IN ('vigente', 'escriturando', 'firmado por inmobiliaria')
+ JOIN `propiedad_unidad` pu ON pu.`propiedad` = `venta`.`propiedad` AND pu.`principal` = 1
+ JOIN `unidad` ON `unidad`.`id` = pu.`unidad`
+ JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`
+ JOIN `proyecto` ON `proyecto`.`id` = ptu.`proyecto`
+ ) v1 ON v1.`pie` = a.`pie`
+WHERE p1.`fecha` BETWEEN DATE_ADD(CURDATE(), INTERVAL 1 DAY) AND DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
+GROUP BY p1.`fecha`, v1.`descripcion`
+ORDER BY p1.`fecha`, v1.`descripcion`";
+ return $this->fetchAsArray($query);
+ }
+ public function fetchByPie(int $pie_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pie = ?')
+ ->group('id');
+ return $this->fetchMany($query, [$pie_id]);
+ }
+ public function fetchVigenteByPie(int $pie_id): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN `pago` ON `pago`.`id` = a.`pago`
+ JOIN (SELECT e1.* FROM `estado_pago` e1 JOIN (SELECT MAX(`id`) AS 'id', `pago` FROM `estado_pago` GROUP BY `pago`) e0 ON e0.`id` = e1.`id`) ep ON ep.`pago` = `pago`.`id`
+ JOIN `tipo_estado_pago` tep ON tep.`id` = ep.`estado`
+WHERE a.`pie` = ? AND tep.`active` = 1
+GROUP BY a.`id`";
+ return $this->fetchMany($query, [$pie_id]);
+ }
+ public function fetchByPago(int $pago_id): Model\Venta\Cuota
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pago = ?');
+ return $this->fetchOne($query, [$pago_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Entrega.php b/app/src/Repository/Venta/Entrega.php
new file mode 100644
index 0000000..0859eeb
--- /dev/null
+++ b/app/src/Repository/Venta/Entrega.php
@@ -0,0 +1,39 @@
+setTable('entrega');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['fecha', 'fondo_operacion', 'fondo_reserva', 'fecha_fondo_operacion', 'fecha_fondo_reserva',
+ 'pago_operacion', 'pago_reserva']);
+ return $this->parseData(new Model\Venta\Entrega(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['fecha', 'fondo_operacion', 'fondo_reserva', 'fecha_fondo_operacion', 'fecha_fondo_reserva',
+ 'pago_operacion', 'pago_reserva'],
+ [$model->fecha->format('Y-m-d'), $model->operacion->valor, $model->reserva->valor,
+ $model->operacion->fecha('Y-m-d'), $model->reserva->fecha('Y-m-d'), $model->operacion->id,
+ $model->reserva->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['fecha', 'fondo_operacion', 'fondo_reserva', 'fecha_fondo_operacion',
+ 'fecha_fondo_reserva', 'pago_operacion', 'pago_reserva'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Venta/Escritura.php b/app/src/Repository/Venta/Escritura.php
new file mode 100644
index 0000000..0b81440
--- /dev/null
+++ b/app/src/Repository/Venta/Escritura.php
@@ -0,0 +1,67 @@
+setTable('escritura');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pagoService->getById($data['pago']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'));
+ return $this->parseData(new Model\Venta\Escritura(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['valor', 'fecha', 'uf', 'abonado', 'fecha_abono', 'pago'],
+ [$model->pago->valor, $model->fecha->format('Y-m-d'), $model->pago->uf, null, null, $model->pago->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['valor', 'fecha', 'uf', 'abonado', 'fecha_abono', 'pago'], $new_data);
+ }
+
+ public function fetchByValue(int $value): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor = ?');
+ return $this->fetchMany($query, [$value]);
+ }
+ public function fetchByPago(int $pago_id): Model\Venta\Escritura
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('pago = ?');
+ return $this->fetchOne($query, [$pago_id]);
+ }
+ public function fetchByVenta(int $venta_id): Model\Venta\Escritura
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.escritura = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/EstadoCierre.php b/app/src/Repository/Venta/EstadoCierre.php
new file mode 100644
index 0000000..2b183a0
--- /dev/null
+++ b/app/src/Repository/Venta/EstadoCierre.php
@@ -0,0 +1,60 @@
+setTable('estado_cierre');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('cierre', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->cierreRepository->fetchById($data['cierre']);
+ }))
+ ->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('tipoEstadoCierre')
+ ->setFunction(function($data) {
+ return $this->tipoEstadoCierreRepository->fetchById($data['tipo']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'));
+ return $this->parseData(new Model\Venta\EstadoCierre(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['cierre', 'tipo', 'fecha'],
+ [$model->cierre->id, $model->tipoEstadoCierre->id, $model->fecha->format('Y-m-d')]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['cierre', 'tipo', 'fecha'], $new_data);
+ }
+
+ public function fetchByCierre(int $cierre_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `cierre` = ?";
+ return $this->fetchMany($query, [$cierre_id]);
+ }
+ public function fetchCurrentByCierre(int $cierre_id): Define\Model
+ {
+ $query = "SELECT e1.*
+FROM `{$this->getTable()}` e1
+ JOIN (SELECT MAX(`id`) AS 'id', `cierre` FROM `{$this->getTable()}` GROUP BY `cierre`) e0 ON e0.`id` = e1.`id`
+WHERE e1.`cierre` = ?";
+ return $this->fetchOne($query, [$cierre_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/EstadoPago.php b/app/src/Repository/Venta/EstadoPago.php
new file mode 100644
index 0000000..250eb8d
--- /dev/null
+++ b/app/src/Repository/Venta/EstadoPago.php
@@ -0,0 +1,69 @@
+setTable('estado_pago');
+ }
+
+ public function create(?array $data = null): Model\Venta\EstadoPago
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pagoRepository->fetchById($data['pago']);
+ }))
+ ->register('estado', (new Implement\Repository\Mapper())
+ ->setProperty('tipoEstadoPago')
+ ->setFunction(function($data) {
+ return $this->tipoEstadoPagoRepository->fetchById($data['estado']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'));
+ return $this->parseData(new Model\Venta\EstadoPago(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Model\Venta\EstadoPago
+ {
+ $model->id = $this->saveNew(
+ ['pago', 'estado', 'fecha'],
+ [$model->pago->id, $model->tipoEstadoPago->id, $model->fecha->format('Y-m-d')]
+ );
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Model\Venta\EstadoPago
+ {
+ return $this->update($model, ['pago', 'estado', 'fecha'], $new_data);
+ }
+
+ public function fetchByPago(int $pago_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `pago` = ?";
+ return $this->fetchMany($query, [$pago_id]);
+ }
+ public function fetchCurrentByPago(int $pago_id): Model\Venta\EstadoPago
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT MAX(`id`) AS 'id', `pago` FROM `{$this->getTable()}` GROUP BY `pago`) e0 ON e0.`id` = a.`id`
+WHERE a.`pago` = ?";
+ return $this->fetchOne($query, [$pago_id]);
+ }
+ public function fetchByPagoAndEstado(int $pago_id, int $estado_id): Model\Venta\EstadoPago
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `pago` = ? AND `estado` = ?";
+ return $this->fetchOne($query, [$pago_id, $estado_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/EstadoPrecio.php b/app/src/Repository/Venta/EstadoPrecio.php
new file mode 100644
index 0000000..e1e0858
--- /dev/null
+++ b/app/src/Repository/Venta/EstadoPrecio.php
@@ -0,0 +1,59 @@
+setTable('estado_precio');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('precio', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->precioRepository->fetchById($data['precio']);
+ }))
+ ->register('estado', (new Implement\Repository\Mapper())
+ ->setProperty('tipoEstadoPrecio')
+ ->setFunction(function($data) {
+ return $this->tipoEstadoPrecioRepository->fetchById($data['estado']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'));
+ return $this->parseData(new Model\Venta\EstadoPrecio(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['precio', 'estado', 'fecha'],
+ [$model->precio->id, $model->tipoEstadoPrecio->id, $model->fecha->format('Y-m-d')]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['precio', 'estado', 'fecha'], $new_data);
+ }
+
+ public function fetchByPrecio(int $precio_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `precio` = ?";
+ return $this->fetchMany($query, [$precio_id]);
+ }
+ public function fetchCurrentByPrecio(int $precio_id): Define\Model
+ {
+ $query = "SELECT e1.*
+FROM `{$this->getTable()}` e1 JOIN (SELECT MAX(`id`) AS 'id', `precio` FROM `{$this->getTable()}` GROUP BY `precio`) e0 ON e0.`id` = e1.`id`
+WHERE e1.`precio` = ?";
+ return $this->fetchOne($query, [$precio_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/EstadoVenta.php b/app/src/Repository/Venta/EstadoVenta.php
new file mode 100644
index 0000000..07e7820
--- /dev/null
+++ b/app/src/Repository/Venta/EstadoVenta.php
@@ -0,0 +1,65 @@
+setTable('estado_venta');
+ }
+
+ public function create(?array $data = null): Model\Venta\EstadoVenta
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('venta', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->ventaRepository->fetchById($data['venta']);
+ }))
+ ->register('estado', (new Implement\Repository\Mapper())
+ ->setProperty('tipoEstadoVenta')
+ ->setFunction(function($data) {
+ return $this->tipoEstadoVentaRepository->fetchById($data['estado']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'));
+ return $this->parseData(new Model\Venta\EstadoVenta(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\EstadoVenta
+ {
+ $model->id = $this->saveNew(
+ ['venta', 'estado', 'fecha'],
+ [$model->venta->id, $model->tipoEstadoVenta->id, $model->fecha->format('Y-m-d')]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\EstadoVenta
+ {
+ return $this->update($model, ['venta', 'estado', 'fecha'], $new_data);
+ }
+
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('venta = ?');
+ return $this->fetchMany($query, [$venta_id]);
+ }
+ public function fetchCurrentByVenta(int $venta_id): Model\Venta\EstadoVenta
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined("JOIN (SELECT MAX(id) AS id, venta FROM {$this->getTable()} GROUP BY venta) ev0 ON ev0.id = a.id")
+ ->where('a.venta = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Pago.php b/app/src/Repository/Venta/Pago.php
new file mode 100644
index 0000000..4847037
--- /dev/null
+++ b/app/src/Repository/Venta/Pago.php
@@ -0,0 +1,120 @@
+setTable('pago');
+ }
+
+ public function create(?array $data = null): Model\Venta\Pago
+ {
+ $map = (new Implement\Repository\MapperParser(['valor', 'identificador', 'uf', 'pagador']))
+ ->register('banco', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['banco'] === null or $data['banco'] === 0) {
+ return null;
+ }
+ return $this->bancoRepository->fetchById($data['banco']);
+ }))
+ ->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('tipoPago')
+ ->setFunction(function($data) {
+ if ($data['tipo'] === null) {
+ return null;
+ }
+ return $this->tipoPagoRepository->fetchById($data['tipo']);
+ }))
+ ->register('fecha', (new Implement\Repository\Mapper\DateTime('fecha'))
+ ->setDefault(null))
+ ->register('asociado', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['asociado'] === null) {
+ return null;
+ }
+ return $this->fetchById($data['asociado']);
+ }));
+ return $this->parseData(new Model\Venta\Pago(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Pago
+ {
+ $model->id = $this->saveNew(
+ ['valor', 'banco', 'tipo', 'identificador', 'fecha', 'uf', 'pagador', 'asociado'],
+ [$model->valor, $model->banco?->id, $model->tipoPago?->id, $model->identificador, $model->fecha?->format('Y-m-d H:i:s'), $model->uf, $model->pagador, $model->asociado?->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Pago
+ {
+ return $this->update($model, ['valor', 'banco', 'tipo', 'identificador', 'fecha', 'uf', 'pagador', 'asociado'], $new_data);
+ }
+
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = "SELECT a.*
+FROM (
+ SELECT a.*, venta.id AS venta_id, 'cuota' AS fuente
+ FROM pago a
+ JOIN cuota ON cuota.pago = a.id
+ JOIN venta ON venta.pie = cuota.pie
+ UNION ALL
+ SELECT a.*, venta.id AS venta_id, 'reajuste' AS fuente
+ FROM pago a
+ JOIN pie ON pie.reajuste = a.id
+ JOIN venta ON venta.pie = pie.id
+ UNION ALL
+ SELECT a.*, venta.id AS venta_id, 'credito' AS fuente
+ FROM pago a
+ JOIN credito ON credito.pago = a.id
+ JOIN venta ON venta.credito = credito.id
+ UNION ALL
+ SELECT a.*, venta.id AS venta_id, 'escritura' AS fuente
+ FROM pago a
+ JOIN escritura ON escritura.pago = a.id
+ JOIN venta ON venta.escritura = escritura.id
+ UNION ALL
+ SELECT a.*, venta.id AS venta_id, 'subsidio' AS fuente
+ FROM pago a
+ JOIN subsidio ON subsidio.subsidio = a.id
+ JOIN venta ON venta.subsidio = subsidio.id
+ UNION ALL
+ SELECT a.*, venta.id AS venta_id, 'ahorro' AS fuente
+ FROM pago a
+ JOIN subsidio ON subsidio.pago = a.id
+ JOIN venta ON venta.subsidio = subsidio.id
+ ) a
+ JOIN (SELECT e1.* FROM estado_pago e1 JOIN (SELECT MAX(id) AS id, pago FROM estado_pago GROUP BY pago) e0 ON e0.id = e1.id) ep ON ep.pago = a.id
+ JOIN tipo_estado_pago tep ON tep.id = ep.estado
+WHERE venta_id = ?";
+ return $this->fetchMany($query, [$venta_id]);
+ }
+ public function fetchByValue(int $value): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor = ? OR ROUND(valor/uf, 3) = ?');
+ return $this->fetchMany($query, [$value, $value]);
+ }
+ public function fetchDevolucionByVenta(int $venta_id): Model\Venta\Pago
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.devolucion = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Pie.php b/app/src/Repository/Venta/Pie.php
new file mode 100644
index 0000000..7faf91b
--- /dev/null
+++ b/app/src/Repository/Venta/Pie.php
@@ -0,0 +1,84 @@
+setTable('pie');
+ }
+
+ public function create(?array $data = null): Model\Venta\Pie
+ {
+ $map = (new Implement\Repository\MapperParser(['valor', 'uf', 'cuotas']))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('asociado', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['asociado'] === null or $data['asociado'] === 0) {
+ return null;
+ }
+ return $this->fetchById($data['asociado']);
+ }))
+ ->register('reajuste', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['reajuste'] === null or $data['reajuste'] === 0) {
+ return null;
+ }
+ return $this->pagoRepository->fetchById($data['reajuste']);
+ }));
+ return $this->parseData(new Model\Venta\Pie(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Pie
+ {
+ $model->id = $this->saveNew(
+ ['fecha', 'valor', 'uf', 'cuotas', 'asociado', 'reajuste'],
+ [$model->fecha->format('Y-m-d H:i:s'), $model->valor, $model->uf, $model->cuotas, $model->asociado?->id, $model->reajuste?->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Pie
+ {
+ return $this->update($model, ['fecha', 'valor', 'uf', 'cuotas', 'asociado', 'reajuste'], $new_data);
+ }
+
+ public function fetchAsociados(int $pie_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('asociado = ?');
+ return $this->fetchMany($query, [$pie_id]);
+ }
+ public function fetchByValue(float $value): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('valor = ?');
+ return $this->fetchMany($query, [$value]);
+ }
+ public function fetchByReajuste(int $reajuste_id): Model\Venta\Pie
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('reajuste = ?');
+ return $this->fetchOne($query, [$reajuste_id]);
+ }
+ public function fetchByVenta(int $venta_id): Model\Venta\Pie
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.pie = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Precio.php b/app/src/Repository/Venta/Precio.php
new file mode 100644
index 0000000..f569afe
--- /dev/null
+++ b/app/src/Repository/Venta/Precio.php
@@ -0,0 +1,80 @@
+setTable('precio');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['valor']))
+ ->register('unidad', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->unidadRepository->fetchById($data['unidad']);
+ }));
+ return $this->parseData(new Model\Venta\Precio(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['unidad', 'valor'],
+ [$model->unidad->id, $model->valor]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['unidad', 'valor'], $new_data);
+ }
+
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.* FROM `estado_precio` e1 JOIN (SELECT MAX(`id`) AS 'id', `precio` FROM `estado_precio` GROUP BY `precio`) e0 ON e0.`id` = e1.`id`) ep ON ep.`precio` = a.`id`
+ JOIN `tipo_estado_precio` tep ON tep.`id` = ep.`estado`
+ JOIN `unidad` ON `unidad`.`id` = a.`unidad`
+ JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = `unidad`.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`
+WHERE ptu.`proyecto` = ? AND tep.`descripcion` = 'vigente'
+ORDER BY tu.`orden`, ptu.`nombre`, `unidad`.`subtipo`, LPAD(`unidad`.`descripcion`, 4, '0')";
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchByUnidad(int $unidad_id): array
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.* FROM `estado_precio` e1 JOIN (SELECT MAX(`id`) AS 'id', `precio` FROM `estado_precio` GROUP BY `precio`) e0 ON e0.`id` = e1.`id`) ep ON ep.`precio` = a.`id`
+ JOIN `tipo_estado_precio` tep ON tep.`id` = ep.`estado`
+WHERE `unidad` = ?";
+ return $this->fetchMany($query, [$unidad_id]);
+ }
+ public function fetchVigenteByUnidad(int $unidad_id): Define\Model
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.* FROM `estado_precio` e1 JOIN (SELECT MAX(`id`) AS 'id', `precio` FROM `estado_precio` GROUP BY `precio`) e0 ON e0.`id` = e1.`id`) ep ON ep.`precio` = a.`id`
+ JOIN `tipo_estado_precio` tep ON tep.`id` = ep.`estado`
+WHERE `unidad` = ? AND tep.`descripcion` = 'vigente'";
+ return $this->fetchOne($query, [$unidad_id]);
+ }
+ public function fetchByUnidadAndDate(int $unidad_id, string $date_time): Define\Model
+ {
+ $query = "SELECT a.*
+FROM `{$this->getTable()}` a
+ JOIN (SELECT e1.* FROM `estado_precio` e1 JOIN (SELECT MAX(`id`) AS 'id', `precio` FROM `estado_precio` GROUP BY `precio`) e0 ON e0.`id` = e1.`id`) ep ON ep.`precio` = a.`id`
+ JOIN `tipo_estado_precio` tep ON tep.`id` = ep.`estado`
+WHERE `unidad` = ? AND ep.`fecha` <= ? AND tep.`descripcion` = 'vigente'";
+ return $this->fetchOne($query, [$unidad_id, $date_time]);
+ }
+}
diff --git a/app/src/Repository/Venta/Propiedad.php b/app/src/Repository/Venta/Propiedad.php
new file mode 100644
index 0000000..1549295
--- /dev/null
+++ b/app/src/Repository/Venta/Propiedad.php
@@ -0,0 +1,53 @@
+setTable('propiedad');
+ }
+
+ public function create(?array $data = null): Model\Venta\Propiedad
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('unidad_principal', (new Implement\Repository\Mapper())
+ ->setProperty('unidades')
+ ->setFunction(function($data) {
+ if (isset($data['id'])) {
+ return $this->unidadService->getByPropiedad($data['id']);
+ }
+ return [$this->unidadService->getById($data['unidad_principal'])];
+ }))
+ ->register('estado', new Implement\Repository\Mapper\Boolean('estado'));
+ return $this->parseData(new Model\Venta\Propiedad(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Propiedad
+ {
+ $model->id = $this->saveNew(
+ ['unidad_principal', 'estacionamientos', 'bodegas', 'estado'],
+ [$model->departamentos()[0]->id,
+ implode(',', array_map(function(Model\Venta\Unidad $unidad) {return $unidad->id;}, $model->estacionamientos())),
+ implode(',', array_map(function(Model\Venta\Unidad $unidad) {return $unidad->id;}, $model->bodegas())),
+ 1]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Propiedad
+ {
+ return $this->update($model, ['unidad_principal', 'estacionamientos', 'bodegas', 'estado'], $new_data);
+ }
+
+ public function fetchVigenteByUnidad(int $unidad_id): Model\Venta\Propiedad
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `unidad_principal` = ?";
+ return $this->fetchOne($query, [$unidad_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/PropiedadUnidad.php b/app/src/Repository/Venta/PropiedadUnidad.php
new file mode 100644
index 0000000..0febced
--- /dev/null
+++ b/app/src/Repository/Venta/PropiedadUnidad.php
@@ -0,0 +1,125 @@
+setTable('propiedad_unidad');
+ }
+
+ public function load(array $data_row): Define\Model
+ {
+ $unidad = $this->unidadRepository->fetchById($data_row['unidad']);
+ $data = [
+ 'id' => $unidad->id,
+ 'subtipo' => $unidad->subtipo,
+ 'piso' => $unidad->piso,
+ 'descripcion' => $unidad->descripcion,
+ 'orientacion' => $unidad->orientacion,
+ 'prorrateo' => $unidad->prorrateo,
+ 'pt' => $unidad->proyectoTipoUnidad->id,
+ 'pu_id' => $data_row['id'],
+ 'propiedad' => $data_row['propiedad'],
+ 'valor' => $data_row['valor']
+ ];
+ return parent::load($data);
+ }
+
+ public function create(?array $data = null): Model\Venta\PropiedadUnidad
+ {
+ $map = (new Implement\Repository\MapperParser(['subtipo', 'piso', 'descripcion', 'orientacion', 'prorrateo', 'valor', 'id']))
+ ->register('propiedad', (new Implement\Repository\Mapper())
+ ->setProperty('propiedad_id'))
+ ->register('pt', (new Implement\Repository\Mapper())
+ ->setProperty('proyectoTipoUnidad')
+ ->setFunction(function($data) {
+ return $this->proyectoTipoUnidadService->getById($data['pt']);
+ }));
+ return $this->parseData(new Model\Venta\PropiedadUnidad(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\PropiedadUnidad
+ {
+ $model->pu_id = $this->saveNew(['propiedad', 'unidad', 'valor'], [$model->propiedad_id, $model->id, $model->valor]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\PropiedadUnidad
+ {
+ return $this->update($model, ['propiedad', 'unidad', 'valor'], $new_data);
+ }
+
+ public function fetchById(int $id): Define\Model
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where("id = ?");
+ return $this->fetchOne($query, [$id]);
+ }
+
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN unidad ON a.unidad = unidad.id
+ JOIN venta ON venta.propiedad = a.propiedad')
+ ->where('venta.id = ?');
+ return $this->fetchMany($query, [$venta_id]);
+ }
+ public function fetchByPropiedad(int $propiedad_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN `unidad` ON a.`unidad` = `unidad`.`id`')
+ ->where('a.`propiedad` = ?')
+ ->group('`unidad`.`id`');
+ return $this->fetchMany($query, [$propiedad_id]);
+ }
+ public function remove(Define\Model $model): void
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->delete()->from($this->getTable())
+ ->where("id = ?");
+ $this->connection->execute($query, [$model->pu_id]);
+ }
+
+ protected function update(Define\Model $model, array $columns, array $data): Define\Model
+ {
+ $changes = [];
+ $values = [];
+ foreach ($columns as $column) {
+ if (isset($data[$column])) {
+ $changes []= $column;
+ $values []= $data[$column];
+ }
+ }
+
+ if (count($changes) === 0) {
+ return $model;
+ }
+ $columns_string = implode(', ', array_map(function($property) {return "`{$property}` = ?";}, $changes));
+ $query = $this->connection->getQueryBuilder()
+ ->update($this->getTable())
+ ->set($columns_string)
+ ->where("id = ?");
+ $values []= $model->{$this->getKey()};
+ $this->connection->execute($query, $values);
+ return $this->fetchById($model->{$this->getKey()});
+ }
+
+ protected function getKey(): string
+ {
+ return 'pu_id';
+ }
+}
diff --git a/app/src/Repository/Venta/Propietario.php b/app/src/Repository/Venta/Propietario.php
new file mode 100644
index 0000000..ff23398
--- /dev/null
+++ b/app/src/Repository/Venta/Propietario.php
@@ -0,0 +1,77 @@
+setTable('propietario');
+ }
+
+ protected function getKey(): string
+ {
+ return 'rut';
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['rut', 'dv', 'nombres']))
+ ->register('apellido_paterno', (new Implement\Repository\Mapper())
+ ->setProperty('apellidos')
+ ->setFunction(function($data) {
+ $arr = [
+ 'paterno' => $data['apellido_paterno']
+ ];
+ if ($data['apellido_materno'] !== '') {
+ $arr['materno'] = $data['apellido_materno'];
+ }
+ return $arr;
+ }))
+ ->register('direccion', (new Implement\Repository\Mapper())
+ ->setProperty('datos')
+ ->setFunction(function($data) {
+ $datos = new Model\Venta\Datos();
+ if ($data['direccion'] !== null and $data['direccion'] !== 0) {
+ $datos->direccion = $this->direccionRepository->fetchById($data['direccion']);
+ }
+ return $datos;
+ }))
+ ->register('representante', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['representante'] === null or $data['representante'] === 0) {
+ return null;
+ }
+ return $this->fetchById($data['representante']);
+ }))
+ ->register('otro', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ if ($data['otro'] === null) {
+ return null;
+ }
+ return $data['otro'] !== 0;
+ })
+ ->setDefault(null));
+ return $this->parseData(new Model\Venta\Propietario(), $data, $map);
+ }
+
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->rut = $this->saveNew(
+ ['rut', 'dv', 'nombres', 'apellido_paterno', 'apellido_materno', 'direccion', 'otro', 'representante'],
+ [$model->rut, $model->dv, $model->nombres, $model->apellidos['paterno'], $model->apellidos['materno'], $model->datos->direccion->id, $model->otro->rut ?? 0, $model->representante->rut ?? 0]
+ );
+ return $model;
+ }
+
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['dv', 'nombres', 'apellido_paterno', 'apellido_materno', 'direccion', 'otro', 'representante'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Venta/Subsidio.php b/app/src/Repository/Venta/Subsidio.php
new file mode 100644
index 0000000..7ae4563
--- /dev/null
+++ b/app/src/Repository/Venta/Subsidio.php
@@ -0,0 +1,61 @@
+setTable('subsidio');
+ }
+
+ public function create(?array $data = null): Model\Venta\Subsidio
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('pago', (new Implement\Repository\Mapper())
+ ->setProperty('ahorro')
+ ->setFunction(function($data) {
+ return $this->pagoRepository->fetchById($data['pago']);
+ }))
+ ->register('subsidio', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->pagoRepository->fetchById($data['subsidio']);
+ }));
+ return $this->parseData(new Model\Venta\Subsidio(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Subsidio
+ {
+ $model->id = $this->saveNew(
+ ['pago', 'subsidio'],
+ [$model->ahorro->id, $model->subsidio->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Subsidio
+ {
+ return $this->update($model, ['pago', 'subsidio'], $new_data);
+ }
+
+ public function fetchByPago(int $pago_id): Model\Venta\Subsidio
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('subsidio = ? OR pago = ?');
+ return $this->fetchOne($query, [$pago_id, $pago_id]);
+ }
+ public function fetchByVenta(int $venta_id): Model\Venta\Subsidio
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*')
+ ->from("{$this->getTable()} a")
+ ->joined('JOIN venta ON venta.subsidio = a.id')
+ ->where('venta.id = ?');
+ return $this->fetchOne($query, [$venta_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoEstadoCierre.php b/app/src/Repository/Venta/TipoEstadoCierre.php
new file mode 100644
index 0000000..2264d4b
--- /dev/null
+++ b/app/src/Repository/Venta/TipoEstadoCierre.php
@@ -0,0 +1,35 @@
+setTable('tipo_estado_cierre');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']))
+ ->register('vigente', new Implement\Repository\Mapper\Boolean('vigente'));
+ return $this->parseData(new Model\Venta\TipoEstadoCierre(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'vigente'],
+ [$model->descripcion, $model->vigente ? 1 : 0]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion', 'vigente'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoEstadoPago.php b/app/src/Repository/Venta/TipoEstadoPago.php
new file mode 100644
index 0000000..394739e
--- /dev/null
+++ b/app/src/Repository/Venta/TipoEstadoPago.php
@@ -0,0 +1,41 @@
+setTable('tipo_estado_pago');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']))
+ ->register('active', (new Implement\Repository\Mapper\Boolean('active', 'activo', true)));
+ return $this->parseData(new Model\Venta\TipoEstadoPago(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Define\Model
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoEstadoPrecio.php b/app/src/Repository/Venta/TipoEstadoPrecio.php
new file mode 100644
index 0000000..a684168
--- /dev/null
+++ b/app/src/Repository/Venta/TipoEstadoPrecio.php
@@ -0,0 +1,34 @@
+setTable('tipo_estado_precio');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion']);
+ return $this->parseData(new Model\Venta\TipoEstadoPrecio(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoEstadoVenta.php b/app/src/Repository/Venta/TipoEstadoVenta.php
new file mode 100644
index 0000000..5043963
--- /dev/null
+++ b/app/src/Repository/Venta/TipoEstadoVenta.php
@@ -0,0 +1,41 @@
+setTable('tipo_estado_venta');
+ }
+
+ public function create(?array $data = null): Model\Venta\TipoEstadoVenta
+ {
+ $map = (new Implement\Repository\MapperParser(['descripcion']))
+ ->register('activa', new Implement\Repository\Mapper\Boolean('activa'));
+ return $this->parseData(new Model\Venta\TipoEstadoVenta(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\TipoEstadoVenta
+ {
+ $model->id = $this->saveNew(
+ ['descripcion', 'activa'],
+ [$model->descripcion, $model->activa ? 1 : 0]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\TipoEstadoVenta
+ {
+ return $this->update($model, ['descripcion', 'activa'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Model\Venta\TipoEstadoVenta
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoPago.php b/app/src/Repository/Venta/TipoPago.php
new file mode 100644
index 0000000..0b2f365
--- /dev/null
+++ b/app/src/Repository/Venta/TipoPago.php
@@ -0,0 +1,40 @@
+setTable('tipo_pago');
+ }
+
+ public function create(?array $data = null): Model\Venta\TipoPago
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion']);
+ return $this->parseData(new Model\Venta\TipoPago(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\TipoPago
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\TipoPago
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+
+ public function fetchByDescripcion(string $descripcion): Model\Venta\TipoPago
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `descripcion` = ?";
+ return $this->fetchOne($query, [$descripcion]);
+ }
+}
diff --git a/app/src/Repository/Venta/TipoValorCierre.php b/app/src/Repository/Venta/TipoValorCierre.php
new file mode 100644
index 0000000..4237a6d
--- /dev/null
+++ b/app/src/Repository/Venta/TipoValorCierre.php
@@ -0,0 +1,34 @@
+setTable('tipo_valor_cierre');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = new Implement\Repository\MapperParser(['descripcion']);
+ return $this->parseData(new Model\Venta\TipoValorCierre(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['descripcion'],
+ [$model->descripcion]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['descripcion'], $new_data);
+ }
+}
diff --git a/app/src/Repository/Venta/Unidad.php b/app/src/Repository/Venta/Unidad.php
new file mode 100644
index 0000000..cdefc57
--- /dev/null
+++ b/app/src/Repository/Venta/Unidad.php
@@ -0,0 +1,203 @@
+setTable('unidad');
+ }
+
+ public function create(?array $data = null): Model\Venta\Unidad
+ {
+ $map = (new Implement\Repository\MapperParser(['subtipo', 'piso', 'descripcion', 'orientacion', 'prorrateo']))
+ ->register('pt', (new Implement\Repository\Mapper())
+ ->setProperty('proyectoTipoUnidad')
+ ->setFunction(function($data) {
+ return $this->proyectoTipoUnidadService->getById($data['pt']);
+ }));
+ return $this->parseData(new Model\Venta\Unidad(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Unidad
+ {
+ $model->id = $this->saveNew(
+ ['subtipo', 'piso', 'descripcion', 'orientacion', 'pt'],
+ [$model->subtipo, $model->piso, $model->descripcion, $model->orientacion, $model->proyectoTipoUnidad->id]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Unidad
+ {
+ return $this->update($model, ['subtipo', 'piso', 'descripcion', 'orientacion', 'pt'], $new_data);
+ }
+ public function editProrrateo(Model\Venta\Unidad $model, array $new_data): Model\Venta\Unidad
+ {
+ try {
+ $query = $this->connection->getQueryBuilder()
+ ->select('prorrateo')
+ ->from('unidad_prorrateo')
+ ->where('unidad_id = ?');
+ $result = $this->connection->execute($query, [$model->id])->fetch(PDO::FETCH_ASSOC);
+ if ($result === false) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ if ($new_data['prorrateo'] !== $result['prorrateo']) {
+ $query = $this->connection->getQueryBuilder()
+ ->update('unidad_prorrateo')
+ ->set('prorrateo = ?')
+ ->where('unidad_id = ?');
+ $this->connection->execute($query, [$new_data['prorrateo'], $model->id]);
+ $model->prorrateo = $new_data['prorrateo'];
+ }
+ } catch (PDOException | Implement\Exception\EmptyResult) {
+ $query = $this->connection->getQueryBuilder()
+ ->insert()
+ ->into('unidad_prorrateo')
+ ->columns(['unidad_id', 'prorrateo'])
+ ->values(['?', '?']);
+ try {
+ $this->connection->execute($query, [$model->id, $new_data['prorrateo']]);
+ $model->prorrateo = $new_data['prorrateo'];
+ } catch (PDOException) {
+ throw new Implement\Exception\EmptyResult($query);
+ }
+ }
+ return $model;
+ }
+
+ public function fetchById(int $id): Model\Venta\Unidad
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->where('a.id = ?');
+ return $this->fetchOne($query, [$id]);
+ }
+
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined('JOIN propiedad_unidad pu ON pu.unidad = a.id
+ JOIN venta ON venta.propiedad = pu.propiedad')
+ ->where('venta.id = ?');
+ return $this->fetchMany($query, [$venta_id]);
+ }
+ public function fetchByPropiedad(int $propiedad_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined('JOIN `propiedad_unidad` pu ON pu.`unidad` = a.`id`')
+ ->where('pu.propiedad = ?')
+ ->group('a.id');
+ return $this->fetchMany($query, [$propiedad_id]);
+ }
+ public function fetchByCierre(int $cierre_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined("JOIN `unidad_cierre` uc ON uc.`unidad` = a.`id`
+ JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = a.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`")
+ ->where('uc.cierre = ?')
+ ->group('a.id')
+ ->order("tu.orden, LPAD(a.descripcion, 4, '0')");
+ return $this->fetchMany($query, [$cierre_id]);
+ }
+ public function fetchByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined("JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = a.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`")
+ ->where('ptu.proyecto = ?')
+ ->order('tu.orden');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchDisponiblesByProyecto(int $proyecto_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('DISTINCT a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined("JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = a.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`
+ LEFT OUTER JOIN `propiedad_unidad` pu ON pu.`unidad` = a.`id`
+ LEFT OUTER JOIN `venta` ON `venta`.`propiedad` = `pu`.`propiedad`
+ LEFT OUTER JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) as 'id', `venta` FROM `estado_venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ LEFT OUTER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`")
+ ->where("ptu.`proyecto` = ? AND (pu.`id` IS NULL OR `venta`.`id` IS NULL OR tev.`activa` = 0)")
+ ->order('tu.orden');
+ return $this->fetchMany($query, [$proyecto_id]);
+ }
+ public function fetchDisponiblesByDescripcionAndTipo(string $descripcion, string $tipo): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('DISTINCT a.*, up.prorrateo')
+ ->from("{$this->getTable()} a")
+ ->joined($this->joinProrrateo())
+ ->joined("JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = a.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`
+ LEFT OUTER JOIN `propiedad_unidad` pu ON pu.`unidad` = a.`id`
+ LEFT OUTER JOIN `venta` ON `venta`.`propiedad` = pu.`propiedad`
+ LEFT OUTER JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) as 'id', `venta` FROM `estado_venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ LEFT OUTER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`")
+ ->where("a.`descripcion` LIKE ? AND tu.`descripcion` = ? AND (pu.`id` IS NULL OR `venta`.`id` IS NULL OR tev.`activa` = 0)");
+ return $this->fetchMany($query, [$descripcion, $tipo]);
+ }
+ public function fetchDisponiblesIdsByDescripcionAndTipo(string $descripcion, string $tipo): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('a.id')
+ ->from("{$this->getTable()} a")
+ ->joined("JOIN `proyecto_tipo_unidad` ptu ON ptu.`id` = a.`pt`
+ JOIN `tipo_unidad` tu ON tu.`id` = ptu.`tipo`
+ LEFT OUTER JOIN `propiedad_unidad` pu ON pu.`unidad` = a.`id`
+ LEFT OUTER JOIN `venta` ON `venta`.`propiedad` = pu.`propiedad`
+ LEFT OUTER JOIN (SELECT ev1.* FROM `estado_venta` ev1 JOIN (SELECT MAX(`id`) as 'id', `venta` FROM `estado_venta`) ev0 ON ev0.`id` = ev1.`id`) ev ON ev.`venta` = `venta`.`id`
+ LEFT OUTER JOIN `tipo_estado_venta` tev ON tev.`id` = ev.`estado`")
+ ->where("a.`descripcion` LIKE ? AND tu.`descripcion` = ? AND (pu.`id` IS NULL OR `venta`.`id` IS NULL OR tev.`activa` = 0)");
+ return $this->connection->execute($query, [$descripcion, $tipo])->fetchAll(PDO::FETCH_ASSOC);
+ }
+ public function fetchByIdForSearch(int $unidad_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select('unidad.id AS id, unidad.descripcion AS descripcion')
+ ->columns('proyecto.id AS proyecto_id, proyecto.descripcion AS proyecto_descripcion')
+ ->columns('tu.descripcion AS tipo_unidad_descripcion')
+ ->columns('ptu.m2 + ptu.logia + ptu.terraza AS superficie')
+ ->columns('precio.valor AS precio')
+ ->from($this->getTable())
+ ->joined('JOIN proyecto_tipo_unidad ptu ON ptu.id = unidad.pt')
+ ->joined('JOIN proyecto ON proyecto.id = ptu.proyecto')
+ ->joined('JOIN tipo_unidad tu ON tu.id = ptu.tipo')
+ ->joined('JOIN precio ON precio.unidad = unidad.id')
+ ->joined('JOIN (SELECT ep1.* FROM estado_precio ep1 JOIN (SELECT MAX(id) AS id, precio FROM estado_precio GROUP BY precio) ep0 ON ep0.id = ep1.id) ep ON ep.precio = precio.id')
+ ->where('unidad.id = ?')
+ ->group('unidad.id');
+ return $this->connection->execute($query, [$unidad_id])->fetch(PDO::FETCH_ASSOC);
+ }
+
+ protected function joinProrrateo(): string
+ {
+ return "LEFT OUTER JOIN unidad_prorrateo up ON up.unidad_id = a.id";
+ }
+}
diff --git a/app/src/Repository/Venta/ValorCierre.php b/app/src/Repository/Venta/ValorCierre.php
new file mode 100644
index 0000000..5997e1b
--- /dev/null
+++ b/app/src/Repository/Venta/ValorCierre.php
@@ -0,0 +1,52 @@
+setTable('valor_cierre');
+ }
+
+ public function create(?array $data = null): Define\Model
+ {
+ $map = (new Implement\Repository\MapperParser(['valor']))
+ ->register('cierre', (new Implement\Repository\Mapper())
+ ->setFunction(function($data) {
+ return $this->cierreRepository->fetchById($data['cierre']);
+ }))
+ ->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('tipoValorCierre')
+ ->setFunction(function($data) {
+ return $this->tipoValorCierreRepository->fetchById($data['tipo']);
+ }));
+ return $this->parseData(new Model\Venta\ValorCierre(), $data, $map);
+ }
+ public function save(Define\Model $model): Define\Model
+ {
+ $model->id = $this->saveNew(
+ ['cierre', 'tipo', 'valor'],
+ [$model->cierre->id, $model->tipoValorCierre->id, $model->valor]
+ );
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Define\Model
+ {
+ return $this->update($model, ['cierre', 'tipo', 'valor'], $new_data);
+ }
+
+ public function fetchByCierre(int $cierre_id): array
+ {
+ $query = "SELECT * FROM `{$this->getTable()}` WHERE `cierre` = ?";
+ return $this->fetchMany($query, [$cierre_id]);
+ }
+}
diff --git a/app/src/Service/Cartola.php b/app/src/Service/Cartola.php
new file mode 100644
index 0000000..488feb8
--- /dev/null
+++ b/app/src/Service/Cartola.php
@@ -0,0 +1,127 @@
+bancos[$name] = $banco;
+ return $this;
+ }
+ public function process(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $mes, UploadedFileInterface $file): array
+ {
+ return $this->bancos[strtolower($banco->nombre)]->process($file);
+ }
+ public function export(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $mes, array $movimientos): string
+ {
+ return $this->exporter->export($inmobiliaria, $banco, $mes, $movimientos);
+ }
+ public function diaria(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, UploadedFileInterface $file): array
+ {
+ $ms = $this->getMovimientosDiarios($cuenta->banco, $file);
+
+ $cartolaData = [
+ 'cargos' => 0,
+ 'abonos' => 0,
+ 'saldo' => 0
+ ];
+ $movimientos = [];
+ foreach ($ms as $m) {
+ $movimiento = $this->buildMovimiento($cuenta, $m);
+ $movimiento = $this->movimientoService->process($movimiento);
+
+ if ($movimiento->fecha->getTimestamp() === $fecha->getTimestamp()) {
+ $movimientos []= $movimiento;
+ $cartolaData['cargos'] += $movimiento->cargo;
+ $cartolaData['abonos'] += $movimiento->abono;
+ }
+ if ($movimiento->fecha->getTimestamp() > $fecha->getTimestamp()) {
+ continue;
+ }
+ $cartolaData['saldo'] = $movimiento->saldo;
+ }
+ $cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
+ return compact('cartola', 'movimientos');
+ }
+ public function diariaManual(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, array $data): array
+ {
+ $cartolaData = [
+ 'cargos' => 0,
+ 'abonos' => 0,
+ 'saldos' => 0
+ ];
+ $movimientos = [];
+ foreach ($data as $row) {
+ $dataMovimiento = $row;
+ $dataMovimiento['fecha'] = $fecha->format('Y-m-d');
+ $dataMovimiento['documento'] = '';
+ $movimiento = $this->buildMovimiento($cuenta, $dataMovimiento);
+ $movimiento = $this->movimientoService->process($movimiento);
+
+ $movimientos []= $movimiento;
+ $cartolaData['cargos'] += $movimiento->cargo;
+ $cartolaData['abonos'] += $movimiento->abono;
+ $cartolaData['saldo'] = $movimiento->saldo;
+ }
+ $cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
+ return compact('cartola', 'movimientos');
+ }
+
+ protected function getMovimientosDiarios(Model\Banco $banco, UploadedFileInterface $file): array
+ {
+ $movimientos = $this->bancos[strtolower($banco->nombre)]->process($file);
+ return $this->bancos[strtolower($banco->nombre)]->processMovimientosDiarios($movimientos);
+ }
+ protected function buildCartola(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, array $data): Model\Cartola
+ {
+ try {
+ return $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ } catch (Exception\EmptyResult) {
+ $data['cuenta_id'] = $cuenta->id;
+ $data['fecha'] = $fecha->format('Y-m-d');
+ $cartola = $this->cartolaRepository->create($data);
+ return $this->cartolaRepository->save($cartola);
+ }
+ }
+ protected function buildMovimiento(Model\Inmobiliaria\Cuenta $cuenta, array $data): Model\Movimiento
+ {
+ try {
+ return $this->movimientoRepository
+ ->fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo(
+ $cuenta->id,
+ new DateTimeImmutable($data['fecha']),
+ $data['cargo'] ?? 0,
+ $data['abono'] ?? 0,
+ $data['saldo']
+ );
+ } catch (Exception\EmptyResult $exception) {
+ $data['cuenta_id'] = $cuenta->id;
+ $movimiento = $this->movimientoRepository->create($data);
+ return $this->movimientoRepository->save($movimiento);
+ }
+ }
+}
diff --git a/app/src/Service/Cartola/Itau.php b/app/src/Service/Cartola/Itau.php
new file mode 100644
index 0000000..0e3c486
--- /dev/null
+++ b/app/src/Service/Cartola/Itau.php
@@ -0,0 +1,168 @@
+ 'fecha',
+ 'Número de operación' => 'documento',
+ 'Descripción' => 'glosa',
+ 'Depósitos o abonos' => 'abono',
+ 'Giros o cargos' => 'cargo',
+ 'Documentos' => 'documento',
+ 'Movimientos' => 'glosa',
+ 'Saldos' => 'saldo'
+ ];
+ }
+
+ protected function parseFile(UploadedFileInterface $uploadedFile): array
+ {
+ $filename = '/tmp/cartola.xls';
+ $uploadedFile->moveTo($filename);
+
+ $reader = PhpSpreadsheet\IOFactory::createReader('Xls');
+ $xlsx = $reader->load($filename);
+ $sheet = $xlsx->getActiveSheet();
+
+ $data = [];
+ try {
+ switch ($this->identifySheet($sheet)) {
+ case self::CUENTA_CORRIENTE:
+ $data = $this->parseCuentaCorriente($sheet);
+ break;
+ case self::ULTIMOS_MOVIMIENTOS:
+ $data = $this->parseUltimosMovimientos($sheet);
+ break;
+ }
+ } catch (PhpSpreadsheet\Exception $exception) {
+ $this->logger->critical($exception);
+ } finally {
+ unlink($filename);
+ }
+ return $data;
+ }
+ protected function parseCuentaCorriente(PhpSpreadsheet\Worksheet\Worksheet $sheet): array
+ {
+ $found = false;
+ $year = 0;
+ $columns = [];
+ $data = [];
+ foreach ($sheet->getRowIterator() as $row) {
+ if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Cartola Histórica') {
+ $columnIndex = 'A';
+ foreach ($row->getColumnIterator() as $column) {
+ if ($column->getValue() !== 'Periodo') {
+ continue;
+ }
+ $columnIndex = $column->getColumn();
+ break;
+ }
+ $dates = explode(' - ', $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue());
+ $date = DateTimeImmutable::createFromFormat('d/m/Y', $dates[0]);
+ $year = $date->format('Y');
+ }
+ if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Movimientos') {
+ $found = true;
+ foreach ($row->getColumnIterator() as $column) {
+ if ($column->getValue() === null) {
+ break;
+ }
+ $columns[$column->getColumn()] = trim($column->getValue());
+ }
+ continue;
+ }
+ if (!$found) {
+ continue;
+ }
+ if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) {
+ break;
+ }
+ $rowData = [];
+ foreach ($columns as $columnIndex => $column) {
+ $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue();
+ $mapped = $this->columnMap()[$column];
+ if ($mapped === 'fecha') {
+ list($d, $m) = explode('/', $value);
+ $value = "{$year}-{$m}-{$d}";
+ }
+ if (in_array($mapped, ['cargo', 'abono', 'saldo'])) {
+ $value = (int) $value;
+ }
+ $rowData[$column] = $value;
+ }
+ $data []= $rowData;
+ }
+
+ return $data;
+ }
+ protected function parseUltimosMovimientos(PhpSpreadsheet\Worksheet\Worksheet $sheet): array
+ {
+ $found = false;
+ $data = [];
+ $columns = [];
+ foreach ($sheet->getRowIterator() as $row) {
+ if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Últimos Movimientos') {
+ $found = true;
+ continue;
+ }
+ if (!$found) {
+ continue;
+ }
+ if (count($columns) === 0) {
+ foreach ($row->getColumnIterator() as $cell) {
+ if ($cell->getValue() === null) {
+ break;
+ }
+ $columns[$cell->getColumn()] = trim($cell->getValue());
+ }
+ continue;
+ }
+ if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) {
+ break;
+ }
+ $rowData = [];
+ foreach ($columns as $columnIndex => $column) {
+ $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue();
+ $mapped = $this->columnMap()[$column] ?? $column;
+ if ($mapped === 'fecha') {
+ $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value, 'America/Santiago')->format('Y-m-d');
+ }
+ if (in_array($mapped, ['abono', 'cargo', 'saldo'])) {
+ $value = (int) $value;
+ }
+ $rowData[$column] = $value;
+ }
+ $data []= $rowData;
+ }
+ return $data;
+ }
+
+ protected function identifySheet(PhpSpreadsheet\Worksheet\Worksheet $sheet): int
+ {
+ foreach ($sheet->getRowIterator(1, 10) as $row) {
+ $value = $sheet->getCell("A{$row->getRowIndex()}")->getValue();
+ if ($value === 'Estado de Cuenta Corriente') {
+ return self::CUENTA_CORRIENTE;
+ }
+ if ($value === 'Consulta Saldos y Últimos movimientos') {
+ return self::ULTIMOS_MOVIMIENTOS;
+ }
+ }
+ throw new PhpSpreadsheet\Exception();
+ }
+}
diff --git a/app/src/Service/Cartola/Santander.php b/app/src/Service/Cartola/Santander.php
new file mode 100644
index 0000000..b6af374
--- /dev/null
+++ b/app/src/Service/Cartola/Santander.php
@@ -0,0 +1,141 @@
+ 'cargo',
+ 'abono' => 'abono',
+ 'DESCRIPCIÓN MOVIMIENTO' => 'glosa',
+ 'FECHA' => 'fecha',
+ 'N° DOCUMENTO' => 'documento',
+ 'SALDO' => 'saldo',
+ 'Fecha' => 'fecha',
+ 'Cargo ($)' => 'cargo',
+ 'Abono ($)' => 'abono',
+ 'Descripcin' => 'glosa',
+ 'Saldo Diario' => 'saldo'
+ ];
+ }
+ protected function parseFile(UploadedFileInterface $uploadedFile): array
+ {
+ $filename = '/tmp/cartola.xlsx';
+ $uploadedFile->moveTo($filename);
+
+ $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx');
+ try {
+ $xlsx = $reader->load($filename);
+ } catch (PhpSpreadsheet\Reader\Exception) {
+ return $this->parseHtml($filename);
+ }
+ $sheet = $xlsx->getActiveSheet();
+
+ $found = false;
+ $columns = [];
+ $data = [];
+ foreach ($sheet->getRowIterator() as $row) {
+ if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'MONTO') {
+ $found = true;
+ foreach ($row->getColumnIterator() as $column) {
+ if ($column->getValue() === null) {
+ break;
+ }
+ $columns[$column->getColumn()] = trim($column->getValue());
+ }
+ continue;
+ }
+ if (!$found) {
+ continue;
+ }
+ if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) {
+ break;
+ }
+ $rowData = [];
+ foreach ($columns as $columnIndex => $column) {
+ $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue();
+ $mapped = $this->columnMap()[$column] ?? $column;
+ if ($mapped === 'fecha') {
+ $value = implode('-', array_reverse(explode('/', $value)));
+ }
+ if ($column === 'MONTO') {
+ $value = (int) $value;
+ }
+ $rowData[$column] = $value;
+ }
+ if ($rowData['CARGO/ABONO'] === 'C') {
+ $rowData['MONTO'] = -$rowData['MONTO'];
+ $rowData['cargo'] = $rowData['MONTO'];
+ $rowData['abono'] = 0;
+ } else {
+ $rowData['cargo'] = 0;
+ $rowData['abono'] = $rowData['MONTO'];
+ }
+ $data []= $rowData;
+ }
+
+ return $data;
+ }
+ protected function parseHtml(string $filename): array
+ {
+ $data = [];
+ $lines = explode("\r\n", file_get_contents($filename));
+ $columns = [];
+ $found = false;
+ for ($rowIndex = 0; $rowIndex < count($lines); $rowIndex ++) {
+ if (!$found and str_contains($lines[$rowIndex], 'Cuenta Corriente: ')) {
+ $found = true;
+ $rowIndex += 2;
+ $columns = $this->parseHtmlRow($lines, $rowIndex);
+ continue;
+ }
+ if (!$found) {
+ continue;
+ }
+ $row = $this->parseHtmlRow($lines, $rowIndex);
+ if (str_contains($row[0], 'Saldo Contable')) {
+ break;
+ }
+ $row = array_combine($columns, $row);
+ $row['Fecha'] = implode('-', array_reverse(explode('-', $row['Fecha'])));
+ foreach (['Cargo ($)', 'Abono ($)', 'Saldo Diario'] as $column) {
+ $row[$column] = (int) str_replace('.', '', $row[$column]);
+ }
+ $row['Saldo Diario'] -= ($row['Abono ($)'] - $row['Cargo ($)']);
+ $row['N° DOCUMENTO'] = '';
+ $data []= $row;
+ }
+ return $data;
+ }
+ protected function parseHtmlRow(array $lines, int &$rowIndex): array
+ {
+ if (!str_contains($lines[$rowIndex ++], '')) {
+ return [];
+ }
+ $data = [];
+ while (!str_contains($lines[$rowIndex], '
')) {
+ $tags = substr_count($lines[$rowIndex], '<') - substr_count($lines[$rowIndex], '');
+ $ini = 0;
+ for ($t = 0; $t < $tags; $t ++) {
+ $ini = strpos($lines[$rowIndex], '>', $ini) + 1;
+ }
+ $end = strpos($lines[$rowIndex], '<', $ini + 1);
+ $cell = str_replace(' ', '', substr($lines[$rowIndex], $ini, $end - $ini));
+ $encoding = mb_detect_encoding($cell, ['Windows-1252', 'UTF-8']);
+ if ($encoding !== 'UTF-8') {
+ $cell = mb_convert_encoding($cell, $encoding, 'UTF-8');
+ $cell = str_replace('?', '', $cell);
+ }
+ $data []= $cell;
+ $rowIndex ++;
+ }
+ return $data;
+ }
+}
diff --git a/app/src/Service/Cartola/Security.php b/app/src/Service/Cartola/Security.php
new file mode 100644
index 0000000..fd10992
--- /dev/null
+++ b/app/src/Service/Cartola/Security.php
@@ -0,0 +1,128 @@
+getStream();
+ $stream->seek(3);
+ if ($stream->read(strlen('table')) === 'table') {
+ return $this->processHtm($uploadedFile);
+ }
+ return $this->processXls($uploadedFile);
+ }
+ protected function columnMap(): array
+ {
+ return [
+ 'fecha' => 'fecha',
+ 'descripción' => 'glosa',
+ 'número de documentos' => 'documento',
+ 'nº documento' => 'documento',
+ 'cargos' => 'cargo',
+ 'abonos' => 'abono',
+ 'saldos' => 'saldo'
+ ];
+ }
+
+ private function processXls(UploadedFileInterface $file): array
+ {
+ $filename = '/tmp/cartola.xls';
+ $file->moveTo($filename);
+ $xlsx = @PhpSpreadsheet\IOFactory::load($filename);
+ $worksheet = $xlsx->getActiveSheet();
+ $rows = $worksheet->getRowIterator(3);
+ $dataFound = false;
+ $columns = [];
+ $data = [];
+ foreach ($rows as $row) {
+ $cells = $row->getCellIterator();
+ $rowData = [];
+ foreach ($cells as $cell) {
+ if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() !== null and strtolower($cell->getCalculatedValue()) === "fecha ") {
+ $cols = $row->getColumnIterator();
+ foreach ($cols as $col) {
+ $columns[$col->getColumn()] = trim(strtolower($col->getCalculatedValue()), ' ');
+ }
+ $dataFound = true;
+ break;
+ }
+ if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() === null) {
+ $dataFound = false;
+ break;
+ }
+ if (!$dataFound) {
+ break;
+ }
+ $col = $columns[$cell->getColumn()];
+ $value = $cell->getCalculatedValue();
+ if ($col === 'fecha') {
+ if ((int) $cell->getValue() !== $cell->getValue()) {
+ $value = implode('-', array_reverse(explode('-', $cell->getValue())));
+ } else {
+ $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue(), 'America/Santiago')->format('Y-m-d');
+ }
+ }
+ $rowData[$col] = $value;
+ }
+ if (count($rowData) > 0) {
+ $data []= $rowData;
+ }
+ }
+ unlink($filename);
+ return $data;
+ }
+ private function processHtm(UploadedFileInterface $file): array
+ {
+ $filename = '/tmp/cartola.htm';
+ $file->moveTo($filename);
+
+ $domDocument = new DOMDocument();
+ $domDocument->loadHTML('' . file_get_contents($filename) . '');
+
+ $tables = $domDocument->getElementsByTagName('table');
+ $table = $tables->item(4);
+
+ $columns = [];
+ $data = [];
+ foreach ($table->getElementsByTagName('tr')->getIterator() as $rowIndex => $row) {
+ if ($rowIndex === 0) {
+ continue;
+ }
+ if (str_contains($row->textContent, 'cargos')) {
+ foreach ($row->getElementsByTagName('td')->getIterator() as $cell) {
+ $columns []= trim($cell->textContent);
+ }
+ continue;
+ }
+ $rowData = [];
+ foreach ($row->getElementsByTagName('td')->getIterator() as $colIndex => $cell) {
+ $col = $columns[$colIndex];
+ $value = trim($cell->textContent);
+ if ($col === 'fecha') {
+ $value = DateTimeImmutable::createFromFormat('d/m/Y', $value)->format('Y-m-d');
+ }
+ if (in_array($col, ['cargos', 'abonos', 'saldos'])) {
+ $value = (float) str_replace(',', '.', $value);
+ }
+ $rowData[$col] = $value;
+ }
+ $data []= $rowData;
+ }
+
+ return $data;
+ }
+}
diff --git a/app/src/Service/Contabilidad.php b/app/src/Service/Contabilidad.php
new file mode 100644
index 0000000..a5e87fd
--- /dev/null
+++ b/app/src/Service/Contabilidad.php
@@ -0,0 +1,20 @@
+tesoreriaService->build($fecha);
+ }
+}
diff --git a/app/src/Service/Contabilidad/Exporter/Nubox.php b/app/src/Service/Contabilidad/Exporter/Nubox.php
new file mode 100644
index 0000000..ba32e09
--- /dev/null
+++ b/app/src/Service/Contabilidad/Exporter/Nubox.php
@@ -0,0 +1,115 @@
+getActiveSheet();
+
+ $rowIndex = $this->buildHeaders($sheet);
+
+ foreach ($movimientos as $movimiento) {
+ $tipoCentro = '';
+ $cuenta = '';
+ $centro = '';
+ if ($movimiento->centro_costo !== '') {
+ $centroCosto = $this->centroCostoRepository->fetchById($movimiento->centro_costo);
+ $tipoCentro = substr($centroCosto->tipoCentro->descripcion, 0, 1);
+ $cuenta = $centroCosto->cuentaContable;
+ $centro = $centroCosto->id;
+ }
+ $fecha = (new DateTimeImmutable($movimiento->fecha))->format('d/m/Y');
+ $rowIndex = $this->add($sheet, [
+ 'Número' => '0',
+ 'Tipo' => $tipoCentro,
+ 'Fecha' => $fecha,
+ 'Glosa' => $movimiento->detalle,
+ 'Cuenta Detalle' => $cuenta,
+ 'Glosa Detalle' => '',
+ 'Centro Costo' => $centro,
+ 'Sucursal' => '',
+ 'Debe' => $movimiento->abono === 0 ? '' : $movimiento->abono,
+ 'Haber' => $movimiento->cargo === 0 ? '' : $movimiento->cargo,
+ 'Tipo Auxiliar' => 'B',
+ 'A: Rut Cliente-Proveedor/H: Rut Prestador' => '',
+ 'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador' => $movimiento->glosa,
+ 'A: Tipo De Documento/H: Tipo De Boleta Honorario' => '',
+ 'A: Folio /B: Numero Documento/H: Folio Boleta' => $movimiento->documento,
+ 'A/B/H: Monto' => ($movimiento->abono === 0) ? $movimiento->cargo : $movimiento->abono,
+ 'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión (DD/MM/AAAA)' => $fecha
+ ], $rowIndex);
+ }
+ $sheet->getStyle("I1:J{$rowIndex}")->getNumberFormat()
+ ->setFormatCode('#,##0');
+ $sheet->getStyle("O1:O{$rowIndex}")->getNumberFormat()
+ ->setFormatCode('##0');
+ $sheet->getStyle("P1:P{$rowIndex}")->getNumberFormat()
+ ->setFormatCode('#,##0');
+ foreach (range('A', 'Q') as $col) {
+ $sheet->getColumnDimension($col)->setAutoSize(true);
+ }
+ $sheet->getSheetView()->setZoomScale(90);
+
+ $writer = PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx');
+ $filename = "Cartola {$banco->nombre} - {$inmobiliaria->abreviacion} - {$mes->format('M Y')}.xlsx";
+ $writer->save(implode(DIRECTORY_SEPARATOR, [
+ $this->uploadFolder,
+ $filename
+ ]));
+ return $filename;
+ }
+
+ protected function getHeaders(): array
+ {
+ return [
+ 'Número',
+ 'Tipo',
+ 'Fecha',
+ 'Glosa',
+ 'Cuenta Detalle',
+ 'Glosa Detalle',
+ 'Centro Costo',
+ 'Sucursal',
+ 'Debe',
+ 'Haber',
+ 'Tipo Auxiliar',
+ 'A: Rut Cliente-Proveedor/H: Rut Prestador',
+ 'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador',
+ 'A: Tipo De Documento/H: Tipo De Boleta Honorario',
+ 'A: Folio /B: Numero Documento/H: Folio Boleta',
+ 'A/B/H: Monto',
+ 'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión (DD/MM/AAAA)'
+ ];
+ }
+ protected function buildHeaders(PhpSpreadsheet\Worksheet\Worksheet &$sheet, int $rowIndex = 1): int
+ {
+ $map = $this->getHeaders();
+ foreach ($map as $index => $header) {
+ $columnIndex = $index + 1;
+ $sheet->getCell([$columnIndex, $rowIndex])->setValue($header);
+ }
+ return $rowIndex + 1;
+ }
+ protected function add(PhpSpreadsheet\Worksheet\Worksheet &$sheet, array $row, int $rowIndex): int
+ {
+ $headers = $this->getHeaders();
+ foreach ($headers as $index => $header) {
+ $columnIndex = $index + 1;
+ $sheet->getCell([$columnIndex, $rowIndex])->setValue($row[$header]);
+ $sheet->getCell([$columnIndex, $rowIndex + 1])->setValue(($header === 'Tipo Auxiliar') ? 'A' : '');
+ }
+ return $rowIndex + 2;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria.php b/app/src/Service/Contabilidad/Informe/Tesoreria.php
new file mode 100644
index 0000000..63ff55c
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria.php
@@ -0,0 +1,293 @@
+movimientos = new class() {
+ public function __construct()
+ {
+ $this->dap = new class()
+ {
+ public array $ingresos = [];
+ public array $egresos = [];
+ };
+ }
+ public object $dap;
+ public array $ingresos = [];
+ public array $egresos = [];
+
+ const INGRESOS = 'ingresos';
+ const EGRESOS = 'egresos';
+ public function addDap(string $tipo, array $movimientos)
+ {
+ foreach ($movimientos as $movimiento) {
+ $this->dap->{$tipo} []= $movimiento;
+ }
+ return $this;
+ }
+ public function build(): array
+ {
+ return [
+ 'capital dap' => [
+ 'ingresos' => $this->dap->ingresos,
+ 'egresos' => $this->dap->egresos
+ ],
+ 'ingresos' => $this->ingresos,
+ 'egresos' => $this->egresos
+ ];
+ }
+ };
+ $this->totales = new class() {
+ public int $anterior = 0;
+ public int $actual = 0;
+ public int $ffmm = 0;
+ public int $deposito = 0;
+
+ public function diferencia(): int
+ {
+ return $this->actual - $this->anterior;
+ }
+ public function saldo(): int
+ {
+ return $this->diferencia() + $this->ffmm + $this->deposito;
+ }
+ public function cuentas(): int
+ {
+ return $this->actual;
+ }
+ public function ffmms(): int
+ {
+ return $this->ffmm;
+ }
+ public function depositos(): int
+ {
+ return $this->deposito;
+ }
+ public function caja(): int
+ {
+ return $this->cuentas() + $this->ffmms() + $this->depositos();
+ }
+ };
+ }
+
+ const DAP_INGRESOS = 'dap->ingresos';
+ const DAP_EGRESOS = 'dap->egresos';
+ const INGRESOS = 'ingresos';
+ const EGRESOS = 'egresos';
+ const TOTAL_ANTERIOR = 'anterior';
+ const TOTAL_ACTUAL = 'actual';
+ const TOTAL_FFMM = 'ffmm';
+ const TOTAL_DAP = 'deposito';
+
+ protected DateTimeInterface $anterior;
+ protected object $totales;
+ protected object $movimientos;
+
+ public function getAnterior(DateTimeInterface $fecha): DateTimeInterface
+ {
+ if (!isset($this->anterior)) {
+ $this->anterior = $fecha->sub(new DateInterval('P1D'));
+ if ($this->anterior->format('N') === '7') {
+ $this->anterior = $fecha->sub(new DateInterval('P3D'));
+ }
+ }
+ return $this->anterior;
+ }
+ public function build(DateTimeInterface $fecha): array
+ {
+ try {
+ $inmobiliarias = $this->inmobiliariaRepository->fetchAll();
+ } catch (Implement\Exception\EmptyResult) {
+ return [];
+ }
+ $informe = ['inmobiliarias' => []];
+ foreach ($inmobiliarias as $inmobiliaria) {
+ $informe['inmobiliarias'][$inmobiliaria->rut] = $this->buildInmobiliaria($inmobiliaria, $fecha);
+ }
+ $informe['movimientos'] = $this->buildMovimientos();
+ $informe['totales'] = $this->buildTotales();
+
+ //$this->buildInforme($fecha, $informe);
+
+ return $informe;
+ }
+ public function buildInforme(DateTimeInterface $fecha, array $data, string $type = 'Xlsx', ?string $filename = 'php://output'): void
+ {
+ $informe = $this->excelService->build($fecha, $data);
+ $this->excelService->save($fecha, $informe, $type, $filename);
+ }
+
+ protected function buildInmobiliaria(Model\Inmobiliaria $inmobiliaria, DateTimeInterface $fecha): object
+ {
+ $dataInmobiliaria = new class() {
+ public Model\Inmobiliaria $inmobiliaria;
+ public array $cuentas = [];
+ public function total(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->actual;
+ }, 0);
+ }
+ public function ffmm(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->ffmm;
+ }, 0);
+ }
+ public function deposito(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->deposito;
+ }, 0);
+ }
+ public function caja(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->saldo();
+ }, 0);
+ }
+ };
+ $dataInmobiliaria->inmobiliaria = $inmobiliaria;
+ try {
+ $cuentas = $this->cuentaRepository->fetchByInmobiliaria($inmobiliaria->rut);
+ } catch (Implement\Exception\EmptyResult) {
+ return $dataInmobiliaria;
+ }
+ foreach ($cuentas as $cuenta) {
+ $data = new class() {
+ public string $banco;
+ public string $numero;
+ public int $anterior = 0;
+ public int $actual = 0;
+ public int $ffmm = 0;
+ public int $deposito = 0;
+
+ public function diferencia(): int
+ {
+ return $this->actual - $this->anterior;
+ }
+ public function saldo(): int
+ {
+ return $this->diferencia() + $this->ffmm + $this->deposito;
+ }
+ };
+ $data->banco = $cuenta->banco->nombre;
+ $data->numero = $cuenta->cuenta;
+ try {
+ $depositos = $this->depositoRepository->fetchByCuenta($cuenta->id);
+ foreach ($depositos as $deposito) {
+ if ($deposito->termino < $fecha) {
+ continue;
+ }
+ $data->deposito += $deposito->capital;
+ $this->addTotal(self::TOTAL_DAP, $deposito->capital);
+
+ if ($deposito->inicio === $fecha) {
+ $this->addMovimientos(self::DAP_EGRESOS, [(object) [
+ 'cuenta' => $deposito->cuenta,
+ 'fecha' => $deposito->inicio,
+ 'cargo' => - $deposito->capital,
+ 'abono' => 0,
+ 'saldo' => - $deposito->capital,
+ 'glosa' => 'INVERSION DAP'
+ ]]);
+ }
+ if ($deposito->termino === $fecha) {
+ $data->deposito -= $deposito->capital;
+ $this->addTotal(self::TOTAL_DAP, -$deposito->capital);
+
+ $this->addMovimientos(self::DAP_INGRESOS, [(object) [
+ 'cuenta' => $deposito->cuenta,
+ 'fecha' => $deposito->termino,
+ 'cargo' => 0,
+ 'abono' => $deposito->capital,
+ 'saldo' => $deposito->capital,
+ 'glosa' => 'RESCATE DAP'
+ ]]);
+ }
+ }
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $cartola = $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ $data->actual = $cartola->saldo;
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $cartola = $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $this->getAnterior($fecha));
+ $data->anterior = $cartola->saldo;
+ } catch (Implement\Exception\EmptyResult) {}
+ if ($data->diferencia() !== 0) {
+ try {
+ $movimientos = $this->movimientoRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ $this->addMovimientos(self::INGRESOS,
+ array_filter($movimientos, function(Model\Movimiento $movimiento) {
+ return $movimiento->abono > 0;
+ }));
+ $this->addMovimientos(self::EGRESOS,
+ array_filter($movimientos, function(Model\Movimiento $movimiento) {
+ return $movimiento->cargo > 0;
+ }));
+ } catch (Implement\Exception\EmptyResult) {}
+ }
+ $dataInmobiliaria->cuentas []= $data;
+
+ $this->addTotal(
+ [self::TOTAL_ANTERIOR, self::TOTAL_ACTUAL],
+ [$data->anterior, $data->actual]
+ );
+ }
+ return $dataInmobiliaria;
+ }
+ protected function buildMovimientos(): array
+ {
+ return $this->movimientos->build();
+ }
+ protected function buildTotales(): object
+ {
+ return $this->totales;
+ }
+ protected function addMovimientos(string $tipo, array $movimientos): Tesoreria
+ {
+ if (str_contains($tipo, 'dap')) {
+ list($d, $t) = explode('->', $tipo);
+ $this->movimientos->addDap($t, $movimientos);
+ return $this;
+ }
+ foreach ($movimientos as $movimiento) {
+ $this->movimientos->{$tipo} []= $movimiento;
+ }
+ return $this;
+ }
+ protected function addTotal(string|array $tipo, int|array $total): Tesoreria
+ {
+ if (is_array($tipo)) {
+ foreach ($tipo as $i => $t) {
+ $this->addTotal($t, $total[$i]);
+ }
+ return $this;
+ }
+ $this->totales->{$tipo} += $total;
+ return $this;
+ }
+
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php
new file mode 100644
index 0000000..566908d
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php
@@ -0,0 +1,503 @@
+format('d.m.Y')}";
+ $informe = new PhpSpreadsheet\Spreadsheet();
+ $informe->getProperties()
+ ->setCompany('Incoviba')
+ ->setCreator('admin@incoviba.cl')
+ ->setTitle($title)
+ ->setSubject($title)
+ ->setCreated($fecha->getTimestamp());
+
+ $styles = [
+ 'font' => [
+ 'name' => 'Gill Sans MT',
+ 'size' => 12
+ ]
+ ];
+ $informe->getDefaultStyle()->applyFromArray($styles);
+
+ $sheet = $informe->getActiveSheet();
+ $sheet->setTitle($title);
+
+ $sheet->getColumnDimension('A')->setWidth('5.43');
+
+ $this->fillTitle($sheet, $fecha);
+ $this->fillFechas($sheet, $fecha);
+ $this->fillMonedas($sheet, $fecha);
+
+ $finalRow = $this->fillEmpresas($sheet, $data);
+ $finalRow = $this->fillCaja($sheet, $data, $finalRow + 2);
+
+ foreach (range('B', 'V') as $columnIndex) {
+ $sheet->getColumnDimension($columnIndex)->setAutoSize(true);
+ }
+
+ $this->setPageSetup($sheet, $finalRow);
+
+ return $informe;
+ }
+ public function save(DateTimeInterface $fecha, PhpSpreadsheet\Spreadsheet $informe, string $type = 'Xlsx', ?string $filename = null): void
+ {
+ if ($filename === null) {
+ $ext = strtolower($type);
+ $filename = implode(DIRECTORY_SEPARATOR, [$this->folder, "{$informe->getActiveSheet()->getTitle()}.{$ext}"]);
+ }
+ $writer = PhpSpreadsheet\IOFactory::createWriter($informe, $type);
+
+ if (str_starts_with($filename, 'php://')) {
+ $downloadFilename = "Informe de Tesorería {$fecha->format('d.m.Y')}.xlsx";
+ // ZipStream, used by PhpSpreadsheet when saving, sends headers
+ header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+ header("Content-Disposition: attachment;filename=\"{$downloadFilename}\"");
+ header('Cache-Control: max-age=0');
+ }
+
+ $writer->save($filename);
+ }
+
+ protected function getAnterior(DateTimeInterface $fecha): DateTimeInterface
+ {
+ if (!isset($this->anterior)) {
+ $this->anterior = $fecha->sub(new DateInterval('P1D'));
+ if ($this->anterior->format('N') === '7') {
+ $this->anterior = $fecha->sub(new DateInterval('P3D'));
+ }
+ }
+ return $this->anterior;
+ }
+ protected function fillTitle(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void
+ {
+ $intl = new IntlDateFormatter('es-CL');
+ $intl->setPattern('dd MMM yyyy');
+
+ $sheet->getCell('B2')->setValue('CONTROL DIARIO CAJA EMPRESAS');
+ $sheet->mergeCells('B2:V2');
+ $styles = [
+ 'font' => [
+ 'bold' => true,
+ 'size' => 18
+ ],
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'startColor' => [
+ 'argb' => 'FFFFC000'
+ ]
+ ],
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
+ ],
+ 'borders' => [
+ 'outline' => [
+ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN
+ ]
+ ]
+ ];
+ $sheet->getStyle('B2:V2')->applyFromArray($styles);
+ $sheet->getCell('B3')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha));
+ $styles = [
+ 'font' => [
+ 'size' => 18
+ ],
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
+ ],
+ 'numberFormat' => [
+ 'formatCode' => 'DD MMMM YYYY'
+ ]
+ ];
+ $sheet->getCell('B3')->getStyle()->applyFromArray($styles);
+ $sheet->mergeCells('B3:V3');
+ }
+ protected function fillFechas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void
+ {
+ $anterior = $this->getAnterior($fecha);
+ $sheet->getCell('B4')->setValue('Informe anterior');
+ $sheet->getCell('B5')->setValue('Informe actual');
+ $sheet->getCell('C4')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($anterior));
+ $sheet->getCell('C5')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha));
+ $sheet->getStyle('C4:C5')->getNumberFormat()->setFormatCode(PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY);
+ $sheet->getStyle('B4:C5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN);
+ }
+ protected function fillMonedas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void
+ {
+ $sheet->getCell('E4')->setValue('Valor UF');
+ $sheet->getCell('E5')->setValue('Valor Dólar');
+ $sheet->getCell('F4')->setValue($this->ufService->get($fecha));
+ $sheet->getCell('F5')->setValue($this->usdService->get($fecha));
+ $sheet->getStyle('F4:F5')->getNumberFormat()->setFormatCode("$ #,##0.00");
+ $sheet->getStyle('E4:F5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN);
+ }
+ protected function fillEmpresas(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, int $startRow = 7): int
+ {
+ $columns = ['EMPRESA', 'Banco', 'Cuenta', 'Saldo anterior', 'Saldo actual', 'Diferencia', 'FFMM', 'DAP',
+ 'Saldo empresa', 'Total Cuentas', 'Total FFMM', 'Total DAP', 'Caja Total'];
+ $styles = [
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
+ ],
+ 'borders' => [
+ 'outline' => [
+ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN
+ ]
+ ],
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'color' => [
+ 'argb' => 'FF333F4F'
+ ]
+ ],
+ 'font' => [
+ 'color' => [
+ 'argb' => PhpSpreadsheet\Style\Color::COLOR_WHITE
+ ]
+ ]
+ ];
+ $this->fillColumns($sheet, $columns, $styles, $startRow);
+
+ $rowIndex = $startRow + 1;
+ foreach ($data['inmobiliarias'] as $dataInmobiliaria) {
+ $rowIndex += $this->fillInmobiliaria($sheet, $dataInmobiliaria, $rowIndex);
+ }
+ $finalRow = $rowIndex;
+
+ $sheet->getStyle("B7:N{$finalRow}")->getBorders()->getAllBorders()
+ ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN)
+ ->getColor()->setARGB('FFD9D9D9');
+ $sheet->getStyle("C8:D{$finalRow}")->getAlignment()
+ ->setHorizontal(PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
+
+ $this->fillTotals($sheet, 7, $finalRow ++);
+ $sheet->getStyle("E8:N{$finalRow}")->getNumberFormat()
+ ->setFormatCode(self::CURRENCY_CODE);
+
+ return $finalRow;
+ }
+ protected function fillCaja(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, $startRow): int
+ {
+ $sheet->getCell("B{$startRow}")->setValue('CUADRATURA CAJA DÍA ANTERIOR');
+ $sheet->mergeCells("B{$startRow}:V{$startRow}");
+
+ $sheet->getStyle("B{$startRow}:V{$startRow}")->applyFromArray([
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER
+ ],
+ 'borders' => [
+ 'outline' => [
+ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN
+ ]
+ ],
+ 'font' => [
+ 'bold' => true
+ ],
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'color' => [
+ 'argb' => 'FFFFC000'
+ ]
+ ]
+ ]);
+
+ $rowIndex = $startRow;
+
+ $columns = ['EMPRESA', 'INGRESOS', 'EGRESOS', 'FECHA', 'BANCO', 'DESCRIPCIÓN', '', 'CATEGORIA', '', 'CC',
+ 'DETALLE', '', 'N° DOC.', 'RUT', 'NOMBRES', '', '', '', '', '', ''];
+ $styles = [
+ 'borders' => [
+ 'allBorders' => [
+ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN
+ ]
+ ],
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'startColor' => [
+ 'argb' => 'FFD9D9D9'
+ ]
+ ]
+ ];
+
+ $this->fillColumns($sheet, $columns, $styles, ++ $rowIndex);
+ $sheet->mergeCells("G{$rowIndex}:H{$rowIndex}")
+ ->mergeCells("I{$rowIndex}:J{$rowIndex}")
+ ->mergeCells("L{$rowIndex}:M{$rowIndex}")
+ ->mergeCells("P{$rowIndex}:R{$rowIndex}")
+ ->mergeCells("S{$rowIndex}:V{$rowIndex}");
+
+ $rowIndex += 2;
+ $sheet->getCell("T{$rowIndex}")
+ ->setValue("Saldo Consolidado al")
+ ->getStyle()->applyFromArray([
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT
+ ],
+ 'font' => [
+ 'bold' => true
+ ]
+ ]);
+ $sheet->getCell("U{$rowIndex}")->setValue("=C4")
+ ->getStyle()->applyFromArray([
+ 'font' => [
+ 'bold' => true
+ ],
+ 'numberFormat' => [
+ 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY
+ ]
+ ]);
+ $sheet->getCell("V{$rowIndex}")->setValue(0)->getStyle()->applyFromArray([
+ 'font' => [
+ 'bold' => true
+ ],
+ 'numberFormat' => [
+ 'formatCode' => self::CURRENCY_CODE
+ ]
+ ]);
+ $rowSaldoAnterior = $rowIndex;
+ $rowIndex ++;
+
+ $styles = [
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'startColor' => [
+ 'argb' => 'FFD9E1F2'
+ ]
+ ],
+ 'font' => [
+ 'bold' => true
+ ]
+ ];
+ $rowDap = null;
+ $rowIngreso = null;
+ $rowEgreso = null;
+ foreach ($data['movimientos'] as $tipo => $movimientos) {
+ if ($tipo === 'capital dap') {
+ $sheet->getCell("B{$rowIndex}")->setValue('CAPITAL DAP');
+ $sheet->getCell("T{$rowIndex}")->setValue('SUMA DAP');
+ $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles);
+ $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat()->setFormatCode(self::CURRENCY_CODE);
+ $totalRow = $rowIndex;
+ $rowDap = $rowIndex;
+ $rowIndex ++;
+ if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0) {
+ $sheet->getCell("V{$totalRow}")->setValue(0);
+ continue;
+ }
+ $start = $rowIndex;
+ foreach ($movimientos as $ms) {
+ foreach ($ms as $movimiento) {
+ $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon);
+ $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono);
+ $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo);
+ $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha));
+ $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre);
+ $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa);
+ $rowIndex ++;
+ }
+ }
+ $end = $rowIndex;
+ $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})");
+ $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE);
+ continue;
+ }
+ $sheet->getCell("B{$rowIndex}")->setValue(strtoupper($tipo));
+ $sheet->getCell("T{$rowIndex}")->setValue('SUMA '.strtoupper($tipo));
+ $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles);
+ $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat()
+ ->setFormatCode(self::CURRENCY_CODE);
+ $totalRow = $rowIndex;
+ if (!isset($rowIngreso) or $rowIngreso === null) {
+ $rowIngreso = $rowIndex;
+ } else {
+ $rowEgreso = $rowIndex;
+ }
+ $rowIndex ++;
+ if (count($movimientos) === 0) {
+ $sheet->getCell("V{$totalRow}")->setValue(0);
+ continue;
+ }
+ $start = $rowIndex;
+ foreach ($movimientos as $movimiento) {
+ $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon);
+ $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono);
+ $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo);
+ $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha));
+ $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre);
+ $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa);
+ $rowIndex ++;
+ }
+ $end = $rowIndex;
+ $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})");
+ $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat()
+ ->setFormatCode(self::CURRENCY_CODE);
+ }
+ $end = $rowIndex;
+ $rowIndex ++;
+
+ $sheet->getCell("B{$rowIndex}")->setValue('TOTAL');
+ $sheet->getCell("C{$rowIndex}")->setValue("=SUM(C{$startRow}:C{$end})");
+ $sheet->getCell("D{$rowIndex}")->setValue("=SUM(D{$startRow}:D{$end})");
+ $sheet->getCell("T{$rowIndex}")->setValue('Saldo final al')
+ ->getStyle()->applyFromArray([
+ 'alignment' => [
+ 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT
+ ],
+ 'font' => [
+ 'bold' => true
+ ]
+ ]);
+ $sheet->getCell("U{$rowIndex}")->setValue('=C5')
+ ->getStyle()->applyFromArray([
+ 'font' => [
+ 'bold' => true
+ ],
+ 'numberFormat' => [
+ 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY
+ ]
+ ]);
+ $sheet->getCell("V{$rowIndex}")->setValue("=V{$rowSaldoAnterior}+V{$rowDap}+V{$rowIngreso}+V{$rowEgreso}")->getStyle()->applyFromArray([
+ 'font' => [
+ 'bold' => true
+ ],
+ 'numberFormat' => [
+ 'formatCode' => self::CURRENCY_CODE
+ ]
+ ]);
+
+ $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray([
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'startColor' => [
+ 'argb' => 'FFD9D9D9'
+ ]
+ ],
+ 'font' => [
+ 'bold' => true
+ ]
+ ]);
+ $sheet->getStyle("C{$startRow}:D{$rowIndex}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE);
+ $columnRanges = [
+ ['B', 'B'],
+ ['C', 'C'],
+ ['D', 'D'],
+ ['E', 'E'],
+ ['F', 'F'],
+ ['G', 'H'],
+ ['I', 'J'],
+ ['K', 'K'],
+ ['L', 'M'],
+ ['N', 'N'],
+ ['O', 'O'],
+ ['P', 'R'],
+ ['S', 'V']
+ ];
+ foreach ($columnRanges as $range) {
+ $sheet->getStyle("{$range[0]}{$startRow}:{$range[1]}{$rowIndex}")->getBorders()->getOutline()
+ ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN);
+ }
+
+ return $rowIndex;
+ }
+ protected function fillColumns(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $columns, array $styles, $rowIndex): void
+ {
+ $columnIndex = 2;
+ foreach ($columns as $index => $column) {
+ $columnIndex = 2 + $index;
+ $sheet->getCell([$columnIndex, $rowIndex])->setValue($column);
+ }
+ $sheet->getStyle([2, $rowIndex, $columnIndex, $rowIndex])->applyFromArray($styles);
+ }
+ protected function fillInmobiliaria(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $dataInmobiliaria, int $baseRowIndex): int
+ {
+ $rowIndex = $baseRowIndex;
+ $sheet->getCell("B{$rowIndex}")->setValue($dataInmobiliaria->inmobiliaria->razon);
+ foreach ($dataInmobiliaria->cuentas as $cuentaRowIndex => $cuenta) {
+ $this->fillCuenta($sheet, $cuenta, 3, $baseRowIndex + $cuentaRowIndex);
+ }
+ $sheet->getCell("K{$rowIndex}")->setValue($dataInmobiliaria->total());
+ $sheet->getCell("L{$rowIndex}")->setValue($dataInmobiliaria->ffmm());
+ $sheet->getCell("M{$rowIndex}")->setValue($dataInmobiliaria->deposito());
+ $sheet->getCell("N{$rowIndex}")->setValue($dataInmobiliaria->caja());
+
+ if (count($dataInmobiliaria->cuentas) > 1) {
+ $finalRow = $rowIndex + count($dataInmobiliaria->cuentas) - 1;
+ $sheet->mergeCells("B{$rowIndex}:B{$finalRow}");
+ $sheet->mergeCells("K{$rowIndex}:K{$finalRow}");
+ $sheet->mergeCells("L{$rowIndex}:L{$finalRow}");
+ $sheet->mergeCells("M{$rowIndex}:M{$finalRow}");
+ $sheet->mergeCells("N{$rowIndex}:N{$finalRow}");
+ }
+ return count($dataInmobiliaria->cuentas);
+ }
+ protected function fillCuenta(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $cuenta, int $startColumnIndex, int $rowIndex): void
+ {
+ $columnIndex = $startColumnIndex;
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->banco);
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->numero);
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->anterior);
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->actual);
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue("=F{$rowIndex}-E{$rowIndex}");
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->ffmm);
+ $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->deposito);
+ $sheet->getCell([$columnIndex, $rowIndex])->setValue("=SUM(F{$rowIndex},H{$rowIndex}:I{$rowIndex})");
+ }
+ protected function fillTotals(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $startRow, int $finalRow): void
+ {
+ $rowIndex = $finalRow + 1;
+ $sheet->getCell("B{$rowIndex}")->setValue('TOTAL');
+ foreach (range('E', 'N') as $columnIndex) {
+ $sheet->getCell("{$columnIndex}{$rowIndex}")->setValue("=SUBTOTAL(109,{$columnIndex}{$startRow}:{$columnIndex}{$finalRow})");
+ }
+
+ $styles = [
+ 'font' => [
+ 'bold' => true
+ ],
+ 'fill' => [
+ 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID,
+ 'startColor' => [
+ 'argb' => 'FFD9D9D9'
+ ]
+ ],
+ 'borders' => [
+ 'outline' => [
+ 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN,
+ 'color' => [
+ 'argb' => PhpSpreadsheet\Style\Color::COLOR_BLACK
+ ]
+ ]
+ ]
+ ];
+ $sheet->getStyle("B{$rowIndex}:N{$rowIndex}")->applyFromArray($styles);
+ }
+ protected function setPageSetup(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $finalRow): void
+ {
+ $sheet->getPageSetup()
+ ->setPrintArea("B2:V{$finalRow}")
+ ->setFitToWidth(1)
+ ->setPaperSize(PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_LEGAL)
+ ->setOrientation(PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
+ $sheet->setShowGridlines(false);
+ $sheet->getSheetView()
+ ->setView(PhpSpreadsheet\Worksheet\SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW)
+ ->setZoomScale(70);
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php b/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php
new file mode 100644
index 0000000..7357299
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php
@@ -0,0 +1,12 @@
+tokens[$inmobiliaria_rut])) {
+ $redisKey = "token_nubox:{$inmobiliaria_rut}";
+ try {
+ $this->tokens[$inmobiliaria_rut] = $this->redisService->get($redisKey);
+ } catch (Exception\EmptyRedis) {
+ $nubox = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut);
+ $request = $this->requestFactory
+ ->createRequest('POST', implode('/', [$this->api_url, 'autenticar']))
+ ->withHeader('Authorization', "Basic {$nubox->getLogin()}")
+ ->withHeader('Content-Type', 'application/json')
+ ->withHeader('Accept', 'application/json');
+ $response = $this->client->sendRequest($request);
+ if ($response->getStatusCode() !== 200) {
+ throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
+ }
+ $sistemas = json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
+
+ $this->setToken($inmobiliaria_rut, $response->getHeaderLine('Token'))
+ ->setSistemas($inmobiliaria_rut, $sistemas['Sistemas']);
+ }
+ }
+ return $this->tokens[$inmobiliaria_rut];
+ }
+ public function setToken(int $inmobiliaria_rut, string $token): Nubox
+ {
+ $this->tokens[$inmobiliaria_rut] = $token;
+
+ $redisKey = "token_nubox:{$inmobiliaria_rut}";
+ $this->redisService->set($redisKey, $this->tokens[$inmobiliaria_rut], 60 * 15);
+
+ return $this;
+ }
+
+ protected array $sistemas;
+ public function getSistemas(int $inmobiliaria_rut): array
+ {
+ if (!isset($this->sistemas[$inmobiliaria_rut])) {
+ $redisKey = "nubox:{$inmobiliaria_rut}";
+ $this->sistemas[$inmobiliaria_rut] = json_decode($this->redisService->get($redisKey));
+ }
+ return $this->sistemas[$inmobiliaria_rut];
+ }
+ public function setSistemas(int $inmobiliaria_rut, array $sistemas): Nubox
+ {
+ $this->sistemas[$inmobiliaria_rut] = $sistemas;
+
+ $redisKey = "nubox:{$inmobiliaria_rut}";
+ $this->redisService->set($redisKey, json_encode($sistemas));
+
+ return $this;
+ }
+
+ public function getLibroMayor(int $inmobiliaria_rut, DateTimeInterface $from, DateTimeInterface $to): array
+ {
+ $inmobiliaria = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut);
+ $query = [
+ 'NumeroSerie' => 1,
+ 'CodigoEmpresa' => $inmobiliaria->alias,
+ 'DDInicio' => $from->format('j'),
+ 'MMInicio' => $from->format('n'),
+ 'YYInicio' => $from->format('Y'),
+ 'DDTermino' => $to->format('j'),
+ 'MMTermino' => $to->format('n'),
+ 'YYTermino' => $to->format('Y'),
+ 'CodigoCentroDeCosto' => 0,
+ 'CodigoSucursal' => 0,
+ 'CodigoCuenta' => 0,
+ 'ModoIFRS' => 'false',
+ 'CuentasConSaldo' => 'false',
+ 'IncluirCodigoCuenta' => 'true',
+ ];
+ $uri = 'contabilidad/libro-mayor?' . http_build_query($query);
+ $response = $this->send($uri, $inmobiliaria_rut);
+ if ($response->getStatusCode() !== 200) {
+ throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
+ }
+ return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
+ }
+ public function getLibroDiario(int $inmobiliaria_rut, DateTimeInterface $from, DateTimeInterface $to): array
+ {
+ $inmobiliaria = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut);
+ $query = [
+ 'ModoIFRS' => 0,
+ 'DDInicio' => $from->format('j'),
+ 'MMInicio' => $from->format('n'),
+ 'YYInicio' => $from->format('Y'),
+ 'DDTermino' => $to->format('j'),
+ 'MMTermino' => $to->format('n'),
+ 'YYTermino' => $to->format('Y'),
+ 'Sucursal' => 0,
+ 'codigoEmpresa' => $inmobiliaria->alias,
+ 'NumeroSerie' => 1,
+ 'CuentasConSaldo' => 0,
+ 'incluirCodigoCuenta' => 1
+ ];
+ $uri = 'contabilidad/libro-diario?' . http_build_query($query);
+ $response = $this->send($uri, $inmobiliaria_rut);
+ if ($response->getStatusCode() !== 200) {
+ $this->logger->debug($uri);
+ throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
+ }
+ return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
+ }
+
+ private function send(string $uri, int $inmobiliaria_rut, string $method = 'GET', ?StreamInterface $body = null): ResponseInterface
+ {
+ $request = $this->requestFactory
+ ->createRequest($method, implode('/', [$this->api_url, $uri]))
+ ->withHeader('token', $this->getToken($inmobiliaria_rut));
+ if ($body !== null) {
+ $request = $request->withBody($body);
+ }
+ return $this->client->sendRequest($request);
+ }
+}
diff --git a/app/src/Service/Format.php b/app/src/Service/Format.php
new file mode 100644
index 0000000..69bde98
--- /dev/null
+++ b/app/src/Service/Format.php
@@ -0,0 +1,36 @@
+setPattern($format);
+ return $formatter->format($date);
+
+ }
+ public function number(float|string $number, int $decimal_places = 0): string
+ {
+ return number_format($number, $decimal_places, ',', '.');
+ }
+ public function percent(float|string $number, int $decimal_places = 2): string
+ {
+ return "{$this->number($number, $decimal_places)}%";
+ }
+ public function pesos(string $valor, int $decimal_places = 0): string
+ {
+ return "$ {$this->number($valor, $decimal_places)}";
+ }
+ public function ufs(string $valor, int $decimal_places = 2): string
+ {
+ return "{$this->number($valor, $decimal_places)} UF";
+ }
+}
diff --git a/app/src/Service/IPC.php b/app/src/Service/IPC.php
new file mode 100644
index 0000000..b75398d
--- /dev/null
+++ b/app/src/Service/IPC.php
@@ -0,0 +1,45 @@
+ $now) {
+ return 0;
+ }
+ $dateKey = "{$from->format('Y-m')}|{$to->format('Y-m')}";
+ $ipcs = [];
+ try {
+ $ipcs = json_decode($this->redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY);
+ if (!isset($ipcs[$dateKey])) {
+ throw new EmptyRedis($this->redisKey);
+ }
+ } catch (EmptyRedis) {
+ $ipc = $this->moneyService->getIPC($from, $to);
+ if ($ipc === -1.0) {
+ return 0;
+ }
+ $ipcs[$dateKey] = $ipc;
+ ksort($ipcs);
+ $this->redisService->set($this->redisKey, json_encode($ipcs), 60 * 60 * 24 * 30);
+ }
+ return $ipcs[$dateKey];
+ }
+ public function readjust(float $base, DateTimeInterface $from, DateTimeInterface $to = new DateTimeImmutable()):float
+ {
+ if (($ipc = $this->get($from, $to->sub(new DateInterval('P1M')))) === 0.0) {
+ return $base;
+ }
+ return $base * (1 + $ipc);
+ }
+}
diff --git a/app/src/Service/Informe.php b/app/src/Service/Informe.php
new file mode 100644
index 0000000..6202e89
--- /dev/null
+++ b/app/src/Service/Informe.php
@@ -0,0 +1,34 @@
+folder)) {
+ mkdir($this->folder);
+ }
+ }
+
+ protected array $informes;
+
+ public function register(string $name, string $informeClass): Informe
+ {
+ $this->informes[$name] = $informeClass;
+ return $this;
+ }
+
+ public function build(string $type, string $filename, string $title, array $data): void
+ {
+ $informe = new $this->informes[$type]();
+ $filename = implode(DIRECTORY_SEPARATOR, [$this->folder, "{$filename}.xlsx"]);
+ $informe->setFilename($filename);
+ $informe->setTitle($title);
+ $informe->addData($data);
+ $informe->build();
+ }
+}
diff --git a/app/src/Service/Informe/Excel.php b/app/src/Service/Informe/Excel.php
new file mode 100644
index 0000000..f11e8a3
--- /dev/null
+++ b/app/src/Service/Informe/Excel.php
@@ -0,0 +1,63 @@
+title = $title;
+ return $this;
+ }
+ public function setFilename(string $filename): Excel
+ {
+ $this->filename = $filename;
+ return $this;
+ }
+ public function addData(array $rows): Excel
+ {
+ foreach ($rows as $row) {
+ $this->addRow($row);
+ }
+ return $this;
+ }
+ public function addRow(array $row): Excel
+ {
+ foreach ($row as $cell) {
+ $this->addCell($cell);
+ }
+ return $this;
+ }
+ public function addCell(PhpSpreadsheet\Cell\Cell $cell): Excel
+ {
+ $this->data []= $cell;
+ return $this;
+ }
+
+ public function build(): void
+ {
+ $spreadsheet = new PhpSpreadsheet\Spreadsheet();
+ $spreadsheet->getProperties()
+ ->setCreator('admin@incoviba.cl')
+ ->setSubject($this->title)
+ ->setCompany('Incoviba')
+ ->setTitle($this->title);
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setTitle($this->title);
+
+ foreach ($this->data as $rowIndex => $row) {
+ foreach ($row as $columnIndex => $cell) {
+ $sheet->getCell([$columnIndex + 1, $rowIndex + 1])->setValue($cell);
+ }
+ }
+
+ $writer = PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
+ $writer->save($this->filename);
+ }
+}
diff --git a/app/src/Service/Login.php b/app/src/Service/Login.php
new file mode 100644
index 0000000..175be0d
--- /dev/null
+++ b/app/src/Service/Login.php
@@ -0,0 +1,135 @@
+loadCookie();
+ }
+
+ protected string $selector = '';
+ protected string $token = '';
+
+ public function isIn(): bool
+ {
+ try {
+ $login = $this->repository->fetchActiveBySelector($this->selector);
+ if (!$this->validToken($login)) {
+ return false;
+ }
+ $now = new DateTimeImmutable();
+ if ($login->dateTime->add(new DateInterval("PT{$this->max_login_time}H")) > $now) {
+ return true;
+ }
+ } catch (PDOException|EmptyResult) {
+ }
+ return false;
+ }
+ public function getUser(): Model\User
+ {
+ $login = $this->repository->fetchActiveBySelector($this->selector);
+ if (!$this->validToken($login)) {
+ throw new Exception('User not found');
+ }
+ return $login->user;
+ }
+
+ public function login(Model\User $user): bool
+ {
+ try {
+ $login = $this->repository->fetchActiveByUser($user->id);
+ $this->logout($login->user);
+ } catch (PDOException|EmptyResult) {
+ }
+
+ try {
+ $now = new DateTimeImmutable();
+ $login = $this->repository->create([
+ 'user_id' => $user->id,
+ 'time' => $now->format('Y-m-d H:i:s'),
+ 'status' => 1
+ ]);
+ list('selector' => $selector, 'token' => $token) = $this->generateToken($login);
+ $login->selector = $selector;
+ $login->token = password_hash($token, PASSWORD_DEFAULT);
+ $this->repository->save($login);
+ $this->saveCookie($selector, $token, $login->dateTime->add(new DateInterval("PT{$this->max_login_time}H")));
+ return true;
+ } catch (PDOException|Exception) {
+ return false;
+ }
+ }
+ public function logout(Model\User $user): bool
+ {
+ $this->removeCookie();
+ try {
+ $logins = $this->repository->fetchByUser($user->id);
+ } catch (PDOException) {
+ return true;
+ }
+ try {
+ foreach ($logins as $login) {
+ $this->repository->edit($login, ['status' => 0]);
+ }
+ return true;
+ } catch (PDOException) {
+ return false;
+ }
+ }
+
+ protected function loadCookie(): void
+ {
+ if (!isset($_COOKIE[$this->cookie_name])) {
+ return;
+ }
+ $cookie = $_COOKIE[$this->cookie_name];
+ list($this->selector, $this->token) = explode($this->cookie_separator, $cookie);
+ }
+ protected function saveCookie(string $selector, string $token, DateTimeInterface $expires): void
+ {
+ setcookie(
+ $this->cookie_name,
+ implode($this->cookie_separator, [$selector, $token]),
+ $expires->getTimestamp(),
+ $this->path,
+ $this->domain
+ );
+ $this->selector = $selector;
+ $this->token = $token;
+ }
+ protected function removeCookie(): void
+ {
+ setcookie(
+ $this->cookie_name,
+ '',
+ (new DateTimeImmutable())->getTimestamp(),
+ $this->path,
+ $this->domain
+ );
+ }
+
+ protected function validToken(Model\Login $login): bool
+ {
+ return password_verify($this->token, $login->token);
+ }
+ protected function generateToken(Model\Login $login)
+ {
+ $selector = bin2hex(random_bytes(12));
+ $token = bin2hex(random_bytes(20));
+ return ['selector' => $selector, 'token' => $token];
+ }
+}
diff --git a/app/src/Service/Menu.php b/app/src/Service/Menu.php
new file mode 100644
index 0000000..c2a6140
--- /dev/null
+++ b/app/src/Service/Menu.php
@@ -0,0 +1,44 @@
+getValid($user_id);
+ $output = [];
+ foreach ($menus as $menu) {
+ $output []= $this->buildItem($menu);
+ }
+ return implode(PHP_EOL, $output);
+ }
+ protected function buildItem(mixed $item): string
+ {
+ if (isset($item->submenus)) {
+ return $this->buildDropdown($item);
+ }
+ return "urls->base}}/{{$item->url}}\">{{$item->title}}";
+ }
+ protected function buildDropdown(mixed $item): string
+ {
+ $output []= '';
+ $output []= $item->title;
+ $output []= '';
+ $output []= '';
+ $output []= '
';
+ return implode(PHP_EOL, $output);
+ }
+
+ public function getValid(int $user_id): array
+ {
+ return $this->menuRepository->fetchByUser($user_id);
+ }
+}
diff --git a/app/src/Service/Money.php b/app/src/Service/Money.php
new file mode 100644
index 0000000..5a9dddf
--- /dev/null
+++ b/app/src/Service/Money.php
@@ -0,0 +1,64 @@
+providers) and isset($this->providers[$name]) and $this->providers[$name] === $provider) {
+ return $this;
+ }
+ $this->providers[$name] = $provider;
+ return $this;
+ }
+ public function getProvider(string $name): Provider
+ {
+ return $this->providers[$name];
+ }
+
+ public function get(string $provider, DateTimeInterface $dateTime): float
+ {
+ try {
+ $upper = strtoupper($provider);
+ return $this->getProvider($provider)->get(MiIndicador::getSymbol($provider), $dateTime);
+ } catch (EmptyResponse) {
+ return 0;
+ }
+ }
+ public function getUF(DateTimeInterface $dateTime): float
+ {
+ try {
+ return $this->getProvider('uf')->get(MiIndicador::UF, $dateTime);
+ } catch (EmptyResponse) {
+ return 0;
+ }
+ }
+ public function getIPC(DateTimeInterface $start, DateTimeInterface $end): float
+ {
+ try {
+ return $this->getProvider('ipc')->getVar($start, $end);
+ } catch (EmptyResponse) {
+ return 0;
+ }
+ }
+ public function getUSD(DateTimeInterface $dateTime): float
+ {
+ try {
+ return $this->getProvider('usd')->get(MiIndicador::USD, $dateTime);
+ } catch (EmptyResponse $exception) {
+ $this->logger->critical($exception);
+ return 0;
+ }
+ }
+}
diff --git a/app/src/Service/Money/Ine.php b/app/src/Service/Money/Ine.php
new file mode 100644
index 0000000..79093fb
--- /dev/null
+++ b/app/src/Service/Money/Ine.php
@@ -0,0 +1,49 @@
+format('Y-m-1'));
+ $start = $end->sub(new DateInterval('P1M'));
+ return $this->getVar($start, $end);
+ }
+
+ public function getVar(DateTimeInterface $start, DateTimeInterface $end): float
+ {
+ $base = 1000000000;
+ $request_query = [
+ 'mesInicio' => $start->format('m'),
+ 'AnioInicio' => $start->format('Y'),
+ 'mesTermino' => $end->format('m'),
+ 'AnioTermino' => $end->format('Y'),
+ 'valor_a_ajustar' => $base
+ ];
+ $request_uri = implode('?', [
+ $this->uri,
+ implode('&', array_map(function($val, $key) {
+ return "{$key}={$val}";
+ }, $request_query, array_keys($request_query)))
+ ]);
+ try {
+ $response = $this->client->get($request_uri);
+ } catch (GuzzleException) {
+ throw new EmptyResponse($request_uri);
+ }
+ $body = $response->getBody();
+ $json = json_decode($body->getContents());
+ return ((int) str_replace('.', '', $json[0]->valorajustado) - $base) / $base;
+ }
+}
diff --git a/app/src/Service/Money/MiIndicador.php b/app/src/Service/Money/MiIndicador.php
new file mode 100644
index 0000000..21dba16
--- /dev/null
+++ b/app/src/Service/Money/MiIndicador.php
@@ -0,0 +1,46 @@
+format('d-m-Y')}";
+ try {
+ $response = $this->client->get($request_uri);
+ } catch (GuzzleException) {
+ throw new EmptyResponse($request_uri);
+ }
+
+ if ((int) floor($response->getStatusCode() / 100) !== 2) {
+ throw new EmptyResponse($request_uri);
+ }
+
+ $body = $response->getBody();
+ $json = json_decode($body->getContents());
+
+ if ($json->codigo !== $money_symbol or count($json->serie) === 0) {
+ throw new EmptyResponse($request_uri);
+ }
+ return $json->serie[0]->valor;
+ }
+ public static function getSymbol(string $identifier): string
+ {
+ $upper = strtoupper($identifier);
+ $output = '';
+ eval("\$output = self::{$upper};");
+ return $output;
+ }
+}
diff --git a/app/src/Service/Movimiento.php b/app/src/Service/Movimiento.php
new file mode 100644
index 0000000..5d9ad67
--- /dev/null
+++ b/app/src/Service/Movimiento.php
@@ -0,0 +1,43 @@
+process($this->movimientoRepository->fetchById($movimiento_id));
+ }
+ public function setDetalles(Model\Movimiento $movimiento, array $data): Model\Movimiento
+ {
+ try {
+ $detalles = $this->detalleRepository->fetchByMovimiento($movimiento->id);
+ $this->detalleRepository->edit($detalles, $data);
+ } catch (Implement\Exception\EmptyResult) {
+ $data['movimiento_id'] = $movimiento->id;
+ $detalles = $this->detalleRepository->create($data);
+ $this->detalleRepository->save($detalles);
+ }
+ return $movimiento;
+ }
+
+ public function process(Model\Movimiento $movimiento): Model\Movimiento
+ {
+ $movimiento->addFactory('detalles', (new Implement\Repository\Factory())->setCallable(function(int $movimiento_id) {
+ return $this->detalleRepository->fetchByMovimiento($movimiento_id);
+ })->setArgs(['movimiento_id' => $movimiento->id]));
+ return $movimiento;
+ }
+}
diff --git a/app/src/Service/Permission.php b/app/src/Service/Permission.php
new file mode 100644
index 0000000..f729201
--- /dev/null
+++ b/app/src/Service/Permission.php
@@ -0,0 +1,9 @@
+proyectoRepository->fetchAllActive();
+ }
+ public function getEscriturando(): array
+ {
+ return $this->proyectoRepository->fetchAllEscriturando();
+ }
+ public function getById(int $proyecto_id): Model\Proyecto
+ {
+ return $this->process($this->proyectoRepository->fetchById($proyecto_id));
+ }
+ public function getByName(string $name): Model\Proyecto
+ {
+ return $this->process($this->proyectoRepository->fetchByName($name));
+ }
+ public function getByInmobiliaria(int $inmobiliaria_rut): array
+ {
+ return array_map([$this, 'process'], $this->proyectoRepository->fetchByInmobiliaria($inmobiliaria_rut));
+ }
+
+ protected function process(Model\Proyecto $proyecto): Model\Proyecto
+ {
+ $proyecto->addFactory('estados', (new Implement\Repository\Factory())
+ ->setCallable([$this->estadoProyecto, 'fetchByProyecto'])
+ ->setArgs([$proyecto->id]));
+ $proyecto->addFactory('currentEstado', (new Implement\Repository\Factory())
+ ->setCallable([$this->estadoProyecto, 'fetchCurrentByProyecto'])
+ ->setArgs([$proyecto->id]));
+ return $proyecto;
+ }
+}
diff --git a/app/src/Service/Proyecto/ProyectoTipoUnidad.php b/app/src/Service/Proyecto/ProyectoTipoUnidad.php
new file mode 100644
index 0000000..3804b25
--- /dev/null
+++ b/app/src/Service/Proyecto/ProyectoTipoUnidad.php
@@ -0,0 +1,22 @@
+proyectoTipoUnidadRepository->fetchById($proyecto_tipo_unidad_id);
+ if ($ptu->tipoUnidad->descripcion === 'departamento') {
+ $ptu->tipologias = $this->tipologiaRepository->fetchByProyectoTipoUnidad($proyecto_tipo_unidad_id);
+ }
+ return $ptu;
+ }
+}
diff --git a/app/src/Service/Redis.php b/app/src/Service/Redis.php
new file mode 100644
index 0000000..d8d61ce
--- /dev/null
+++ b/app/src/Service/Redis.php
@@ -0,0 +1,22 @@
+client->exists($name)) {
+ throw new EmptyRedis($name);
+ }
+ return $this->client->get($name);
+ }
+ public function set(string $name, mixed $value, int $expirationTTL = 60 * 60 * 24): void
+ {
+ $this->client->set($name, $value, 'EX', $expirationTTL);
+ }
+}
diff --git a/app/src/Service/Search.php b/app/src/Service/Search.php
new file mode 100644
index 0000000..43966dd
--- /dev/null
+++ b/app/src/Service/Search.php
@@ -0,0 +1,336 @@
+findCualquiera($query);
+ } else {
+ $results = $this->find($query, $tipo);
+ }
+ return $results;
+ //return $this->sort($results);
+ }
+
+ protected function findCualquiera(string $query): array
+ {
+ $tipos = [
+ 'departamento',
+ 'estacionamiento',
+ 'bodega',
+ 'propietario',
+ 'precio_venta',
+ 'proyecto',
+ 'pago',
+ 'unidad'
+ ];
+ $results = [];
+ foreach ($tipos as $t) {
+ $this->add($results, $this->find($query, $t));
+ }
+ return $results;
+ }
+ protected function find(string $query, string $tipo): array
+ {
+ preg_match_all('/["\']([\s\w\-]+)["\']|([\w\-]+)/iu', $query, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL);
+ $queries = array_map(function($match) {
+ array_shift($match);
+ $valid = array_filter($match, function($line) {return $line !== null and trim($line); });
+ return implode(' ', $valid);
+ }, $matches);
+ $tiposUnidades = $this->getTiposUnidades();
+ $results = [];
+ foreach ($queries as $q) {
+ $this->add($results, $this->findVentas($q, $tipo));
+ if (in_array($tipo, $tiposUnidades)) {
+ $disponibles = $this->findUnidadesDisponibles($q, $tipo);
+ if (count($disponibles) === 0) {
+ continue;
+ }
+ $this->add($results, $disponibles, false);
+ }
+ }
+ return $results;
+ }
+ protected function findVentas(string $query, string $tipo): array
+ {
+ $tiposUnidades = $this->getTiposUnidades();
+ if (in_array($tipo, $tiposUnidades)) {
+ return $this->findUnidad($query, $tipo);
+ }
+ switch ($tipo) {
+ case 'unidad':
+ $results = [];
+ foreach ($tiposUnidades as $t) {
+ $this->add($results, $this->findVentas($query, $t));
+ }
+ return $results;
+ case 'propietario':
+ return $this->findPropietario($query);
+ case 'precio_venta':
+ return $this->findPrecio($query);
+ case 'proyecto':
+ return $this->findProyecto($query);
+ case 'pago':
+ return $this->findPago($query);
+ }
+ return [];
+ }
+ protected function findUnidadesDisponibles(string $query, string $tipo): array
+ {
+ try {
+ return $this->unidadRepository->fetchDisponiblesIdsByDescripcionAndTipo($query, $tipo);
+ } catch (EmptyResponse) {
+ return [];
+ }
+ }
+ protected function findUnidad(string $query, string $tipo): array
+ {
+ try {
+ return $this->ventaRepository->fetchIdsByUnidad($query, $tipo);
+ } catch (EmptyResult) {
+ return [];
+ }
+ }
+ protected function findPropietario(string $query): array
+ {
+ try {
+ return $this->ventaRepository->fetchIdsByPropietario($query);
+ } catch (EmptyResult) {
+ return [];
+ }
+ }
+ protected function findPrecio(string $query): array
+ {
+ try {
+ $precio = str_replace(['$', '.', ','], ['', '', '.'], $query);
+ return $this->ventaRepository->fetchIdsByPrecio($precio);
+ } catch (EmptyResult) {
+ return [];
+ }
+ }
+ protected function findProyecto(string $query): array
+ {
+ try {
+ $proyecto = $this->proyectoService->getByName($query);
+ return $this->ventaRepository->fetchIdsByProyecto($proyecto->id);
+ } catch (EmptyResult) {
+ return [];
+ }
+ }
+ protected function findPago(string $query): array
+ {
+ if ((int) $query === 0) {
+ return [];
+ }
+ $methods = [
+ 'findPie',
+ 'findEscritura',
+ 'findSubsidio',
+ 'findCredito',
+ 'findPromociones',
+ ];
+ $valor = str_replace(['$', '.', ','], ['', '', '.'], $query);
+ $pagos = [];
+ try {
+ $pagos = $this->pagoRepository->fetchByValue((int) $valor);
+ } catch (EmptyResult) {}
+ $results = [];
+ foreach ($methods as $method) {
+ $this->add($results, $this->{$method}($valor, $pagos));
+ }
+ return $results;
+ }
+ protected function findPie(string $query, array $pagos): array
+ {
+ $results = [];
+ try {
+ $pies = $this->pieRepository->fetchByValue((float) $query);
+ foreach ($pies as $pie) {
+ try {
+ $this->add($results, [$this->ventaRepository->fetchIdByPie($pie->id)]);
+ } catch (EmptyResult) {}
+ }
+ } catch (EmptyResult) {}
+ $this->add($results, $this->findReajuste($query, $pagos));
+ $this->add($results, $this->findCuota($query, $pagos));
+ return $results;
+ }
+ protected function findReajuste(string $query, array $pagos): array
+ {
+ $results = [];
+ foreach ($pagos as $pago) {
+ try {
+ $pie = $this->pieRepository->fetchByReajuste((int) $pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdByPie($pie->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+ protected function findCuota(string $query, array $pagos): array
+ {
+ $results = [];
+ foreach ($pagos as $pago) {
+ try {
+ $cuota = $this->cuotaRepository->fetchByPago($pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdByPie($cuota->pie->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+ protected function findEscritura(string $query, array $pagos): array
+ {
+ $results = [];
+ try {
+ $escrituras = $this->escrituraRepository->fetchByValue((int) $query);
+ foreach ($escrituras as $escritura) {
+ try {
+ $this->add($results, [$this->ventaRepository->fetchIdByEscritura($escritura->id)]);
+ } catch (EmptyResult) {}
+ }
+ } catch (EmptyResult) {}
+ foreach ($pagos as $pago) {
+ try {
+ $escritura = $this->escrituraRepository->fetchByPago($pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdByEscritura($escritura->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+ protected function findSubsidio(string $query, array $pagos): array
+ {
+ $results = [];
+ foreach ($pagos as $pago) {
+ try {
+ $subsidio = $this->subsidioRepository->fetchByPago($pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdBySubsidio($subsidio->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+ protected function findCredito(string $query, array $pagos): array
+ {
+ $results = [];
+ try {
+ $creditos = $this->creditoRepository->fetchByValue((int) $query);
+ foreach ($creditos as $credito) {
+ try {
+ $this->add($results, [$this->ventaRepository->fetchIdByCredito($credito->id)]);
+ } catch (EmptyResult) {}
+ }
+ } catch (EmptyResult) {}
+ foreach ($pagos as $pago) {
+ try {
+ $credito = $this->creditoRepository->fetchByPago($pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdByCredito($credito->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+ protected function findPromociones(string $query, array $pagos): array
+ {
+ $results = [];
+ $this->add($results, $this->findBonoPie($query, $pagos));
+ return $results;
+ }
+ protected function findBonoPie(string $query, array $pagos): array
+ {
+ $results = [];
+ try {
+ $bonos = $this->bonoPieRepository->fetchByValue((float) $query);
+ foreach ($bonos as $bono) {
+ try {
+ $this->add($results, [$this->ventaRepository->fetchIdByBono($bono->id)]);
+ } catch (EmptyResult) {}
+ }
+ } catch (EmptyResult) {}
+ foreach ($pagos as $pago) {
+ try {
+ $bono = $this->bonoPieRepository->fetchByPago($pago->id);
+ $this->add($results, [$this->ventaRepository->fetchIdByBono($bono->id)]);
+ } catch (EmptyResult) {}
+ }
+ return $results;
+ }
+
+ protected array $tipos;
+ protected function getTiposUnidades(): array
+ {
+ if (!isset($this->tipos)) {
+ $this->tipos = array_map(function(Model\Proyecto\TipoUnidad $tipoUnidad) {
+ return $tipoUnidad->descripcion;
+ }, $this->tipoUnidadRepository->fetchAll());
+ }
+ return $this->tipos;
+ }
+ protected function add(array &$results, array $found, bool $is_venta = true): void
+ {
+ foreach ($found as $item) {
+ if (!isset($item['tipo'])) {
+ $item['tipo'] = ($is_venta) ? 'venta' : 'unidad';
+ }
+ if (!$this->inResults($item, $results)) {
+ $results []= $item;
+ }
+ }
+ }
+ protected function inResults($item, array $results): bool
+ {
+ return in_array($item, $results, true);
+ }
+ protected function sort(&$results): array
+ {
+ usort($results, function($a, $b) {
+ if (is_a($a, Model\Venta::class)) {
+ $pa = $a->proyecto()->descripcion;
+ $ta = $a->propiedad()->departamentos()[0]->proyectoTipoUnidad->tipoUnidad->descripcion;
+ $ua = $a->propiedad()->departamentos()[0]->descripcion;
+ } else {
+ $pa = $a->proyectoTipoUnidad->proyecto->descripcion;
+ $ta = $a->proyectoTipoUnidad->tipoUnidad->descripcion;
+ $ua = $a->descripcion;
+ }
+ if (is_a($b, Model\Venta::class)) {
+ $pb = $b->proyecto()->descripcion;
+ $tb = $b->propiedad()->departamentos()[0]->proyectoTipoUnidad->tipoUnidad->descripcion;
+ $ub = $b->propiedad()->departamentos()[0]->descripcion;
+ } else {
+ $pb = $b->proyectoTipoUnidad->proyecto->descripcion;
+ $tb = $b->proyectoTipoUnidad->tipoUnidad->descripcion;
+ $ub = $b->descripcion;
+ }
+ $p = strcmp($pa, $pb);
+ if ($p !== 0) {
+ return $p;
+ }
+ $t = strcmp($ta, $tb);
+ if ($t !== 0) {
+ return $t;
+ }
+ return strcmp($ua, $ub);
+ });
+ return $results;
+ }
+}
diff --git a/app/src/Service/UF.php b/app/src/Service/UF.php
new file mode 100644
index 0000000..d1da508
--- /dev/null
+++ b/app/src/Service/UF.php
@@ -0,0 +1,40 @@
+redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY);
+ if (!isset($ufs[$date->format('Y-m-d')])) {
+ throw new EmptyRedis($this->redisKey);
+ }
+ $uf = $ufs[$date->format('Y-m-d')];
+ } catch (EmptyRedis) {
+ $uf = $this->moneyService->getUF($date);
+ $ufs[$date->format('Y-m-d')] = $uf;
+ ksort($ufs);
+ $this->redisService->set($this->redisKey, json_encode($ufs), 60 * 60 * 24 * 30);
+ }
+ return $uf;
+ }
+ public function transform(DateTimeInterface $date, float $input, string $from = 'uf'): float
+ {
+
+ $uf = $this->get($date);
+ return $input * (($from === 'uf') ? $uf : 1/$uf);
+ }
+}
diff --git a/app/src/Service/USD.php b/app/src/Service/USD.php
new file mode 100644
index 0000000..edfeed5
--- /dev/null
+++ b/app/src/Service/USD.php
@@ -0,0 +1,34 @@
+redisService->get($this->redisKey), JSON_OBJECT_AS_ARRAY);
+ if (!isset($usds[$date->format('Y-m-d')])) {
+ throw new EmptyRedis($this->redisKey);
+ }
+ $usd = $usds[$date->format('Y-m-d')];
+ } catch (EmptyRedis) {
+ $usd = $this->moneyService->getUSD($date);
+ $usds[$date->format('Y-m-d')] = $usd;
+ ksort($usds);
+ $this->redisService->set($this->redisKey, json_encode($usds), 60 * 60 * 24 * 30);
+ }
+ return $usd;
+ }
+}
diff --git a/app/src/Service/Venta.php b/app/src/Service/Venta.php
new file mode 100644
index 0000000..34bee46
--- /dev/null
+++ b/app/src/Service/Venta.php
@@ -0,0 +1,490 @@
+process($this->ventaRepository->fetchById($venta_id));
+ }
+ public function getByProyecto(int $proyecto_id): array
+ {
+ $ventas = $this->ventaRepository->fetchByProyecto($proyecto_id);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getActivaByProyecto(int $proyecto_id): array
+ {
+ $ventas = $this->ventaRepository->fetchActivaByProyecto($proyecto_id);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getByProyectoAndUnidad(string $proyecto_nombre, int $unidad_descripcion): Model\Venta
+ {
+ $venta = $this->ventaRepository->fetchByProyectoAndUnidad($proyecto_nombre, $unidad_descripcion);
+ return $this->process($venta);
+ }
+ public function getByUnidad(string $unidad, string $tipo): array
+ {
+ $ventas = $this->ventaRepository->fetchByUnidad($unidad, $tipo);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getByUnidadId(int $unidad_id): Model\Venta
+ {
+ return $this->process($this->ventaRepository->fetchByUnidadId($unidad_id));
+ }
+ public function getByPropietario(string $propietario): array
+ {
+ $ventas = $this->ventaRepository->fetchByPropietario($propietario);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getByPrecio(string $precio): array
+ {
+ $ventas = $this->ventaRepository->fetchByPrecio($precio);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getEscriturasByProyecto(int $proyecto_id): array
+ {
+ $ventas = $this->ventaRepository->fetchEscriturasByProyecto($proyecto_id);
+ return array_map([$this, 'process'], $ventas);
+ }
+ public function getByIdForSearch(int $venta_id): array
+ {
+ return $this->ventaRepository->fetchByIdForSearch($venta_id);
+ }
+ public function getByIdForList(int $venta_id): array
+ {
+ return $this->ventaRepository->fetchByIdForList($venta_id);
+ }
+
+ protected function process(Model\Venta $venta): Model\Venta
+ {
+ $venta->addFactory('formaPago', (new Implement\Repository\Factory())
+ ->setCallable([$this->formaPagoService, 'getByVenta'])
+ ->setArgs(['venta_id' => $venta->id]));
+ $venta->addFactory('estados', (new Implement\Repository\Factory())
+ ->setCallable([$this->estadoVentaRepository, 'fetchByVenta'])
+ ->setArgs([$venta->id]));
+ $venta->addFactory('currentEstado', (new Implement\Repository\Factory())
+ ->setCallable([$this->estadoVentaRepository, 'fetchCurrentByVenta'])
+ ->setArgs([$venta->id]));
+ return $venta;
+ }
+
+ public function add(array $data): Model\Venta
+ {
+ $fecha = new DateTimeImmutable($data['fecha_venta']);
+ $data['uf'] = $this->moneyService->getUF($fecha);
+ $propietario = $this->addPropietario($data);
+ $propiedad = $this->addPropiedad($data);
+ $forma_pago = $this->addFormaPago($data);
+ $venta_data = [
+ 'propietario' => $propietario->rut,
+ 'propiedad' => $propiedad->id,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'valor_uf' => $this->cleanValue($data['valor']),
+ 'fecha_ingreso' => (new DateTimeImmutable())->format('Y-m-d'),
+ 'uf' => $data['uf']
+ ];
+ $map = ['pie', 'subsidio', 'credito', 'bono_pie'];
+ foreach ($map as $field) {
+ $name = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $field))));
+ if (isset($forma_pago->{$name})) {
+ $venta_data[$field] = $forma_pago->{$name}->id;
+ }
+ }
+ try {
+ return $this->ventaRepository->fetchByPropietarioAndPropiedad($propietario->rut, $propiedad->id);
+ } catch (Implement\Exception\EmptyResult) {
+ $venta = $this->ventaRepository->create($venta_data);
+ $venta = $this->ventaRepository->save($venta);
+
+ $tipoEstado = $this->tipoEstadoVentaRepository->fetchByDescripcion('vigente');
+ $estado = $this->estadoVentaRepository->create([
+ 'venta' => $venta->id,
+ 'estado' => $tipoEstado->id,
+ 'fecha' => $venta->fecha->format('Y-m-d')
+ ]);
+ $this->estadoVentaRepository->save($estado);
+
+ return $venta;
+ }
+ }
+ protected function addPropietario(array $data): Model\Venta\Propietario
+ {
+ if (isset($data['natural_uno'])) {
+ if (isset($data['natural_multiple'])) {
+ return $this->addDosPropietarios($data);
+ }
+ return $this->addUnPropietario($data);
+ }
+ return $this->addSociedad($data);
+ }
+ protected function addUnPropietario(array $data): Model\Venta\Propietario
+ {
+ $fields = array_fill_keys([
+ 'rut',
+ 'nombres',
+ 'apellido_paterno',
+ 'apellido_materno',
+ 'calle',
+ 'numero',
+ 'extra',
+ 'comuna'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ return $this->propietarioService->addPropietario($filtered_data);
+ }
+ protected function addDosPropietarios(array $data): Model\Venta\Propietario
+ {
+ $fields = array_fill_keys([
+ 'rut_otro',
+ 'nombres_otro',
+ 'apellido_paterno_otro',
+ 'apellido_materno_otro',
+ 'calle_otro',
+ 'numero_otro',
+ 'extra_otro',
+ 'comuna_otro'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'rut',
+ 'nombres',
+ 'apellido_paterno',
+ 'apellido_materno',
+ 'calle',
+ 'numero',
+ 'extra',
+ 'comuna'
+ ], $filtered_data);
+ $otro = $this->propietarioService->addPropietario($mapped_data);
+
+ $data['otro'] = $otro->rut;
+ $fields = array_fill_keys([
+ 'rut',
+ 'nombres',
+ 'apellido_paterno',
+ 'apellido_materno',
+ 'calle',
+ 'numero',
+ 'extra',
+ 'comuna',
+ 'otro'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ return $this->propietarioService->addPropietario($filtered_data);
+ }
+ protected function addSociedad(array $data): Model\Venta\Propietario
+ {
+ $representante = $this->addUnPropietario($data);
+
+ $data['representante'] = $representante->rut;
+ $fields = array_fill_keys([
+ 'rut_sociedad',
+ 'razon_social',
+ 'calle_comercial',
+ 'numero_comercial',
+ 'extra_comercial',
+ 'comuna_comercial',
+ 'representante'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'rut',
+ 'razon_social',
+ 'calle',
+ 'numero',
+ 'extra',
+ 'comuna',
+ 'representante'
+ ], $filtered_data);
+ return $this->propietarioService->addSociedad($mapped_data);
+ }
+ protected function addPropiedad(array $data): Model\Venta\Propiedad
+ {
+ $ids = array_filter($data, function($key) {
+ return str_contains($key, 'unidad');
+ }, ARRAY_FILTER_USE_KEY);
+
+ return $this->propiedadService->addPropiedad($ids);
+ }
+ protected function addFormaPago(array $data): Model\Venta\FormaPago
+ {
+ return $this->formaPagoService->add($data);
+ /*$fields = [
+ 'pie',
+ 'subsidio',
+ 'credito',
+ 'bono_pie'
+ ];
+ $forma_pago = new Model\Venta\FormaPago();
+ foreach ($fields as $name) {
+ if (isset($data["has_{$name}"])) {
+ $method = 'add' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
+ $obj = $this->{$method}($data);
+ $forma_pago->{$name} = $obj;
+ }
+ }
+ return $forma_pago;*/
+ }
+ /*protected function addPie(array $data): Model\Venta\Pie
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'pie',
+ 'cuotas',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor',
+ 'cuotas',
+ 'uf'
+ ], $filtered_data);
+ $mapped_data['valor'] = $this->cleanValue($mapped_data['valor']);
+ return $this->pieService->add($mapped_data);
+ }
+ protected function addSubsidio(array $data): Model\Venta\Subsidio
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'ahorro',
+ 'subsidio',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'ahorro',
+ 'subsidio',
+ 'uf'
+ ], $filtered_data);
+ return $this->subsidioService->add($mapped_data);
+ }
+ protected function addCredito(array $data): Model\Venta\Credito
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'credito',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor',
+ 'uf'
+ ], $filtered_data);
+ return $this->creditoService->add($mapped_data);
+ }
+ protected function addBonoPie(array $data): Model\Venta\BonoPie
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'bono_pie'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor'
+ ], $filtered_data);
+ return $this->bonoPieService->add($mapped_data);
+ }*/
+ protected function addEstado(Model\Venta $venta, Model\Venta\TipoEstadoVenta $tipoEstadoVenta, array $data): void
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $estadoData = [
+ 'venta' => $venta->id,
+ 'estado' => $tipoEstadoVenta->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ $estado = $this->estadoVentaRepository->create($estadoData);
+ $this->estadoVentaRepository->save($estado);
+ }
+ protected function cleanValue($value): float
+ {
+ if ((float) $value == $value) {
+ return (float) $value;
+ }
+ return (float) str_replace(['.', ','], ['', '.'], $value);
+ }
+
+ public function escriturar(Model\Venta $venta, array $data): bool
+ {
+ if (in_array($venta->currentEstado()->tipoEstadoVenta->descripcion, ['escriturando', 'firmado por inmobiliaria', 'archivado'])) {
+ return true;
+ }
+ try {
+ if ($this->validarData($data, ['fecha_reajuste', 'valor_reajuste'])) {
+ $this->reajustarEscritura($venta, $data);
+ }
+ if ($this->validarData($data, ['fecha_pago'], ['valor_pago_pesos', 'valor_pago_ufs'])) {
+ $this->abonoEscritura($venta, $data);
+ }
+ if ($this->validarData($data, ['banco_credito'], ['valor_credito'])) {
+ $this->editCredito($venta, $data);
+ }
+ if ($this->validarData($data, ['valor_subsidio', 'valor_ahorro', 'fecha'])) {
+ $this->subsidioEscritura($venta, $data);
+ }
+ $tipoEstado = $this->tipoEstadoVentaRepository->fetchByDescripcion('escriturando');
+ $this->addEstado($venta, $tipoEstado, ['fecha' => $data['fecha']]);
+ return true;
+ } catch (Implement\Exception\EmptyResult) {
+ return false;
+ }
+ }
+ protected function validarData(array $data, array $keys, array $optionals = []): bool
+ {
+ foreach ($keys as $key) {
+ if (!isset($data[$key])) {
+ return false;
+ }
+ if ($data[$key] === '') {
+ return false;
+ }
+ }
+ foreach ($optionals as $key) {
+ if (isset($data[$key]) and $data[$key] !== '') {
+ break;
+ }
+ }
+ return true;
+ }
+ protected function reajustarEscritura(Model\Venta $venta, array $data): void
+ {
+ $fecha = new DateTimeImmutable($data['fecha_reajuste']);
+ $reajusteData = [
+ 'valor' => $data['valor_reajuste'],
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ $pie = $venta->formaPago()->pie;
+ $this->pieService->reajustar($pie, $reajusteData);
+ }
+ protected function abonoEscritura(Model\Venta $venta, array $data): void
+ {
+ $fecha = new DateTimeImmutable($data['fecha_pago']);
+ $uf = $this->moneyService->getUF($fecha);
+ $valor = $data['valor_pago_ufs'] !== '' ? $data['valor_pago_ufs'] * $uf : $data['valor_pago_pesos'];
+ $pagoData = [
+ 'valor' => $valor,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'uf' => $uf
+ ];
+ $pago = $this->pagoService->add($pagoData);
+ $escrituraData = [
+ 'valor' => $valor,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'uf' => $uf,
+ 'pago' => $pago->id
+ ];
+ $escritura = $this->escrituraRepository->create($escrituraData);
+ $escritura = $this->escrituraRepository->save($escritura);
+ $this->ventaRepository->edit($venta, ['escritura' => $escritura->id]);
+ }
+ protected function subsidioEscritura(Model\Venta $venta, array $data): void
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $uf = $this->moneyService->getUF($fecha);
+ $subsidioData = [
+ 'fecha_venta' => $fecha->format('Y-m-d'),
+ 'ahorro' => $data['valor_ahorro'],
+ 'subsidio' => $data['valor_subsidio'],
+ 'uf' => $uf
+ ];
+ $subsidio = $this->addSubsidio($subsidioData);
+ $this->ventaRepository->edit($venta, ['subsidio' => $subsidio->id]);
+ }
+ protected function editCredito(Model\Venta $venta, array $data): void
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $uf = $this->moneyService->getUF($fecha);
+ $valor = $data['valor_credito'] * $uf;
+ if ($venta->formaPago()->credito === null) {
+ $pagoData = [
+ 'valor' => $valor,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'uf' => $uf
+ ];
+ $pago = $this->pagoService->add($pagoData);
+ $creditoData = [
+ 'banco' => $data['banco_credito'],
+ 'valor' => $valor,
+ 'pago' => $pago->id
+ ];
+ $credito = $this->creditoRepository->create($creditoData);
+ $credito = $this->creditoRepository->save($credito);
+ $this->ventaRepository->edit($venta, ['credito' => $credito->id]);
+ return;
+ }
+ $this->pagoRepository->edit($venta->formaPago()->credito->pago, [
+ 'valor' => $valor,
+ 'banco' => $data['banco_credito'],
+ 'uf' => $uf
+ ]);
+ $this->estadoPagoRepository->edit($venta->formaPago()->credito->pago->currentEstado, [
+ 'fecha' => $fecha->format('Y-m-d')
+ ]);
+ $this->creditoRepository->edit($venta->formaPago()->credito, [
+ 'valor' => $valor,
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'uf' => $uf
+ ]);
+ }
+
+ public function desistir(Model\Venta $venta, array $data): bool
+ {
+ try {
+ if ($this->validarData($data, ['fecha', 'devolucion'])) {
+ $pago = $this->pagoService->add(['fecha' => $data['fecha'], 'valor' => str_replace(['.', ','], ['', '.'], $data['devolucion'])]);
+ $this->ventaRepository->edit($venta, ['resciliacion' => $pago->id]);
+ }
+ $tipoEstado = $this->tipoEstadoVentaRepository->fetchByDescripcion('desistida');
+ $this->addEstado($venta, $tipoEstado, ['fecha' => $data['fecha']]);
+ return true;
+ } catch (Implement\Exception\EmptyResult) {
+ return false;
+ }
+ }
+ public function insistir(Model\Venta $venta): bool
+ {
+ try {
+ $pago = $venta->resciliacion();
+ $this->pagoService->delete($pago);
+ $estado = $venta->currentEstado();
+ $this->estadoVentaRepository->remove($estado);
+ $this->ventaRepository->edit($venta, ['resciliacion' => null]);
+ return true;
+ } catch (Implement\Exception\EmptyResult) {
+ return false;
+ }
+ }
+}
diff --git a/app/src/Service/Venta/BonoPie.php b/app/src/Service/Venta/BonoPie.php
new file mode 100644
index 0000000..2702558
--- /dev/null
+++ b/app/src/Service/Venta/BonoPie.php
@@ -0,0 +1,19 @@
+bonoPieRepository->fetchByVenta($venta_id);
+ }
+}
diff --git a/app/src/Service/Venta/Cierre.php b/app/src/Service/Venta/Cierre.php
new file mode 100644
index 0000000..02c921d
--- /dev/null
+++ b/app/src/Service/Venta/Cierre.php
@@ -0,0 +1,39 @@
+cierreRepository->fetchByProyecto($proyecto_id);
+ foreach ($cierres as &$cierre) {
+ $cierre->estados = $this->estadoCierreRepository->fetchByCierre($cierre->id);
+ $cierre->current = $this->estadoCierreRepository->fetchCurrentByCierre($cierre->id);
+ $cierre->unidades = $this->unidadRepository->fetchByCierre($cierre->id);
+ }
+ return $cierres;
+ }
+ public function getById(int $cierre_id): Model\Venta\Cierre
+ {
+ $cierre = $this->cierreRepository->fetchById($cierre_id);
+ $cierre->estados = $this->estadoCierreRepository->fetchByCierre($cierre_id);
+ $cierre->current = $this->estadoCierreRepository->fetchCurrentByCierre($cierre_id);
+ $cierre->unidades = $this->unidadRepository->fetchByCierre($cierre_id);
+ foreach ($cierre->unidades as &$unidad) {
+ $unidad->currentPrecio = $this->precioRepository->fetchByUnidadAndDate($unidad->id, $cierre->dateTime->format('Y-m-d'));
+ }
+ $cierre->valoresCierre = $this->valorCierreRepository->fetchByCierre($cierre_id);
+ return $cierre;
+ }
+}
diff --git a/app/src/Service/Venta/Credito.php b/app/src/Service/Venta/Credito.php
new file mode 100644
index 0000000..cc11a9b
--- /dev/null
+++ b/app/src/Service/Venta/Credito.php
@@ -0,0 +1,78 @@
+creditoRepository->fetchByVenta($venta_id);
+ }
+
+ public function add(array $data): Model\Venta\Credito
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $uf = $data['uf'] ?? $this->moneyService->getUF($fecha);
+ $tipoPago = $this->tipoPagoRepository->fetchByDescripcion('carta de resguardo');
+ $pago = $this->addPago(['fecha' => $fecha->format('Y-m-d'), 'valor' => $data['valor'] * $uf, 'uf' => $uf, 'tipo' => $tipoPago->id]);
+ $credito = $this->creditoRepository->create([
+ 'valor' => $data['valor'],
+ 'fecha' => $fecha->format('Y-m-d'),
+ 'pago' => $pago->id
+ ]);
+ return $this->creditoRepository->save($credito);
+ }
+ public function edit(Model\Venta\Credito $credito, array $data): Model\Venta\Credito
+ {
+ $uf = $this->moneyService->getUF($credito->pago->fecha);
+ if (array_key_exists('fecha', $data)) {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $data['fecha'] = $fecha->format('Y-m-d');
+ $uf = $this->moneyService->getUF($fecha);
+ $data['uf'] = $uf;
+ }
+ if (array_key_exists('valor', $data)) {
+ $data['valor'] = round(((float) $data['valor']) * $uf);
+ }
+ $filteredData = array_intersect_key($data, array_fill_keys([
+ 'fecha',
+ 'uf',
+ 'valor',
+ 'banco'
+ ], 0));
+ $credito->pago = $this->pagoRepository->edit($credito->pago, $filteredData);
+ return $this->creditoRepository->edit($credito, $filteredData);
+ }
+ protected function addPago(array $data): Model\Venta\Pago
+ {
+ $pago = $this->pagoRepository->create($data);
+ $pago = $this->pagoRepository->save($pago);
+ $tipoEstado = $this->tipoEstadoPagoRepository->fetchByDescripcion('no pagado');
+ $data = [
+ 'pago' => $pago->id,
+ 'fecha' => $pago->fecha->format('Y-m-d'),
+ 'estado' => $tipoEstado->id
+ ];
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return $pago;
+ }
+}
diff --git a/app/src/Service/Venta/Cuota.php b/app/src/Service/Venta/Cuota.php
new file mode 100644
index 0000000..8f022ca
--- /dev/null
+++ b/app/src/Service/Venta/Cuota.php
@@ -0,0 +1,120 @@
+cuotaRepository->fetchPendientes();
+ $cuotas_pendientes = [];
+ $today = new DateTimeImmutable();
+ $formatter = new IntlDateFormatter('es_ES');
+ $formatter->setPattern('EEEE dd');
+ foreach ($cuotas as $cuota) {
+ $date = new DateTimeImmutable($cuota['fecha']);
+ $day = clone $date;
+ $weekday = $date->format('N');
+ if ($weekday > 5) {
+ $diff = 7 - $weekday + 1;
+ $day = $day->add(new DateInterval("P{$diff}D"));
+ }
+ $cuotas_pendientes []= [
+ 'id' => $cuota['cuota_id'],
+ 'venta_id' => $cuota['venta_id'],
+ 'Proyecto' => $cuota['Proyecto'],
+ 'Departamento' => $cuota['Departamento'],
+ 'Valor' => $cuota['Valor'],
+ 'Dia' => $formatter->format($day),
+ 'Numero' => $cuota['Numero'],
+ 'Propietario' => $cuota['Propietario'],
+ 'Banco' => $cuota['Banco'],
+ 'Fecha Cheque' => $date->format('d-m-Y'),
+ 'Vencida' => $today->diff($date)->days,
+ 'Fecha ISO' => $date->format('Y-m-d')
+ ];
+ }
+ return $cuotas_pendientes;
+ }
+ public function depositadas(): array
+ {
+ $cuotas = $this->cuotaRepository->fetchDepositadas();
+ $cuotas_depositadas = [];
+ $today = new DateTimeImmutable();
+ $formatter = new IntlDateFormatter('es_ES');
+ $formatter->setPattern('EEEE dd');
+ foreach ($cuotas as $cuota) {
+ $date = new DateTimeImmutable($cuota['fecha']);
+ $deposito = new DateTimeImmutable($cuota['Fecha Depositada']);
+ $cuotas_depositadas []= [
+ 'id' => $cuota['cuota_id'],
+ 'venta_id' => $cuota['venta_id'],
+ 'Proyecto' => $cuota['Proyecto'],
+ 'Departamento' => $cuota['Departamento'],
+ 'Valor' => $cuota['Valor'],
+ 'Numero' => $cuota['Numero'],
+ 'Propietario' => $cuota['Propietario'],
+ 'Banco' => $cuota['Banco'],
+ 'Fecha Cheque' => $date->format('d-m-Y'),
+ 'Fecha ISO' => $date->format('Y-m-d'),
+ 'Fecha Depositada' => $deposito->format('d-m-Y')
+ ];
+ }
+ return $cuotas_depositadas;
+ }
+ public function getByPie(int $pie_id): array
+ {
+ return $this->cuotaRepository->fetchByPie($pie_id);
+ /*return array_filter($this->cuotaRepository->fetchByPie($pie_id), function(Model\Venta\Cuota $cuota) {
+ return !in_array($cuota->pago->currentEstado->tipoEstadoPago->descripcion, ['anulado']);
+ });*/
+ }
+ public function getVigenteByPie(int $pie_id): array
+ {
+ return $this->cuotaRepository->fetchVigenteByPie($pie_id);
+ }
+
+ public function add(array $data): Model\Venta\Cuota
+ {
+ $tipoPago = $this->tipoPagoRepository->fetchByDescripcion('cheque');
+ $fields = array_fill_keys([
+ 'fecha',
+ 'banco',
+ 'valor',
+ 'identificador'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $pago_data = array_merge($filtered_data, ['tipo' => $tipoPago->id]);
+ $pago = $this->pagoService->add($pago_data);
+ $data['pago'] = $pago->id;
+ $data['estado'] = $pago->currentEstado->tipoEstadoPago->id;
+ $fields = array_fill_keys([
+ 'pie',
+ 'fecha',
+ 'valor',
+ 'estado',
+ 'banco',
+ 'uf',
+ 'pago',
+ 'numero'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = $filtered_data;
+ $mapped_data['valor_$'] = $mapped_data['valor'];
+ unset($mapped_data['valor']);
+ $cuota = $this->cuotaRepository->create($mapped_data);
+ $this->cuotaRepository->save($cuota);
+ return $cuota;
+ }
+}
diff --git a/app/src/Service/Venta/FormaPago.php b/app/src/Service/Venta/FormaPago.php
new file mode 100644
index 0000000..6a113ef
--- /dev/null
+++ b/app/src/Service/Venta/FormaPago.php
@@ -0,0 +1,143 @@
+pie = $this->pieService->getByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $formaPago->bonoPie = $this->bonoPieService->getByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $formaPago->credito = $this->creditoService->getByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $formaPago->escritura = $this->escrituraRepository->fetchByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $formaPago->subsidio = $this->subsidioService->getByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $formaPago->devolucion = $this->pagoService->getDevolucionByVenta($venta_id);
+ } catch (Implement\Exception\EmptyResult) {}
+
+ return $formaPago;
+ }
+
+ public function add(array $data): Model\Venta\FormaPago
+ {
+ $fields = [
+ 'pie',
+ 'subsidio',
+ 'credito',
+ 'bono_pie'
+ ];
+ $forma_pago = new Model\Venta\FormaPago();
+ foreach ($fields as $name) {
+ if (isset($data["has_{$name}"])) {
+ try {
+ $method = 'add' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
+ $obj = $this->{$method}($data);
+ $forma_pago->{$name} = $obj;
+ } catch (\Error $error) {
+ $this->logger->critical($error);
+ }
+ }
+ }
+ return $forma_pago;
+ }
+
+ protected function addPie(array $data): Model\Venta\Pie
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'pie',
+ 'cuotas',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $this->logger->critical(var_export($filtered_data,true));
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor',
+ 'cuotas',
+ 'uf'
+ ], $filtered_data);
+ $mapped_data['valor'] = $this->cleanValue($mapped_data['valor']);
+ return $this->pieService->add($mapped_data);
+ }
+ protected function addSubsidio(array $data): Model\Venta\Subsidio
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'ahorro',
+ 'subsidio',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'ahorro',
+ 'subsidio',
+ 'uf'
+ ], $filtered_data);
+ return $this->subsidioService->add($mapped_data);
+ }
+ protected function addCredito(array $data): Model\Venta\Credito
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'credito',
+ 'uf'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor',
+ 'uf'
+ ], $filtered_data);
+ return $this->creditoService->add($mapped_data);
+ }
+ protected function addBonoPie(array $data): Model\Venta\BonoPie
+ {
+ $fields = array_fill_keys([
+ 'fecha_venta',
+ 'bono_pie'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'fecha',
+ 'valor'
+ ], $filtered_data);
+ return $this->bonoPieService->add($mapped_data);
+ }
+
+ protected function cleanValue($value): float
+ {
+ if ((float) $value == $value) {
+ return (float) $value;
+ }
+ return (float) str_replace(['.', ','], ['', '.'], $value);
+ }
+}
diff --git a/app/src/Service/Venta/Pago.php b/app/src/Service/Venta/Pago.php
new file mode 100644
index 0000000..fe8c8b1
--- /dev/null
+++ b/app/src/Service/Venta/Pago.php
@@ -0,0 +1,178 @@
+tipoEstadoPagoRepository->fetchByDescripcion('depositado');
+ $data = [
+ 'pago' => $pago->id,
+ 'estado' => $tipo_estado->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ try {
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return true;
+ } catch (PDOException) {
+ return false;
+ }
+ }
+ public function abonar(Model\Venta\Pago $pago, DateTimeInterface $fecha): bool
+ {
+ $tipo_estado = $this->tipoEstadoPagoRepository->fetchByDescripcion('abonado');
+ $data = [
+ 'pago' => $pago->id,
+ 'estado' => $tipo_estado->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ try {
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return true;
+ } catch (PDOException) {
+ return false;
+ }
+ }
+ public function devolver(Model\Venta\Pago $pago, DateTimeInterface $fecha): bool
+ {
+ $tipo_estado = $this->tipoEstadoPagoRepository->fetchByDescripcion('devuelto');
+ $data = [
+ 'pago' => $pago->id,
+ 'estado' => $tipo_estado->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ try {
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return true;
+ } catch (PDOException) {
+ return false;
+ }
+ }
+ public function anular(Model\Venta\Pago $pago, DateTimeInterface $fecha): bool
+ {
+ $tipo_estado = $this->tipoEstadoPagoRepository->fetchByDescripcion('anulado');
+ $data = [
+ 'pago' => $pago->id,
+ 'estado' => $tipo_estado->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ];
+ try {
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return true;
+ } catch (PDOException) {
+ return false;
+ }
+ }
+ public function getById(?int $pago_id): ?Model\Venta\Pago
+ {
+ if ($pago_id === null) {
+ return null;
+ }
+ $pago = $this->pagoRepository->fetchById($pago_id);
+ return $this->process($pago);
+ }
+
+ public function getByVenta(int $venta_id): array
+ {
+ return array_map([$this, 'process'], $this->pagoRepository->fetchByVenta($venta_id));
+ }
+
+ public function getPendientes(): array
+ {
+ return [];
+ }
+ public function getDepositados(): array
+ {
+ return [];
+ }
+ public function getRebotes(): array
+ {
+ return [];
+ }
+ public function getDevolucionByVenta(int $venta_id): Model\Venta\Pago
+ {
+ return $this->process($this->pagoRepository->fetchDevolucionByVenta($venta_id));
+ }
+
+ public function add(array $data): Model\Venta\Pago
+ {
+ if (!isset($data['uf'])) {
+ $data['uf'] = $this->moneyService->getUF(new DateTimeImmutable($data['fecha']));
+ }
+ $fields = array_fill_keys([
+ 'valor',
+ 'banco',
+ 'tipo',
+ 'identificador',
+ 'fecha',
+ 'uf',
+ 'pagador',
+ 'asociado'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $pago = $this->pagoRepository->create($filtered_data);
+ $pago = $this->pagoRepository->save($pago);
+ $tipoEstado = $this->tipoEstadoPagoRepository->fetchByDescripcion('no pagado');
+ $estado = $this->estadoPagoRepository->create([
+ 'pago' => $pago->id,
+ 'fecha' => $pago->fecha->format('Y-m-d'),
+ 'estado' => $tipoEstado->id
+ ]);
+ $estado = $this->estadoPagoRepository->save($estado);
+ $pago->currentEstado = $estado;
+ return $pago;
+ }
+ public function delete(Model\Venta\Pago $pago): bool
+ {
+ try {
+ $this->pagoRepository->remove($pago);
+ return true;
+ } catch (EmptyResult|PDOException) {
+ return false;
+ }
+ }
+
+ protected function process($pago): Model\Venta\Pago
+ {
+ $pago->estados = $this->estadoPagoRepository->fetchByPago($pago->id);
+ $pago->currentEstado = $this->estadoPagoRepository->fetchCurrentByPago($pago->id);
+ $pago->uf = $this->getUF($pago);
+ return $pago;
+ }
+ protected function getUF(Model\Venta\Pago $pago): ?float
+ {
+ if (($pago->uf === null or $pago->uf === 0.0)
+ and $pago->currentEstado->tipoEstadoPago->descripcion === 'abonado'
+ and $pago->currentEstado->fecha <= new DateTimeImmutable()) {
+ $uf = $this->moneyService->getUF($pago->currentEstado->fecha);
+ if ($uf !== 0.0) {
+ $this->pagoRepository->edit($pago, ['uf' => $uf]);
+ return $uf;
+ }
+ } elseif ($pago->uf === 0.0) {
+ $this->pagoRepository->edit($pago, ['uf' => null]);
+ return null;
+ }
+ return $pago->uf;
+ }
+}
diff --git a/app/src/Service/Venta/Pie.php b/app/src/Service/Venta/Pie.php
new file mode 100644
index 0000000..dfeda57
--- /dev/null
+++ b/app/src/Service/Venta/Pie.php
@@ -0,0 +1,52 @@
+process($this->pieRepository->fetchById($pie_id));
+ }
+ public function getByVenta(int $venta_id): Model\Venta\Pie
+ {
+ return $this->process($this->pieRepository->fetchByVenta($venta_id));
+ }
+
+ public function add(array $data): Model\Venta\Pie
+ {
+ $pie = $this->pieRepository->create($data);
+ return $this->pieRepository->save($pie);
+ }
+ public function addCuota(array $data): Model\Venta\Cuota
+ {
+ return $this->cuotaService->add($data);
+ }
+ public function edit(Model\Venta\Pie $pie, array $data): Model\Venta\Pie
+ {
+ return $this->pieRepository->edit($pie, $data);
+ }
+ public function reajustar(Model\Venta\Pie $pie, array $data): Model\Venta\Pie
+ {
+ $pago = $this->pagoService->add($data);
+ return $this->pieRepository->edit($pie, ['reajuste' => $pago->id]);
+ }
+
+ protected function process(Model\Venta\Pie $pie): Model\Venta\Pie
+ {
+ $pie->cuotasArray = $this->cuotaService->getByPie($pie->id);
+ try {
+ $pie->asociados = $this->pieRepository->fetchAsociados($pie->id);
+ } catch (EmptyResult) {}
+ return $pie;
+ }
+}
diff --git a/app/src/Service/Venta/Precio.php b/app/src/Service/Venta/Precio.php
new file mode 100644
index 0000000..d6ec40a
--- /dev/null
+++ b/app/src/Service/Venta/Precio.php
@@ -0,0 +1,36 @@
+precioRepository->fetchByProyecto($proyecto_id);
+ foreach ($precios as &$precio) {
+ $precio->estados = $this->estadoPrecioRepository->fetchByPrecio($precio->id);
+ $precio->current = $this->estadoPrecioRepository->fetchCurrentByPrecio($precio->id);
+ }
+ return $precios;
+ }
+ public function getVigenteByUnidad(int $unidad_id): Model\Venta\Precio
+ {
+ $precio = $this->precioRepository->fetchVigenteByUnidad($unidad_id);
+ $precio->estados = $this->estadoPrecioRepository->fetchByPrecio($precio->id);
+ $precio->current = $this->estadoPrecioRepository->fetchCurrentByPrecio($precio->id);
+ return $precio;
+ }
+ public function getByUnidad(int $unidad_id): array
+ {
+ $precios = $this->precioRepository->fetchByUnidad($unidad_id);
+ foreach ($precios as &$precio) {
+ $precio->estados = $this->estadoPrecioRepository->fetchByPrecio($precio->id);
+ $precio->current = $this->estadoPrecioRepository->fetchCurrentByPrecio($precio->id);
+ }
+ return $precios;
+ }
+}
diff --git a/app/src/Service/Venta/Propiedad.php b/app/src/Service/Venta/Propiedad.php
new file mode 100644
index 0000000..58788c3
--- /dev/null
+++ b/app/src/Service/Venta/Propiedad.php
@@ -0,0 +1,87 @@
+unidadRepository->fetchById($unidad_id);
+ }
+ usort($unidades, function(Model\Venta\Unidad $a, Model\Venta\Unidad $b) {
+ $t = $a->proyectoTipoUnidad->tipoUnidad->orden - $b->proyectoTipoUnidad->tipoUnidad->orden;
+ if ($t === 0) {
+ return strcmp(str_pad($a->descripcion, 4, '0', STR_PAD_LEFT), str_pad($b->descripcion, 4, '0', STR_PAD_LEFT));
+ }
+ return $t;
+ });
+ try {
+ $propiedad = $this->propiedadRepository->fetchVigenteByUnidad($unidades[0]->id);
+ } catch (EmptyResult) {
+ $propiedad = $this->propiedadRepository->create([
+ 'unidad_principal' => $unidades[0]->id,
+ 'estado' => 1
+ ]);
+ $propiedad = $this->propiedadRepository->save($propiedad);
+ }
+ $this->addUnidades($propiedad, $unidades);
+ $this->cleanUpUnidades($propiedad, $unidades);
+
+ return $propiedad;
+ }
+ protected function addUnidades(Model\Venta\Propiedad $propiedad, array $unidades): void
+ {
+ $query = "SELECT 1 FROM `propiedad_unidad` WHERE `propiedad` = ? AND `unidad` = ?";
+ $statement = $this->connection->prepare($query);
+ $query2 = "INSERT INTO `propiedad_unidad` (`propiedad`, `unidad`, `principal`) VALUES (?, ?, ?)";
+ $insert = $this->connection->prepare($query2);
+ foreach ($unidades as $ix => $unidad) {
+ try {
+ $statement->execute([$propiedad->id, $unidad->id]);
+ $result = $statement->fetch(PDO::FETCH_ASSOC);
+ if (!$result) {
+ throw new EmptyResult($query);
+ }
+ } catch (PDOException|EmptyResult) {
+ $insert->execute([$propiedad->id, $unidad->id, ($ix === 0) ? 1 : 0]);
+ }
+ }
+ }
+ protected function cleanUpUnidades(Model\Venta\Propiedad $propiedad, array $unidades): void
+ {
+ $query = "SELECT `unidad` FROM `propiedad_unidad` WHERE `propiedad` = ?";
+ $statement = $this->connection->prepare($query);
+ $statement->execute([$propiedad->id]);
+ $results = $statement->fetchAll(PDO::FETCH_ASSOC);
+
+ if (!$results) {
+ return;
+ }
+
+ $all_ids = array_map(function($row) {return $row['unidad'];}, $results);
+ $new_ids = array_map(function(Model\Venta\Unidad $unidad) {return $unidad->id;}, $unidades);
+ $diff = array_diff($all_ids, $new_ids);
+ if (count($diff) === 0) {
+ return;
+ }
+ $query = "DELETE FROM `propiedad_unidad` WHERE `propiedad` = ? AND `unidad` = ?";
+ $statement = $this->connection->prepare($query);
+ foreach ($diff as $id) {
+ $statement->execute([$propiedad->id, $id]);
+ }
+ }
+}
diff --git a/app/src/Service/Venta/PropiedadUnidad.php b/app/src/Service/Venta/PropiedadUnidad.php
new file mode 100644
index 0000000..29000ec
--- /dev/null
+++ b/app/src/Service/Venta/PropiedadUnidad.php
@@ -0,0 +1,61 @@
+process($this->propiedadUnidadRepository->fetchById($unidad_id));
+ }
+ public function getByVenta(int $venta_id): array
+ {
+ return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByVenta($venta_id));
+ }
+ public function getByPropiedad(int $propiedad_id): array
+ {
+ return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByPropiedad($propiedad_id));
+ }
+ public function add(array $data): Model\Venta\PropiedadUnidad
+ {
+ $unidad = $this->unidadRepository->fetchById($data['unidad']);
+ $temp = json_decode(json_encode($unidad), JSON_OBJECT_AS_ARRAY);
+ $columnMap = [
+ 'proyecto_tipo_unidad' => 'pt'
+ ];
+ foreach ($temp as $key => $value) {
+ if (isset($columnMap[$key])) {
+ $temp[$columnMap[$key]] = $value['id'];
+ }
+ }
+ $temp['propiedad'] = $data['propiedad'];
+ $temp['valor'] = $data['valor'];
+ $pu = $this->propiedadUnidadRepository->create($temp);
+ return $this->process($this->propiedadUnidadRepository->save($pu));
+ }
+ public function edit(Model\Venta\PropiedadUnidad $propiedadUnidad, array $data): Model\Venta\PropiedadUnidad
+ {
+ return $this->process($this->propiedadUnidadRepository->edit($propiedadUnidad, $data));
+ }
+
+ protected function process($unidad): Model\Venta\PropiedadUnidad
+ {
+ try {
+ $unidad->precios = $this->precioService->getByUnidad($unidad->id);
+ $unidad->currentPrecio = $this->precioService->getVigenteByUnidad($unidad->id);
+ if ($unidad->valor === 0) {
+ $unidad->valor = $unidad->currentPrecio->valor;
+ }
+ } catch (EmptyResult) {
+ }
+ return $unidad;
+ }
+}
diff --git a/app/src/Service/Venta/Propietario.php b/app/src/Service/Venta/Propietario.php
new file mode 100644
index 0000000..68db0f8
--- /dev/null
+++ b/app/src/Service/Venta/Propietario.php
@@ -0,0 +1,111 @@
+addDireccion($data);
+ $data['direccion'] = $direccion->id;
+ $data['dv'] = 'i';
+
+ if (str_contains($data['rut'], '-')) {
+ list($rut, $dv) = explode('-', $data['rut']);
+ $data['rut'] = $rut;
+ $data['dv'] = $dv;
+ }
+
+ $fields = array_fill_keys([
+ 'rut',
+ 'dv',
+ 'nombres',
+ 'apellido_paterno',
+ 'apellido_materno',
+ 'direccion'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+
+ try {
+ $propietario = $this->propietarioRepository->fetchById($data['rut']);
+ $edits = [];
+ if ($propietario->datos->direccion->id !== $filtered_data['direccion']) {
+ $edits['direccion'] = $filtered_data['direccion'];
+ }
+ $propietario = $this->propietarioRepository->edit($propietario, $edits);
+ } catch (EmptyResult) {
+ $propietario = $this->propietarioRepository->create($filtered_data);
+ $propietario = $this->propietarioRepository->save($propietario);
+ }
+ return $propietario;
+ }
+ public function addSociedad(array $data): Model\Venta\Propietario
+ {
+ $direccion = $this->addDireccion($data);
+ $data['direccion'] = $direccion->id;
+
+ if (str_contains($data['rut'], '-')) {
+ $data['rut'] = explode('-', $data['rut'])[0];
+ }
+
+ $fields = array_fill_keys([
+ 'rut',
+ 'razon_social',
+ 'direccion',
+ 'representante'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ $mapped_data = array_combine([
+ 'rut',
+ 'nombres',
+ 'direccion',
+ 'representante'
+ ], $filtered_data);
+
+ try {
+ $sociedad = $this->propietarioRepository->fetchById($data['rut']);
+ $edits = [];
+ if ($sociedad->datos->direccion->id !== $mapped_data['direccion']) {
+ $edits['direccion'] = $mapped_data['direccion'];
+ }
+ if ($sociedad->representante->rut !== $mapped_data['representante']) {
+ $edits['representante'] = $mapped_data['representante'];
+ }
+ $sociedad = $this->propietarioRepository->edit($sociedad, $edits);
+ } catch (EmptyResult) {
+ $sociedad = $this->propietarioRepository->create($mapped_data);
+ $sociedad = $this->propietarioRepository->save($sociedad);
+ }
+ return $sociedad;
+ }
+ protected function addDireccion(array $data): Model\Direccion
+ {
+ $fields = array_fill_keys([
+ 'calle',
+ 'numero',
+ 'extra',
+ 'comuna'
+ ], 0);
+ $filtered_data = array_intersect_key($data, $fields);
+ try {
+ $direccion = $this->direccionRepository->fetchByCalleAndNumeroAndExtra($filtered_data['calle'], $filtered_data['numero'], $filtered_data['extra']);
+ } catch (EmptyResult) {
+ $direccion = $this->direccionRepository->create($filtered_data);
+ $direccion = $this->direccionRepository->save($direccion);
+ }
+ return $direccion;
+ }
+}
diff --git a/app/src/Service/Venta/Subsidio.php b/app/src/Service/Venta/Subsidio.php
new file mode 100644
index 0000000..bcce88a
--- /dev/null
+++ b/app/src/Service/Venta/Subsidio.php
@@ -0,0 +1,49 @@
+subsidioRepository->fetchByVenta($venta_id);
+ }
+
+ public function add(array $data): Model\Venta\Subsidio
+ {
+ $fecha = new DateTimeImmutable($data['fecha']);
+ $uf = $data['uf'] ?? $this->moneyService->getUF($fecha);
+ $tipoPago = $this->tipoPagoRepository->fetchByDescripcion('vale vista');
+ $ahorro = $this->addPago(['fecha' => $fecha->format('Y-m-d'), 'valor' => $data['ahorro'] * $uf, 'uf' => $uf, 'tipo' => $tipoPago->id]);
+ $subsidio = $this->addPago(['fecha' => $fecha->format('Y-m-d'), 'valor' => $data['subsidio'] * $uf, 'uf' => $uf, 'tipo' => $tipoPago->id]);
+ $subsidio = $this->subsidioRepository->create(['pago' => $ahorro->id, 'subsidio' => $subsidio->id]);
+ return $this->subsidioRepository->save($subsidio);
+ }
+ protected function addPago(array $data): Model\Venta\Pago
+ {
+ $pago = $this->pagoRepository->create($data);
+ $pago = $this->pagoRepository->save($pago);
+ $tipoEstado = $this->tipoEstadoPagoRepository->fetchByDescripcion('no pagado');
+ $data = [
+ 'pago' => $pago->id,
+ 'fecha' => $pago->fecha->format('Y-m-d'),
+ 'estado' => $tipoEstado->id
+ ];
+ $estado = $this->estadoPagoRepository->create($data);
+ $this->estadoPagoRepository->save($estado);
+ return $pago;
+ }
+}
diff --git a/app/src/Service/Venta/Unidad.php b/app/src/Service/Venta/Unidad.php
new file mode 100644
index 0000000..1f5276f
--- /dev/null
+++ b/app/src/Service/Venta/Unidad.php
@@ -0,0 +1,50 @@
+process($this->unidadRepository->fetchById($unidad_id));
+ }
+ public function getByVenta(int $venta_id): array
+ {
+ return array_map([$this, 'process'], $this->unidadRepository->fetchByVenta($venta_id));
+ }
+ public function getByPropiedad(int $propiedad_id): array
+ {
+ return array_map([$this, 'process'], $this->unidadRepository->fetchByPropiedad($propiedad_id));
+ }
+ public function getByCierre(int $cierre_id): array
+ {
+ return array_map([$this, 'process'], $this->unidadRepository->fetchByCierre($cierre_id));
+ }
+ public function getDisponiblesByProyecto(int $proyecto_id): array
+ {
+ return $this->unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
+ }
+ public function getByIdForSearch(int $unidad_id): array
+ {
+ return $this->unidadRepository->fetchByIdForSearch($unidad_id);
+ }
+
+ protected function process($unidad): Model\Venta\Unidad
+ {
+ try {
+ $unidad->precios = $this->precioService->getByUnidad($unidad->id);
+ $unidad->currentPrecio = $this->precioService->getVigenteByUnidad($unidad->id);
+ } catch (EmptyResult) {
+ }
+ return $unidad;
+ }
+}
diff --git a/bin/Pipfile b/bin/Pipfile
deleted file mode 100644
index 8108982..0000000
--- a/bin/Pipfile
+++ /dev/null
@@ -1,12 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-
-[packages]
-gunicorn = "*"
-
-[requires]
-python_version = "3.8"
diff --git a/bin/console b/bin/console
deleted file mode 100644
index 11aaaef..0000000
--- a/bin/console
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-php /code/bin/index.php "$@"
diff --git a/bin/index.php b/bin/index.php
deleted file mode 100644
index f5683c7..0000000
--- a/bin/index.php
+++ /dev/null
@@ -1,8 +0,0 @@
-run();
diff --git a/bin/informes/Pipfile b/bin/informes/Pipfile
deleted file mode 100644
index e8687af..0000000
--- a/bin/informes/Pipfile
+++ /dev/null
@@ -1,16 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-
-[packages]
-pandas = "*"
-xlsxwriter = "*"
-httpx = "*"
-flask = "*"
-numpy = "*"
-
-[requires]
-python_version = "3.8"
diff --git a/bin/informes/app.py b/bin/informes/app.py
deleted file mode 100644
index ff2a8f0..0000000
--- a/bin/informes/app.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import argparse
-from flask import Flask
-from controllers.ventas import ventas_blueprint
-
-
-app = Flask(__name__)
-app.register_blueprint(ventas_blueprint, url_prefix='/ventas')
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('-p', '--port', default=8011)
- args = parser.parse_args()
- app.run(port=args.port, debug=True)
diff --git a/bin/informes/controllers/ventas.py b/bin/informes/controllers/ventas.py
deleted file mode 100644
index ab3ffce..0000000
--- a/bin/informes/controllers/ventas.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from flask import Blueprint, request, Response
-import io
-import json
-import pandas as pd
-import numpy as np
-import datetime
-
-
-ventas_blueprint = Blueprint('ventas', __name__,)
-
-
-def format_data(data):
- df = pd.DataFrame(data)
- int_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
- for col in int_columns:
- df[col] = pd.to_numeric(df[col], errors='ignore')
- float_columns = ['Valor Promesa', 'Pie', 'Pie Pagado', '% Pie Pagado', 'Bono Pie', 'Valor Operador',
- 'Premios', 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto',
- 'UF/m²*', 'Comision', 'Venta s/Comision', 'Precio']
- for col in float_columns:
- if col in df.columns:
- df[col] = pd.to_numeric(df[col], errors='coerce')
- df = df.replace(np.nan, 0, regex=True)
-
- df['Fecha Venta'] = pd.to_datetime(df['Fecha Venta'], format='%Y-%m-%d')
- df = df.sort_values(by=['Fecha Venta', 'Departamento'])
- df['Fecha Venta'] = df['Fecha Venta'].dt.strftime('%d.%m.%Y')
-
- return df
-
-
-def format_columns(workbook, columns):
- column_settings = [{'header': column} for column in columns]
-
- center_format = workbook.add_format({'align': 'center'})
- amount_format = workbook.add_format({'num_format': '#,##0.00'})
- percent_format = workbook.add_format({'num_format': '0.00%'})
-
- amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios',
- 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision',
- 'Venta s/Comision', 'Precio']
- center_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
- sum_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Subsidio', 'Ahorro', 'Credito',
- 'Valor Operador', 'Premios', 'Valor Ests & Bods', 'Valor Neto', 'Comision']
- count_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
-
- for (k, col) in enumerate(column_settings):
- if col['header'] in amount_columns:
- column_settings[k]['format'] = amount_format
- if col['header'] in center_columns:
- column_settings[k]['format'] = center_format
- if col['header'] in sum_columns:
- column_settings[k]['total_function'] = 'sum'
- if col['header'] in count_columns:
- column_settings[k]['total_function'] = 'count'
- if col['header'] == '% Pie Pagado':
- column_settings[k]['format'] = percent_format
- if col['header'] == 'Propietario':
- column_settings[k]['total_string'] = 'TOTAL'
-
- return column_settings
-
-
-def format_excel(workbook, worksheet, data):
- center_format = workbook.add_format({'align': 'center'})
- amount_format = workbook.add_format({'num_format': '#,##0.00'})
- percent_format = workbook.add_format({'num_format': '0.00%'})
-
- amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios',
- 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision',
- 'Venta s/Comision', 'Precio']
- center_columns = ['Departamento', 'Estacionamientos', 'Bodegas']
-
- for col in amount_columns:
- if col not in data.columns:
- continue
- k = data.columns.get_loc(col) + 1
- worksheet.set_column(k, k, cell_format=amount_format)
- for col in center_columns:
- if col not in data.columns:
- continue
- k = data.columns.get_loc(col) + 1
- worksheet.set_column(k, k, cell_format=center_format)
- col = '% Pie Pagado'
- k = data.columns.get_loc(col) + 1
- worksheet.set_column(k, k, cell_format=percent_format)
-
- return worksheet
-
-
-@ventas_blueprint.route('', methods=['POST'])
-def ventas():
- data = json.loads(request.data)
- output = io.BytesIO()
- writer = pd.ExcelWriter('tmp.xlsx', engine='xlsxwriter')
- df = format_data(data['data'])
-
- start_row = 4
- if 'Compañía' in data:
- start_row += 1
- df.to_excel(writer, startrow=start_row+1, startcol=1, header=False, index=False, sheet_name='Ventas')
- wb = writer.book
- wb.filename = output
-
- title_format = wb.add_format({'font_size': 16, 'bold': True})
- ws = writer.sheets['Ventas']
- (max_row, max_col) = df.shape
-
- if 'Compañía' in data:
- ws.merge_range(1, 1, 1, max_col, data['Compañía'])
- ws.merge_range(start_row-3, 1, start_row-3, max_col, data['Proyecto'], cell_format=title_format)
- ws.write_string(start_row-2, 1, 'Ventas')
- column_settings = format_columns(wb, df.columns)
- ws.add_table(start_row, 1, max_row+start_row+1, max_col, {'name': 'Ventas', 'total_row': 1,
- 'columns': column_settings,
- 'style': 'Table Style Medium 1'})
- ws = format_excel(wb, ws, df)
-
- column_widths = {
- 'B': 46,
- 'C': 16,
- 'D': 18,
- 'E': 10,
- 'F': 13,
- 'G': 7,
- 'H': 8,
- 'I': 16,
- 'J': 16,
- 'K': 13,
- 'L': 14
- }
- for (col, wd) in column_widths.items():
- ws.set_column('{0}:{0}'.format(col), wd)
-
- writer.save()
- output.seek(0)
- date = datetime.date.today()
- filename = "Informe de Ventas - {0} - {1}.xlsx".format(data['Proyecto'], date.strftime('%Y-%m-%d'))
- return Response(output, mimetype="application/ms-excel",
- headers={"Content-Disposition": "attachment;filename={0}".format(filename),
- "Content-Type": 'application/octet-stream; charset=utf-8'})
diff --git a/bootstrap/autoload.php b/bootstrap/autoload.php
deleted file mode 100644
index 318f80d..0000000
--- a/bootstrap/autoload.php
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/bootstrap/database.php b/bootstrap/database.php
deleted file mode 100644
index 4372bf2..0000000
--- a/bootstrap/database.php
+++ /dev/null
@@ -1,29 +0,0 @@
- $data) {
- load($data, $name);
-}
-
-function load($data, $name = '') {
- if (!isset($data['port'])) {
- $port = 3306;
- } else {
- $port = $data['port'];
- }
- $dsn = 'mysql:host=' . $data['host'] . ';port=' . $port . ';dbname=' . $data['database'] . ';charset=utf8';
-
- if ($name != '') {
- ORM::configure($dsn, null, $name);
- ORM::configure('username', $data['username'], $name);
- ORM::configure('password', $data['password'], $name);
- } else {
- ORM::configure($dsn, null);
- ORM::configure('username', $data['username']);
- ORM::configure('password', $data['password']);
- }
-}
-
-Model::$short_table_names = true;
diff --git a/bootstrap/dotenv.php b/bootstrap/dotenv.php
deleted file mode 100644
index 799a5b1..0000000
--- a/bootstrap/dotenv.php
+++ /dev/null
@@ -1,12 +0,0 @@
-isDir() or $file->getExtension() != 'env') {
- continue;
- }
- $env = Dotenv::createImmutable($file->getPath(), $file->getBasename());
- $env->load();
-}
diff --git a/bootstrap/errors.php b/bootstrap/errors.php
deleted file mode 100644
index 0e54dc4..0000000
--- a/bootstrap/errors.php
+++ /dev/null
@@ -1,7 +0,0 @@
-pushHandler(new \Whoops\Handler\PrettyPageHandler);
- $whoops->register();
-}*/
-?>
diff --git a/bootstrap/logs.php b/bootstrap/logs.php
deleted file mode 100644
index 249be53..0000000
--- a/bootstrap/logs.php
+++ /dev/null
@@ -1,26 +0,0 @@
-underscored();
- Route::add(['GET', 'POST'], $route, $name);
-}
-
-Route::add(['GET', 'POST'], 'buscar', 'Buscar');
-?>
\ No newline at end of file
diff --git a/cli/.env.sample b/cli/.env.sample
new file mode 100644
index 0000000..8666955
--- /dev/null
+++ b/cli/.env.sample
@@ -0,0 +1,2 @@
+APP_NAME=incoviba_cli
+API_URL=http://proxy/api
diff --git a/cli/bin/incoviba b/cli/bin/incoviba
new file mode 100755
index 0000000..7a750c3
--- /dev/null
+++ b/cli/bin/incoviba
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+. /etc/profile
+
+/usr/local/bin/php /code/bin/index.php "$@"
\ No newline at end of file
diff --git a/cli/bin/index.php b/cli/bin/index.php
new file mode 100644
index 0000000..9e47d85
--- /dev/null
+++ b/cli/bin/index.php
@@ -0,0 +1,13 @@
+run();
+} catch (Error $error) {
+ $app->getContainer()->get(Psr\Log\LoggerInterface::class)->error($error);
+} catch (Exception $exception) {
+ $app->getContainer()->get(Psr\Log\LoggerInterface::class)->notice($exception);
+}
diff --git a/cli/common/Alias/Application.php b/cli/common/Alias/Application.php
new file mode 100644
index 0000000..6565ed1
--- /dev/null
+++ b/cli/common/Alias/Application.php
@@ -0,0 +1,20 @@
+container->has('APP_NAME')) {
+ $name = $this->container->get('APP_NAME');
+ }
+ parent::__construct($name, $version);
+ }
+ public function getContainer(): ContainerInterface
+ {
+ return $this->container;
+ }
+}
diff --git a/cli/common/Alias/Command.php b/cli/common/Alias/Command.php
new file mode 100644
index 0000000..bce5031
--- /dev/null
+++ b/cli/common/Alias/Command.php
@@ -0,0 +1,14 @@
+> /logs/commands 2>&1
+0 2 * * * /code/bin/incoviba ventas:cuotas:pendientes >> /logs/commands 2>&1
+0 2 * * * /code/bin/incoviba ventas:cuotas:vencer >> /logs/commands 2>&1
+0 2 * * * /code/bin/incoviba ventas:cierres:vigentes >> /logs/commands 2>&1
+* */3 * * * /code/bin/incoviba proyectos:activos >> /logs/commands 2>&1
+0 2 * * * /code/bin/incoviba comunas >> /logs/commands 2>&1
+0 2 * * * /code/bin/incoviba money:uf >> /logs/commands 2>&1
+0 2 1 * * /code/bin/incoviba money:ipc >> /logs/commands 2>&1
diff --git a/cli/resources/commands/base.php b/cli/resources/commands/base.php
new file mode 100644
index 0000000..3150c18
--- /dev/null
+++ b/cli/resources/commands/base.php
@@ -0,0 +1,2 @@
+add($app->getContainer()->get(Incoviba\Command\Full::class));
diff --git a/cli/resources/commands/comunas.php b/cli/resources/commands/comunas.php
new file mode 100644
index 0000000..e1f1fa8
--- /dev/null
+++ b/cli/resources/commands/comunas.php
@@ -0,0 +1,2 @@
+add($app->getContainer()->get(Incoviba\Command\Comunas::class));
diff --git a/cli/resources/commands/money.php b/cli/resources/commands/money.php
new file mode 100644
index 0000000..2e087bc
--- /dev/null
+++ b/cli/resources/commands/money.php
@@ -0,0 +1,3 @@
+add($app->getContainer()->get(Incoviba\Command\Money\UF::class));
+$app->add($app->getContainer()->get(Incoviba\Command\Money\IPC::class));
diff --git a/cli/resources/commands/proyectos.php b/cli/resources/commands/proyectos.php
new file mode 100644
index 0000000..c9cb911
--- /dev/null
+++ b/cli/resources/commands/proyectos.php
@@ -0,0 +1,9 @@
+isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+}
diff --git a/cli/resources/commands/proyectos/activos.php b/cli/resources/commands/proyectos/activos.php
new file mode 100644
index 0000000..836ba5b
--- /dev/null
+++ b/cli/resources/commands/proyectos/activos.php
@@ -0,0 +1,2 @@
+add($app->getContainer()->get(Incoviba\Command\Proyectos\Activos::class));
diff --git a/cli/resources/commands/ventas.php b/cli/resources/commands/ventas.php
new file mode 100644
index 0000000..dd4cf66
--- /dev/null
+++ b/cli/resources/commands/ventas.php
@@ -0,0 +1,9 @@
+isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+}
diff --git a/cli/resources/commands/ventas/cierres.php b/cli/resources/commands/ventas/cierres.php
new file mode 100644
index 0000000..1ab6cff
--- /dev/null
+++ b/cli/resources/commands/ventas/cierres.php
@@ -0,0 +1,2 @@
+add($app->getContainer()->get(Incoviba\Command\Ventas\Cierres\Vigentes::class));
diff --git a/cli/resources/commands/ventas/cuotas.php b/cli/resources/commands/ventas/cuotas.php
new file mode 100644
index 0000000..8dd8fd5
--- /dev/null
+++ b/cli/resources/commands/ventas/cuotas.php
@@ -0,0 +1,4 @@
+add($app->getContainer()->get(Incoviba\Command\Ventas\Cuotas\Hoy::class));
+$app->add($app->getContainer()->get(Incoviba\Command\Ventas\Cuotas\Pendientes::class));
+$app->add($app->getContainer()->get(Incoviba\Command\Ventas\Cuotas\PorVencer::class));
diff --git a/cli/setup/app.php b/cli/setup/app.php
new file mode 100644
index 0000000..2310f7c
--- /dev/null
+++ b/cli/setup/app.php
@@ -0,0 +1,42 @@
+isDir()) {
+ continue;
+ }
+ $builder->addDefinitions($file->getRealPath());
+ }
+ }
+ $app = new Application($builder->build());
+
+ $folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'middlewares']);
+ if (file_exists($folder)) {
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+ }
+
+ return $app;
+}
+return buildApp();
diff --git a/cli/setup/composer.php b/cli/setup/composer.php
new file mode 100644
index 0000000..b451f96
--- /dev/null
+++ b/cli/setup/composer.php
@@ -0,0 +1,6 @@
+getContainer()->get('folders')->commands);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+}
+loadCommands($app);
diff --git a/cli/setup/middlewares/98_logs.php b/cli/setup/middlewares/98_logs.php
new file mode 100644
index 0000000..b81e521
--- /dev/null
+++ b/cli/setup/middlewares/98_logs.php
@@ -0,0 +1,2 @@
+getContainer()->get(Psr\Log\LoggerInterface::class));
diff --git a/cli/setup/settings/env.php b/cli/setup/settings/env.php
new file mode 100644
index 0000000..580b775
--- /dev/null
+++ b/cli/setup/settings/env.php
@@ -0,0 +1,2 @@
+ function() {
+ $arr = ['base' => dirname(__FILE__, 3)];
+ $arr['resources'] = implode(DIRECTORY_SEPARATOR, [
+ $arr['base'],
+ 'resources'
+ ]);
+ $arr['commands'] = implode(DIRECTORY_SEPARATOR, [
+ $arr['resources'],
+ 'commands'
+ ]);
+ return (object) $arr;
+ }
+];
diff --git a/cli/setup/setups/client.php b/cli/setup/setups/client.php
new file mode 100644
index 0000000..12292f8
--- /dev/null
+++ b/cli/setup/setups/client.php
@@ -0,0 +1,15 @@
+ function(ContainerInterface $container) {
+ return new GuzzleHttp\Client([
+ 'base_uri' => $container->get('API_URL'),
+ 'headers' => [
+ 'Authorization' => [
+ 'Bearer ' . md5($container->get('API_KEY'))
+ ]
+ ]
+ ]);
+ }
+];
diff --git a/cli/setup/setups/logs.php b/cli/setup/setups/logs.php
new file mode 100644
index 0000000..ec4195f
--- /dev/null
+++ b/cli/setup/setups/logs.php
@@ -0,0 +1,37 @@
+ function(ContainerInterface $container) {
+ return new Monolog\Logger('incoviba', [
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/debug.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Debug,
+ Monolog\Level::Debug
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/info.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Info,
+ Monolog\Level::Warning,
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/error.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Error,
+ Monolog\Level::Error
+ ),
+ new Monolog\Handler\FilterHandler(
+ (new Monolog\Handler\RotatingFileHandler('/logs/critical.log', 10))
+ ->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
+ Monolog\Level::Critical
+ )
+ ], [
+ $container->get(Monolog\Processor\PsrLogMessageProcessor::class),
+ $container->get(Monolog\Processor\IntrospectionProcessor::class),
+ $container->get(Monolog\Processor\MemoryUsageProcessor::class),
+ $container->get(Monolog\Processor\MemoryPeakUsageProcessor::class)
+ ]);
+ }
+];
diff --git a/cli/src/Command/Comunas.php b/cli/src/Command/Comunas.php
new file mode 100644
index 0000000..0db83ce
--- /dev/null
+++ b/cli/src/Command/Comunas.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/direcciones/region/13/comunas';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Full.php b/cli/src/Command/Full.php
new file mode 100644
index 0000000..5c7d9d0
--- /dev/null
+++ b/cli/src/Command/Full.php
@@ -0,0 +1,32 @@
+ $command
+ ]);
+ $this->getApplication()->doRun($cmd, $output);
+ }
+ return Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Money/IPC.php b/cli/src/Command/Money/IPC.php
new file mode 100644
index 0000000..7ed75b4
--- /dev/null
+++ b/cli/src/Command/Money/IPC.php
@@ -0,0 +1,36 @@
+logger->debug("Running {$this->getName()}");
+ $lastMonth = (new DateTimeImmutable())->sub(new DateInterval('P1M'));
+ $endLastYear = (new DateTimeImmutable())->sub(new DateInterval('P1Y'));
+ $uri = '/api/money/ipc';
+ $current = new DateTimeImmutable($lastMonth->format('Y-m-d'));
+ while ($current->diff($endLastYear)->days > 30) {
+ $data = [
+ 'start' => $endLastYear->format('Y-12-1'),
+ 'end' => $current->format('Y-m-1')
+ ];
+ $output->writeln("POST {$uri}");
+ $response = $this->client->post($uri, [
+ 'body' => http_build_query($data),
+ 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded']
+ ]);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ $current = $current->sub(new DateInterval('P1M'));
+ }
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Money/UF.php b/cli/src/Command/Money/UF.php
new file mode 100644
index 0000000..7e700ce
--- /dev/null
+++ b/cli/src/Command/Money/UF.php
@@ -0,0 +1,29 @@
+logger->debug("Running {$this->getName()}");
+ $now = new DateTimeImmutable();
+ $uri = '/api/money/uf';
+ $data = [
+ 'fecha' => $now->format('Y-m-d')
+ ];
+ $output->writeln("POST {$uri}");
+ $response = $this->client->post($uri, [
+ 'body' => http_build_query($data),
+ 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded']
+ ]);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Proyectos/Activos.php b/cli/src/Command/Proyectos/Activos.php
new file mode 100644
index 0000000..a3d941a
--- /dev/null
+++ b/cli/src/Command/Proyectos/Activos.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/proyectos';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Ventas/Cierres/Vigentes.php b/cli/src/Command/Ventas/Cierres/Vigentes.php
new file mode 100644
index 0000000..0ee10cc
--- /dev/null
+++ b/cli/src/Command/Ventas/Cierres/Vigentes.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/ventas/cierres/vigentes';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Ventas/Cuotas/Hoy.php b/cli/src/Command/Ventas/Cuotas/Hoy.php
new file mode 100644
index 0000000..3fa17c2
--- /dev/null
+++ b/cli/src/Command/Ventas/Cuotas/Hoy.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/ventas/cuotas/hoy';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Ventas/Cuotas/Pendientes.php b/cli/src/Command/Ventas/Cuotas/Pendientes.php
new file mode 100644
index 0000000..576475e
--- /dev/null
+++ b/cli/src/Command/Ventas/Cuotas/Pendientes.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/ventas/cuotas/pendiente';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/cli/src/Command/Ventas/Cuotas/PorVencer.php b/cli/src/Command/Ventas/Cuotas/PorVencer.php
new file mode 100644
index 0000000..30849b3
--- /dev/null
+++ b/cli/src/Command/Ventas/Cuotas/PorVencer.php
@@ -0,0 +1,21 @@
+logger->debug("Running {$this->getName()}");
+ $uri = '/api/ventas/cuotas/vencer';
+ $output->writeln("GET {$uri}");
+ $response = $this->client->get($uri);
+ $output->writeln("Response Code: {$response->getStatusCode()}");
+ return Console\Command\Command::SUCCESS;
+ }
+}
diff --git a/composer.json b/composer.json
deleted file mode 100644
index 55f9f15..0000000
--- a/composer.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "name" : "aldarien/incoviba",
- "description" : "Intranet portal for Incoviba",
- "type" : "project",
- "require" : {
- "aldarien/asset": "*",
- "aldarien/config": "*",
- "aldarien/format": "*",
- "aldarien/response": "*",
- "aldarien/session": "*",
- "aldarien/url": "*",
- "aldarien/view": "*",
- "guzzlehttp/guzzle": "*",
- "incoviba/modelos": "*",
- "j4mie/paris": "^1.5",
- "monolog/monolog": "^3",
- "nesbot/carbon": "^2",
- "nyholm/psr7": "*",
- "nyholm/psr7-server": "*",
- "php-di/php-di": "*",
- "php-di/slim-bridge": "*",
- "phpoffice/phpspreadsheet": "^1",
- "phpoffice/phpword": "^0",
- "rubellum/slim-blade-view": "*",
- "slam/php-excel": "^4.4",
- "slim/slim": "^4",
- "symfony/console": "6.4.x-dev",
- "vlucas/phpdotenv": "^5.3",
- "voku/stringy": "^6"
- },
- "require-dev" : {
- "phpunit/phpunit" : "*",
- "kint-php/kint" : "*",
- "filp/whoops" : "*"
- },
- "license" : "GNU AGPLv3",
- "authors" : [{
- "name" : "Aldarien",
- "email" : "jpvial@gmail.com"
- }
- ],
- "autoload" : {
- "psr-4" : {
- "App\\" : "app/",
- "ProVM\\Common\\": "provm/common/"
- },
- "files" : [
- "app/Helper/functions.php"
- ]
- },
- "minimum-stability": "dev",
- "repositories": [
- {
- "type": "path",
- "url": "./aldarien/**",
- "options": {
- "symlink": true
- }
- },
- {
- "type": "path",
- "url": "./incoviba/modelos"
- }
- ],
- "config": {
- "sort-packages": true
- }
-}
diff --git a/config/app.php b/config/app.php
deleted file mode 100644
index 4db5c28..0000000
--- a/config/app.php
+++ /dev/null
@@ -1,9 +0,0 @@
- 'America/Santiago',
- 'locale' => 'es',
- 'database' => 'mysql',
- 'debug' => false,
- 'benchmark' => false,
- 'login_hours' => 5*24
-];
diff --git a/config/databases.php b/config/databases.php
deleted file mode 100644
index 14e279f..0000000
--- a/config/databases.php
+++ /dev/null
@@ -1,24 +0,0 @@
- [
- 'host' => $_ENV['MYSQL_HOST'],
- 'database' => $_ENV['MYSQL_DATABASE'],
- 'username' => $_ENV['MYSQL_USER'],
- 'password' => $_ENV['MYSQL_PASSWORD']
- ],
- 'mysql_copy' => [
- 'host' => 'localhost',
- 'database' => 'incoviba3',
- 'username' => 'incoviba',
- 'password' => $_ENV['MYSQL_PASSWORD']
- ]
- ];
- if (isset($_ENV['MYSQL_PORT'])) {
- $arr['mysql']['port'] = $_ENV['MYSQL_PORT'];
- }
- return $arr;
-}
-return buildDatabaseConfig();
diff --git a/config/incoviba.php b/config/incoviba.php
deleted file mode 100644
index d21d9e8..0000000
--- a/config/incoviba.php
+++ /dev/null
@@ -1,6 +0,0 @@
- [
- 'caducidad' => 30
- ]
-];
diff --git a/config/locations.php b/config/locations.php
deleted file mode 100644
index 05442b6..0000000
--- a/config/locations.php
+++ /dev/null
@@ -1,16 +0,0 @@
- root(),
- 'cache' => '{locations.base}/cache',
- 'public' => '{locations.base}/public',
- 'resources' => '{locations.base}/resources',
- 'views' => '{locations.resources}/views',
- 'src' => '{locations.base}/src',
- //'languages' => '{locations.resources}/languages'
- 'app' => '{locations.base}/app',
- 'controllers' => '{locations.app}/Controller',
- 'money' => 'provm.cl/optimus/money',
- 'api' => '192.168.1.100/intranet/api',
- 'api_url' => '/api'
-];
-?>
diff --git a/docker-compose.yml b/docker-compose.yml
index 4052376..866cf6f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,67 +1,57 @@
-version: '3'
-
-x-restart: &restart
- restart: unless-stopped
-
services:
- web:
+ proxy:
profiles:
- app
image: nginx:alpine
- container_name: incoviba_web
- <<: *restart
+ container_name: incoviba_proxy
+ restart: unless-stopped
ports:
- - "8080:80"
+ - "${APP_PORT}:80"
volumes:
- - .:/code
+ - ${APP_PATH:-.}/:/code
- ./nginx.conf:/etc/nginx/conf.d/default.conf
+ - ./logs/proxy:/logs
- php:
+ web:
profiles:
- app
build: .
- container_name: incoviba_php
- <<: *restart
+ container_name: incoviba_web
+ restart: unless-stopped
env_file:
- - .env
- - .db.env
- - .remote.env
+ - ${APP_PATH:-.}/.env
+ - ./.key.env
volumes:
- - .:/code
- - ./php-errors.ini:/usr/local/etc/php/conf.d/docker-php-errors.ini
- - ./logs:/logs
+ - ${APP_PATH:-.}/:/code
+ - ./logs/php:/logs
db:
profiles:
- db
image: mariadb:latest
container_name: incoviba_db
- <<: *restart
- env_file: .db.env
+ restart: unless-stopped
+ env_file: ${APP_PATH:-.}/.db.env
volumes:
- dbdata:/var/lib/mysql
+ - ./incoviba.sql.gz:/docker-entrypoint-initdb.d/incoviba.sql.gz
+ ports:
+ - "33060:3306"
networks:
- default
- adminer_network
- adminer:
+ redis:
profiles:
- - db
- image: adminer:latest
- container_name: incoviba_adminer
- <<: *restart
+ - cache
+ image: redis
+ container_name: incoviba_redis
+ restart: unless-stopped
+ env_file: ${APP_PATH:-.}/.redis.env
+ volumes:
+ - incoviba_redis:/data
ports:
- - "8083:8080"
- env_file: .adminer.env
-
- python:
- profiles:
- - python
- build:
- context: .
- dockerfile: Python.Dockerfile
- container_name: incoviba_python
- <<: *restart
+ - "63790:6379"
logview:
profiles:
@@ -75,12 +65,27 @@ services:
WEB_URL: 'http://provm.cl:8084'
WEB_PORT: '8084'
volumes:
- - "./logs:/logs"
+ - ./logs:/logs
ports:
- "8084:80"
+ cli:
+ profiles:
+ - cli
+ build:
+ context: .
+ dockerfile: CLI.Dockerfile
+ container_name: incoviba_cli
+ restart: unless-stopped
+ env_file:
+ - ${CLI_PATH:-.}/.env
+ - ./.key.env
+ volumes:
+ - ${CLI_PATH:-.}:/code
+ - ./logs/cli:/logs
volumes:
- dbdata:
+ dbdata: {}
+ incoviba_redis: {}
networks:
adminer_network: {}
diff --git a/fontify.json b/fontify.json
deleted file mode 100644
index 923703c..0000000
--- a/fontify.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "modules": [
- "bootstrap",
- "font-awesome"
- ],
- "dest": "public"
-}
\ No newline at end of file
diff --git a/incoviba.sql.gz b/incoviba.sql.gz
new file mode 100644
index 0000000..3839f9c
Binary files /dev/null and b/incoviba.sql.gz differ
diff --git a/incoviba/modelos/.gitignore b/incoviba/modelos/.gitignore
deleted file mode 100644
index 9aa7c69..0000000
--- a/incoviba/modelos/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Composer
-/vendor/
-composer.lock
diff --git a/incoviba/modelos/common/Alias/Model.php b/incoviba/modelos/common/Alias/Model.php
deleted file mode 100644
index 88ef3c9..0000000
--- a/incoviba/modelos/common/Alias/Model.php
+++ /dev/null
@@ -1,87 +0,0 @@
-id;
- $orm = $this->orm;
- $ref = new \ReflectionObject($orm);
- if (!$ref->hasProperty('_dirty_fields')) {
- return;
- }
- $dirty = $ref->getProperty('_dirty_fields');
- $dirty->setAccessible(true);
- $new_values = $dirty->getValue($orm);
- $changes = array_combine(array_keys($new_values), array_fill(0, count($new_values), ['old' => '', 'new' => '']));
- if ($this->isNew()) {
- $old = (object) array_combine(array_keys($new_values), array_fill(0, count($new_values), ''));
- } else {
- $old = model(get_called_class())->findOne($this->{$this->getId()});
- }
- foreach ($new_values as $column => $value) {
- $changes[$column] = ['column' => $column, 'old' => $old->$column, 'new' => $value];
- }
- $action = '[' . get_called_class() . ']';
- doLog($user, $action, $changes);
- }
- public function getId()
- {
- if (property_exists(get_called_class(), '_id_column')) {
- return static::$_id_column;
- }
- return $this->id;
- }
- public function save()
- {
- $ref = new \ReflectionObject($this);
- if ($ref->hasProperty('_timestamps')) {
- $ref = $ref->getProperty('_timestamps');
- $ref->setAccessible(true);
- if ($ref->getValue()) {
- if ($this->is_new()) {
- $this->setExpr('created_at', 'NOW()');
- }
- $this->setExpr('updated_at', 'NOW()');
- }
- }
- if (!\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->beginTransaction();
- }
- try {
- parent::save();
- if (\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->commit();
- }
- } catch (\Exception $e) {
- if (\ORM::getDb()->inTransaction()) {
- \ORM::getDb()->rollBack();
- }
- throw $e;
- }
- $this->log();
- }
- public function __call($method, $args)
- {
- if (!method_exists($this, $method)) {
- $str = '' . Stringy::create($method)->underscored();
- if (method_exists($this, $str)) {
- return call_user_func_array([$this, $str], $args);
- }
- throw new \BadMethodCallException($method . ' not found in ' . get_class($this));
- }
- return call_user_func_array([$this, $str], $args);
- }
-}
-?>
diff --git a/incoviba/modelos/common/Alias/NewEstado.php b/incoviba/modelos/common/Alias/NewEstado.php
deleted file mode 100644
index 2ec1ba1..0000000
--- a/incoviba/modelos/common/Alias/NewEstado.php
+++ /dev/null
@@ -1,20 +0,0 @@
-fecha, config('app.timezone'));
- }
-}
-?>
diff --git a/incoviba/modelos/common/Alias/NewModel.php b/incoviba/modelos/common/Alias/NewModel.php
deleted file mode 100644
index fbc209c..0000000
--- a/incoviba/modelos/common/Alias/NewModel.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/incoviba/modelos/common/Alias/NewTipo.php b/incoviba/modelos/common/Alias/NewTipo.php
deleted file mode 100644
index e33d83c..0000000
--- a/incoviba/modelos/common/Alias/NewTipo.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
diff --git a/incoviba/modelos/common/Alias/OldModel.php b/incoviba/modelos/common/Alias/OldModel.php
deleted file mode 100644
index f12a3cd..0000000
--- a/incoviba/modelos/common/Alias/OldModel.php
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/incoviba/modelos/common/Factory/Model.php b/incoviba/modelos/common/Factory/Model.php
deleted file mode 100644
index 2aef844..0000000
--- a/incoviba/modelos/common/Factory/Model.php
+++ /dev/null
@@ -1,204 +0,0 @@
-class = $class;
- $this->is_aggregator = true;
- if (is_subclass_of($class, 'Model')) {
- $this->is_aggregator = false;
- }
- }
- public function new()
- {
- $class = $this->class;
- if ($this->is_aggregator) {
- return new $class();
- }
- return model($class)->create();
- }
- public function create($data)
- {
- $class = $this->class;
- if ($this->is_aggregator) {
- $obj = new $class();
- $obj->create($data);
- return $obj;
- }
- return model($class)->create($data);
- }
- /**
- * [column => value, column => [value, operator]]
- * @var array
- */
- protected $conditions;
- public function where(array $data)
- {
- if ($this->conditions == null) {
- $this->conditions = $data;
- return $this;
- }
- $this->conditions = array_merge($this->conditions, $data);
- return $this;
- }
- /**
- * [column, column => order]
- * @var array
- */
- protected $order;
- public function order(array $data)
- {
- if ($this->order == null) {
- $this->order = $data;
- return $this;
- }
- $this->order = array_merge($this->order, $data);
- return $this;
- }
- protected $limit;
- public function limit(array $data)
- {
- if (!isset($data['limit'])) {
- $data['limit'] = $data[0];
- }
- if (!isset($data['offset'])) {
- $data['offset'] = 0;
- if (isset($data[1])) {
- $data['offset'] = $data[1];
- }
- }
- $this->limit = (object) ['limit' => $data['limit'], 'offset' => $data['offset']];
- return $this;
- }
- protected $many;
- public function find($many = false)
- {
- $this->many = $many;
- if ($this->is_aggregator) {
- return $this->findAggregator();
- }
- return $this->findModel();
- }
-
- protected function findModel()
- {
- $objs = model($this->class);
- $objs = $this->parseLimit($this->parseOrder($this->parseConditions($objs)));
-
- if ($this->many) {
- return $objs->findMany();
- }
- return $objs->findOne();
- }
- protected function parseConditions($orm)
- {
- if ($this->conditions == null) {
- return $orm;
- }
- foreach ($this->conditions as $column => $value) {
- if (is_array($value)) {
- list($value, $op) = $value;
- switch ($op) {
- case '>':
- case 'gt':
- $orm = $orm->whereGt($column, $value);
- break;
- }
- } else {
- $orm = $orm->where($column, $value);
- }
- }
- return $orm;
- }
- protected function parseOrder($orm)
- {
- if ($this->order == null) {
- return $orm;
- }
- foreach ($this->order as $column => $order) {
- if (is_numeric($column)) {
- $column = $order;
- $order = 'asc';
- }
- switch (strtolower($order)) {
- case 'asc':
- default:
- $orm = $orm->orderByAsc($column);
- break;
- case 'desc':
- $orm = $orm->orderByDesc($column);
- break;
- case 'expr':
- $orm = $orm->orderByExpr($column);
- break;
- }
- }
- return $orm;
- }
- protected function parseLimit($orm)
- {
- if ($this->limit == null) {
- return $orm;
- }
- $orm = $orm->limit($this->limit->limit);
- if (isset($this->limit->offset)) {
- $orm = $orm->offset($this->limit->offset);
- }
- return $orm;
- }
- protected function findAggregator()
- {
- $model = $this->modelName($this->class);
- $ids = $this->getIds($model);
- $class = $this->class;
- if (count($ids) == 0) {
- return false;
- }
- if ($this->many) {
- $objs = [];
- foreach ($ids as $id) {
- $objs []= new $class($id);
- }
- } else {
- $objs = new $class($ids[0]);
- }
- return $objs;
- }
- protected function getIds($model)
- {
- $id = $this->getModelId($model);
- $table = $this->getTable($model);
- $st = \ORM::forTable($table)->select($id);
- $st = $this->parseConditions($st);
- $results = $st->findArray();
- $output = array_map(function($a) use($id) {
- return $a[$id];
- }, $results);
- return $output;
- }
- protected function modelName($class)
- {
- $arr = explode("\\", $class);
- \array_push($arr, end($arr));
- return implode("\\", $arr);
- }
- protected function getModelId($model)
- {
- $table = $this->getTable($model);
- $query = "SHOW KEYS FROM {$table} WHERE Key_name = 'PRIMARY'";
- $st = \ORM::getDb()->query($query);
- $results = $st->fetchAll(\PDO::FETCH_OBJ);
- return $results[0]->Column_name;
- }
- protected function getTable($model)
- {
- $arr = explode("\\", $model);
- return Stringy::create(end($arr))->toLowerCase() . '';
- }
-}
diff --git a/incoviba/modelos/composer.json b/incoviba/modelos/composer.json
deleted file mode 100644
index 55767f2..0000000
--- a/incoviba/modelos/composer.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "incoviba/modelos",
- "description": "Modelos para Incoviba",
- "type": "library",
- "require": {
- "j4mie/paris": "^1.5",
- "nesbot/carbon": "^2.28"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5",
- "kint-php/kint": "^3.3"
- },
- "license": "UNLICENSED",
- "authors": [
- {
- "name": "Aldarien",
- "email": "aldarien85@gmail.com"
- }
- ],
- "autoload": {
- "psr-4": {
- "Incoviba\\Common\\": "common",
- "Incoviba\\": "src"
- }
- }
-}
diff --git a/incoviba/modelos/src/common/Action.php b/incoviba/modelos/src/common/Action.php
deleted file mode 100644
index 8a46229..0000000
--- a/incoviba/modelos/src/common/Action.php
+++ /dev/null
@@ -1,12 +0,0 @@
-belongsTo(User::class, 'user_id')->findOne();
- }
- public function token($token = null)
- {
- if ($token == null) {
- return false;
- }
- $this->token = \password_hash($token, \PASSWORD_DEFAULT);
- }
- public function time($time = null)
- {
- if ($time == null) {
- return Carbon::parse($this->time, config('app.timezone'));
- }
- if (!\is_a($time, \DateTime::class)) {
- $time = Carbon::parse($time, config('app.timezone'));
- }
- $this->time = $time;
- }
- public function save()
- {
- if (!\is_string($this->time)) {
- $this->time = $this->time->format('Y-m-d H:i:s');
- }
- parent::save();
- }
- public function isIn()
- {
- if ($this->status == 0) {
- return false;
- }
- $now = Carbon::now(config('app.timezone'));
- $diff = $now->diffAsCarbonInterval($this->time, true);
- if ($diff->totalHours > config('app.login_hours')) {
- return false;
- }
- return true;
- }
-}
-?>
diff --git a/incoviba/modelos/src/common/Location.php b/incoviba/modelos/src/common/Location.php
deleted file mode 100644
index 5d3323d..0000000
--- a/incoviba/modelos/src/common/Location.php
+++ /dev/null
@@ -1,23 +0,0 @@
-hasMany(Permission::class, 'location')->findMany();
- }
-}
-?>
diff --git a/incoviba/modelos/src/common/Permission.php b/incoviba/modelos/src/common/Permission.php
deleted file mode 100644
index c283e7e..0000000
--- a/incoviba/modelos/src/common/Permission.php
+++ /dev/null
@@ -1,49 +0,0 @@
-all == 0) {
- return $this->belongsTo(Location::class, 'location')->findOne();
- }
- if ($this->locations == null) {
- $this->locations = \Model::factory(Location::class)->findMany();
- }
- return $this->locations;
- }*/
- public function who()
- {
- switch ($this->type) {
- case 1:
- return $this->belongsTo(User::class, 'ext_id')->findOne();
- case 2:
- return $this->belongsTo(Role::class, 'ext_id')->findOne();
- }
- }
- public function action()
- {
- return $this->belongsTo(Action::class, 'action_id')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/common/Registry.php b/incoviba/modelos/src/common/Registry.php
deleted file mode 100644
index aae8a0a..0000000
--- a/incoviba/modelos/src/common/Registry.php
+++ /dev/null
@@ -1,64 +0,0 @@
-belongsTo(User::class, 'user')->findOne();
- }
- protected $model;
- public function model()
- {
- if ($this->model == null) {
- list($model, $actions) = explode(']', $this->action);
- $model = str_replace(['Incoviba\\old\\', 'Incoviba\\nuevo\\', '\\'], ['', '', '->'], trim($model, '['));
- $this->model = $model;
- }
- return $this->model;
- }
- protected $actions;
- public function actions()
- {
- if ($this->actions == null) {
- list($model, $actions) = explode(']', $this->action);
- $actions = explode(', ', trim($actions));
- $resultados = [];
- foreach ($actions as $action) {
- if (strpos($action, ': ') !== false) {
- list($columna, $valor) = explode(': ', $action);
- } else {
- $columna = '';
- $valor = $action;
- }
- if (strpos($valor, ' -> ') !== false) {
- list($old, $new) = explode(' -> ', $valor);
- } else {
- $old = '';
- $new = $valor;
- }
- $resultados[$columna] = (object) ['old' => $old, 'new' => $new];
- }
- $this->actions = $resultados;
- }
- return $this->actions;
- }
- public function time(Carbon $time = null)
- {
- if ($time == null) {
- return Carbon::parse($this->time);
- }
- $this->time = $time->toDateTimeString();
- }
-}
diff --git a/incoviba/modelos/src/common/RegistryData.php b/incoviba/modelos/src/common/RegistryData.php
deleted file mode 100644
index 18dee39..0000000
--- a/incoviba/modelos/src/common/RegistryData.php
+++ /dev/null
@@ -1,16 +0,0 @@
-inherits != 0) {
- return $this->belongsTo(Role::class, 'inherits')->findOne();
- }
- return false;
- }
- protected $permissions;
- public function permissions()
- {
- if ($this->permissions == null) {
- $permissions = $this->hasMany(Permission::class, 'ext_id')->where('permissions.type', 2)->findMany();
- if ($this->inherits()) {
- $permissions = array_merge($permissions, $this->inherits()->permissions());
- }
- usort($permissions, function($a, $b) {
- return strcmp($a->action()->description, $b->action()->description);
- });
- $this->permissions = $permissions;
- }
- return $this->permissions;
- }
- public function users()
- {
- return $this->hasManyThrough(User::class, UserRole::class, 'role', 'user')->findMany();
- }
- public function hasAccess($route)
- {
- $action = $route->getArgument('action');
- $action = (new Factory(Action::class))->where(['description' => $action])->find();
- if (!$action) {
- return false;
- }
-
- $data = [
- 'type' => 2,
- 'ext_id' => $this->id,
- 'action_id' => $action->id,
- 'status' => 1
- ];
- $permission = (new Factory(Permission::class))->where($data)->find();
- if ($permission !== false) {
- return true;
- }
-
- if ($this->inherits()) {
- return $this->inherits()->hasAccess($route);
- }
- return false;
- }
- public function checkAccess($action_name)
- {
- $action = (new Factory(Action::class))->where(['description' => $action_name])->find();
- if (!$action) {
- throw new \Exception('Action ' . $action_name . ' not found.');
- }
- $permission = (new Factory(Permission::class))->where([
- 'type' => 2,
- 'ext_id' => $this->id,
- 'action_id' => $action->id,
- 'status' => 1
- ])->find();
- if ($permission !== false) {
- return true;
- }
- if ($this->inherits()) {
- return $this->inherits()->checkAccess($action_name);
- }
- return false;
- }
- public function addPermission($action_name)
- {
- if ($this->checkAccess($action_name)) {
- return;
- }
- $action = (new Factory(Action::class))->where(['description' => $action_name])->find();
- if (!$action) {
- throw new \InvalidArgumentException($action_name . ' not found.');
- }
- $data = [
- 'type' => 2,
- 'ext_id' => $this->id,
- 'action_id' => $action->id
- ];
- $permission = (new Factory(Permission::class))->where($data)->find();
- if (!$permission) {
- $permission = (new Factory(Permission::class))->create($data);
- }
- $permission->status = 1;
- $permission->save();
- }
- public function removePermission($action_name)
- {
- if (!$this->checkAccess($action_name)) {
- return;
- }
- $action = (new Factory(Action::class))->where(['description' => $action_name])->find();
- if (!$action) {
- throw new \InvalidArgumentException($action_name . ' not found.');
- }
- $data = [
- 'type' => 2,
- 'ext_id' => $this->id,
- 'action_id' => $action->id
- ];
- $permission = (new Factory(Permission::class))->where($data)->find();
- if (!$permission) {
- return;
- }
- $permission->status = 0;
- $permission->save();
- }
- public function hasUser($user)
- {
- $user = \Model::factory(User::class)
- ->select('users.*')
- ->join('user_roles', ['user_roles.user', '=', 'users.id'])
- ->join('roles', ['roles.id', '=', 'user_roles.role'])
- ->where('roles.id', $this->id)
- ->whereAnyIs([['users.name' => $user], ['users.id' => $user]])
- ->findOne();
- if ($user !== false) {
- return true;
- }
- return false;
- }
- public function isInherited($action_name)
- {
- if (!$this->checkAccess($action_name)) {
- return false;
- }
- $action = (new Factory(Action::class))->where(['description' => $action_name])->find();
- $permission = (new Factory(Permission::class))->where([
- 'type' => 2,
- 'ext_id' => $this->id,
- 'action_id' => $action->id,
- 'status' => 1
- ])->find();
- if ($permission !== false) {
- return false;
- }
- return true;
- }
-}
-?>
diff --git a/incoviba/modelos/src/common/User.php b/incoviba/modelos/src/common/User.php
deleted file mode 100644
index 7d4844e..0000000
--- a/incoviba/modelos/src/common/User.php
+++ /dev/null
@@ -1,104 +0,0 @@
-password = \password_hash($password, \PASSWORD_BCRYPT);
- }
- protected $permissions = null;
- public function permissions()
- {
- if ($this->permissions == null) {
- $permissions = $this->hasMany(Permission::class, 'ext_id')->where('permissions.type', 1)->findMany();
- if ($permissions == false) {
- $permissions = [];
- }
- foreach ($this->roles() as $role) {
- $rp = $role->permissions();
- if ($rp !== false) {
- $permissions = array_merge($permissions, $rp);
- }
- }
- if (count($permissions) == 0) {
- $permissions = false;
- }
- $this->permissions = $permissions;
- }
- return $this->permissions;
- }
- public function roles()
- {
- return $this->hasManyThrough(Role::class, UserRole::class, 'user', 'role')->findMany();
- }
- public function hasAccess($route)
- {
- foreach ($this->roles() as $role) {
- if ($role->hasAccess($route) === true) {
- return true;
- }
- }
-
- $action = $route->getArgument('action');
- $action = (new Factory(Action::class))->where(['description' => $action])->find();
- if (!$action) {
- return false;
- }
-
- $data = [
- 'type' => 1,
- 'ext_id' => $this->id,
- 'action_id' => $action->id,
- 'status' => 1
- ];
- $permission = (new Factory(Permission::class))->where($data)->find();
- if ($permission !== false) {
- return true;
- }
- return false;
- }
- public function checkAccess($action_name)
- {
- foreach ($this->roles() as $role) {
- if ($role->checkAccess($action_name) === true) {
- return true;
- }
- }
- $action = (new Factory(Action::class))->where(['description' => $action_name])->find();
-
- $permission = (new Factory(Permission::class))->where([
- 'type' => 1,
- 'ext_id' => $this->id,
- 'action_id' => $action->id,
- 'status' => 1
- ])->find();
- if ($permission !== false) {
- return true;
- }
- return false;
- }
- public function hasRole($role)
- {
- foreach ($this->roles() as $r) {
- if ($r->description == $role or $r->id == $role) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/incoviba/modelos/src/common/UserRole.php b/incoviba/modelos/src/common/UserRole.php
deleted file mode 100644
index 646bf01..0000000
--- a/incoviba/modelos/src/common/UserRole.php
+++ /dev/null
@@ -1,26 +0,0 @@
-belongsTo(User::class, 'user')->findOne();
- }
- public function role()
- {
- return $this->belongsTo(Role::class, 'role')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/nuevo/Common/Banco.php b/incoviba/modelos/src/nuevo/Common/Banco.php
deleted file mode 100644
index 365cbb8..0000000
--- a/incoviba/modelos/src/nuevo/Common/Banco.php
+++ /dev/null
@@ -1,22 +0,0 @@
-has_many(\Incoviba\nuevo\Inmobiliaria\Cuenta::class, 'banco_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/Comuna.php b/incoviba/modelos/src/nuevo/Common/Comuna.php
deleted file mode 100644
index 4e25192..0000000
--- a/incoviba/modelos/src/nuevo/Common/Comuna.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongs_to(Provincia::class, 'provincia_id')->findOne();
- }
- public function direcciones()
- {
- return $this->has_many(Direccion::class, 'comuna_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/Direccion.php b/incoviba/modelos/src/nuevo/Common/Direccion.php
deleted file mode 100644
index b195681..0000000
--- a/incoviba/modelos/src/nuevo/Common/Direccion.php
+++ /dev/null
@@ -1,24 +0,0 @@
-belongs_to(Comuna::class, 'comuna_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/M2.php b/incoviba/modelos/src/nuevo/Common/M2.php
deleted file mode 100644
index 9c4f05d..0000000
--- a/incoviba/modelos/src/nuevo/Common/M2.php
+++ /dev/null
@@ -1,33 +0,0 @@
-has_many(\Incoviba\nuevo\Proyecto\UnidadProyecto::class, 'm2_id')->findMany();
- }
- public function vendibles()
- {
- return $this->util + $this->logia + $this->terraza / 2 + $this->cubierta / 3;
- }
- public function total()
- {
- return $this->util + $this->logia + $this->terraza + $this->cubierta;
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/Provincia.php b/incoviba/modelos/src/nuevo/Common/Provincia.php
deleted file mode 100644
index 2f74d80..0000000
--- a/incoviba/modelos/src/nuevo/Common/Provincia.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongs_to(Region::class, 'region_id')->findOne();
- }
- public function comunas()
- {
- return $this->has_many(Comuna::class, 'provincia_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/Region.php b/incoviba/modelos/src/nuevo/Common/Region.php
deleted file mode 100644
index e3e211e..0000000
--- a/incoviba/modelos/src/nuevo/Common/Region.php
+++ /dev/null
@@ -1,24 +0,0 @@
-has_many(Provincia::class, 'region_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Common/UF.php b/incoviba/modelos/src/nuevo/Common/UF.php
deleted file mode 100644
index 53f7329..0000000
--- a/incoviba/modelos/src/nuevo/Common/UF.php
+++ /dev/null
@@ -1,33 +0,0 @@
-fecha, config('app.timezone'));
- $uf = uf($fecha);
-
- if ($uf != null) {
- $this->valor = $uf->uf->value;
- }
- }
-
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Agente.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Agente.php
deleted file mode 100644
index 2b7d828..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Agente.php
+++ /dev/null
@@ -1,47 +0,0 @@
-belongsTo(Representante::class, 'representante_rut', 'rut')->findOne();
- }
- public function direccion()
- {
- return $this->belongsTo(Direccion::class, 'direccion_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoAgente::class, 'tipo_agente_id')->findOne();
- }
- public function contratos()
- {
- return $this->hasMany(Contrato::class, 'agente_id')->findMany();
- }
- public function comision($inmobiliaria_rut)
- {
- return $this->hasMany(Contrato::class, 'agente_id')->where('inmobiliaria_rut', $inmobiliaria_rut)->sum('valor');
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/CategoriaCuentaContable.php b/incoviba/modelos/src/nuevo/Inmobiliaria/CategoriaCuentaContable.php
deleted file mode 100644
index 8c6de25..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/CategoriaCuentaContable.php
+++ /dev/null
@@ -1,21 +0,0 @@
-hasMany(CuentaContable::class, 'categoria_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Cobro.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Cobro.php
deleted file mode 100644
index ed856f2..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Cobro.php
+++ /dev/null
@@ -1,36 +0,0 @@
-belongsTo(Contrato::class, 'contrato_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoCobro::class, 'tipo_cobro_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Contrato.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Contrato.php
deleted file mode 100644
index 903f7f6..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Contrato.php
+++ /dev/null
@@ -1,37 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria_rut', 'rut')->findOne();
- }
- public function agente()
- {
- return $this->belongsTo(Agente::class, 'agente_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoContrato::class, 'tipo_contrato_id')->findOne();
- }
- public function cobros()
- {
- return $this->hasMany(Cobro::class, 'contrato_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Cuenta.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Cuenta.php
deleted file mode 100644
index 94dbfc8..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Cuenta.php
+++ /dev/null
@@ -1,31 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria_rut', 'rut')->findOne();
- }
- public function banco()
- {
- return $this->belongsTo(Banco::class, 'banco_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/CuentaContable.php b/incoviba/modelos/src/nuevo/Inmobiliaria/CuentaContable.php
deleted file mode 100644
index 7c28136..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/CuentaContable.php
+++ /dev/null
@@ -1,44 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria_rut', 'rut')->findOne();
- }
- public function categoria()
- {
- return $this->belongsTo(CategoriaCuentaContable::class, 'categoria_id')->findOne();
- }
- public function cargos()
- {
- return $this->hasMany(TransaccionContable::class, 'cuenta_de')->findMany();
- }
- public function abonos()
- {
- return $this->hasMany(TransaccionContable::class, 'cuenta_para')->findMany();
- }
- public function transacciones()
- {
- $transacciones = model(TransaccionContable::class)->whereAnyIs([['cuenta_de', $this->id], ['cuenta_para', $this->id]])->orderByAsc('fecha')->findMany();
- return $transacciones;
- }
- public function unidades()
- {
- return null;
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/EstadoCobro.php b/incoviba/modelos/src/nuevo/Inmobiliaria/EstadoCobro.php
deleted file mode 100644
index 251c914..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/EstadoCobro.php
+++ /dev/null
@@ -1,26 +0,0 @@
-belongsTo(Cobro::class, 'cobro_id')->findOne();
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoCobro::class, 'estado_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Inmobiliaria.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Inmobiliaria.php
deleted file mode 100644
index c28388a..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Inmobiliaria.php
+++ /dev/null
@@ -1,50 +0,0 @@
-belongs_to(Direccion::class, 'direccion_id')->findOne();
- }
- public function representante()
- {
- return $this->belongs_to(Representante::class, 'representante_rut', 'rut')->findOne();
- }
- public function estado()
- {
- return ($estado != 0);
- }
-
- public function proyectos()
- {
- return $this->has_many(Proyecto::class, 'inmobiliaria_rut', 'rut')->findMany();
- }
- public function inversionistas()
- {
- return $this->has_many_through(Socio::class, Participacion::class, 'socio_id', 'inmobiliaria_rut', 'rut')->findMany();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Participacion.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Participacion.php
deleted file mode 100644
index f56388a..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Participacion.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria_rut', 'rut')->findOne();
- }
- public function socio()
- {
- return $this->belongsTo(Socio::class, 'socio_rut', 'rut')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Representante.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Representante.php
deleted file mode 100644
index 1bc76b3..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Representante.php
+++ /dev/null
@@ -1,56 +0,0 @@
-belongsTo(Direccion::class, 'direccion_id')->findMany();
- }
- public function nombreCompleto()
- {
- return $this->nombres . ' ' . $this->apellidos;
- }
-
- public function inmobiliarias()
- {
- return $this->hasMany(Inmobiliaria::class, 'representante_rut', 'rut')->findMany();
- }
- public function agentes()
- {
- return $this->hasMany(Agente::class, 'representante_rut', 'rut')->findMany();
- }
- public function apelativo()
- {
- if ($this->sexo == 'f') {
- return 'doña';
- }
- return 'don';
- }
- public function articulo()
- {
- if ($this->sexo == 'f') {
- return 'la';
- }
- return 'el';
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/Socio.php b/incoviba/modelos/src/nuevo/Inmobiliaria/Socio.php
deleted file mode 100644
index dddd84e..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/Socio.php
+++ /dev/null
@@ -1,23 +0,0 @@
-hasMany(Participacion::class, 'socio_rut', 'rut')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoAgente.php b/incoviba/modelos/src/nuevo/Inmobiliaria/TipoAgente.php
deleted file mode 100644
index 7455f90..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoAgente.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasMany(Agente::class, 'tipo_agente_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoCobro.php b/incoviba/modelos/src/nuevo/Inmobiliaria/TipoCobro.php
deleted file mode 100644
index 3bb0f1a..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoCobro.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasMany(Cobro::class, 'tipo_cobro_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoContrato.php b/incoviba/modelos/src/nuevo/Inmobiliaria/TipoContrato.php
deleted file mode 100644
index 15ae99d..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoContrato.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasMany(Contrato::class)->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoEstadoCobro.php b/incoviba/modelos/src/nuevo/Inmobiliaria/TipoEstadoCobro.php
deleted file mode 100644
index 777e97f..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/TipoEstadoCobro.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasMany(EstadoCobro::class, 'estado_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Inmobiliaria/TransaccionContable.php b/incoviba/modelos/src/nuevo/Inmobiliaria/TransaccionContable.php
deleted file mode 100644
index ddbbed5..0000000
--- a/incoviba/modelos/src/nuevo/Inmobiliaria/TransaccionContable.php
+++ /dev/null
@@ -1,46 +0,0 @@
-belongsTo(CuentaContable::class, 'cuenta_de');
- }
- public function para()
- {
- return $this->belongsTo(CuentaContable::class, 'cuenta_para');
- }
-
- public function valor($tipo = 'pesos')
- {
- if ($tipo == 'ufs') {
- $uf = model(UF::class)->where('fecha', $this->fecha)->findOne();
- if (!$uf) {
- $uf = model(UF::class)->create();
- $uf->fecha = $this->fecha;
- $uf->getValor();
- $uf->save();
- }
- return ($this->valor / $uf->valor) ?: 0;
- }
- return $this->valor;
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/EstadoProyecto.php b/incoviba/modelos/src/nuevo/Proyecto/EstadoProyecto.php
deleted file mode 100644
index c400628..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/EstadoProyecto.php
+++ /dev/null
@@ -1,25 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto_id')->findOne();
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoProyecto::class, 'estado_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/Etapa.php b/incoviba/modelos/src/nuevo/Proyecto/Etapa.php
deleted file mode 100644
index 9dbda32..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/Etapa.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasMany(TipoEstadoProyecto::class, 'etapa_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/Participe.php b/incoviba/modelos/src/nuevo/Proyecto/Participe.php
deleted file mode 100644
index 1aafd6f..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/Participe.php
+++ /dev/null
@@ -1,27 +0,0 @@
-hasManyThrough(Proyecto::class, ProyectoParticipe::class, 'proyecto_id', 'participe_rut', 'rut')->findMany();
- }
- public function participaciones()
- {
- return $this->hasMany(ProyectoParticipe::class, 'participe_rut', 'rut')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/Proyecto.php b/incoviba/modelos/src/nuevo/Proyecto/Proyecto.php
deleted file mode 100644
index 922573e..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/Proyecto.php
+++ /dev/null
@@ -1,132 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria_rut', 'rut')->findOne();
- }
- public function direccion()
- {
- return $this->belongsTo(Direccion::class, 'direccion_id')->findOne();
- }
-
- public function participaciones()
- {
- return $this->hasMany(ProyectoParticipe::class, 'proyecto_id')->findMany();
- }
- public function participes()
- {
- return $this->hasManyThrough(Participe::class, ProyectoParticipe::class, 'proyecto_id', 'participe_rut', 'rut')->findMany();
- }
- public function unidades()
- {
- return $this->hasMany(UnidadProyecto::class, 'proyecto_id')->findMany();
- }
- public function cantidad($tipo = 'departamento')
- {
- $total = 0;
- $unidades = $this->unidades;
- foreach ($unidades as $unidad) {
- if ($unidad->tipo->descripcion == $tipo) {
- $total += $unidad->unidades->count();
- }
- }
- return $total;
- }
- public function unidadesPrincipales()
- {
- if ($this->tipoUnidades()) {
- return $this->cantidad('departamento');
- } else {
- return $this->cantidad('casa');
- }
- }
- public function pisos()
- {
- $max_piso = 0;
- $unidades = $this->unidades;
- foreach ($unidades as $unidad) {
- $piso = $unidad->unidades->max('piso');
- if ($max_piso < $piso) {
- $max_piso = $piso;
- }
- }
- return $max_piso;
- }
- public function m2Construidos()
- {
- $total = 0;
- $unidades = $this->unidades;
- foreach ($unidades as $unidad) {
- $total += $unidad->m2->total() * $unidad->unidades->count();
- }
- return $total;
- }
- public function tipoUnidades()
- {
- return (!$this->unidades->isEmpty() and $this->unidades[0]->tipo->descripcion == 'departamento');
- }
- public function ventas()
- {
- $ventas = [];
- foreach ($this->unidades as $up) {
- foreach ($up->unidades as $u) {
- if (isset($u->propiedad)) {
- $ventas->add($u->propiedad->venta);
- }
- }
- }
- $ventas = sort($ventas, function($a, $b) {
- return $a->propiedad->unidadPrincipal->numeracion - $b->propiedad->unidadPrincipal->numeracion;
- });
- return $ventas;
- }
- public function ventasActivas()
- {
- $ventas = $this->ventas();
- $output = [];
- foreach ($ventas as $venta) {
- $estado = $venta->ultimoEstado()->estado->descripcion;
- if ($estado == 'promesado' or $estado == 'escriturado' or $estado == 'entregado') {
- $output []= $venta;
- }
- }
- return $output;
- }
- public function pVendido()
- {
- return $this->ventasActivas()->count() / $this->unidadesPrincipales();
- }
- public function m2Vendidos()
- {
- $ventas = $this->ventasActivas();
- $sum = 0;
- foreach ($ventas as $venta) {
- $sum += $venta->propiedad->unidadPrincipal->unidadProyecto->m2->vendibles();
- }
- return $sum;
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/ProyectoParticipe.php b/incoviba/modelos/src/nuevo/Proyecto/ProyectoParticipe.php
deleted file mode 100644
index 743e218..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/ProyectoParticipe.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto_id')->findOne();
- }
- public function participe()
- {
- $this->belongsTo(Participe::class, 'participe_rut', 'rut')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/Tema.php b/incoviba/modelos/src/nuevo/Proyecto/Tema.php
deleted file mode 100644
index 8f665e5..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/Tema.php
+++ /dev/null
@@ -1,75 +0,0 @@
-belongsTo(Proyecto::class)->findOne();
- if ($proyecto) {
- return $proyecto;
- }
- return $this->belongsTo(P::class)->findOne();
- }
- public function inicio()
- {
- return Carbon::parse($this->inicio, config('app.timezone'));
- }
- public function cierre()
- {
- return Carbon::parse($this->cierre, config('app.timezone'));
- }
- public function texto()
- {
- $text = $this->texto;
- $text = explode("\n", $text);
- foreach ($text as &$line) {
- $line = trim(rtrim($line, '.')) . '.';
- if ($line != ltrim($line, '-')) {
- $line = ' ' . $line;
- }
- }
- $text = implode('
', $text);
-
- preg_match_all('/\[\[.*\]\]/', $text, $matches);
- $search = [];
- $replace = [];
- if (count($matches[0]) > 0) {
- foreach ($matches[0] as $match) {
- $search []= $match;
- list($model, $where, $value) = explode(':', str_replace(['[',']'], ['', ''], $match));
- $class = '\\Incoviba\\old\\' . $model;
- $obj = model($class)->where($where, $value)->findOne();
-
- $str = $value;
- if ($obj->venta()) {
- $str = '' . $value . '';
- }
- $replace []= $str;
- }
- }
-
- $text = str_replace($search, $replace, $text);
-
- return $text;
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Proyecto/TipoEstadoProyecto.php b/incoviba/modelos/src/nuevo/Proyecto/TipoEstadoProyecto.php
deleted file mode 100644
index 8d87e4d..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/TipoEstadoProyecto.php
+++ /dev/null
@@ -1,28 +0,0 @@
-belongsTo(Etapa::class, 'etapa_id')->findOne();
- }
-
- public function estados()
- {
- return $this->hasMany(EstadoProyecto::class, 'estado_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/TipoUnidad.php b/incoviba/modelos/src/nuevo/Proyecto/TipoUnidad.php
deleted file mode 100644
index 2eb403d..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/TipoUnidad.php
+++ /dev/null
@@ -1,21 +0,0 @@
-hasMany(UnidadProyecto::class, 'tipo_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Proyecto/UnidadProyecto.php b/incoviba/modelos/src/nuevo/Proyecto/UnidadProyecto.php
deleted file mode 100644
index 0cd665c..0000000
--- a/incoviba/modelos/src/nuevo/Proyecto/UnidadProyecto.php
+++ /dev/null
@@ -1,50 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto_id')->findOne();
- }
- public function m2()
- {
- return $this->belongsTo(M2::class, 'm2_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoUnidad::class, 'tipo_id')->findOne();
- }
- public function unidades()
- {
- return $this->hasMany(Unidad::class, 'unidad_proyecto_id')->findMany();
- }
- public function orientaciones()
- {
- $orientaciones = [];
- foreach ($this->unidades as $unidad) {
- if (array_search($unidad->orientacion, $orientaciones) === false) {
- $orientaciones []= $unidad->orientacion;
- }
- }
- return $orientaciones;
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Cierre.php b/incoviba/modelos/src/nuevo/Venta/Cierre.php
deleted file mode 100644
index ce5a28e..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Cierre.php
+++ /dev/null
@@ -1,59 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto_id')->findOne();
- }
- public function agente()
- {
- return $this->belongsTo(Agente::class, 'agente_id')->findOne();
- }
- public function propietario()
- {
- return $this->belongsTo(Propietario::class, 'propietario_rut')->findOne();
- }
- public function reserva()
- {
- return $this->belongsTo(Reserva::class, 'reserva_id')->findOne();
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- public function pie($type = 'ufs')
- {
- if ($type == 'ufs') {
- return $this->pie;
- }
- $uf = uf($this->fecha());
- return $this->pie * $uf->uf->value;
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Comentario.php b/incoviba/modelos/src/nuevo/Venta/Comentario.php
deleted file mode 100644
index 4c99f66..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Comentario.php
+++ /dev/null
@@ -1,23 +0,0 @@
-belongsTo(Venta::class, 'venta_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Cuota.php b/incoviba/modelos/src/nuevo/Venta/Cuota.php
deleted file mode 100644
index d273578..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Cuota.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Pie::class, 'pie_id')->findOne();
- }
- public function pago()
- {
- return $this->belongsTo(Pago::class, 'pago_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Entrega.php b/incoviba/modelos/src/nuevo/Venta/Entrega.php
deleted file mode 100644
index fb15691..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Entrega.php
+++ /dev/null
@@ -1,47 +0,0 @@
-belongs_to(Venta::class, 'venta_id')->findOne();
- }
-
- public function fondos()
- {
- return $this->has_many_through(Pago::class, FondoEntrega::class, 'entrega_id', 'pago_id')->findMany();
- }
- public function mediciones()
- {
- return $this->has_many_through(Medicion::class, MedicionEntrega::class, 'entrega_id', 'medicion_id')->findMany();
- }
- public function observaciones()
- {
- return $this->has_many_through(Observacion::class, EntregaObservacion::class, 'entrega_id', 'observacion_id')->findMany();
- }
- public function observacionesPendientes()
- {
- return $this->has_many_through(Observacion::class, EntregaObservacion::class, 'entrega_id', 'observacion_id')
- ->select('observaciones.*')
- ->rawJoin('JOIN (SELECT e1.* FROM (SELECT MAX(id) AS id, observacion_id FROM estado_observaciones GROUP BY observacion_id) e0 JOIN estado_observaciones e1 ON e1.id = e0.id)', ['ep.observacion_id', '=', 'observaciones.id'], 'ep')
- ->leftOuterJoin('tipo_estado_observaciones', ['tipo_estado_observaciones.id', '=', 'ep.tipo_estado_observacion_id'])
- ->where('tipo_estado_observaciones.descripcion', 'ingresada')
- ->findMany();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/EstadoCierre.php b/incoviba/modelos/src/nuevo/Venta/EstadoCierre.php
deleted file mode 100644
index d9be83e..0000000
--- a/incoviba/modelos/src/nuevo/Venta/EstadoCierre.php
+++ /dev/null
@@ -1,26 +0,0 @@
-belongsTo(Cierre::class)->findOne();
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoCierre::class)->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/EstadoObservacion.php b/incoviba/modelos/src/nuevo/Venta/EstadoObservacion.php
deleted file mode 100644
index e4fc984..0000000
--- a/incoviba/modelos/src/nuevo/Venta/EstadoObservacion.php
+++ /dev/null
@@ -1,26 +0,0 @@
-belongs_to(Observacion::class, 'observacion_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoEstadoObservacion::class, 'tipo_estado_observacion_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/EstadoPago.php b/incoviba/modelos/src/nuevo/Venta/EstadoPago.php
deleted file mode 100644
index a163d9d..0000000
--- a/incoviba/modelos/src/nuevo/Venta/EstadoPago.php
+++ /dev/null
@@ -1,25 +0,0 @@
-belongsTo(Pago::class, 'pago_id')->findOne();
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoPago::class, 'estado_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/EstadoPostventa.php b/incoviba/modelos/src/nuevo/Venta/EstadoPostventa.php
deleted file mode 100644
index ba8b6be..0000000
--- a/incoviba/modelos/src/nuevo/Venta/EstadoPostventa.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongs_to(Postventa::class, 'postventa_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoEstadoPostventa::class, 'tipo_estado_postventa_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/EstadoVenta.php b/incoviba/modelos/src/nuevo/Venta/EstadoVenta.php
deleted file mode 100644
index 52ac3df..0000000
--- a/incoviba/modelos/src/nuevo/Venta/EstadoVenta.php
+++ /dev/null
@@ -1,25 +0,0 @@
-belongsTo(Venta::class, 'venta_id')->findOne();
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoVenta::class, 'estado_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/FondoVenta.php b/incoviba/modelos/src/nuevo/Venta/FondoVenta.php
deleted file mode 100644
index 7e5c689..0000000
--- a/incoviba/modelos/src/nuevo/Venta/FondoVenta.php
+++ /dev/null
@@ -1,31 +0,0 @@
-belongs_to(Venta::class, 'venta_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoFondo::class, 'tipo_id')->findOne();
- }
- public function pago()
- {
- return $this->belongs_to(Pago::class, 'pago_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/FormaPago.php b/incoviba/modelos/src/nuevo/Venta/FormaPago.php
deleted file mode 100644
index 43ffff0..0000000
--- a/incoviba/modelos/src/nuevo/Venta/FormaPago.php
+++ /dev/null
@@ -1,35 +0,0 @@
-belongsTo(Pie::class, 'pie_id')->findOne();
- }
- public function escritura()
- {
- return $this->belongsTo(Pago::class, 'escritura_id')->findOne();
- }
- public function credito()
- {
- return $this->belongsTo(Pago::class, 'credito_id')->findOne();
- }
- public function subsidio()
- {
- return $this->belongs_to(Subsidio::class, 'subsidio_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Medicion.php b/incoviba/modelos/src/nuevo/Venta/Medicion.php
deleted file mode 100644
index 4e8c25f..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Medicion.php
+++ /dev/null
@@ -1,24 +0,0 @@
-belongs_to(TipoMedicion::class, 'tipo_medicion_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Observacion.php b/incoviba/modelos/src/nuevo/Venta/Observacion.php
deleted file mode 100644
index af3d10e..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Observacion.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Pago.php b/incoviba/modelos/src/nuevo/Venta/Pago.php
deleted file mode 100644
index 2aa1d18..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Pago.php
+++ /dev/null
@@ -1,35 +0,0 @@
-belongsTo(TipoPago::class, 'tipo_id')->findOne();
- }
- public function banco()
- {
- return $this->belongsTo(Banco::class, 'banco_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Pie.php b/incoviba/modelos/src/nuevo/Venta/Pie.php
deleted file mode 100644
index 70a292a..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Pie.php
+++ /dev/null
@@ -1,39 +0,0 @@
-belongsTo(Pie::class, 'asociado_id');
- if ($pie) {
- return $pie->findOne();
- }
- return null;
- }
- public function Cuotas()
- {
- return $this->hasMany(Cuota::class, 'pie_id')->findMany();
- }
- public function CuotasPagadas()
- {
- return $this->hasMany(Cuota::class, 'pie_id')->filter(function($cuota) {
- $estado = $cuota->pago->ultimoEstado()->estado->descripcion;
- return ($estado == 'depositado' or $estado == 'abonado');
- });
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Postventa.php b/incoviba/modelos/src/nuevo/Venta/Postventa.php
deleted file mode 100644
index defd340..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Postventa.php
+++ /dev/null
@@ -1,38 +0,0 @@
-belongs_to(Venta::class, 'venta_id')->findOne();
- }
- public function observaciones()
- {
- return $this->has_many_through(Observacion::class, PostventaObservacion::class, 'postventa_id', 'observacion_id')->findMany();
- }
- public function observacionesPendientes()
- {
- return $this->has_many_through(Observacion::class, PostventaObservacion::class, 'postventa_id', 'observacion_id')
- ->select('observaciones.*')
- ->rawJoin('JOIN (SELECT e1.* FROM (SELECT MAX(id) AS id, observacion_id FROM estado_observaciones GROUP BY observacion_id) e0 JOIN estado_observaciones e1 ON e1.id = e0.id)', ['ep.observacion_id', '=', 'observaciones.id'], 'ep')
- ->leftOuterJoin('tipo_estado_observaciones', ['tipo_estado_observaciones.id', '=', 'ep.tipo_estado_observacion_id'])
- ->where('tipo_estado_observaciones.descripcion', 'ingresada')
- ->findMany();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/PostventaObservacion.php b/incoviba/modelos/src/nuevo/Venta/PostventaObservacion.php
deleted file mode 100644
index f16309a..0000000
--- a/incoviba/modelos/src/nuevo/Venta/PostventaObservacion.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongs_to(Postventa::class, 'postventa_id')->findOne();
- }
- public function observacion()
- {
- return $this->belongs_to(Observacion::class, 'observacion_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Premio.php b/incoviba/modelos/src/nuevo/Venta/Premio.php
deleted file mode 100644
index 0ea45c0..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Premio.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Venta::class, 'venta_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoPremio::class, 'tipo_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Propiedad.php b/incoviba/modelos/src/nuevo/Venta/Propiedad.php
deleted file mode 100644
index edc7299..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Propiedad.php
+++ /dev/null
@@ -1,30 +0,0 @@
-belongsTo(Unidad::class, 'unidad_id')->findOne();
- }
- public function unidades()
- {
- return $this->hasMany(UnidadPropiedad::class, 'propiedad_id')->findMany();
- }
- public function venta()
- {
- return $this->hasMany(Venta::class, 'propiedad_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Propietario.php b/incoviba/modelos/src/nuevo/Venta/Propietario.php
deleted file mode 100644
index be00555..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Propietario.php
+++ /dev/null
@@ -1,71 +0,0 @@
-belongsTo(Direccion::class, 'direccion_id')->findOne();
- }
- public function representante()
- {
- $prop = $this->belongsTo(Propietario::class, 'representante_rut', 'rut');
- if ($prop) {
- return $prop->findOne();
- }
- return null;
- }
- public function otro()
- {
- $prop = $this->belongsTo(Propietario::class, 'otro_rut', 'rut');
- if ($prop) {
- return $prop->findOne();
- }
- return null;
- }
-
- public function nombreCompleto()
- {
- return implode(' ', [$this->nombres, $this->apellido_paterno, $this->apellido_materno]);
- }
-
- public function represntado()
- {
- $prop = $this->has_many(Propietario::class, 'representante_rut', 'rut');
- if ($prop) {
- return $prop->findOne();
- }
- return null;
- }
- public function ventas()
- {
- return $this->hasMany(Venta::class, 'propietario_rut', 'rut')->findMany();
- }
- public function articulo()
- {
- if ($this->sexo == 'f') {
- return 'la';
- }
- return 'el';
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/ProyectoTipoMedicion.php b/incoviba/modelos/src/nuevo/Venta/ProyectoTipoMedicion.php
deleted file mode 100644
index 6d479c7..0000000
--- a/incoviba/modelos/src/nuevo/Venta/ProyectoTipoMedicion.php
+++ /dev/null
@@ -1,28 +0,0 @@
-belongs_to(Proyecto::class, 'proyecto_id')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoMedicion::class, 'tipo_medicion_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Reserva.php b/incoviba/modelos/src/nuevo/Venta/Reserva.php
deleted file mode 100644
index 3f68449..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Reserva.php
+++ /dev/null
@@ -1,30 +0,0 @@
-belongsTo(Unidad::class, 'unidad_id')->findOne();
- }
- public function unidades()
- {
- return $this->hasMany(UnidadReserva::class, 'reserva_id')->findMany();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoEstadoCierre.php b/incoviba/modelos/src/nuevo/Venta/TipoEstadoCierre.php
deleted file mode 100644
index 50498bc..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoEstadoCierre.php
+++ /dev/null
@@ -1,10 +0,0 @@
-
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoEstadoObservacion.php b/incoviba/modelos/src/nuevo/Venta/TipoEstadoObservacion.php
deleted file mode 100644
index ba0eb69..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoEstadoObservacion.php
+++ /dev/null
@@ -1,10 +0,0 @@
-
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoEstadoPago.php b/incoviba/modelos/src/nuevo/Venta/TipoEstadoPago.php
deleted file mode 100644
index 0224436..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoEstadoPago.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasMany(EstadoPago::class, 'estado_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoEstadoPostventa.php b/incoviba/modelos/src/nuevo/Venta/TipoEstadoPostventa.php
deleted file mode 100644
index 3a50841..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoEstadoPostventa.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoEstadoVenta.php b/incoviba/modelos/src/nuevo/Venta/TipoEstadoVenta.php
deleted file mode 100644
index 044dcbf..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoEstadoVenta.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasMany(EstadoVenta::class, 'estado_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoFondo.php b/incoviba/modelos/src/nuevo/Venta/TipoFondo.php
deleted file mode 100644
index 0374e5f..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoFondo.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasMany(FontoVenta::class, 'tipo_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoMedicion.php b/incoviba/modelos/src/nuevo/Venta/TipoMedicion.php
deleted file mode 100644
index 64d21cd..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoMedicion.php
+++ /dev/null
@@ -1,10 +0,0 @@
-
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoPago.php b/incoviba/modelos/src/nuevo/Venta/TipoPago.php
deleted file mode 100644
index 0ce8a64..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoPago.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasMany(Pago::class, 'tipo_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/TipoPremio.php b/incoviba/modelos/src/nuevo/Venta/TipoPremio.php
deleted file mode 100644
index 381cc39..0000000
--- a/incoviba/modelos/src/nuevo/Venta/TipoPremio.php
+++ /dev/null
@@ -1,14 +0,0 @@
-hasMany(Premio::class, 'tipo_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/Unidad.php b/incoviba/modelos/src/nuevo/Venta/Unidad.php
deleted file mode 100644
index 7e43358..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Unidad.php
+++ /dev/null
@@ -1,47 +0,0 @@
-belongsTo(UnidadProyecto::class, 'unidad_proyecto_id')->findOne();
- }
- public function uPropiedad()
- {
- $up = $this->hasMany(UnidadPropiedad::class, 'unidad_id');
- if ($up) {
- return $up->findOne();
- }
- return null;
- }
- public function propiedad()
- {
- $prop = $this->hasMany(Propiedad::class, 'unidad_id');
- if ($prop) {
- return $prop->findOne();
- }
- return null;
- }
- public function cuentas()
- {
- return $this->belongsTo(CuentaContable::class, 'cuenta_unidades', 'unidad_id', 'cuenta_id')->findMany();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/UnidadPropiedad.php b/incoviba/modelos/src/nuevo/Venta/UnidadPropiedad.php
deleted file mode 100644
index d8a8465..0000000
--- a/incoviba/modelos/src/nuevo/Venta/UnidadPropiedad.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Propiedad::class, 'propiedad_id')->findOne();
- }
- public function unidad()
- {
- return $this->belongsTo(Unidad::class, 'unidad_id')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/nuevo/Venta/UnidadReserva.php b/incoviba/modelos/src/nuevo/Venta/UnidadReserva.php
deleted file mode 100644
index f0355cb..0000000
--- a/incoviba/modelos/src/nuevo/Venta/UnidadReserva.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Reserva::class, 'reserva_id')->findOne();
- }
- public function unidad()
- {
- return $this->belongsTo(Unidad::class, 'unidad_id')->findOne();
- }
-}
-?>
\ No newline at end of file
diff --git a/incoviba/modelos/src/nuevo/Venta/Venta.php b/incoviba/modelos/src/nuevo/Venta/Venta.php
deleted file mode 100644
index d5bad0d..0000000
--- a/incoviba/modelos/src/nuevo/Venta/Venta.php
+++ /dev/null
@@ -1,104 +0,0 @@
-belongs_to(Propietario::class, 'propietario_rut', 'rut')->findOne();
- }
- public function propiedad()
- {
- return $this->belongs_to(Propiedad::class, 'propiedad_id')->findOne();
- }
- public function formaPago()
- {
- return $this->belongs_to(FormaPago::class, 'forma_pago_id')->findOne();
- }
- public function agente()
- {
- $agente = $this->belongs_to(Agente::class, 'agente_id');
- if ($agente) {
- return $agente->findOne();
- }
- return null;
- }
-
- public function valor()
- {
- return $this->valor_promesa * $this->uf;
- }
- public function proyecto()
- {
- return $this->propiedad->unidadPrincipal->unidadProyecto->proyecto();
- }
- public function comision()
- {
- return $this->agente->comision($this->proyecto->inmobiliaria->rut);
- }
- public function ufM2()
- {
- if (!$this->agente) {
- return 0;
- }
- return ($this->valor_promesa - $this->premios->sum('valor') - $this->comision() - $this->propiedad->unidades->sum('valor')) / $this->propiedad->unidadPrincipal->unidadProyecto->m2->vendibles();
- }
- public function fechaPromesa()
- {
- return Carbon::parse($this->fecha_promesa, config('app.timezone'));
- }
-
- public function premios()
- {
- $premios = $this->has_many(Premio::class, 'venta_id');
- if ($premios) {
- return $premios->findMany();
- }
- return [];
- }
- public function comentarios()
- {
- $comentarios = $this->has_many(Comentario::class, 'venta_id');
- if ($comentarios) {
- return $comentarios->findMany();
- }
- return [];
- }
- public function fondos()
- {
- return $this->has_many(FondoVenta::class, 'venta_id')->findMany();
- }
- public function postventas()
- {
- $postventas = $this->has_many(Postventa::class, 'venta_id');
- if ($postventas) {
- return $postventas->findMany();
- }
- return null;
- }
-}
diff --git a/incoviba/modelos/src/old/Common/Banco.php b/incoviba/modelos/src/old/Common/Banco.php
deleted file mode 100644
index d11cb22..0000000
--- a/incoviba/modelos/src/old/Common/Banco.php
+++ /dev/null
@@ -1,29 +0,0 @@
-nombre) {
- case 'Estado':
- case 'Chile':
- case 'Edwards':
- $str .= 'Banco ';
- }
- $str .= $this->nombre;
- return $str;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Common/Comuna.php b/incoviba/modelos/src/old/Common/Comuna.php
deleted file mode 100644
index 58266a6..0000000
--- a/incoviba/modelos/src/old/Common/Comuna.php
+++ /dev/null
@@ -1,22 +0,0 @@
-belongs_to(Provincia::class, 'provincia')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Common/Direccion.php b/incoviba/modelos/src/old/Common/Direccion.php
deleted file mode 100644
index 2ab38fc..0000000
--- a/incoviba/modelos/src/old/Common/Direccion.php
+++ /dev/null
@@ -1,36 +0,0 @@
-belongs_to(Comuna::class, 'comuna')->findOne();
- }
-
- public function completa($comuna = false)
- {
- $str = $this->calle . ' ' . $this->numero;
- if ($this->extra != '') {
- $str .= ', ' . $this->extra;
- }
- if ($comuna) {
- $str .= ', ' . $this->comuna()->descripcion;
- }
- return $str;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Common/Provincia.php b/incoviba/modelos/src/old/Common/Provincia.php
deleted file mode 100644
index 8571dca..0000000
--- a/incoviba/modelos/src/old/Common/Provincia.php
+++ /dev/null
@@ -1,26 +0,0 @@
-belongsTo(Region::class, 'region')->findOne();
- }
- public function comunas()
- {
- return $this->hasMany(Comuna::class, 'provincia')->findMany();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Common/Region.php b/incoviba/modelos/src/old/Common/Region.php
deleted file mode 100644
index b182609..0000000
--- a/incoviba/modelos/src/old/Common/Region.php
+++ /dev/null
@@ -1,44 +0,0 @@
-provincias == null) {
- $this->provincias = $this->hasMany(Provincia::class, 'region')->findMany();
- }
- return $this->provincias;
- }
- public function comunas()
- {
- if ($this->comunas == null) {
- $provincias = $this->provincias();
- $comunas = [];
- foreach ($provincias as $prov) {
- $comunas = array_merge($comunas, $prov->comunas());
- }
- usort($comunas, function($a, $b) {
- return strcmp($a->descripcion, $b->descripcion);
- });
- $this->comunas = $comunas;
- }
- return $this->comunas;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Inmobiliaria/Cuenta.php b/incoviba/modelos/src/old/Inmobiliaria/Cuenta.php
deleted file mode 100644
index dc14e8c..0000000
--- a/incoviba/modelos/src/old/Inmobiliaria/Cuenta.php
+++ /dev/null
@@ -1,23 +0,0 @@
-belongsTo(Inmobiliaria::class, 'inmobiliaria', 'rut')->findOne();
- }
- public function banco()
- {
- return $this->belongsTo(Banco::class, 'banco')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Inmobiliaria/Inmobiliaria.php b/incoviba/modelos/src/old/Inmobiliaria/Inmobiliaria.php
deleted file mode 100644
index 5f7f9d7..0000000
--- a/incoviba/modelos/src/old/Inmobiliaria/Inmobiliaria.php
+++ /dev/null
@@ -1,135 +0,0 @@
-cuenta()->banco();
- //return $this->belongsTo(Banco::class, 'banco')->findOne();
- }
- public function proyectos()
- {
- return $this->hasMany(Proyecto::class, 'inmobiliaria', 'rut')->orderByAsc('descripcion')->findMany();
- }
- public function nombre(bool $tipo = false)
- {
- return $this->abreviacion . (($tipo) ? ' ' . $this->sociedad()->abreviacion . '.' : '');
- }
- public function rut()
- {
- return format('rut', $this->rut) . '-' . $this->dv;
- }
- public function sociedad() {
- return $this->belongsTo(TipoSociedad::class, 'sociedad')->findOne();
- }
- public function razon(bool $tipo = false, bool $abreviado = false) {
- return $this->razon . (($tipo) ? ' ' . (($abreviado) ? $this->sociedad()->abreviacion . '.' : $this->sociedad()->descripcion) : '');
- }
- /**
- * $data = ['descripcion', 'calle', 'numero', 'extra', 'comuna']
- */
- public function addProyecto(array $data)
- {
- //$proyecto = model(Proyecto::class)->where('inmobiliaria', $this->rut)->where('descripcion', $data['descripcion'])->findOne();
- $data = [
- 'inmobiliaria' => $this->rut,
- 'descripcion' => $data['descripcion']
- ];
- $proyecto = (new Factory(Proyecto::class))->where($data)->find();
- if (!$proyecto) {
- //$proyecto = model(Proyecto::class)->create();
- $proyecto = (new Factory(Proyecto::class))->create($data);
- /*$proyecto->inmobiliaria = $this->rut;
- $proyecto->descripcion = $data['descripcion'];*/
- $proyecto->setDireccion($data);
- $proyecto->save();
- }
- }
- public function removeProyecto(array $data)
- {
- $proyecto = (new Factory(Proyecto::class))->where([
- 'inmobiliaria' => $this->rut,
- 'descripcion' => $data['descripcion']
- ])->find();
- if ($proyecto) {
- $proyecto->delete();
- }
- }
- public function cuenta()
- {
- if (count($this->cuentas()) == 0) {
- return false;
- }
- return $this->cuentas()[0];
- }
- public function cuentas()
- {
- return $this->hasMany(Cuenta::class, 'inmobiliaria', 'rut')->findMany();
- }
- public function addCuenta(array $data)
- {
- if (!is_numeric($data['banco'])) {
- $banco = (new Factory(Banco::class))->where(['descripcion' => $data['banco']])->find();
- $data['banco'] = $banco->id;
- }
- $data = [
- 'inmobiliaria' => $this->rut,
- 'cuenta' => $data['cuenta'],
- 'banco' => $data['banco']
- ];
- $cuenta = (new Factory(Cuenta::class))->where($data)->find();
- if (!$cuenta) {
- $cuenta = (new Factory(Cuenta::class))->create($data);
- $cuenta->save();
- }
- }
- public function removeCuenta(array $data)
- {
- $cuenta = (new Factory(Cuenta::class))->where(['inmobiliaria' => $this->rut]);
- if (isset($data['cuenta'])) {
- $cuenta = $cuenta->where(['cuenta' => $data['cuenta']]);
- }
- if (isset($data['banco'])) {
- if (!is_numeric($data['banco'])) {
- $banco = (new Factory(Banco::class))->where(['descripcion' => $data['banco']])->find();
- $data['banco'] = $banco->id;
- }
- $cuenta = $cuenta->where(['banco' => $data['banco']]);
- }
- $cuenta = $cuenta->find();
- if ($cuenta) {
- $cuenta->delete();
- }
- }
- public function modify(array $data)
- {
- $fields = ['rut', 'dv', 'razon', 'abreviacion'];
- foreach ($data as $column => $value) {
- if (array_search($column, $fields) !== false) {
- $this->$column = $value;
- }
- }
- $this->cuenta()->modify($data);
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Inmobiliaria/RelacionInmobiliarias.php b/incoviba/modelos/src/old/Inmobiliaria/RelacionInmobiliarias.php
deleted file mode 100644
index b86593d..0000000
--- a/incoviba/modelos/src/old/Inmobiliaria/RelacionInmobiliarias.php
+++ /dev/null
@@ -1,24 +0,0 @@
-belongsTo(Inmobiliaria::class, 'padre', 'rut')->findOne();
- }
- public function hijo()
- {
- return $this->belongsTo(Inmobiliaria::class, 'hijo', 'rut')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Inmobiliaria/TipoSociedad.php b/incoviba/modelos/src/old/Inmobiliaria/TipoSociedad.php
deleted file mode 100644
index d2f0ce0..0000000
--- a/incoviba/modelos/src/old/Inmobiliaria/TipoSociedad.php
+++ /dev/null
@@ -1,12 +0,0 @@
-belongs_to(Direccion::class, 'direccion')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoAgente::class, 'tipo')->findOne();
- }
- public function tipos(int $tipo = 0)
- {
- if ($tipo == 0) {
- return $this->hasMany(AgenteTipo::class, 'agente')->findMany();
- }
- return $this->hasMany(AgenteTipo::class, 'agente')->where('tipo', $tipo)->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/AgenteTipo.php b/incoviba/modelos/src/old/Proyecto/AgenteTipo.php
deleted file mode 100644
index 91be4e3..0000000
--- a/incoviba/modelos/src/old/Proyecto/AgenteTipo.php
+++ /dev/null
@@ -1,20 +0,0 @@
-belongsTo(Agente::class, 'agente')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoAgente::class, 'tipo')->findOne();
- }
-}
\ No newline at end of file
diff --git a/incoviba/modelos/src/old/Proyecto/AvanceConstruccion.php b/incoviba/modelos/src/old/Proyecto/AvanceConstruccion.php
deleted file mode 100644
index 93b30a4..0000000
--- a/incoviba/modelos/src/old/Proyecto/AvanceConstruccion.php
+++ /dev/null
@@ -1,86 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- protected $pagare;
- public function pagare()
- {
- if ($this->pagare == null) {
- $this->pagare = $this->hasMany(Pagare::class, 'estado_pago', 'numero')
- ->where('proyecto', $this->proyecto)
- ->findOne();
- }
- return $this->pagare;
- }
- protected $pagares;
- public function pagares()
- {
- if ($this->pagares == null) {
- $this->pagares = $this->hasMany(Pagare::class, 'estado_pago', 'numero')
- ->where('proyecto', $this->proyecto)
- ->findMany();
- }
- return $this->pagares;
- }
- public function uf()
- {
- if ($this->uf == 0) {
- $uf = uf($this->fecha());
- if ($uf->total > 0) {
- $this->uf = $uf->uf->value;
- $this->save();
- }
- }
- return $this->uf;
- }
- public function pagado($tipo = 'ufs')
- {
- if ($tipo == 'ufs') {
- return $this->pagado / $this->uf();
- }
- return $this->pagado;
- }
- public function fechaPago(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha_pagado, config('app.timezone'));
- }
- $this->fecha_pagado = $fecha->format('Y-m-d');
- }
- public function edit(array $data)
- {
- foreach ($data as $column => $value) {
- if (isset($this->$column) and $this->$column != $value) {
- $this->$column = $value;
- }
- }
- $this->save();
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/Cobro.php b/incoviba/modelos/src/old/Proyecto/Cobro.php
deleted file mode 100644
index 47a1a0a..0000000
--- a/incoviba/modelos/src/old/Proyecto/Cobro.php
+++ /dev/null
@@ -1,35 +0,0 @@
-has_one(Proyecto::class);
- }
- public function agente()
- {
- return $this->has_one(Agente::class);
- }
- public function tipo()
- {
- return $this->has_one(TipoCobro::class);
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/Costo.php b/incoviba/modelos/src/old/Proyecto/Costo.php
deleted file mode 100644
index ef0de2e..0000000
--- a/incoviba/modelos/src/old/Proyecto/Costo.php
+++ /dev/null
@@ -1,21 +0,0 @@
-has_one(Proyecto::class, 'proyecto')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/EstadoCobro.php b/incoviba/modelos/src/old/Proyecto/EstadoCobro.php
deleted file mode 100644
index 787edb7..0000000
--- a/incoviba/modelos/src/old/Proyecto/EstadoCobro.php
+++ /dev/null
@@ -1,25 +0,0 @@
-has_one(Cobro::class, 'cobro')->findOne();
- }
- public function tipo()
- {
- return $this->has_one(TipoEstadoCobro::class, 'estado')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/EstadoProyecto.php b/incoviba/modelos/src/old/Proyecto/EstadoProyecto.php
deleted file mode 100644
index 245fe0f..0000000
--- a/incoviba/modelos/src/old/Proyecto/EstadoProyecto.php
+++ /dev/null
@@ -1,30 +0,0 @@
-belongs_to(Proyecto::class, 'proyecto')->findOne();
- }
- public function tipo()
- {
- return $this->belongs_to(TipoEstadoProyecto::class, 'estado')->findOne();
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/EstadoProyectoAgente.php b/incoviba/modelos/src/old/Proyecto/EstadoProyectoAgente.php
deleted file mode 100644
index 0811ce8..0000000
--- a/incoviba/modelos/src/old/Proyecto/EstadoProyectoAgente.php
+++ /dev/null
@@ -1,29 +0,0 @@
-belongsTo(ProyectoAgente::class, 'agente')->findOne();
- }
- public function fecha(\DateTime $fecha = null) {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- public function tipo()
- {
- return $this->belongsTo(TipoEstadoProyectoAgente::class, 'tipo')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/EtapaProyecto.php b/incoviba/modelos/src/old/Proyecto/EtapaProyecto.php
deleted file mode 100644
index e98c087..0000000
--- a/incoviba/modelos/src/old/Proyecto/EtapaProyecto.php
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/Pagare.php b/incoviba/modelos/src/old/Proyecto/Pagare.php
deleted file mode 100644
index ab5bd4d..0000000
--- a/incoviba/modelos/src/old/Proyecto/Pagare.php
+++ /dev/null
@@ -1,142 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
- public function moneda()
- {
- return $this->belongsTo(TipoMonedaPagare::class, 'moneda')->findOne();
- }
- public function renovaciones()
- {
- return $this->hasMany(RenovacionPagare::class, 'pagare')->findMany();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- public function fechaBanco(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha_banco, config('app.timezone'));
- }
- $this->fecha_banco = $fecha->format('Y-m-d');
- }
- public function vencimiento()
- {
- return $this->fechaBanco()->addDays($this->duracion);
- }
- public function uf()
- {
- if ($this->uf == 0 and $this->fecha != '0000-00-00') {
- $uf = uf($this->fecha());
- if ($uf->total > 0) {
- $this->uf = $uf->uf->value;
- $this->save();
- }
- }
- return $this->uf;
- }
- protected $valores;
- public function valor($tipo = 'ufs')
- {
- if ($this->valores == null) {
- $valores = [];
- switch (strtolower($this->moneda()->descripcion)) {
- case 'uf':
- $valores = (object) ['uf' => $this->capital, 'pesos' => $this->capital * $this->uf()];
- break;
- case 'pesos':
- $valores = (object) ['uf' => $this->capital / $this->uf(), 'pesos' => $this->capital];
- break;
- }
- $this->valores = $valores;
- }
- switch (strtolower($tipo)) {
- case 'uf':
- case 'ufs':
- return $this->valores->uf;
- case 'peso':
- case 'pesos':
- case '$':
- return $this->valores->pesos;
- }
- }
- public function abonado($tipo = 'ufs')
- {
- if ($tipo == 'ufs') {
- if ($this->uf() > 0) {
- return $this->abonado / $this->uf();
- }
- return 0;
- }
- return $this->abonado;
- }
- public function edit(array $data)
- {
- foreach ($data as $column => $value) {
- if (isset($this->$column) and $this->$column != $value) {
- $this->$column = $value;
- }
- }
- $this->save();
- }
- protected $intereses;
- public function intereses($tipo = 'ufs') {
- if ($this->intereses == null) {
- $this->intereses = (object) ['uf' => 0, 'pesos' => 0];
- if ($this->renovaciones()) {
- $arr = $this->renovaciones();
- $this->intereses->uf = array_reduce($arr, function($accum, $item) {
- return $accum + $item->intereses();
- });
- $this->intereses->pesos = array_reduce($arr, function($accum, $item) {
- return $accum + $item->intereses('pesos');
- });
- }
- }
- switch (strtolower($tipo)) {
- case 'uf':
- case 'ufs':
- return $this->intereses->uf;
- case 'peso':
- case 'pesos':
- case '$':
- return $this->intereses->pesos;
- }
- if ($fecha == null) {
- $fecha = $this->vencimiento();
- }
- $dif = $fecha->diffInDays($this->fecha());
- $duracion = ($dif > $this->duracion) ? $this->duracion : $dif;
- return $this->valor() * ($this->tasa / 365 * $duracion) / 100;
- }
- public function estado_pago() {
- if ($this->estado_pago == 0) {
- return false;
- }
- return $this->belongsTo(AvanceConstruccion::class, 'estado_pago', 'numero')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/Proyectista.php b/incoviba/modelos/src/old/Proyecto/Proyectista.php
deleted file mode 100644
index 95c40fe..0000000
--- a/incoviba/modelos/src/old/Proyecto/Proyectista.php
+++ /dev/null
@@ -1,21 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/Proyectistas.php b/incoviba/modelos/src/old/Proyecto/Proyectistas.php
deleted file mode 100644
index a004d21..0000000
--- a/incoviba/modelos/src/old/Proyecto/Proyectistas.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/Proyecto.php b/incoviba/modelos/src/old/Proyecto/Proyecto.php
deleted file mode 100644
index aac09ae..0000000
--- a/incoviba/modelos/src/old/Proyecto/Proyecto.php
+++ /dev/null
@@ -1,873 +0,0 @@
-belongs_to(Inmobiliaria::class, 'inmobiliaria', 'rut')->findOne();
- }
- public function direccion()
- {
- return $this->belongs_to(Direccion::class, 'direccion')->findOne();
- }
- public function unidades($tipo = null)
- {
- if ($tipo == null) {
- if (!isset($this->unidades) or !isset($this->unidades->total)) {
- $unidades = [];
- if (isset($this->unidades)) {
- $unidades = (array) $this->unidades;
- }
- $unidades['total'] = $this->has_many(Unidad::class, 'proyecto')->findMany();
- $this->unidades = (object) $unidades;
- }
- return $this->unidades->total;
- }
- switch ($tipo) {
- case 1:
- case 'departamento':
- case 'departamentos':
- $tipo = 'departamento';
- $id_tipo = 1;
- break;
- case 2:
- case 'estacionamiento':
- case 'estacionamientos':
- $tipo = 'estacionamiento';
- $id_tipo = 2;
- break;
- case 3:
- case 'bodega':
- case 'bodegas':
- $tipo = 'bodega';
- $id_tipo = 3;
- break;
- default:
- return $this->unidades();
- }
- if (!isset($this->unidades) or !isset($this->unidades->{$tipo})) {
- $unidades = [];
- if (isset($this->unidades)) {
- $unidades = (array) $this->unidades;
- }
- $unidades[$tipo] = $this->has_many(Unidad::class, 'proyecto')->where('tipo', $id_tipo)->findMany();
- $this->unidades = (object) $unidades;
- }
- return $this->unidades->{$tipo};
- }
- public function unidadesDisponibles($tipo = null)
- {
- switch ($tipo) {
- case 1:
- case 'departamento':
- case 'departamentos':
- $tipo = 'departamento';
- $id_tipo = 1;
- break;
- case 2:
- case 'estacionamiento':
- case 'estacionamientos':
- $tipo = 'estacionamiento';
- $id_tipo = 2;
- break;
- case 3:
- case 'bodega':
- case 'bodegas':
- $tipo = 'bodega';
- $id_tipo = 3;
- break;
- default:
- $tipo = 'total';
- $id_tipo = null;
- }
- if (!isset($this->unidades) or !isset($this->unidades->disponibles) or !isset($this->unidades->disponibles->{$tipo})) {
- $unidades = ['disponibles' => []];
- if (isset($this->unidades)) {
- $unidades = (array) $this->unidades;
- $unidades['disponibles'] = [];
- if (isset($this->unidades->disponibles)) {
- $unidades['disponibles'] = (array) $this->unidades->disponibles;
- }
- }
- /*$q_s = "SELECT u.*
- FROM
- (SELECT * FROM unidad WHERE proyecto = ? ORDER BY tipo) AS u
- LEFT JOIN
- (SELECT unidad.*
- FROM venta
- JOIN propiedad ON propiedad.id = venta.propiedad
- JOIN unidad ON unidad.id = propiedad.unidad_principal
- WHERE venta.estado = 1) AS v ON v.id = u.id
- LEFT JOIN
- (SELECT unidad.*
- FROM venta
- JOIN propiedad ON propiedad.id = venta.propiedad
- JOIN unidad ON propiedad.estacionamientos LIKE unidad.id
- OR propiedad.estacionamientos LIKE CONCAT(unidad.id, ';%')
- OR propiedad.estacionamientos LIKE CONCAT('%;', unidad.id)
- OR propiedad.estacionamientos LIKE CONCAT('%;', unidad.id, ';%')
- WHERE venta.estado = 1) AS e ON e.id = u.id
- LEFT JOIN
- (SELECT unidad.*
- FROM venta
- JOIN propiedad ON propiedad.id = venta.propiedad
- JOIN unidad ON propiedad.bodegas LIKE unidad.id
- OR propiedad.bodegas LIKE CONCAT(unidad.id, ';%')
- OR propiedad.bodegas LIKE CONCAT('%;', unidad.id)
- OR propiedad.bodegas LIKE CONCAT('%;', unidad.id, ';%')
- WHERE venta.estado = 1) AS b ON b.id = u.id
- WHERE v.id IS NULL AND e.id IS NULL AND b.id IS NULL";*/
- $q_s = "SELECT u.*
- FROM
- (SELECT * FROM unidad WHERE proyecto = ? ORDER BY tipo) AS u
- LEFT JOIN (SELECT unidad.*
- FROM unidad
- JOIN propiedad_unidad pu ON pu.unidad = unidad.id
- JOIN venta ON venta.propiedad = pu.propiedad
- JOIN (SELECT e1.* FROM estado_venta e1
- JOIN (SELECT venta, MAX(id) AS id FROM estado_venta GROUP BY venta) e0 ON e0.id = e1.id) ev ON ev.venta = venta.id
- WHERE ev.estado = 1) AS v ON v.id = u.id
- WHERE v.id IS NULL";
- $q_p = " ORDER BY u.tipo, LPAD(u.descripcion, 4, '0')";
- switch (strtolower($id_tipo)) {
- case null:
- default:
- $q = $q_s . $q_p;
- break;
- case 1:
- case 'departamento':
- case 'departamentos':
- $q = $q_s . ' AND u.tipo = 1' . $q_p;
- break;
- case 2:
- case 'estacionamiento':
- case 'estacionamientos':
- $q = $q_s . ' AND u.tipo = 2' . $q_p;
- break;
- case 3:
- case 'bodega':
- case 'bodegas':
- $q = $q_s . ' AND u.tipo = 3' . $q_p;
- break;
- }
- $disponibles = model(Unidad::class)->rawQuery($q, [$this->id])->findMany();
- $unidades['disponibles'][$tipo] = $disponibles;
- $unidades['disponibles'] = (object) $unidades['disponibles'];
- $this->unidades = (object) $unidades;
- }
- return $this->unidades->disponibles->{$tipo};
- }
- public function proyectoTipoUnidades()
- {
- return $this->hasMany(ProyectoTipoUnidad::class, 'proyecto')->orderByAsc('tipo')->findMany();
- }
- public function tipoUnidades()
- {
- if (!isset($this->tipos_unidades)) {
- $tipos = \Model::factory(TipoUnidad::class)
- ->select('tipo_unidad.*')
- ->join('unidad', ['unidad.tipo', '=', 'tipo_unidad.id'])
- ->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
- ->where('proyecto.id', $this->id)
- ->order_by_asc('tipo_unidad.id')
- ->group_by('tipo_unidad.id')
- ->findMany();
- $this->tipos_unidades = $tipos;
- }
- return $this->tipos_unidades;
- }
- public function ventas($order = 'departamento')
- {
- if (!isset($this->ventas)) {
- $ventas = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->rawJoin('JOIN (SELECT `e1`.* FROM (SELECT `venta`, MAX(`id`) AS `id` FROM `estado_venta` GROUP BY `venta`) AS `e0` JOIN `estado_venta` AS `e1` ON `e1`.`id` = `e0`.`id`)', ['estado_venta.venta', '=', 'venta.id'], 'estado_venta')
- ->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
- ->where('unidad.proyecto', $this->id)
- ->where('unidad.tipo', 1)
- ->where('tipo_estado_venta.activa', 1);
- switch (strtolower($order)) {
- case 'fecha':
- $ventas = $ventas->orderByAsc('venta.fecha');
- case 'departamento':
- default:
- $ventas = $ventas->orderByExpr('LPAD(`unidad`.`descripcion`, 4, "0")');
- break;
- }
- $ventas = $ventas->find_many();
- $this->ventas = $ventas;
- }
- return $this->ventas;
- }
- protected $resciliaciones;
- public function resciliaciones()
- {
- if ($this->resciliaciones == null) {
- $resciliaciones = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->rawJoin('JOIN (SELECT `e1`.* FROM (SELECT `venta`, MAX(`id`) AS `id` FROM `estado_venta` GROUP BY `venta`) AS `e0` JOIN `estado_venta` AS `e1` ON `e1`.`id` = `e0`.`id`)', ['estado_venta.venta', '=', 'venta.id'], 'estado_venta')
- ->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
- ->where('unidad.proyecto', $this->id)
- ->where('unidad.tipo', 1)
- ->where('tipo_estado_venta.activa', 0)
- ->orderByExpr('LPAD(`unidad`.`descripcion`, 4, "0")')
- ->find_many()
- ;
- $this->resciliaciones = $resciliaciones;
- }
- return $this->resciliaciones;
- }
- public function escrituras()
- {
- if (!isset($escrituras)) {
- $ventas = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->where('unidad.proyecto', $this->id)
- ->where('venta.estado', 1)
- ->where('unidad.tipo', 1)
- ->whereNotEqual('venta.escriturado', '0')
- ->orderByExpr('LPAD(unidad.descripcion, 4, "0")')
- ->find_many()
- ;
- $this->escrituras = $ventas;
- }
- return $this->escrituras;
- }
- public function entregas()
- {
- if (!isset($this->entregas)) {
- $entregas = [];
- $escrituras = $this->escrituras();
- foreach ($escrituras as $escritura) {
- if ($escritura->entrega == '0') {
- continue;
- }
- $entregas []= $escritura;
- }
- usort($entregas, function($a, $b) {
- $fa = \Carbon\Carbon::parse($a->entrega()->find_one()->fecha);
- $fb = \Carbon\Carbon::parse($b->entrega()->find_one()->fecha);
- $dif = $fb->diffInDays($fa, false);
- if ($dif == 0) {
- return $a->unidad()->descripcion - $b->unidad()->descripcion;
- }
- return $dif;
- });
- $this->entregas = $entregas;
- }
- return $this->entregas;
- }
- public function estados()
- {
- return $this->has_many(EstadoProyecto::class, 'proyecto')->orderByAsc('fecha')->findMany();
- }
- public function estado()
- {
- if (!isset($this->estado)) {
- $id = $this->has_many(EstadoProyecto::class, 'proyecto')->max('id');
- $this->estado = $this->has_many(EstadoProyecto::class, 'proyecto')->findOne($id);
- }
- return $this->estado;
- }
- public function avances()
- {
- return $this->hasMany(AvanceConstruccion::class, 'proyecto')->orderByAsc('fecha')->findMany();
- }
- protected $avance;
- public function avance()
- {
- if ($this->avance == null and $this->avances()) {
- $avance = array_reduce($this->avances(), function($carry, $item) {
- return ($carry += $item->avance);
- });
- $this->avance = $avance;
- }
- return $this->avance;
- }
- protected $inicio;
- public function inicio()
- {
- if (!isset($this->inicio) or $this->inicio == null) {
- $id = $this->has_many(EstadoProyecto::class, 'proyecto')->min('id');
- $this->inicio = $this->has_many(EstadoProyecto::class, 'proyecto')->findOne($id);
- }
- return $this->inicio;
- }
- public function valores()
- {
- if (!isset($this->valores)) {
- $ventas = $this->ventas();
-
- /**
- * vendidos
- * departamentos
- * cantidad
- * ingreso
- * neto
- * bruto // suma estacionamientos, bodegas, comision y premios
- * pagado
- * abonado
- * precio
- * minimo
- * promedio
- * maximo
- * mts
- * minimo
- * promedio // total dividido cantidad
- * maximo
- * total
- * uf_m2
- * minimo // minimo de precio dividido mts
- * promedio // ingreso neto dividido mts total
- * maximo // maximo de precio dividido mts
- * estacionamientos // valor estacionamientos
- * bodegas // valor bodegas
- * comision // valor comisiones
- * premios // valor total cada premio
- * estimados // idem vendidos, pero valores estimados proporcional a mts
- * totales // vendidos + estimados
- */
-
- $premios = model(Promocion::class)->findMany();
- $valores = (object) [
- 'vendidos' => new BaseValores(),
- 'estimados' => new BaseValores(),
- 'totales' => new BaseValores()
- ];
- foreach ($valores as &$name) {
- $name->basePremios($premios);
- }
- if ($ventas) {
- $valores->vendidos->ingreso->neto = 0;
- $valores->vendidos->ingreso->neto = array_reduce($ventas, function($sum, $item) {
- return $sum + $item->valorFinal();
- });
- foreach ($ventas as $venta) {
- //$valores->vendidos->ingreso->neto += $venta->valorFinal();
- $valores->vendidos->ingreso->bruto += $venta->valor_uf;
- $valores->vendidos->ingreso->pagado += $venta->valorPagado();
- $valores->vendidos->ingreso->abonado += $venta->valorAbonado();
-
- $valores->vendidos->departamentos->cantidad ++;
- if ($venta->unidad()->precio($venta->fecha())) {
- $valores->vendidos->departamentos->addPrecio($venta->unidad()->precio($venta->fecha())->valor);
- }
- $valores->vendidos->departamentos->addMts('totales', $venta->unidad()->m2('total'));
- $valores->vendidos->departamentos->addMts('vendibles', $venta->unidad()->m2());
-
- //$valores->vendidos->otros->cantidad += ($venta->estacionamientos() or $venta->bodegas()) :
- $valores->vendidos->otros->valor += $venta->valorEstacionamientosYBodegas();
- if ($venta->bono_pie) {
- $valores->vendidos->bono->cantidad ++;
- $valores->vendidos->bono->valor += $venta->bonoPie()->pago()->valor('ufs');
- }
- $valores->vendidos->comision += $venta->valorComision();
- $ps = $venta->promociones();
- if (count($ps) > 0) {
- foreach ($ps as $promo) {
- if ($promo->descripcion != '') {
- $valores->vendidos->premios->{$promo->descripcion} += $promo->valor;
- }
- }
- }
- }
- $valores->vendidos->departamentos->setPromedios();
- }
-
- $valores->estimados->departamentos->cantidad = count($this->unidades(1)) - count($this->ventas());
- $valores->estimados->departamentos->mts->vendibles->total = 0;
- $valores->estimados->departamentos->mts->vendibles->promedio = 0;
- $valores->estimados->departamentos->precio->promedio = 0;
- $valores->estimados->departamentos->uf_m2->promedio = 0;
- if ($valores->estimados->departamentos->cantidad > 0) {
- $valores->estimados->departamentos->mts->vendibles->total = array_reduce($this->unidadesDisponibles(1), function($sum, $item) {
- return $sum + $item->m2();
- });
- $valores->estimados->departamentos->mts->vendibles->promedio = $valores->estimados->departamentos->mts->vendibles->total / $valores->estimados->departamentos->cantidad;
- $valores->estimados->ingreso->neto = array_reduce($this->unidadesDisponibles(1), function($sum, $item) {
- if (!$item->precio()) {
- return $sum;
- }
- return $sum + $item->precio()->valor;
- });
- if ($valores->estimados->ingreso->neto == null) {
- $valores->estimados->ingreso->neto = 0;
- }
- $valores->estimados->departamentos->precio->promedio = $valores->estimados->ingreso->neto / $valores->estimados->departamentos->cantidad;
- $valores->estimados->departamentos->uf_m2->promedio = $valores->estimados->ingreso->neto / $valores->estimados->departamentos->mts->vendibles->total;
- }
-
- $valores->estimados->otros->cantidad = count($this->unidadesDisponibles(2)) + count($this->unidadesDisponibles(3));
- $valores->estimados->otros->valor = count($this->unidadesDisponibles(2)) * 330 + count($this->unidadesDisponibles(3)) * 50;
- foreach ($premios as $premio) {
- $valores->estimados->premios->{$premio->descripcion} = 0;
- if ($valores->vendidos->ingreso->neto > 0) {
- $valores->estimados->premios->{$premio->descripcion} = $valores->vendidos->premios() * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
- }
- }
- $valores->estimados->bono->valor = 0;
- $valores->estimados->comision = 0;
- if ($valores->vendidos->ingreso->neto > 0) {
- $valores->estimados->bono->valor = $valores->vendidos->bono->valor * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
- $valores->estimados->comision = $valores->vendidos->comision * $valores->estimados->ingreso->neto / $valores->vendidos->ingreso->neto;
- }
- $valores->estimados->ingreso->bruto = $valores->estimados->ingreso->neto
- + $valores->estimados->otros->valor
- + $valores->estimados->bono->valor
- + $valores->estimados->premios()
- + $valores->estimados->comision;
-
- $this->valores = $valores;
- }
-
- return $this->valores;
- }
- public function agentes()
- {
- if (!isset($this->agentes)) {
- $this->agentes = \Model::factory(Agente::class)
- ->select('agente.*')
- ->join('proyecto_agente', ['proyecto_agente.agente', '=', 'agente.id'])
- ->where('proyecto_agente.proyecto', $this->id)
- ->orderByAsc('agente.abreviacion')
- ->findMany();
- }
- return $this->agentes;
- }
- public function operadores()
- {
- if (!isset($this->operadores)) {
- $this->operadores = \Model::factory(Agente::class)
- ->select('agente.*')
- ->select('agente_tipo.id', 'agente_tipo')
- ->join('agente_tipo', ['agente_tipo.agente', '=', 'agente.id'])
- ->join('proyecto_agente', ['proyecto_agente.agente', '=', 'agente_tipo.id'])
- ->where('agente_tipo.tipo', 19)
- ->where('proyecto_agente.proyecto', $this->id)
- ->orderByAsc('agente.abreviacion')
- ->groupBy('agente_tipo.id')
- ->findMany();
- }
- return $this->operadores;
- }
- public function operadoresVigentes()
- {
- return $this->hasMany(ProyectoAgente::class, 'proyecto')
- ->select('proyecto_agente.*')
- ->join('agente_tipo', ['agente_tipo.id', '=', 'proyecto_agente.agente'])
- ->rawJoin('JOIN (SELECT e1.* FROM estado_proyecto_agente e1 JOIN (SELECT agente, MAX(id) AS id FROM estado_proyecto_agente GROUP BY agente) e0 ON e0.id = e1.id)', ['ep.agente', '=', 'proyecto_agente.id'], 'ep')
- ->where('agente_tipo.tipo', 19)
- ->where('ep.tipo', 1)
- ->findMany();
- }
- public function promociones()
- {
- if (!isset($this->promociones)) {
- $this->promociones = \Model::factory(Promocion::class)
- ->select('promocion.*')
- ->join('promocion_venta', ['promocion_venta.promocion', '=', 'promocion.id'])
- ->join('venta', ['venta.id', '=', 'promocion_venta.venta'])
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->where('unidad.proyecto', $this->id)
- ->groupBy('promocion.id')
- ->orderByAsc('promocion.titulo')
- ->findMany();
- }
- return $this->promociones;
- }
- public function pisos()
- {
- if ($this->pisos == 0) {
- $pisos = $this->has_many(Unidad::class, 'proyecto')->where('tipo', 1)->max('piso');
- if (!$pisos) {
- return 0;
- }
- $this->pisos = $pisos;
- $this->save();
- }
- return $this->pisos;
- }
- public function cuotasHoy()
- {
- if (!isset($this->cuotas) or !isset($this->cuotas->hoy)) {
- $cuotas = [];
- if (isset($this->cuotas)) {
- $cuotas = (array) $this->cuotas;
- }
- $f = Carbon::today(config('app.timezone'));
- $cuotas['hoy'] = model(Venta::class)
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('cuota', ['cuota.pie', '=', 'venta.pie'])
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->where('unidad.proyecto', $this->id)
- ->where('venta.estado', 1)
- ->where('pago.fecha', $f->format('Y-m-d'))
- ->whereLt('ep.estado', 1)
- ->whereGte('ep.estado', 0)
- ->count('cuota.id');
- $this->cuotas = (object) $cuotas;
- }
- return $this->cuotas->hoy;
- }
- public function cuotasPendientes()
- {
- if (!isset($this->cuotas) or !isset($this->cuotas->pendientes)) {
- $cuotas = [];
- if (isset($this->cuotas)) {
- $cuotas = (array) $this->cuotas;
- }
- $f = Carbon::today(config('app.timezone'));
- $cuotas['pendientes'] = model(Cuota::class)
- ->join('venta', ['cuota.pie', '=', 'venta.pie'])
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->where('unidad.proyecto', $this->id)
- ->where('venta.estado', 1)
- ->whereLt('pago.fecha', $f->format('Y-m-d'))
- ->whereLt('ep.estado', 1)
- ->whereGte('ep.estado', 0)
- ->count('cuota.id');
- $this->cuotas = (object) $cuotas;
- }
- return $this->cuotas->pendientes;
- }
- public function cuotasMes()
- {
- if (!isset($this->cuotas) or !isset($this->cuotas->mes)) {
- $cuotas = [];
- if (isset($this->cuotas)) {
- $cuotas = (array) $this->cuotas;
- }
- $f = Carbon::today(config('app.timezone'));
- $cuotas['mes'] = model(Cuota::class)
- ->join('venta', ['cuota.pie', '=', 'venta.pie'])
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->raw_join('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->where('unidad.proyecto', $this->id)
- ->where('venta.estado', 1)
- ->whereGt('pago.fecha', $f->format('Y-m-d'))
- ->whereLte('pago.fecha', $f->copy()->addMonth(1)->format('Y-m-d'))
- ->where('ep.estado', 0)
- ->findMany();
- $this->cuotas = (object) $cuotas;
- }
- return $this->cuotas->mes;
- }
- public function tiposMediciones()
- {
- $tipos = $this->has_many_through(\Incoviba\nuevo\Venta\TipoMedicion::class, \Incoviba\nuevo\Venta\ProyectoTipoMedicion::class, 'proyecto_id', 'tipo_medicion_id');
- if ($tipos) {
- return $tipos->orderByAsc('descripcion')->findMany();
- }
- return null;
- }
- public function superficie($tipo = 'total')
- {
- if (!isset($this->superficies) or !isset($this->superficies->{$tipo})) {
- $superficies = [];
- if (isset($this->superficies)) {
- $superficies = (array) $this->superficies;
- }
- switch (strtolower($tipo)) {
- case 'total':
- $superficies['total'] = $this->superficie('snt') + $this->superficie('bnt');
- break;
- case 'terreno':
- $superficies['terreno'] = $this->superficie_terreno;
- break;
- case 'sobre_nivel':
- case 'snt':
- $superficies['snt'] = $superficies['sobre_nivel'] = $this->superficie_sobre_nivel;
- break;
- case 'bajo_nivel':
- case 'bnt':
- $superficies['bnt'] = $superficies['bajo_nivel'] = $this->superficie_bajo_nivel;
- break;
- case 'vendible':
- $superficies['vendible'] = 0;
- if ($this->unidades()) {
- $metros = $this->hasMany(Unidad::class, 'proyecto')->selectExpr('SUM(m2 + logia + terraza /2)', 'metros')->where('tipo', 1)->groupBy('proyecto')->findOne();
- $superficies['vendible'] = $metros->metros;
- }
- break;
- case 'vendida':
- $superficies['vendida'] = 0;
- if ($this->ventas()) {
- $metros = model(Venta::class)
- ->selectExpr('SUM(unidad.m2 + unidad.logia + unidad.terraza / 2)', 'metros')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->where('unidad.proyecto', $this->id)
- ->where('venta.estado', 1)
- ->where('unidad.tipo', 1)
- ->groupBy('unidad.proyecto')
- ->findOne();
- if ($metros) {
- $superficies['vendida'] = $metros->metros;
- }
- }
- break;
- case 'por vender':
- $superficies['por vender'] = $this->superficie('vendible') - $this->superficie('vendida');
- break;
- default:
- return 0;
- }
- $this->superficies = (object) $superficies;
- }
- return $this->superficies->{$tipo};
- }
- public function setDireccion(array $data)
- {
- if (!is_numeric($data['comuna'])) {
- $comuna = model(Comuna::class)->where('descripcion', $data['comuna'])->findOne();
- $data['comuna'] = $comuna->id;
- }
- $direccion = model(Direccion::class)
- ->where('calle', $data['calle'])
- ->where('numero', $data['numero'])
- ->where('extra', $data['extra'])
- ->where('comuna', $data['comuna'])
- ->findOne();
- $this->direccion = $direccion->id;
- }
- public function addAgente(array $data)
- {
- $data = ['agente' => $data['agente'], 'tipo' => $data['tipo']];
- $agente = (new Factory(AgenteTipo::class))->create($data);
- $agente->save();
- $this->agentes []= $agente;
- }
- protected $tipologias;
- public function tipologias()
- {
- if ($this->tipologias == null) {
- $pts = $this->proyectoTipoUnidades();
- $tipologias = [];
- foreach ($pts as $pt) {
- if ($pt->tipologia()) {
- if (!isset($tipologias[$pt->tipologia()->tipologia->descripcion])) {
- $tipologias[$pt->tipologia()->tipologia->descripcion] = (object) ['tipologia' => $pt->tipologia()->tipologia, 'tipos' => []];
- }
- $tipologias[$pt->tipologia()->tipologia->descripcion]->tipos []= $pt;
- continue;
- }
- }
- $this->tipologias = $tipologias;
- }
- return $this->tipologias;
- }
- public function pagares()
- {
- return $this->hasMany(Pagare::class, 'proyecto')->findMany();
- }
- protected $cierres;
- public function cierres(int $vigentes = 0)
- {
- if (!isset($this->cierres[$vigentes]) or $this->cierres[$vigentes] == null) {
- $orm = model(Cierre::class)
- ->select('cierre.*')
- ->rawJoin(
- 'join (select e1.* from estado_cierre e1 join (select cierre, max(id) as id from estado_cierre group by cierre) e0 on e0.id = e1.id)',
- ['ec.cierre', '=', 'cierre.id'],
- 'ec')
- ->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'ec.tipo'])
- ->join('proyecto', ['proyecto.id', '=', 'cierre.proyecto'])
- ->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id'])
- ->join('unidad', ['unidad.id', '=', 'unidad_cierre.unidad'])
- ->where('proyecto.id', $this->id)
- ->where('unidad_cierre.principal', 1)
- ->orderByAsc('proyecto.descripcion')
- ->orderByDesc('tipo_estado_cierre.vigente')
- ->orderByDesc('cierre.fecha')
- ->orderByExpr('LPAD(unidad.descripcion, 4, "0")')
- ->groupBy('cierre.id');
- switch ($vigentes) {
- case Cierre::VIGENTES:
- $orm = $orm->where('tipo_estado_cierre.vigente', 1);
- break;
- case Cierre::NO_VIGENTES:
- $orm = $orm->where('tipo_estado_cierre.vigente', 0);
- break;
- case Cierre::VIGENTES + 1:
- $orm = $orm
- ->where('tipo_estado_cierre.vigente', 1)
- ->whereNotLike('tipo_estado_cierre.descripcion', 'promesado')
- ;
- break;
- case Cierre::VIGENTES + 2:
- $orm = $orm
- ->where('tipo_estado_cierre.vigente', 1)
- ->whereLike('tipo_estado_cierre.descripcion', 'promesado')
- ;
- break;
- }
- $this->cierres[$vigentes] = $orm->findMany();
- }
- return $this->cierres[$vigentes];
- }
- public function tipos() {
- return $this->hasMany(ProyectoTipoUnidad::class, 'proyecto')->findMany();
- }
-}
-
-class Departamentos {
- public $cantidad;
- public $precio;
- public $mts;
- public $uf_m2;
- public function __construct() {
- $this->cantidad = 0;
- $base = [
- 'minimo' => 1000000,
- 'promedio' => 0,
- 'maximo' => -1
- ];
- $this->precio = (object) $base;
- $this->mts = (object) [
- 'totales' => (object) array_merge($base, ['total' => 0]),
- 'vendibles' => (object) array_merge($base, ['total' => 0])
- ];
- $this->uf_m2 = (object) $base;
- }
- protected function setMin(&$var, $val) {
- if ($var > $val) {
- $var = $val;
- }
- }
- protected function setMax(&$var, $val) {
- if ($var < $val) {
- $var = $val;
- }
- }
- public function addPrecio($val) {
- $this->precio->promedio += $val;
- $this->setMin($this->precio->minimo, $val);
- $this->setMax($this->precio->maximo, $val);
- $this->uf_m2->promedio += $val;
-
- return $this;
- }
- public function addMts($name, $val) {
- $this->mts->$name->total += $val;
- $this->mts->$name->promedio += $val;
- $this->setMin($this->mts->{$name}->minimo, $val);
- $this->setMax($this->mts->{$name}->maximo, $val);
-
- return $this;
- }
- public function addUfM2($val) {
- $this->setMin($this->uf_m2->minimo, $val);
- $this->setMax($this->uf_m2->maximo, $val);
-
- return $this;
- }
- public function setPromedios() {
- $this->precio->promedio /= $this->cantidad;
- $this->mts->totales->promedio /= $this->cantidad;
- $this->mts->vendibles->promedio /= $this->cantidad;
- $this->uf_m2->promedio /= $this->mts->vendibles->total;
-
- return $this;
- }
-};
-class BaseValores {
- public $ingreso;
- public $departamentos;
- public $otros;
- public $bono;
- public $comision;
- public $premios;
-
- public function __construct() {
- $this->ingreso = (object) [
- 'neto' => 0,
- 'bruto' => 0,
- 'pagado' => 0,
- 'abonado' => 0
- ];
- $this->departamentos = new Departamentos();
- $this->otros = (object) [
- 'cantidad' => 0,
- 'valor' => 0
- ];
- $this->bono = (object) [
- 'cantidad' => 0,
- 'valor' => 0
- ];
- $this->comision = 0;
- $this->premios = [];
- }
- public function basePremios(array $premios) {
- foreach ($premios as $premio) {
- $this->premios[$premio->descripcion] = 0;
- }
- $this->premios = (object) $this->premios;
-
- return $this;
- }
- protected $total_premios;
- public function premios() {
- if ($this->total_premios == null) {
- $this->total_premios = array_reduce((array) $this->premios, function($sum, $item) {
- return $sum + $item;
- });
- }
- return $this->total_premios;
- }
-};
diff --git a/incoviba/modelos/src/old/Proyecto/ProyectoAgente.php b/incoviba/modelos/src/old/Proyecto/ProyectoAgente.php
deleted file mode 100644
index dba7430..0000000
--- a/incoviba/modelos/src/old/Proyecto/ProyectoAgente.php
+++ /dev/null
@@ -1,54 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
- public function agente()
- {
- return $this->belongsTo(AgenteTipo::class, 'agente')->findOne();
- }
- public function estado()
- {
- return $this->hasMany(EstadoProyectoAgente::class, 'agente')
- ->orderByDesc('id')->findOne();
- }
- public function estados()
- {
- return $this->hasMany(EstadoProyectoAgente::class, 'agente')->findMany();
- }
- public function unidadesBloqueadas()
- {
- return $this->hasMany(UnidadBloqueada::class, 'agente')->findMany();
- }
- public function new()
- {
- parent::save();
- $tipo = model(TipoEstadoProyectoAgente::class)->where('descripcion', 'vigente')->findOne();
- $data = [
- 'agente' => $this->id,
- 'fecha' => $this->fecha,
- 'tipo' => $tipo->id
- ];
- $estado = model(EstadoProyectoAgente::class)->create($data);
- $estado->save();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/ProyectoTipoUnidad.php b/incoviba/modelos/src/old/Proyecto/ProyectoTipoUnidad.php
deleted file mode 100644
index d0d97ee..0000000
--- a/incoviba/modelos/src/old/Proyecto/ProyectoTipoUnidad.php
+++ /dev/null
@@ -1,165 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
- public function unidades()
- {
- return $this->hasMany(Unidad::class, 'pt')->orderByExpr('LPAD(subtipo, 3, "0")')->orderByExpr('LPAD(descripcion, 4, "0")')->findMany();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoUnidad::class, 'tipo')->findOne();
- }
- public function m2($tipo = 'vendible')
- {
- return $this->m2 + $this->logia + $this->terraza / (($tipo == 'vendible') ? 2 : 1);
- }
- public function lineas()
- {
- if ($this->lineas == null) {
- $lineas = [];
- foreach ($this->unidades() as $unidad) {
- if (array_search($unidad->subtipo, $lineas) === false) {
- $lineas []= $unidad->subtipo;
- }
- }
- sort($lineas);
- $this->lineas = implode(', ', $lineas);
- }
- return $this->lineas;
- }
- public function precio($fecha = null)
- {
- $sum = 0;
- $cnt = 0;
- foreach ($this->unidades() as $unidad) {
- if ($unidad->precio($fecha)) {
- $sum += $unidad->precio($fecha)->valor;
- $cnt ++;
- }
- }
- if ($cnt == 0) {
- return 0;
- }
- return $sum / $cnt;
- }
- protected $precios;
- public function precioSubtipo($subtipo, $fecha = null)
- {
- if (!isset($this->precios[$subtipo])) {
- $sum = 0;
- $cnt = 0;
- foreach ($this->unidades() as $unidad) {
- if ($unidad->subtipo == $subtipo and $unidad->precio($fecha)) {
- $sum += $unidad->precio($fecha)->valor;
- $cnt ++;
- }
- }
- if ($this->precios == null) {
- $this->precios = [];
- }
- $prom = 0;
- if ($cnt > 0) {
- $prom = $sum / $cnt;
- }
- $this->precios[$subtipo] = $prom;
- }
- return $this->precios[$subtipo];
- }
- public function setPrecios($fecha, $valor)
- {
- foreach ($this->unidades() as $unidad) {
- $unidad->setPrecio($fecha, $valor);
- }
- }
- public function setPreciosSubtipo($subtipo, $fecha, $valor)
- {
- foreach ($this->unidades() as $unidad) {
- if ($unidad->subtipo == $subtipo) {
- $unidad->setPrecio($fecha, $valor);
- }
- }
- }
- protected $tipologia;
- public function tipologia()
- {
- if ($this->tipologia == null) {
- $tipologias = $this->hasMany(TipoTipologia::class, 'tipo')->findMany();
- if (!$tipologias) {
- $this->tipologia = false;
- return false;
- }
- usort($tipologias, function($a, $b) {
- return $a->elemento()->orden - $b->elemento()->orden;
- });
- $tipologia = ['tipologia' => $tipologias[0]->tipologia(), 'detalles' => $tipologias];
- $resumen = [];
- $detalle = [];
- foreach ($tipologias as $t) {
- if (strpos($t->elemento()->descripcion, 'cocina ') !== false) {
- $resumen []= $t->elemento()->abreviacion;
- $detalle []= $t->elemento()->descripcion;
- continue;
- }
- $resumen []= $t->cantidad . '' . $t->elemento()->abreviacion;
- $detalle []= $t->cantidad . ' ' . $t->elemento()->descripcion . (($t->cantidad > 1) ? 's' : '');
- }
- $tipologia['descripcion'] = implode('/', $resumen);
- $tipologia['detalle'] = implode(', ', $detalle) . '.';
-
- $this->tipologia = (object) $tipologia;
- }
- return $this->tipologia;
- }
- protected $ventas;
- public function ventas($order = 'departamento')
- {
- if ($this->ventas == null) {
- $ventas = model(Venta::class)
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('proyecto_tipo_unidad', ['proyecto_tipo_unidad.id', '=', 'unidad.pt'])
- ->rawJoin('JOIN (SELECT e1.* FROM estado_venta e1 JOIN (SELECT venta, MAX(id) AS id FROM estado_venta GROUP BY venta) e0 ON e0.id = e1.id)', ['ev.venta', '=', 'venta.id'], 'ev')
- ->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'ev.estado'])
- ->where('tipo_estado_venta.activa', 1)
- ->where('proyecto_tipo_unidad.id', $this->id);
- switch (strtolower($order)) {
- case 'fecha':
- $ventas = $ventas->orderByAsc('venta.fecha');
- case 'departamento':
- default:
- $ventas = $ventas->orderByExpr('LPAD(unidad.descripcion, 4, "0")');
- break;
- }
- $ventas = $ventas->findMany();
- $this->ventas = $ventas;
- }
- return $this->ventas;
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/RelacionAgentes.php b/incoviba/modelos/src/old/Proyecto/RelacionAgentes.php
deleted file mode 100644
index bf29ce5..0000000
--- a/incoviba/modelos/src/old/Proyecto/RelacionAgentes.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/RenovacionPagare.php b/incoviba/modelos/src/old/Proyecto/RenovacionPagare.php
deleted file mode 100644
index 783f4f9..0000000
--- a/incoviba/modelos/src/old/Proyecto/RenovacionPagare.php
+++ /dev/null
@@ -1,90 +0,0 @@
-belongsTo(Pagare::class, 'pagare')->findOne();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- public function fechaBanco(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha_banco, config('app.timezone'));
- }
- $this->fecha_banco = $fecha->format('Y-m-d');
- }
- public function vencimiento()
- {
- return $this->fecha()->addDays($this->duracion);
- }
- public function uf()
- {
- if ($this->uf == 0) {
- $uf = uf($this->fecha());
- if ($uf->total > 0) {
- $this->uf = $uf->uf->value;
- $this->save();
- }
- }
- return $this->uf;
- }
- protected $valores;
- public function valor($tipo = 'ufs')
- {
- if ($this->valores == null) {
- $valores = [];
- switch (strtolower($this->pagare()->moneda()->descripcion)) {
- case 'uf':
- $valores = (object) ['uf' => $this->insoluto, 'pesos' => $this->insoluto * $this->uf()];
- break;
- case 'pesos':
- $valores = (object) ['uf' => $this->insoluto / $this->uf(), 'pesos' => $this->insoluto];
- break;
- }
- $this->valores = $valores;
- }
- switch (strtolower($tipo)) {
- case 'uf':
- case 'ufs':
- return $this->valores->uf;
- case 'peso':
- case 'pesos':
- return $this->valores->pesos;
- }
- }
- protected $intereses_arr;
- public function intereses($tipo = 'ufs') {
- if ($this->intereses_arr == null) {
- $this->intereses_arr = (object) ['uf' => $this->intereses / $this->uf(), 'pesos' => $this->intereses];
- }
- switch (strtolower($tipo)) {
- case 'uf':
- case 'ufs':
- return $this->intereses_arr->uf;
- case 'peso':
- case 'pesos':
- return $this->intereses_arr->pesos;
- }
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/TipoAgente.php b/incoviba/modelos/src/old/Proyecto/TipoAgente.php
deleted file mode 100644
index 3611f44..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoAgente.php
+++ /dev/null
@@ -1,24 +0,0 @@
-hasManyThrough(Agente::class, AgenteTipo::class, 'tipo', 'agente')->findMany();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/TipoCobro.php b/incoviba/modelos/src/old/Proyecto/TipoCobro.php
deleted file mode 100644
index 20adb76..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoCobro.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/TipoElemento.php b/incoviba/modelos/src/old/Proyecto/TipoElemento.php
deleted file mode 100644
index a7e636b..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoElemento.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/TipoEstadoProyecto.php b/incoviba/modelos/src/old/Proyecto/TipoEstadoProyecto.php
deleted file mode 100644
index d65896c..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoEstadoProyecto.php
+++ /dev/null
@@ -1,23 +0,0 @@
-belongs_to(EtapaProyecto::class, 'etapa')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Proyecto/TipoEstadoProyectoAgente.php b/incoviba/modelos/src/old/Proyecto/TipoEstadoProyectoAgente.php
deleted file mode 100644
index deb2c51..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoEstadoProyectoAgente.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Proyecto/TipoTipologia.php b/incoviba/modelos/src/old/Proyecto/TipoTipologia.php
deleted file mode 100644
index a6cdc3d..0000000
--- a/incoviba/modelos/src/old/Proyecto/TipoTipologia.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(ProyectoTipoUnidad::class, 'tipo')->findOne();
- }
- public function tipologia()
- {
- return $this->belongsTo(Tipologia::class, 'tipologia')->findOne();
- }
- public function elemento()
- {
- return $this->belongsTo(TipoElemento::class, 'elemento')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Proyecto/Tipologia.php b/incoviba/modelos/src/old/Proyecto/Tipologia.php
deleted file mode 100644
index eab84d8..0000000
--- a/incoviba/modelos/src/old/Proyecto/Tipologia.php
+++ /dev/null
@@ -1,12 +0,0 @@
-belongs_to(Pago::class, 'pago')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Cierre.php b/incoviba/modelos/src/old/Venta/Cierre.php
deleted file mode 100644
index ad9027a..0000000
--- a/incoviba/modelos/src/old/Venta/Cierre.php
+++ /dev/null
@@ -1,341 +0,0 @@
-select('cierre.*')
- ->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id'])
- ->where('cierre.proyecto', $proyecto->id)
- ->where('unidad_cierre.unidad', $unidad->id)
- ->where('cierre.precio', $precio);
- }
- public static function vigentes()
- {
- return model(Cierre::class)
- ->select('cierre.*')
- ->join('estado_cierre', ['estado_cierre.cierre', '=', 'cierre.id'])
- ->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'estado_cierre.tipo'])
- ->join('proyecto', ['proyecto.id', '=', 'cierre.proyecto'])
- ->where('tipo_estado_cierre.vigente', 1)
- ->orderByAsc('proyecto.descripcion')
- ->orderByAsc('cierre.fecha')
- ->groupBy('cierre.id')
- ->findMany();
- }
- public static function proyectos()
- {
- return model(Proyecto::class)
- ->select('proyecto.*')
- ->join('cierre', ['proyecto.id', '=', 'cierre.proyecto'])
- ->join('estado_cierre', ['estado_cierre.cierre', '=', 'cierre.id'])
- ->join('tipo_estado_cierre', ['tipo_estado_cierre.id', '=', 'estado_cierre.tipo'])
- ->where('tipo_estado_cierre.vigente', 1)
- ->orderByAsc('proyecto.descripcion')
- ->orderByAsc('cierre.fecha')
- ->groupBy('proyecto.id')
- ->findMany();
- }
-
- public function proyecto()
- {
- return $this->belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
- public function unidades()
- {
- return $this->hasMany(UnidadCierre::class, 'cierre')->where('principal', 0)->findMany();
- }
- public function unidadPrincipal()
- {
- return $this->hasMany(UnidadCierre::class, 'cierre')->where('principal', 1)->findOne();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- public function propietario()
- {
- $propietario = $this->belongsTo(Propietario::class, 'propietario');
- if ($propietario) {
- return $propietario->findOne();
- }
- return false;
- }
- public function uf_m2()
- {
- return $this->neto() / $this->unidadPrincipal()->unidad()->m2();
- }
- public function neto()
- {
- $valor = $this->precio;
- foreach ($this->unidades() as $unidad) {
- $valor -= $unidad->unidad()->precio($this->fecha())->valor;
- }
- foreach ($this->valores() as $v) {
- if ($v->tipo()->descripcion == 'pie') {
- continue;
- }
- $valor -= $v->valor;
- }
- return $valor;
- }
- public function valores()
- {
- return $this->hasMany(ValorCierre::class, 'cierre')->findMany();
- }
- public function valor($tipo = 'pie')
- {
- return $this->hasMany(ValorCierre::class, 'cierre')
- ->select('valor_cierre.*')
- ->join('tipo_valor_cierre', ['tipo_valor_cierre.id', '=', 'valor_cierre.tipo'])
- ->where('tipo_valor_cierre.descripcion', $tipo)
- ->findOne();
- }
- public function estados()
- {
- return $this->hasMany(EstadoCierre::class, 'cierre')->findMany();
- }
- public function estado(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- $estado = $this->hasMany(EstadoCierre::class, 'cierre')->orderByDesc('id')->findOne();
- if ($estado->tipo()->vigente == 1 and $this->oldest()) {
- if ($this->promesa() and $estado->tipo()->descripcion != 'promesado') {
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'promesado')->findOne();
- $data = [
- 'cierre' => $this->id,
- 'tipo' => $tipo->id,
- 'fecha' => $this->promesa()->fecha
- ];
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- }
- }
- } else {
- $estado = $this->hasMany(EstadoCierre::class, 'cierre')->whereLte('fecha', $fecha->format('Y-m-d'))->orderByDesc('id')->findOne();
- }
- return $estado;
- }
- public function isVigente(): bool {
- if ($this->estado()->tipo()->vigente == 1) {
- return true;
- }
- return false;
- }
- public function new(\DateTime $fecha)
- {
- $this->save();
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'revisado')->findOne();
- $data = [
- 'cierre' => $this->id,
- 'tipo' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
-
- if ($this->other()) {
- $this->replace($fecha);
- }
- }
- protected function cierresUnidad() {
- $up = $this->unidadPrincipal();
- if (!$up) {
- return false;
- }
- $up = $up->id;
- $cierres = model(Cierre::class)
- ->select('cierre.*')
- ->join('unidad_cierre', ['unidad_cierre.cierre', '=', 'cierre.id'])
- ->where('unidad_cierre.unidad', $up)
- ->findMany();
- $id = $this->id;
- $cierres = array_filter($cierres, function($item) use ($id) {
- return ($id != $item->id);
- });
- return $cierres;
- }
- protected function other(): bool {
- $cierres = $this->cierresUnidad();
- if ($cierres and count($cierres) > 0) {
- return true;
- }
- return false;
- }
- protected function oldest(): bool {
- if ($this->other()) {
- $last = $this->cierresUnidad()[count($this->cierresUnidad()) - 1];
- if ($last->fecha < $this->fecha) {
- return true;
- }
- return false;
- }
- return true;
- }
- protected function replace(\DateTime $fecha) {
- $cierres = $this->cierresUnidad();
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'abandonado')->findOne();
- array_walk($cierres, function($item) use ($tipo, $fecha) {
- $data = [
- 'cierre' => $item->id,
- 'tipo' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- });
- }
- public function addUnidad(array $data)
- {
- $data['cierre'] = $this->id;
- $unidad = model(UnidadCierre::class)->create($data);
- $unidad->save();
- }
- public function addValor(array $data)
- {
- $data['cierre'] = $this->id;
- $tipo = model(TipoValorCierre::class)->where('descripcion', $data['tipo'])->findOne();
- $data['tipo'] = $tipo->id;
- $valor = model(ValorCierre::class)->create($data);
- $valor->save();
- }
- public static function evaluar($precio_neto, $unidad, $fecha, $relacionado = false)
- {
- $precio_oferta = round($precio_neto, 2);
- $precio_lista = round($unidad->precio($fecha)->valor * (($relacionado) ? (1 - 0.06) : 1), 2);
- if ($precio_oferta >= $precio_lista) {
- return true;
- }
- return false;
- }
- public function guardar(object $input)
- {
- $this->proyecto = $input->proyecto->id;
- $this->precio = $input->precio;
- $this->fecha = $input->fecha->format('Y-m-d');
- $this->relacionado = 0;
- if (isset($input->relacionado) and $input->relacionado) {
- $this->relacionado = 1;
- }
- if (isset($input->subrelacionado) and $input->subrelacionado) {
- $this->relacionado = 2;
- }
- $fecha = Carbon::today(config('app.timezone'));
- $this->new($fecha);
-
- $data = [
- 'unidad' => $input->departamento->id,
- 'principal' => 1
- ];
- $this->addUnidad($data);
-
- foreach ($input->unidades as $unidad) {
- $data = ['unidad' => $unidad->id];
- $this->addUnidad($data);
- }
-
- if (isset($input->pie)) {
- $data = [
- 'tipo' => 'pie',
- 'valor' => $input->pie
- ];
- $this->addValor($data);
- }
- if (isset($input->bono)) {
- $data = [
- 'tipo' => 'bono pie',
- 'valor' => $input->bono
- ];
- $this->addValor($data);
- }
- if (isset($input->promocion)) {
- $data = [
- 'tipo' => 'premio',
- 'valor' => $input->promocion
- ];
- $this->addValor($data);
- }
- if (isset($input->operador)) {
- $data = [
- 'tipo' => 'operador',
- 'valor' => $input->operador * $this->precio / 100
- ];
- $this->addValor($data);
- }
- }
- public function aprobar(\DateTime $fecha)
- {
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'aprobado')->findOne();
- $data = [
- 'cierre' => $this->id,
- 'tipo' => $tipo->id
- ];
- $estado = (new Factory(EstadoCierre::class))->where($data)->find();
- if (!$estado) {
- $data['fecha'] = $fecha->format('Y-m-d');
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- }
- }
- public function rechazar(\DateTime $fecha)
- {
- $tipo = model(TipoEstadoCierre::class)->where('descripcion', 'rechazado')->findOne();
- $data = [
- 'cierre' => $this->id,
- 'tipo' => $tipo->id
- ];
- $estado = (new Factory(EstadoCierre::class))->where($data)->find();
- if (!$estado) {
- $data['fecha'] = $fecha->format('Y-m-d');
- $estado = model(EstadoCierre::class)->create($data);
- $estado->save();
- }
- }
- protected $promesa;
- public function promesa()
- {
- if ($this->promesa == null) {
- $propiedad = model(Propiedad::class)->where('unidad_principal', $this->unidadPrincipal()->unidad)->findOne();
- if (!$propiedad) {
- return false;
- }
- $this->promesa = model(Venta::class)->where('propiedad', $propiedad->id)->where('estado', 1)->findOne();
- if ($this->promesa != null and $this->propietario == 0) {
- $this->propietario = $this->promesa->propietario;
- $this->save();
- }
- }
- return $this->promesa;
- }
- public function isRelacionado() {
- return ($this->relacionado == 1) ? true : false;
- }
- public function isSubrelacionado() {
- return ($this->relacionado == 2) ? true : false;
- }
- public function periodo() {
- $today = Carbon::today(config('app.timezone'));
- $dif = $today->diffInDays($this->fecha());
- return $dif;
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Comentario.php b/incoviba/modelos/src/old/Venta/Comentario.php
deleted file mode 100644
index f6953ab..0000000
--- a/incoviba/modelos/src/old/Venta/Comentario.php
+++ /dev/null
@@ -1,22 +0,0 @@
-belongsTo(Venta::class, 'venta')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Credito.php b/incoviba/modelos/src/old/Venta/Credito.php
deleted file mode 100644
index 33d1315..0000000
--- a/incoviba/modelos/src/old/Venta/Credito.php
+++ /dev/null
@@ -1,29 +0,0 @@
-belongs_to(Pago::class, 'pago')->findOne();
- }
- public function venta()
- {
- return $this->hasOne(Venta::class, 'credito')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Cuota.php b/incoviba/modelos/src/old/Venta/Cuota.php
deleted file mode 100644
index e52aeb1..0000000
--- a/incoviba/modelos/src/old/Venta/Cuota.php
+++ /dev/null
@@ -1,72 +0,0 @@
-belongs_to(Pago::class, 'pago')->findOne();
- }
- public function pie()
- {
- return $this->belongs_to(Pie::class, 'pie')->findOne();
- }
- public function uf()
- {
- if ($this->uf == 0) {
- $uf = $this->pago()->uf();
- if ($uf == 1) {
- $uf = $this->pie()->uf();
- }
- $this->uf = $uf;
- }
- return $this->uf;
- }
- public function valor($tipo = 'pesos')
- {
- $valor = $this->pago()->valor;
- if ($tipo == 'pesos') {
- return $valor;
- }
- $uf = $this->uf();
- if ($uf == 0) {
- return 0;
- }
- return $valor / $uf;
- }
- public function numero()
- {
- if ($this->numero == '') {
- $cuotas = $this->pie()->cuotas('fecha');
- $n = 0;
- foreach ($cuotas as $cuota) {
- $n ++;
- if ($cuota->id == $this->id) {
- $this->numero = $n;
- $this->save();
- break;
- }
- }
- }
- return $this->numero;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Entrega.php b/incoviba/modelos/src/old/Venta/Entrega.php
deleted file mode 100644
index 035a227..0000000
--- a/incoviba/modelos/src/old/Venta/Entrega.php
+++ /dev/null
@@ -1,21 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/Escritura.php b/incoviba/modelos/src/old/Venta/Escritura.php
deleted file mode 100644
index 0763e7d..0000000
--- a/incoviba/modelos/src/old/Venta/Escritura.php
+++ /dev/null
@@ -1,29 +0,0 @@
-belongs_to(Pago::class, 'pago')->findOne();
- }
-
- public function valor(string $tipo = 'pesos')
- {
- return $this->pago()->valor($tipo);
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/EstadoCierre.php b/incoviba/modelos/src/old/Venta/EstadoCierre.php
deleted file mode 100644
index e3ec49a..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoCierre.php
+++ /dev/null
@@ -1,30 +0,0 @@
-belongsTo(Cierre::class, 'cierre')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoEstadoCierre::class, 'tipo')->findOne();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/EstadoPago.php b/incoviba/modelos/src/old/Venta/EstadoPago.php
deleted file mode 100644
index 7f18da1..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoPago.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongs_to(TipoEstadoPago::class, 'estado')->findOne();
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/EstadoPrecio.php b/incoviba/modelos/src/old/Venta/EstadoPrecio.php
deleted file mode 100644
index 58c3657..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoPrecio.php
+++ /dev/null
@@ -1,33 +0,0 @@
-belongsTo(Precio::class, 'precio')->findOne();
- }
- public function fecha($fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- if (is_a($fecha, \DateTime::class)) {
- $fecha = $fecha->format('Y-m-d');
- }
- $this->fecha = $fecha;
- }
- public function estado()
- {
- return $this->belongsTo(TipoEstadoPrecio::class, 'estado')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/EstadoProblema.php b/incoviba/modelos/src/old/Venta/EstadoProblema.php
deleted file mode 100644
index c6b8ce2..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoProblema.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/EstadoUnidadBloqueada.php b/incoviba/modelos/src/old/Venta/EstadoUnidadBloqueada.php
deleted file mode 100644
index f11ea1b..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoUnidadBloqueada.php
+++ /dev/null
@@ -1,30 +0,0 @@
-belongsTo(UnidadBloqueada::class, 'unidad')->findOne();
- }
- public function fecha(\DateTime $fecha = null)
- {
- if ($fecha == null) {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- $this->fecha = $fecha->format('Y-m-d');
- }
- public function tipo()
- {
- return $this->belongsTo(TipoEstadoUnidadBloqueada::class, 'tipo')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/EstadoVenta.php b/incoviba/modelos/src/old/Venta/EstadoVenta.php
deleted file mode 100644
index 5e75070..0000000
--- a/incoviba/modelos/src/old/Venta/EstadoVenta.php
+++ /dev/null
@@ -1,27 +0,0 @@
-belongsTo(Venta::class, 'venta')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoEstadoVenta::class, 'estado')->findOne();
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Pago.php b/incoviba/modelos/src/old/Venta/Pago.php
deleted file mode 100644
index 9b2d4ed..0000000
--- a/incoviba/modelos/src/old/Venta/Pago.php
+++ /dev/null
@@ -1,159 +0,0 @@
-belongs_to(Banco::class, 'banco');
- if ($banco) {
- return $banco->findOne();
- }
- return null;
- }
- public function tipo()
- {
- return $this->belongs_to(TipoPago::class, 'tipo')->findOne();
- }
- public function estados($order = 'fecha', $direction = 'desc')
- {
- $estados = $this->has_many(EstadoPago::class, 'pago');
- if ($direction == 'desc') {
- $estados->orderByDesc($order);
- if ($order != 'id') {
- $estados->orderByDesc('id');
- }
- } else {
- $estados->orderByAsc($order);
- if ($order != 'id') {
- $estados->orderByAsc('id');
- }
- }
- return $estados->findMany();
- }
- public function estado()
- {
- $estado = $this->has_many(EstadoPago::class, 'pago')->order_by_desc('id')->findOne();
- return $estado;
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, config('app.timezone'));
- }
- public function uf()
- {
- if ($this->uf == 0) {
- $uf = uf($this->fecha);
- if (!$uf or $uf->total == 0) {
- return 1;
- }
- if ($uf->total > 0) {
- $this->uf = $uf->uf->value;
- $this->save();
- }
- }
- return $this->uf;
- }
- public function valor($tipo = 'pesos')
- {
- $valor = $this->valor;
- if ($tipo == 'ufs') {
- $uf = $this->uf();
- if ($uf == 1 and method_exists($this->fuente()[0]->obj, 'uf')) {
- $uf = $this->fuente()[0]->obj->uf();
- }
- if ($uf == 0) {
- $uf = 1;
- }
- $valor /= $uf;
- if ($this->asociado() and $this->asociado == 0) {
- $valor += $this->asociado()->valor('ufs');
- }
- return $valor;
- }
- if ($this->asociado() and $this->asociado == 0) {
- $valor += $this->asociado()->valor();
- }
- return $valor;
- }
- public function new()
- {
- $this->save();
-
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $this->id;
- $estado->fecha = $this->fecha;
- $estado->estado = 0;
- $estado->save();
- }
- public function newPagado()
- {
- $this->new();
-
- $estado = \Model::factory(EstadoPago::class)->create();
- $estado->pago = $this->id;
- $estado->fecha = $this->fecha;
- $estado->estado = 1;
- $estado->save();
- }
- public function fuente()
- {
- $results = [];
- $cuota = model(Cuota::class)->where('pago', $this->id)->findOne();
- if ($cuota) {
- $results []= (object) ['tipo' => 'cuota', 'obj' => $cuota];
- }
- $credito = model(Credito::class)->where('pago', $this->id)->findOne();
- if ($credito) {
- $results []= (object) ['tipo' => 'credito', 'obj' => $credito];
- }
- $escritura = model(Escritura::class)->where('pago', $this->id)->findOne();
- if ($escritura) {
- $results []= (object) ['tipo' => 'escritura', 'obj' => $escritura];
- }
- $subsidio = model(Subsidio::class)->where('pago', $this->id)->findOne();
- if ($subsidio) {
- $results []= (object) ['tipo' => 'subsidio', 'obj' => $subsidio];
- }
- $bono = model(BonoPie::class)->where('pago', $this->id)->findOne();
- if ($bono) {
- $results []= (object) ['tipo' => 'bono_pie', 'obj' => $bono];
- }
- return $results;
- }
- public function asociado()
- {
- if ($this->asociado == 0) {
- return $this->hasOne(Pago::class, 'asociado')->findOne();
- }
- return $this->belongsTo(Pago::class, 'asociado')->findOne();
- }
-
- public static function filterEstado(\ORM $orm)
- {
- return $orm->rawJoin(
- 'JOIN (SELECT ep.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago ep ON ep.id = e0.id)',
- ['estado_pago.pago', '=', 'pago.id'],
- 'estado_pago'
- );
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Pie.php b/incoviba/modelos/src/old/Venta/Pie.php
deleted file mode 100644
index 18e505f..0000000
--- a/incoviba/modelos/src/old/Venta/Pie.php
+++ /dev/null
@@ -1,228 +0,0 @@
-asociado != 0) {
- return $this->asociado()->cuotas();
- }
- $cuotas = $this->hasMany(Cuota::class, 'pie')
- ->select('cuota.*')
- ->join('pago', ['pago.id', '=', 'cuota.pago'])
- ->rawJoin('JOIN (SELECT e1.* FROM (SELECT pago, MAX(id) AS id FROM estado_pago GROUP BY pago) e0 JOIN estado_pago e1 ON e1.id = e0.id)', ['ep.pago', '=', 'pago.id'], 'ep')
- ->join('tipo_estado_pago', ['tipo_estado_pago.id', '=', 'ep.estado'])
- ->whereNotEqual('tipo_estado_pago.descripcion', 'reemplazado')
- ->whereNotEqual('tipo_estado_pago.descripcion', 'anulado');
- if ($fecha != null) {
- $cuota = $cuotas->whereLte('ep.fecha', $fecha->format('Y-m-d'));
- }
- switch ($order) {
- case 'numero':
- case 'number':
- default:
- $cuotas = $cuotas->orderByAsc('cuota.numero');
- case 'fecha':
- case 'date':
- $cuotas = $cuotas->orderByAsc('pago.fecha')
- ->orderByDesc('pago.valor');
- break;
- }
- $cuotas = $cuotas->findMany();
- return $cuotas;
- }
- public function pagadas($fecha = null)
- {
- $estado = model(TipoEstadoPago::class)->where('descripcion', 'depositado')->findOne();
- $cuotas = $this->cuotas('numero', $fecha);
- foreach ($cuotas as $i => &$cuota) {
- if ($cuota->pago()->estado()->estado < $estado->id) {
- unset($cuotas[$i]);
- }
- }
- array_values($cuotas);
- return $cuotas;
- }
- public function abonadas($fecha = null)
- {
- $estado = model(TipoEstadoPago::class)->where('descripcion', 'abonado')->findOne();
- $cuotas = $this->pagadas($fecha);
- foreach ($cuotas as $i => &$cuota) {
- if ($cuota->pago()->estado()->estado != $estado->id) {
- unset($cuotas[$i]);
- }
- }
- array_values($cuotas);
- return $cuotas;
- }
- public function rebotadas()
- {
- $estado = model(TipoEstadoPago::class)->where('descripcion', 'devuelto')->findOne();
- $cuotas = $this->cuotas();
- foreach ($cuotas as $i => &$cuota) {
- if ($cuota->pago()->estado()->estado != $estado->id) {
- unset($cuotas[$i]);
- }
- }
- array_values($cuotas);
- return $cuotas;
- }
- public function valorPesos()
- {
- return $this->valor * $this->uf();
- }
- public function valorPagado($tipo = 'uf', $fecha = null)
- {
- $cuotas = $this->pagadas($fecha);
- $sum = 0;
- foreach ($cuotas as $cuota) {
- $pago = $cuota->pago();
- if ($tipo == 'uf' or $tipo == 'ufs') {
- if ($pago->uf() == 0) {
- $sum += $pago->valor / $this->uf();
- continue;
- }
- $sum += $pago->valor / $pago->uf();
- } else {
- $sum += $pago->valor;
- }
- }
-
- return $sum * $this->proporcion();
- }
- public function valorAbonado($tipo = 'uf', $fecha = null)
- {
- $cuotas = $this->abonadas($fecha);
- $sum = 0;
- foreach ($cuotas as $cuota) {
- $pago = $cuota->pago();
- if ($tipo == 'uf' or $tipo == 'ufs') {
- if ($pago->uf() == 0) {
- $sum += $pago->valor / $this->uf();
- continue;
- }
- $sum += $pago->valor / $pago->uf;
- } else {
- $sum += $pago->valor;
- }
- }
-
- return $sum * $this->proporcion();
- }
- public function reajuste()
- {
- $reajuste = $this->belongsTo(Pago::class, 'reajuste');
- if ($reajuste) {
- $reajuste = $reajuste->findOne();
- return $reajuste;
- }
- return null;
- }
- public function venta()
- {
- return $this->has_one(Venta::class, 'pie')->findOne();
- }
- public function asociado()
- {
- $pie = $this->belongs_to(Pie::class, 'asociado')->findOne();
- if ($pie) {
- return $pie;
- }
- return null;
- }
- private $asociados = null;
- public function asociados()
- {
- if ($this->asociados == null) {
- $pie = $this->has_many(Pie::class, 'asociado');
- if (!$pie) {
- return null;
- }
- $asociados = $pie->findMany();
- usort($asociados, function($a, $b) {
- return strcmp($a->venta()->unidad()->descripcion, $b->venta()->unidad()->descripcion);
- });
- $this->asociados = $asociados;
- }
- return $this->asociados;
- }
- public function proporcion()
- {
- $pie = $this;
- if ($this->asociado != 0) {
- $pie = $this->asociado();
- }
- if ($pie->asociados() != null) {
- $pies = $pie->asociados();
- $base = $pie->valor;
- foreach ($pies as $p) {
- $base += $p->valor;
- }
-
- return $this->valor / $base;
- }
- return 1;
- }
- public function pendientes()
- {
- return count($this->cuotas()) - count($this->pagadas());
- }
- public function pagos($estado = 0)
- {
- $pagos = model(Pago::class)
- ->select('pago.*')
- ->join('cuota', ['cuota.pago', '=', 'pago.id'])
- ->filter('filterEstado')
- ->where('estado_pago.estado', $estado)
- ->where('cuota.pie', $this->id)
- ->findMany();
- if ($this->reajuste != 0 and $this->reajuste()->estado()->estado == $estado) {
- $pagos []= $this->reajuste();
- }
- return $pagos;
- }
- public function uf()
- {
- if ($this->uf == 0) {
- $uf = uf($this->fecha);
- if (!$uf) {
- return 1;
- }
- if ($uf->total > 0) {
- $this->uf = $uf->uf->value;
- $this->save();
- }
- }
- return $this->uf;
- }
- public function valor($tipo = 'pesos')
- {
- switch ($tipo) {
- case 'uf':
- case 'ufs':
- return $this->valor;
- break;
- case 'peso':
- case 'pesos':
- default:
- return $this->valorPesos();
- break;
- }
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Precio.php b/incoviba/modelos/src/old/Venta/Precio.php
deleted file mode 100644
index a80c5ed..0000000
--- a/incoviba/modelos/src/old/Venta/Precio.php
+++ /dev/null
@@ -1,81 +0,0 @@
-belongsTo(Unidad::class, 'unidad')->findOne();
- }
- public function estados()
- {
- return $this->hasMany(EstadoPrecio::class, 'precio')->findMany();
- }
- public function estado()
- {
- return \model(EstadoPrecio::class)
- ->select('estado_precio.*')
- ->rawJoin('JOIN (SELECT precio, MAX(id) AS id FROM estado_precio GROUP BY precio)', ['e0.id', '=', 'estado_precio.id'], 'e0')
- ->where('estado_precio.precio', $this->id)
- ->findOne();
- }
- public function inicio()
- {
- return \model(EstadoPrecio::class)
- ->where('estado_precio.precio', $this->id)
- ->orderByAsc('id')
- ->findOne();
- }
- public function vigente()
- {
- if ($this->estado()->estado()->descripcion == 'vigente') {
- return true;
- }
- return false;
- }
- public function reemplazar($fecha)
- {
- if ($this->estado()->estado()->descripcion == 'reemplazado') {
- return;
- }
- $tipo = model(TipoEstadoPrecio::class)->where('descripcion', 'reemplazado')->findOne();
- $data = [
- 'precio' => $this->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'estado' => $tipo->id
- ];
- $estado = model(EstadoPrecio::class)->create($data);
- $estado->save();
- }
- public function actualizar($fecha)
- {
- $tipo = model(TipoEstadoPrecio::class)->where('descripcion', 'vigente')->findOne();
- $data = [
- 'precio' => $this->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'estado' => $tipo->id
- ];
- $estado = model(EstadoPrecio::class)->create($data);
- $estado->save();
- }
- public function new($fecha)
- {
- $this->save();
-
- $tipo = model(TipoEstadoPrecio::class)->where('descripcion', 'vigente')->findOne();
- $data = [
- 'precio' => $this->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'estado' => $tipo->id
- ];
- $estado = model(EstadoPrecio::class)->create($data);
- $estado->save();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Problema.php b/incoviba/modelos/src/old/Venta/Problema.php
deleted file mode 100644
index 080b363..0000000
--- a/incoviba/modelos/src/old/Venta/Problema.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/Promocion.php b/incoviba/modelos/src/old/Venta/Promocion.php
deleted file mode 100644
index 5515566..0000000
--- a/incoviba/modelos/src/old/Venta/Promocion.php
+++ /dev/null
@@ -1,23 +0,0 @@
-belongsTo(Proyecto::class, 'proyecto')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/PromocionVenta.php b/incoviba/modelos/src/old/Venta/PromocionVenta.php
deleted file mode 100644
index 641f3a5..0000000
--- a/incoviba/modelos/src/old/Venta/PromocionVenta.php
+++ /dev/null
@@ -1,24 +0,0 @@
-belongsTo(Promocion::class, 'promocion')->findOne();
- }
- public function venta()
- {
- return $this->belongsTo(Venta::class, 'venta')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Propiedad.php b/incoviba/modelos/src/old/Venta/Propiedad.php
deleted file mode 100644
index f99a3a0..0000000
--- a/incoviba/modelos/src/old/Venta/Propiedad.php
+++ /dev/null
@@ -1,117 +0,0 @@
-belongs_to(Unidad::class, 'unidad_principal')->findOne();
- }
- protected $unidades;
- public function unidades() {
- if ($this->unidades == null) {
- $this->unidades = $this->hasMany(PropiedadUnidad::class, 'propiedad')->findMany();
- }
- return $this->unidades;
- }
- protected $departamentos;
- public function departamentos() {
- if ($this->departamentos == null) {
- $this->departamentos = array_map(function($item) {
- return $item->unidad();
- }, array_filter($this->unidades(), function($item) {
- return ($item->unidad()->tipo()->descripcion == 'departamento');
- }));
- }
- return $this->departamentos;
- }
- public function estacionamientos($mod = null)
- {
- if ($this->estacionamientos_arr == null) {
- if (($unidades = $this->unidades()) !== false) {
- $estacionamientos = array_filter($unidades, function($item) {
- return ($item->unidad()->tipo()->descripcion == 'estacionamiento');
- });
- $this->estacionamientos_arr = array_map(function($item) {
- return $item->unidad();
- }, $estacionamientos);
- } else {
- $ests = explode(';', $this->estacionamientos);
- $estacionamientos = [];
- foreach ($ests as $e) {
- $estacionamiento = \Model::factory(Unidad::class)->findOne($e);
- if ($estacionamiento) {
- $estacionamientos []= $estacionamiento;
- }
- }
- $this->estacionamientos_arr = $estacionamientos;
- }
- }
- if ($mod != null) {
- switch ($mod) {
- case 'array':
- $result = [];
- foreach ($this->estacionamientos_arr as $est) {
- $result []= $est->descripcion;
- }
- return $result;
- }
- }
- return $this->estacionamientos_arr;
- }
- public function bodegas($mod = null)
- {
- if ($this->bodegas_arr == null) {
- if (($unidades = $this->unidades()) !== false) {
- $bodegas = array_filter($unidades, function($item) {
- return ($item->unidad()->tipo()->descripcion == 'bodega');
- });
- $this->bodegas_arr = array_map(function($item) {
- return $item->unidad();
- }, $bodegas);
- } else {
- $bods = explode(';', $this->bodegas);
- $bodegas = [];
- foreach ($bods as $b) {
- $bodega = \Model::factory(Unidad::class)->findOne($b);
- if ($bodega) {
- $bodegas []= $bodega;
- }
- }
- $this->bodegas_arr = $bodegas;
- }
- }
- if ($mod != null) {
- switch ($mod) {
- case 'array':
- $result = [];
- foreach ($this->bodegas_arr as $bod) {
- $result []= $bod->descripcion;
- }
- return $result;
- }
- }
- return $this->bodegas_arr;
- }
- public function venta()
- {
- return $this->has_one(Venta::class, 'propiedad')->findOne();
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/PropiedadUnidad.php b/incoviba/modelos/src/old/Venta/PropiedadUnidad.php
deleted file mode 100644
index b3f9b81..0000000
--- a/incoviba/modelos/src/old/Venta/PropiedadUnidad.php
+++ /dev/null
@@ -1,25 +0,0 @@
-propiedad_model == null) {
- $this->propiedad_model = $this->belongsTo(Propiedad::class, 'propiedad')->findOne();
- }
- return $this->propiedad_model;
- }
- protected $unidad_model;
- public function unidad() {
- if ($this->unidad_model == null) {
- $this->unidad_model = $this->belongsTo(Unidad::class, 'unidad')->findOne();
- }
- return $this->unidad_model;
- }
- protected $is_principal;
- public function isPrincipal() {
- return ($this->principal == 0) ? false : true;
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Propietario.php b/incoviba/modelos/src/old/Venta/Propietario.php
deleted file mode 100644
index 353a30a..0000000
--- a/incoviba/modelos/src/old/Venta/Propietario.php
+++ /dev/null
@@ -1,66 +0,0 @@
-belongs_to(Direccion::class, 'direccion')->findOne();
- }
- public function nombreCompleto($ap = false)
- {
- $str = '';
- if ($ap) {
- $str = $this->apellido_paterno . ' ' . $this->apellido_materno . ', ' . $this->nombres;
- } else {
- $str = $this->nombres . ' ' . $this->apellido_paterno . ' ' . $this->apellido_materno;
- }
- return $str;
- }
- public function representante()
- {
- $r = $this->belongsTo(Propietario::class, 'representante', 'rut');
- if ($r) {
- return $r->findOne();
- }
- return null;
- }
- public function ventas() {
- return $this->hasMany(Venta::class, 'propietario', 'rut')
- ->select('venta.*')
- ->join('propiedad', ['propiedad.id', '=', 'venta.propiedad'])
- ->join('unidad', ['unidad.id', '=', 'propiedad.unidad_principal'])
- ->join('proyecto', ['proyecto.id', '=', 'unidad.proyecto'])
- ->orderByAsc('proyecto.descripcion')
- ->orderByExpr("LPAD(unidad.descripcion, 4, '0')")
- ->findMany();
- }
- public function rut()
- {
- return format('rut', $this->rut) . '-' . $this->dv;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/Subsidio.php b/incoviba/modelos/src/old/Venta/Subsidio.php
deleted file mode 100644
index 7728f41..0000000
--- a/incoviba/modelos/src/old/Venta/Subsidio.php
+++ /dev/null
@@ -1,44 +0,0 @@
-belongs_to(Pago::class, 'pago')->findOne();
- }
- public function subsidio()
- {
- $pago = $this->belongs_to(Pago::class, 'subsidio');
- if ($pago) {
- return $pago->findOne();
- }
- return null;
- }
- public function total($tipo = 'pesos')
- {
- $sum = 0;
- if ($tipo == 'pesos') {
- $sum = $this->pago()->valor;
- if ($this->subsidio != 0) {
- $sum += $this->subsidio()->valor;
- }
- } else {
- $sum = $this->pago()->valor('ufs');
- if ($this->subsidio != 0) {
- $sum += $this->subsidio()->valor('ufs');
- }
- }
- return $sum;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/TipoEstadoCierre.php b/incoviba/modelos/src/old/Venta/TipoEstadoCierre.php
deleted file mode 100644
index 881e3ac..0000000
--- a/incoviba/modelos/src/old/Venta/TipoEstadoCierre.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/TipoEstadoPrecio.php b/incoviba/modelos/src/old/Venta/TipoEstadoPrecio.php
deleted file mode 100644
index 43aee68..0000000
--- a/incoviba/modelos/src/old/Venta/TipoEstadoPrecio.php
+++ /dev/null
@@ -1,12 +0,0 @@
-activo == 1) {
- return true;
- }
- return false;
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/TipoEstadoVenta.php b/incoviba/modelos/src/old/Venta/TipoEstadoVenta.php
deleted file mode 100644
index 28105d1..0000000
--- a/incoviba/modelos/src/old/Venta/TipoEstadoVenta.php
+++ /dev/null
@@ -1,21 +0,0 @@
-hasMany(EstadoVenta::class, 'estado')->findMany();
- }
- public function activa()
- {
- return ($this->activa == 1) ? true : false;
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/TipoPago.php b/incoviba/modelos/src/old/Venta/TipoPago.php
deleted file mode 100644
index 8fc3efb..0000000
--- a/incoviba/modelos/src/old/Venta/TipoPago.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/TipoUnidad.php b/incoviba/modelos/src/old/Venta/TipoUnidad.php
deleted file mode 100644
index 731f8cd..0000000
--- a/incoviba/modelos/src/old/Venta/TipoUnidad.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/incoviba/modelos/src/old/Venta/TipoValorCierre.php b/incoviba/modelos/src/old/Venta/TipoValorCierre.php
deleted file mode 100644
index a35385c..0000000
--- a/incoviba/modelos/src/old/Venta/TipoValorCierre.php
+++ /dev/null
@@ -1,12 +0,0 @@
-belongs_to(Proyecto::class, 'proyecto')->findOne();
- }
- protected $propiedad;
- public function propiedad()
- {
- if ($this->propiedad == null) {
- $this->propiedad = $this->hasMany(PropiedadUnidad::class, 'unidad')->findOne();
- }
- return $this->propiedad;
-
- if ($this->tipo()->descripcion == 'departamento') {
- $propiedad = $this->has_one(Propiedad::class, 'unidad_principal');
- if ($propiedad) {
- return $propiedad->findOne();
- }
- return null;
- }
- if ($this->tipo()->descripcion == 'estacionamiento') {
- // id | id; | ;id | ;id;
- $propiedad = model(Propiedad::class)->whereLike('estacionamientos', $this->id)->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('estacionamientos', '%;' . $this->id)->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('estacionamientos', $this->id . ';%')->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('estacionamientos', '%;' . $this->id . ';%')->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- return null;
- }
- if ($this->tipo()->descripcion == 'bodega') {
- // id | id; | ;id | ;id;
- $propiedad = model(Propiedad::class)->whereLike('bodegas', $this->id)->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('bodegas', '%;' . $this->id)->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('bodegas', $this->id . ';%')->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- $propiedad = model(Propiedad::class)->whereLike('bodegas', '%;' . $this->id . ';%')->findOne();
- if ($propiedad) {
- return $propiedad;
- }
- return null;
- }
- }
- public function tipo()
- {
- return $this->belongs_to(TipoUnidad::class, 'tipo')->findOne();
- }
- private $venta = null;
- public function venta()
- {
- if ($this->venta == null) {
- $propiedad = $this->propiedad();
- if ($propiedad) {
- $venta = $propiedad->propiedad()->venta();
- if ($venta) {
- $this->venta = $venta;
- }
- }
- }
- return $this->venta;
- }
- private $m2t = null;
- public function m2($tipo = 'vendible')
- {
- if ($this->m2t == null or !isset($this->m2t->{$tipo})) {
- if ($this->m2t == null) {
- $this->m2t = [];
- } else {
- $this->m2t = (Array) $this->m2t;
- }
-
- $this->m2t[$tipo] = $this->tipologia()->m2($tipo);
- $this->m2t = (object) $this->m2t;
- }
- return $this->m2t->{$tipo};
- }
- public function precios()
- {
- return $this->hasMany(Precio::class, 'unidad')->findMany();
- }
- public function precio($fecha = null)
- {
- if ($fecha == null) {
- return \model(Precio::class)
- ->select('precio.*')
- ->rawJoin('JOIN (SELECT e1.* FROM (SELECT precio, MAX(id) AS id FROM estado_precio GROUP BY precio) e0 JOIN estado_precio e1 ON e1.id = e0.id)', ['ep.precio', '=', 'precio.id'], 'ep')
- ->where('unidad', $this->id)
- ->where('ep.estado', 1)
- ->findOne();
- }
- return \model(Precio::class)
- ->select('precio.*')
- ->join('estado_precio', ['ep.precio', '=', 'precio.id'], 'ep')
- ->where('precio.unidad', $this->id)
- ->where('ep.estado', 1)
- ->whereLte('ep.fecha', $fecha->format('Y-m-d'))
- ->orderByDesc('ep.fecha')
- ->orderByDesc('ep.id')
- ->findOne();
- }
- public function setPrecio($fecha, $valor)
- {
- $exists = false;
- // Dejar valores antiguos reemplazados (estado = 'reemplazado')
- foreach ($this->precios() as $precio) {
- if (!$precio->vigente()) {
- continue;
- }
- // Ya existe precio a este valor
- if ($precio->valor == $valor) {
- // La fecha es anterior
- if ($precio->estado()->fecha != $fecha->format('Y-m-d')) {
- $precio->actualizar($fecha);
- }
- $exists = true;
- continue;
- }
- $precio->reemplazar($fecha);
- }
- if ($exists) {
- return;
- }
- // Agregar precio
- $data = [
- 'unidad' => $this->id,
- 'valor' => $valor
- ];
- $precio = model(Precio::class)->create($data);
- $precio->new($fecha);
- }
- public function tipologia()
- {
- return $this->belongsTo(ProyectoTipoUnidad::class, 'pt')->findOne();
- }
- protected $is_vendida;
- public function isVendida() {
- if ($this->is_vendidad == null) {
- $this->is_vendida = false;
- try {
- $p = $this->propiedad();
- if ($p) {
- $v = $p->venta();
- if ($v) {
- $this->is_vendida = true;
- }
- }
- } catch(\Exception $e) {}
- }
- return $this->is_vendida;
- }
- protected $cierres;
- public function cierres() {
- if ($this->cierres == null) {
- $ucs = $this->hasMany(UnidadCierre::class, 'unidad')->findMany();
- if (!$ucs) {
- $this->cierres = false;
- return $this->cierres;
- }
- $cierres = [];
- foreach ($ucs as $uc) {
- $c = $uc->cierre();
- if ($c) {
- $cierres []= $c;
- }
- }
- usort($cierres, function($a, $b) {
- return $a->fecha()->diffInDays($b->fecha());
- });
- $this->cierres = $cierres;
- }
- return $this->cierres;
- }
- public function cierre() {
- if ($this->cierres()) {
- return $this->cierres[count($this->cierres) - 1];
- }
- return false;
- }
- protected $is_reservada;
- public function isReservada() {
- if ($this->is_reservada == null) {
- $this->is_reservada = false;
- if (!$this->isVendida()) {
- $cierres = $this->cierres();
- if ($cierres) {
- foreach ($cierres as $cierre) {
- if ($cierre->isVigente()) {
- $this->is_reservada = true;
- }
- }
- }
- }
- }
- return $this->is_reservada;
- }
- protected $linea;
- public function linea() {
- if ($this->linea == null) {
- if ($this->tipo == 1) {
- $this->linea = (int) \substr($this->descripcion, -2);
- }
- }
- return $this->linea;
- }
-}
-?>
diff --git a/incoviba/modelos/src/old/Venta/UnidadBloqueada.php b/incoviba/modelos/src/old/Venta/UnidadBloqueada.php
deleted file mode 100644
index dc05771..0000000
--- a/incoviba/modelos/src/old/Venta/UnidadBloqueada.php
+++ /dev/null
@@ -1,42 +0,0 @@
-belongsTo(ProyectoAgente::class, 'agente')->findOne();
- }
- public function unidad()
- {
- return $this->belongsTo(Unidad::class, 'unidad')->findOne();
- }
- public function estados()
- {
- return $this->hasMany(EstadoUnidadBloqueada::class, 'unidad')->orderByAsc('fecha')->findMany();
- }
- public function estado()
- {
- return $this->hasMany(EstadoUnidadBloqueada::class, 'unidad')->orderByDesc('fecha')->findOne();
- }
- public function new(\DateTime $fecha)
- {
- parent::save();
- $tipo = model(TipoEstadoUnidadBloqueada::class)->where('descripcion', 'bloqueada')->findOne();
- $data = [
- 'unidad' => $this->id,
- 'fecha' => $fecha->format('Y-m-d'),
- 'tipo' => $tipo->id
- ];
- $estado = model(EstadoUnidadBloqueada::class)->create($data);
- $estado->save();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/UnidadCierre.php b/incoviba/modelos/src/old/Venta/UnidadCierre.php
deleted file mode 100644
index 4da11c8..0000000
--- a/incoviba/modelos/src/old/Venta/UnidadCierre.php
+++ /dev/null
@@ -1,22 +0,0 @@
-belongsTo(Cierre::class, 'cierre')->findOne();
- }
- public function unidad()
- {
- return $this->belongsTo(Unidad::class, 'unidad')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/ValorCierre.php b/incoviba/modelos/src/old/Venta/ValorCierre.php
deleted file mode 100644
index e5fd823..0000000
--- a/incoviba/modelos/src/old/Venta/ValorCierre.php
+++ /dev/null
@@ -1,22 +0,0 @@
-belongsTo(Cierre::class, 'cierre')->findOne();
- }
- public function tipo()
- {
- return $this->belongsTo(TipoValorCierre::class, 'tipo')->findOne();
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Venta.php b/incoviba/modelos/src/old/Venta/Venta.php
deleted file mode 100644
index e36ebb9..0000000
--- a/incoviba/modelos/src/old/Venta/Venta.php
+++ /dev/null
@@ -1,514 +0,0 @@
-belongs_to(Propietario::class, 'propietario', 'rut')->findOne();
- }
- public function propiedad()
- {
- return $this->belongs_to(Propiedad::class, 'propiedad')->findOne();
- }
- public function bonoPie()
- {
- $bono = $this->belongs_to(BonoPie::class, 'bono_pie');
- if ($bono) {
- return $bono->findOne();
- }
- return null;
- }
- public function pie()
- {
- $pie = $this->belongs_to(Pie::class, 'pie');
- if ($pie) {
- return $pie->findOne();
- }
- return null;
- }
- public function entrega()
- {
- if ($this->entrega != '0') {
- return $this->belongs_to(Entrega::class, 'entrega')->findOne();
- }
- return null;
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, new \DateTimeZone(config('app.timezone')));
- }
- public function proyecto()
- {
- return $this->propiedad()->unidad()->proyecto();
- }
- public function unidad()
- {
- return $this->propiedad()->unidad();
- }
- public function agente()
- {
- $agente = $this->belongs_to(ProyectoAgente::class, 'agente');
- if ($agente) {
- return $agente->findOne();
- }
- return null;
- }
- public function comision()
- {
- if (!isset($this->comision)) {
- $pa = $this->agente();
- if ($pa and $pa->agente()->tipo == 19) {
- $this->comision = $pa->comision / 100;
- } else {
- $this->comision = 0;
- }
- }
- return $this->comision;
- }
- public function valorComision()
- {
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- return ($this->valor_uf - $bono_pie) * $this->comision();
- }
- protected $superficie_departamentos;
- public function superficie() {
- if ($this->superficie_departamentos == null) {
- $this->superficie_departamentos = array_reduce($this->propiedad()->departamentos(), function($sum, $item) {
- return $sum + $item->m2();
- });
- }
- return $this->superficie_departamentos;
- }
- protected $valor_departamentos;
- public function valorDepartamentos() {
- if ($this->valor_departamentos == null) {
- $fecha = $this->fecha();
- $this->valor_departamentos = array_reduce($this->propiedad()->departamentos(), function($sum, $item) use ($fecha) {
- return $sum + (isset($item->precio($fecha)->valor)) ? $item->precio($fecha)->valor : 0;
- });
- }
- return $this->valor_departamentos;
- }
- protected $valor_unidades;
- public function valorUnidades() {
- if ($this->valor_unidades == null) {
- $fecha = $this->fecha();
- $this->valor_unidades = array_reduce($this->propiedad()->unidades(), function($sum, $item) use ($fecha) {
- return $sum + (isset($item->unidad()->precio($fecha)->valor)) ? $item->unidad()->precio($fecha)->valor : 0;
- });
- }
- return $this->valor_unidades;
- }
- public function valorEstacionamientos()
- {
- $estacionamientos = $this->propiedad()->estacionamientos();
- $sum = 0;
- foreach ($estacionamientos as $estacionamiento) {
- $sum += (isset($estacionamiento->precio($this->fecha())->valor)) ? $estacionamiento->precio($this->fecha())->valor : 0;
- }
- return $sum;
- }
- public function valorBodegas()
- {
- $bodegas = $this->propiedad()->bodegas();
- $sum = 0;
- foreach ($bodegas as $bodega) {
- $sum += (isset($bodega->precio($this->fecha())->valor)) ? $bodega->precio($this->fecha())->valor : 0;
- }
- return $sum;
- }
- public function valorEstacionamientosYBodegas()
- {
- return $this->valorEstacionamientos() + $this->valorBodegas();
- }
- public function valorCorredora()
- {
- if ($this->valor_corredora == null) {
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- $promos = 0;
- $ps = $this->promociones();
- if (count($ps) > 0) {
- foreach ($ps as $promo) {
- $promos += $promo->valor;
- }
- }
- $this->valor_corredora = $this->valor_uf - $bono_pie - $promos;
- }
- return $this->valor_corredora;
- }
- public function valorFinal()
- {
- if (!isset($this->valor_neto)) {
- $comision = $this->valorComision();
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- $ests = $this->valorEstacionamientos();
- $bods = $this->valorBodegas();
- $promos = 0;
- $ps = $this->promociones();
- if (count($ps) > 0) {
- foreach ($ps as $promo) {
- $promos += $promo->valor;
- }
- }
- $this->valor_neto = $this->valor_uf - $bono_pie - $comision - $ests - $bods - $promos;
- }
- return $this->valor_neto;
- }
- public function uf_m2()
- {
- $m2 = array_reduce($this->propiedad()->departamentos(), function($sum, $item) {
- return $sum + $item->m2();
- });
- return $this->valorFinal() / $m2;
- }
- public function escritura()
- {
- $escritura = $this->belongs_to(Escritura::class, 'escritura');
- if ($escritura) {
- return $escritura->findOne();
- }
- return null;
- }
- public function credito()
- {
- $credito = $this->belongs_to(Credito::class, 'credito');
- if ($credito) {
- return $credito->findOne();
- }
- return null;
- }
- public function comentarios()
- {
- return $this->has_many(Comentario::class, 'venta')->findMany();
- }
- public function subsidio()
- {
- $subsidio = $this->belongs_to(Subsidio::class, 'subsidio');
- if ($subsidio) {
- return $subsidio->findOne();
- }
- return null;
- }
-
- public function resciliacion()
- {
- $res = $this->belongs_to(Pago::class, 'resciliacion');
- if ($res) {
- return $res->findOne();
- }
- return null;
- }
- public function postventas()
- {
- $postventas = $this->has_many(\Incoviba\nuevo\Venta\Postventa::class, 'venta_id');
- if ($postventas) {
- return $postventas->findMany();
- }
- return null;
- }
- public function promociones()
- {
- if ($this->promociones == null) {
- $pvs = model(PromocionVenta::class)->where('venta', $this->id)->findMany();
- $this->promociones = $pvs;
- }
- return $this->promociones;
- }
- public function devolucion()
- {
- $devolucion = $this->belongsTo(Pago::class, 'devolucion');
- if ($devolucion) {
- return $devolucion->findOne();
- }
- return null;
- }
- public function anticipo($tipo = 'ufs')
- {
- if (!isset($this->anticipo[$tipo])) {
- $anticipo = 0;
- if ($this->pie != 0) {
- if ($tipo == 'ufs') {
- $anticipo += $this->pieReajustado($tipo);
- } else {
- $anticipo += $this->pie()->valorPagado($tipo);
- }
- if ($this->pie()->reajuste != 0) {
- $anticipo += $this->pie()->reajuste()->valor($tipo);
- }
- }
- if ($this->escritura != 0) {
- $anticipo += $this->escritura()->pago()->valor($tipo);
- }
- if ($this->saldo('ufs') > 0) {
- $anticipo -= $this->saldo($tipo);
- }
- $this->anticipo[$tipo] = $anticipo;
- }
-
- return $this->anticipo[$tipo];
- }
- public function saldo($tipo = 'ufs')
- {
- if (!isset($this->saldo[$tipo])) {
- if ($tipo == 'pesos') {
- $this->saldo[$tipo] = $this->saldo() * $this->uf();
- return $this->saldo[$tipo];
- }
- $saldo = $this->valor($tipo);
- if ($this->bono_pie != 0) {
- $saldo -= $this->bonoPie()->pago()->valor($tipo);
- }
- if ($this->pie != 0) {
- $saldo -= $this->pie()->valorPagado($tipo);
- if ($this->pie()->reajuste != 0) {
- $saldo -= $this->pie()->reajuste()->valor($tipo);
- }
- }
- if ($this->escritura != 0) {
- $saldo -= $this->escritura()->pago()->valor($tipo);
- }
- if ($this->subsidio != 0) {
- $saldo -= $this->subsidio()->total($tipo);
- }
- if ($this->credito != 0) {
- $saldo -= $this->credito()->pago()->valor($tipo);
- }
- if ($this->devolucion) {
- $saldo += $this->devolucion()->valor($tipo);
- }
- if ($this->resciliacion) {
- $saldo += $this->resciliacion()->valor($tipo);
- }
- $this->saldo[$tipo] = -$saldo;
- }
-
- return $this->saldo[$tipo];
- }
- public function valor($tipo = 'ufs')
- {
- if ($tipo == 'ufs') {
- return $this->valor_uf;
- }
- return $this->valor_uf * $this->uf();
- }
- protected $valores;
- public function valorPagado($tipo = 'ufs')
- {
- if ($this->valores == null or !isset($this->valores->pagado->ufs)) {
- $valores = [];
- if (isset($this->valores)) {
- $valores = (array) $valores;
- }
- $valores['pagado'] = (object) ['ufs' => 0, 'pesos' => 0];
- if ($this->pie()) {
- $valores['pagado']->ufs = $this->pie()->valorPagado();
- $valores['pagado']->pesos = $this->pie()->valorPagado('pesos');
- }
- $this->valores = (object) $valores;
- }
- return $this->valores->pagado->{$tipo};
- }
- public function valorAbonado($tipo = 'ufs')
- {
- if ($this->valores == null or !isset($this->valores->abonado->{$tipo})) {
- $valores = [];
- if (isset($this->valores)) {
- $valores = (array) $valores;
- }
- $valores['abonado'] = (object) ['ufs' => 0, 'pesos' => 0];
- if ($this->pie()) {
- $valores['abonado']->ufs = $this->pie()->valorAbonado();
- $valores['abonado']->pesos = $this->pie()->valorAbonado('pesos');
- }
- $this->valores = (object) $valores;
- }
- return $this->valores->abonado->{$tipo};
- }
- public function pagado($tipo = 'ufs')
- {
- if (!isset($this->pagado[$tipo])) {
- if (abs($this->saldo()) / $this->valor() > 0.01 or $tipo == 'pesos') {
- $total = 0;
- $total += $this->anticipo($tipo);
-
- if ($this->subsidio != 0) {
- $total += $this->subsidio()->total($tipo);
- }
- if ($this->credito != 0) {
- $total += $this->credito()->pago()->valor($tipo);
- }
- if ($this->devolucion) {
- $total -= $this->devolucion()->valor($tipo);
- }
- if ($this->resciliacion) {
- $total -= $this->resciliacion()->valor($tipo);
- }
-
- $this->pagado[$tipo] = $total;
- } else {
- $this->pagado[$tipo] = $this->valor($tipo);
- }
- }
- return $this->pagado[$tipo];
- }
- public function pieReajustado($tipo = 'ufs')
- {
- if (abs($this->saldo()) / $this->valor() > 0.01) {
- return $this->pie()->valorPagado($tipo);
- }
- $valor = $this->pie()->valorPagado($tipo) - $this->saldo($tipo);
- return $valor;
- }
- public function uf()
- {
- if ($this->uf == null) {
- $f = $this->fecha();
- $uf = uf($f);
- if ($uf == null) {
- return 1;
- }
- $this->uf = $uf->uf->value;
- }
-
- return $this->uf;
- }
- public function pagos($estado = 0)
- {
- $results = [];
- if ($this->pie != 0) {
- $results = array_merge($results, $this->pie()->pagos($estado));
- }
- if ($this->escritura != 0 and $this->escritura()->pago() and $this->escritura()->pago()->estado()->estado == $estado) {
- $results []= $this->escritura()->pago();
- }
- if ($this->credito != 0 and $this->credito()->pago()->estado()->estado == $estado) {
- $results []= $this->credito()->pago();
- }
- if ($this->subsidio != 0 and $this->subsidio()->pago()->estado()->estado == $estado) {
- $results []= $this->subsidio()->pago();
- }
-
- usort($results, function($a, $b) {
- return $a->estado()->fecha()->diffInDays($b->estado()->fecha(), false);
- });
- return $results;
- }
- public function new()
- {
- parent::save();
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'vigente')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $this->fecha
- ];
- $estado = model(EstadoVenta::class)->create($data);
- $estado->save();
- }
- public function estados()
- {
- return $this->hasMany(EstadoVenta::class, 'venta')->findMany();
- }
- public function estado($estado = null)
- {
- if ($estado == null) {
- return model(EstadoVenta::class)
- ->select('estado_venta.*')
- ->rawJoin('JOIN (SELECT venta, MAX(id) AS id FROM estado_venta GROUP BY venta)', ['estado_venta.id', '=', 'e0.id'], 'e0')
- ->where('estado_venta.venta', $this->id)
- ->findOne();
- }
- return model(EstadoVenta::class)
- ->select('estado_venta.*')
- ->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
- ->where('estado_venta.venta', $this->id)
- ->where('tipo_estado_venta.descripcion', $estado)
- ->orderByDesc('estado_venta.fecha')
- ->findOne();
- }
- public function firmar(Carbon $fecha)
- {
- $estado = $this->estado();
- if ($estado->tipo()->descripcion == 'firmado por inmobiliaria') {
- return true;
- }
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'firmado por inmobiliaria')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data)->save();
- return true;
- }
- public function archivar(Carbon $fecha)
- {
- $estado = $this->estado();
- if ($estado->estado()->tipo()->descripcion == 'archivado') {
- return true;
- }
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'archivado')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data)->save();
- return true;
- }
-}
diff --git a/incoviba/modelos/src/old/Venta/Venta.php.save b/incoviba/modelos/src/old/Venta/Venta.php.save
deleted file mode 100644
index d28df00..0000000
--- a/incoviba/modelos/src/old/Venta/Venta.php.save
+++ /dev/null
@@ -1,517 +0,0 @@
-belongs_to(Propietario::class, 'propietario', 'rut')->findOne();
- }
- public function propiedad()
- {
- return $this->belongs_to(Propiedad::class, 'propiedad')->findOne();
- }
- public function bonoPie()
- {
- $bono = $this->belongs_to(BonoPie::class, 'bono_pie');
- if ($bono) {
- return $bono->findOne();
- }
- return null;
- }
- public function pie()
- {
- $pie = $this->belongs_to(Pie::class, 'pie');
- if ($pie) {
- return $pie->findOne();
- }
- return null;
- }
- public function entrega()
- {
- if ($this->entrega != '0') {
- return $this->belongs_to(Entrega::class, 'entrega')->findOne();
- }
- return null;
- }
- public function fecha()
- {
- return Carbon::parse($this->fecha, new \DateTimeZone(config('app.timezone')));
- }
- public function proyecto()
- {
- return $this->propiedad()->unidad()->proyecto();
- }
- public function unidad()
- {
- return $this->propiedad()->unidad();
- }
- public function agente()
- {
- $agente = $this->belongs_to(ProyectoAgente::class, 'agente');
- if ($agente) {
- return $agente->findOne();
- }
- return null;
- }
- public function comision()
- {
- if (!isset($this->comision)) {
- $pa = $this->agente();
- if ($pa and $pa->agente()->tipo == 19) {
- $this->comision = $pa->comision / 100;
- } else {
- $this->comision = 0;
- }
- }
- return $this->comision;
- }
- public function valorComision()
- {
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- return ($this->valor_uf - $bono_pie) * $this->comision();
- }
- protected $superficie_departamentos;
- public function superficie() {
- if ($this->superficie_departamentos == null) {
- $this->superficie_departamentos = array_reduce($this->propiedad()->departamentos(), function($sum, $item) {
- return $sum + $item->m2();
- });
- }
- return $this->superficie_departamentos;
- }
- protected $valor_departamentos;
- public function valorDepartamentos() {
- if ($this->valor_departamentos == null) {
- $fecha = $this->fecha();
- $this->valor_departamentos = array_reduce($this->propiedad()->departamentos(), function($sum, $item) use ($fecha) {
- return $sum + $item->precio($fecha)->valor;
- });
- }
- return $this->valor_departamentos;
- }
- protected $valor_unidades;
- public function valorUnidades() {
- if ($this->valor_unidades == null) {
- $fecha = $this->fecha();
- $this->valor_unidades = array_reduce($this->propiedad()->unidades(), function($sum, $item) use ($fecha) {
- return $sum + $item->unidad()->precio($fecha)->valor;
- });
- }
- return $this->valor_unidades;
- }
- public function valorEstacionamientos()
- {
- $estacionamientos = $this->propiedad()->estacionamientos();
- $sum = 0;
- foreach ($estacionamientos as $estacionamiento) {
- $sum += $estacionamiento->precio($this->fecha())->valor;
- }
- return $sum;
- }
- public function valorBodegas()
- {
- $bodegas = $this->propiedad()->bodegas();
- $sum = 0;
- foreach ($bodegas as $bodega) {
- $sum += $bodega->precio($this->fecha())->valor;
- }
- return $sum;
- }
- public function valorEstacionamientosYBodegas()
- {
- return $this->valorEstacionamientos() + $this->valorBodegas();
- }
- public function valorCorredora()
- {
- if ($this->valor_corredora == null) {
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- $promos = 0;
- $ps = $this->promociones();
- if (count($ps) > 0) {
- foreach ($ps as $promo) {
- $promos += $promo->valor;
- }
- }
- $this->valor_corredora = $this->valor_uf - $bono_pie - $promos;
- }
- return $this->valor_corredora;
- }
- public function valorFinal()
- {
- if (!isset($this->valor_neto)) {
- $comision = $this->valorComision();
- $bono_pie = $this->bonoPie();
- if ($this->bono_pie != 0) {
- $bono_pie = $bono_pie->pago()->valor('ufs');
- } else {
- $bono_pie = 0;
- }
- $ests = $this->valorEstacionamientos();
- $bods = $this->valorBodegas();
- $promos = 0;
- $ps = $this->promociones();
- if (count($ps) > 0) {
- foreach ($ps as $promo) {
- $promos += $promo->valor;
- }
- }
- $this->valor_neto = $this->valor_uf - $bono_pie - $comision - $ests - $bods - $promos;
- }
- return $this->valor_neto;
- }
- public function uf_m2()
- {
- $m2 = array_reduce($this->propiedad()->departamentos(), function($sum, $item) {
- return $sum + $item->m2();
- });
- return $this->valorFinal() / $m2;
- }
- public function escritura()
- {
- $escritura = $this->belongs_to(Escritura::class, 'escritura');
- if ($escritura) {
- return $escritura->findOne();
- }
- return null;
- }
- public function credito()
- {
- $credito = $this->belongs_to(Credito::class, 'credito');
- if ($credito) {
- return $credito->findOne();
- }
- return null;
- }
- public function comentarios()
- {
- return $this->has_many(Comentario::class, 'venta')->findMany();
- }
- public function subsidio()
- {
- $subsidio = $this->belongs_to(Subsidio::class, 'subsidio');
- if ($subsidio) {
- return $subsidio->findOne();
- }
- return null;
- }
-
- public function resciliacion()
- {
- $res = $this->belongs_to(Pago::class, 'resciliacion');
- if ($res) {
- return $res->findOne();
- }
- return null;
- }
- public function postventas()
- {
- $postventas = $this->has_many(\Incoviba\nuevo\Venta\Postventa::class, 'venta_id');
- if ($postventas) {
- return $postventas->findMany();
- }
- return null;
- }
- public function promociones()
- {
- if ($this->promociones == null) {
- $pvs = model(PromocionVenta::class)->where('venta', $this->id)->findMany();
- $this->promociones = $pvs;
- }
- return $this->promociones;
- }
- public function devolucion()
- {
- $devolucion = $this->belongsTo(Pago::class, 'devolucion');
- if ($devolucion) {
- return $devolucion->findOne();
- }
- return null;
- }
- public function anticipo($tipo = 'ufs')
- {
- if (!isset($this->anticipo[$tipo])) {
- $anticipo = 0;
- if ($this->pie != 0) {
- if ($tipo == 'ufs') {
- $anticipo += $this->pieReajustado($tipo);
- } else {
- $anticipo += $this->pie()->valorPagado($tipo);
- }
- if ($this->pie()->reajuste != 0) {
- $anticipo += $this->pie()->reajuste()->valor($tipo);
- }
- }
- if ($this->escritura != 0) {
- $anticipo += $this->escritura()->pago()->valor($tipo);
- }
- if ($this->saldo('ufs') > 0) {
- $anticipo -= $this->saldo($tipo);
- }
- $this->anticipo[$tipo] = $anticipo;
- }
-
- return $this->anticipo[$tipo];
- }
- public function saldo($tipo = 'ufs')
- {
- if (!isset($this->saldo[$tipo])) {
- if ($tipo == 'pesos') {
- $this->saldo[$tipo] = $this->saldo() * $this->uf();
- return $this->saldo[$tipo];
- }
- $saldo = $this->valor($tipo);
- if ($this->bono_pie != 0) {
- $saldo -= $this->bonoPie()->pago()->valor($tipo);
- }
- if ($this->pie != 0) {
- $saldo -= $this->pie()->valorPagado($tipo);
- if ($this->pie()->reajuste != 0) {
- $saldo -= $this->pie()->reajuste()->valor($tipo);
- }
- }
- if ($this->escritura != 0) {
- $saldo -= $this->escritura()->pago()->valor($tipo);
- }
- if ($this->subsidio != 0) {
- $saldo -= $this->subsidio()->total($tipo);
- }
- if ($this->credito != 0) {
- $saldo -= $this->credito()->pago()->valor($tipo);
- }
- if ($this->devolucion) {
- $saldo += $this->devolucion()->valor($tipo);
- }
- if ($this->resciliacion) {
- $saldo += $this->resciliacion()->valor($tipo);
- }
- $this->saldo[$tipo] = -$saldo;
- }
-
- return $this->saldo[$tipo];
- }
- public function valor($tipo = 'ufs')
- {
- if ($tipo == 'ufs') {
- return $this->valor_uf;
- }
- return $this->valor_uf * $this->uf();
- }
- protected $valores;
- public function valorPagado($tipo = 'ufs')
- {
- if ($this->valores == null or !isset($this->valores->pagado->ufs)) {
- $valores = [];
- if (isset($this->valores)) {
- $valores = (array) $valores;
- }
- $valores['pagado'] = (object) ['ufs' => 0, 'pesos' => 0];
- if ($this->pie()) {
- $valores['pagado']->ufs = $this->pie()->valorPagado();
- $valores['pagado']->pesos = $this->pie()->valorPagado('pesos');
- }
- $this->valores = (object) $valores;
- }
- return $this->valores->pagado->{$tipo};
- }
- public function valorAbonado($tipo = 'ufs')
- {
- if ($this->valores == null or !isset($this->valores->abonado->{$tipo})) {
- $valores = [];
- if (isset($this->valores)) {
- $valores = (array) $valores;
- }
- $valores['abonado'] = (object) ['ufs' => 0, 'pesos' => 0];
- if ($this->pie()) {
- $valores['abonado']->ufs = $this->pie()->valorAbonado();
- $valores['abonado']->pesos = $this->pie()->valorAbonado('pesos');
- }
- $this->valores = (object) $valores;
- }
- return $this->valores->abonado->{$tipo};
- }
- public function pagado($tipo = 'ufs')
- {
- if (!isset($this->pagado[$tipo])) {
- if (abs($this->saldo()) / $this->valor() > 0.01 or $tipo == 'pesos') {
- $total = 0;
- $total += $this->anticipo($tipo);
-
- if ($this->subsidio != 0) {
- $total += $this->subsidio()->total($tipo);
- }
- if ($this->credito != 0) {
- $total += $this->credito()->pago()->valor($tipo);
- }
- if ($this->devolucion) {
- $total -= $this->devolucion()->valor($tipo);
- }
- if ($this->resciliacion) {
- $total -= $this->resciliacion()->valor($tipo);
- }
-
- $this->pagado[$tipo] = $total;
- } else {
- $this->pagado[$tipo] = $this->valor($tipo);
- }
- }
- return $this->pagado[$tipo];
- }
- public function pieReajustado($tipo = 'ufs')
- {
- if (abs($this->saldo()) / $this->valor() > 0.01) {
- return $this->pie()->valorPagado($tipo);
- }
- $valor = $this->pie()->valorPagado($tipo) - $this->saldo($tipo);
- return $valor;
- }
- public function uf()
- {
- if ($this->uf == null) {
- $f = $this->fecha();
- $uf = uf($f);
- if ($uf == null) {
- return 1;
- }
-
-!d($uf);
- $this->uf = $uf->uf->value;
- }
-
- return $this->uf;
- }
- public function pagos($estado = 0)
- {
- $results = [];
- if ($this->pie != 0) {
- $results = array_merge($results, $this->pie()->pagos($estado));
- }
- if ($this->escritura != 0 and $this->escritura()->pago() and $this->escritura()->pago()->estado()->estado == $estado) {
- $results []= $this->escritura()->pago();
- }
- if ($this->credito != 0 and $this->credito()->pago()->estado()->estado == $estado) {
- $results []= $this->credito()->pago();
- }
- if ($this->subsidio != 0 and $this->subsidio()->pago()->estado()->estado == $estado) {
- $results []= $this->subsidio()->pago();
- }
-
- usort($results, function($a, $b) {
- return $a->estado()->fecha()->diffInDays($b->estado()->fecha(), false);
- });
- return $results;
- }
- public function new()
- {
- parent::save();
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'vigente')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $this->fecha
- ];
- $estado = model(EstadoVenta::class)->create($data);
- $estado->save();
- }
- public function estados()
- {
- return $this->hasMany(EstadoVenta::class, 'venta')->findMany();
- }
- public function estado($estado = null)
- {
- if ($estado == null) {
- return model(EstadoVenta::class)
- ->select('estado_venta.*')
- ->rawJoin('JOIN (SELECT venta, MAX(id) AS id FROM estado_venta GROUP BY venta)', ['estado_venta.id', '=', 'e0.id'], 'e0')
- ->where('estado_venta.venta', $this->id)
- ->findOne();
- }
- return model(EstadoVenta::class)
- ->select('estado_venta.*')
- ->join('tipo_estado_venta', ['tipo_estado_venta.id', '=', 'estado_venta.estado'])
- ->where('estado_venta.venta', $this->id)
- ->where('tipo_estado_venta.descripcion', $estado)
- ->orderByDesc('estado_venta.fecha')
- ->findOne();
- }
- public function firmar(Carbon $fecha)
- {
- $estado = $this->estado();
- if ($estado->tipo()->descripcion == 'firmado por inmobiliaria') {
- return true;
- }
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'firmado por inmobiliaria')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data)->save();
- return true;
- }
- public function archivar(Carbon $fecha)
- {
- $estado = $this->estado();
- if ($estado->estado()->tipo()->descripcion == 'archivado') {
- return true;
- }
- $tipo = model(TipoEstadoVenta::class)->where('descripcion', 'archivado')->findOne();
- $data = [
- 'venta' => $this->id,
- 'estado' => $tipo->id,
- 'fecha' => $fecha->format('Y-m-d')
- ];
- $estado = model(EstadoVenta::class)->create($data)->save();
- return true;
- }
-}
-?>
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..8402402
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+docker run --rm -it -v ${PWD}/app:/app composer install
+docker run --rm -it -v ${PWD}/cli:/app composer install
+
+find ./app -name "*.env.sample" | cat -n | while read n f; do
+ cp "$f" "${f%.sample}"
+done
+
+cp ./cli/.env.sample ./cli/.env
+
+cp ./.env.sample ./.env
+
+echo "API_KEY=$(docker run --rm -it nginx openssl rand -hex 64)" > ./.key.env
+printf "MYSQL_ROOT_PASSWORD=%s\nMYSQL_DATABASE=incoviba\nMYSQL_USER=incoviba\nMYSQL_PASSWORD=%s" "$(docker run --rm -it nginx openssl rand -hex 16)" "$(docker run --rm -it nginx openssl rand -hex 64)" > ./app/.db.env
+
diff --git a/nginx.conf b/nginx.conf
index 42bb089..fc138fb 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -2,13 +2,10 @@ server {
listen 80;
server_name web;
index index.php;
- error_log /code/logs/error.log;
- access_log /code/logs/access.log;
+ error_log /logs/error.log;
+ access_log /logs/access.log;
root /code/public;
- location /api {
- try_files $uri /api/index.php$is_args$args;
- }
location / {
try_files $uri /index.php$is_args$args;
}
@@ -21,6 +18,6 @@ server {
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_read_timeout 3600;
- fastcgi_pass php:9000;
+ fastcgi_pass web:9000;
}
}
diff --git a/package.json b/package.json
deleted file mode 100644
index 4c0b879..0000000
--- a/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "incoviba_transition",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "directories": {
- "test": "tests"
- },
- "scripts": {
- "test": "mocha",
- "dev": "npm run development",
- "development": "run-p dev:css dev:js fonts",
- "prod": "npm run production",
- "production": "npm run build:css && npm run build:js",
- "dev:css": "lessc resources/less/app.less public/css/app.css",
- "build:css": "lessc -x resources/less/app.less public/css/app.css",
- "dev:js": "webpack --mode development",
- "dev:js2": "browserify resources/js/app.js -o public/js/app.js",
- "build:js": "webpack --mode production",
- "fonts": "fontify",
- "watch": "run-p watch:css watch:js",
- "watch:css": "chokidar --verbose resources/less/*.less -c \"npm run watching:css\"",
- "watch:js": "chokidar --verbose resources/js/*.js -c \"npm run watching:js\"",
- "watching:css": "run-p dev:css notify:css",
- "watching:js": "run-p dev:js notify:js",
- "notify:css": "notify -t \"Less\" -m \"Done with less\" -s -i https://upload.wikimedia.org/wikipedia/commons/a/a5/Twemoji_26a0.svg",
- "notify:js": "notify -t \"Js\" -m \"Done with js\" -s -i https://upload.wikimedia.org/wikipedia/commons/a/a5/Twemoji_26a0.svg"
- },
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.0.0-beta.51",
- "@babel/preset-env": "^7.0.0-beta.51",
- "ajv": "^5.5.2",
- "bootstrap": "^3.3.7",
- "bootstrap-3-typeahead": "^4.0.2",
- "browserify": "^14.5.0",
- "chart.js": "^2.7.2",
- "chartist": "^0.11.0",
- "chartjs-plugin-annotation": "^0.5.7",
- "chartjs-plugin-barchart-background": "^1.3.0",
- "chokidar-cli": "^1.2.0",
- "font-awesome": "^4.7.0",
- "fontify": "0.0.2",
- "jquery": "^3.3.1",
- "jquery-ui": "^1.12.1",
- "jquery-ui-bootstrap": "^1.0.0",
- "jquery.rut": "^1.1.2",
- "less": "^3.0.4",
- "mocha": "^5.2.0",
- "node-notifier-cli": "^1.1.2",
- "npm-run-all": "^4.1.3",
- "webpack": "^4.14.0",
- "webpack-cli": "^3.0.8",
- "zxcvbn": "^4.4.2"
- },
- "dependencies": {}
-}
diff --git a/php-errors.ini b/php-errors.ini
index c791df7..511b6ac 100644
--- a/php-errors.ini
+++ b/php-errors.ini
@@ -1,3 +1,3 @@
display_errors=no
log_errors=yes
-error_log=/logs/php_errors.log
+#error_log=/logs/errors.log
diff --git a/public/Pipfile b/public/Pipfile
deleted file mode 100644
index b5846df..0000000
--- a/public/Pipfile
+++ /dev/null
@@ -1,11 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-
-[packages]
-
-[requires]
-python_version = "3.8"
diff --git a/public/api/.htaccess b/public/api/.htaccess
deleted file mode 100644
index 66ef8f6..0000000
--- a/public/api/.htaccess
+++ /dev/null
@@ -1,4 +0,0 @@
-RewriteEngine On
-RewriteCond %{REQUEST_FILENAME} !-f
-RewriteCond %{REQUEST_FILENAME} !-d
-RewriteRule ^ index.php [QSA,L]
diff --git a/public/api/index.php b/public/api/index.php
deleted file mode 100644
index cec7741..0000000
--- a/public/api/index.php
+++ /dev/null
@@ -1,8 +0,0 @@
-run();
diff --git a/public/api/keys b/public/api/keys
deleted file mode 100644
index 7660873..0000000
--- a/public/api/keys
+++ /dev/null
@@ -1 +0,0 @@
-[1]
diff --git a/public/css/app.css b/public/css/app.css
deleted file mode 100644
index ab445ec..0000000
--- a/public/css/app.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/*!
- * Bootstrap v3.3.7 (http://getbootstrap.com)
- * Copyright 2011-2016 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eee;color:#777;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform 0.6s ease-in-out;-moz-transition:-moz-transform 0.6s ease-in-out;-o-transition:-o-transform 0.6s ease-in-out;transition:transform 0.6s ease-in-out;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;-moz-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0%, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0%, rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0%, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.dropdown-submenu{position:relative}.dropdown-submenu .dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu:hover>.dropdown-menu a:after{border-left-color:#fff}.dropdown-submenu a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu .pull-left{float:none}.dropdown-submenu .pull-left .dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}@media print{header,footer,.benchmark{display:none}}#print{width:100%}#print div.title{font-size:15pt;font-weight:bold;border-bottom:3px solid black;text-align:center}#print table.data-box{width:100%;border-collapse:collapse}#print table.data-box td{border:thin solid black;padding-left:2px}#print table.details{width:100%;border-collapse:collapse}#print table.details thead{color:white;background-color:black;font-weight:bold}#print table.details tbody tr{border:thin solid black}#print table.details tbody tr:nth-child(odd){background-color:lightgray}#print table.details tbody tr.total{font-weight:bold}#print table.details tbody tr.total td{border-top-style:double;border-top-width:3px}#print table.details td,#print table.details th{border:thin solid black;padding-left:2px}#print label{font-variant:small-caps;font-size:10pt}#print div.data{float:left}#print div.data-value{float:right}#print div.total{float:left;font-weight:bold}#print div.total-value{float:right;font-weight:bold}#print br.clear{clear:both}#print table.signature{width:75%}#print table.signature tr.double{height:24pt}#print table.signature tr.triple{height:36pt}#print table.signature tr.quadruple{height:48pt}#print table.signature tr td{padding-left:2px;border:thin solid black}#print table.signature tr td:nth-child(2){width:70%}.logo_cabezal{padding:1%}.logo_cabezal img{height:100.00000003px}.dropdown-submenu{position:relative}.dropdown-submenu .dropdown-menu{top:0;left:100%;margin-top:-1px}.error{background-color:#d84f4b}.page-heading{padding:3px 10px;margin:auto 0;background-color:#14153c;color:white}.page-heading a{color:inherit}.section-heading{background-color:#808080 !important;color:white !important}.section-heading a{color:inherit !important}.subsection-heading{background-color:#d3d3d3 !important}.agregar,.remover,.click{cursor:pointer}/*!
- * jQuery UI Bootstrap 0.2.5
- * Theme created by @gustavohenke for the jQuery UI Framework 1.9+
- *
- * Useful links:
- * http://jqueryui.com
- * http://gustavohenke.github.com/jquery-ui-bootstrap
- *
- * Licensed under MIT.
- */.ui-widget{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#222222}.ui-widget-content a{color:#222222}.ui-widget-header{border:1px solid #aaaaaa;color:#222222;font-weight:bold}.ui-widget-header a{color:#222222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{font-weight:normal;color:#555555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555555;text-decoration:none}.ui-state-default,.ui-widget-content .ui-state-default{border:1px solid #bbb;background-color:#e6e6e6;background-repeat:no-repeat;background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);color:#555;text-shadow:0 1px 1px rgba(255,255,255,0.75)}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover{border:1px solid #999999;background-position:0 -15px;font-weight:normal;-webkit-transition:.1s linear background-position;-moz-transition:.1s linear background-position;-ms-transition:.1s linear background-position;-o-transition:.1s linear background-position;transition:.1s linear background-position}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaaaaa;font-weight:normal}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fbeed5;background:#fcf8e3;color:#c09853}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #eed3d7;background:#f2dede;color:#b94a48}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:alpha(opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:alpha(opacity=35)}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_333333_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_333333_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_333333_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_B94A48_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:alpha(opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaaaaa;opacity:.3;filter:alpha(opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px}.ui-button,.ui-button.ui-state-default,.ui-slider .ui-slider-handle{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.ui-buttonset .ui-button.ui-state-active,.ui-slider .ui-slider-handle.ui-state-active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.ui-button[disabled],.ui-button.ui-state-disabled{background-image:none;opacity:0.65;filter:alpha(opacity=65)}.ui-tabs{border:0}.ui-tabs .ui-tabs-nav{margin-bottom:5px;border-width:0 0 1px;border-bottom-color:#ddd;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.ui-tabs .ui-tabs-nav li{padding-bottom:1px;border-color:transparent;background:none;filter:none}.ui-tabs .ui-tabs-nav li a{padding:0 15px;line-height:34px;color:#0088CC}.ui-tabs .ui-tabs-nav li:hover{background:#eee}.ui-tabs .ui-tabs-nav li a:hover{color:#005580}.ui-tabs .ui-tabs-nav li.ui-tabs-active,.ui-tabs .ui-tabs-nav li.ui-tabs-active:hover{border:1px solid #ddd;border-bottom-color:#fff;background:#fff}.ui-tabs .ui-tabs-nav li.ui-tabs-active a{color:#555}.ui-tabs .ui-tabs-panel{padding:0}.ui-dialog{padding:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3)}.ui-dialog .ui-dialog-titlebar{padding:9px 15px;border-width:0 0 1px;border-color:#eee;font-size:18px;background:transparent;-webkit-border-radius:0;-khtml-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.ui-dialog .ui-dialog-titlebar-close{right:15px}.ui-dialog a.ui-dialog-titlebar-close{color:#CCC}.ui-dialog a.ui-dialog-titlebar-close.ui-state-hover{border:none;background:transparent}.ui-dialog a.ui-dialog-titlebar-close:hover,.ui-dialog a.ui-dialog-titlebar-close:focus{padding:1px;color:#454545}.ui-dialog .ui-dialog-buttonpane{border-color:#ddd;background:#f5f5f5;text-align:right;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff}.ui-datepicker{width:20em;padding:0}.ui-datepicker .ui-datepicker-header{border-width:0 0 1px;border-color:#ddd;background:#f6f6f6;-webkit-border-radius:4px 4px 0 0;-khtml-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:2px;border:0;background:transparent}.ui-datepicker .ui-datepicker-prev-hover{left:2px}.ui-datepicker .ui-datepicker-next-hover{right:2px}.ui-datepicker td .ui-state-default{padding:5px;border:none;background:transparent;text-align:center;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05);-webkit-border-radius:4px;-khtml-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.ui-datepicker th{color:#555}.ui-datepicker td.ui-datepicker-week-col{padding-left:5px}.ui-datepicker td .ui-state-active{background:#bfbfbf;color:#fff}.ui-accordion .ui-accordion-content{padding:1em}.ui-spinner{border:0}.ui-spinner .ui-spinner-input{margin:0}.ui-spinner a.ui-spinner-button{border:1px solid #ddd}.ui-spinner a.ui-spinner-up{border-bottom-width:0}.ui-spinner a.ui-spinner-down{border-top-width:0}.ui-menu .ui-menu-item a{padding:6px .5em}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{margin:0}.ui-menu .ui-menu-item a.ui-state-active{border:0}.ui-tooltip{border:0;background:transparent;opacity:0.8;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.ui-tooltip .ui-tooltip-content{padding:3px 8px;background:#000;color:#fff;-webkit-border-radius:4px;-khtml-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.ui-autocomplete{z-index:3 !important}.ui-progressbar .ui-progressbar-value,.ui-slider .ui-slider-range,.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active,.ui-widget-content .ui-priority-primary,.ui-datepicker td .ui-state-hover,.ui-datepicker .ui-datepicker-today a{background-color:#006dcc;background-image:-khtml-gradient(linear, left top, left bottom, from(#08c), to(#04c));background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-ms-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #08c), color-stop(100%, #04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(top, #08c, #04c);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.ui-button.ui-priority-primary{border-color:#04c #04c #002a80}.ui-priority-primary.ui-state-hover{background-color:#04c;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.ui-icon.ui-icon-inline{display:inline-block}.ui-progressbar-striped .ui-progressbar-value{background-color:#0079CC;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:4em 4em;-moz-background-size:4em 4em;-o-background-size:4em 4em;background-size:4em 4em}@-webkit-keyframes progressbar-stripes{from{background-position:4em 0}to{background-position:0 0}}@-moz-keyframes progressbar-stripes{from{background-position:4em 0}to{background-position:0 0}}@-o-keyframes progressbar-stripes{from{background-position:0 0}to{background-position:4em 0}}@keyframes progressbar-stripes{from{background-position:4em 0}to{background-position:0 0}}.ui-progressbar-striped.ui-progressbar-animated .ui-progressbar-value{-webkit-animation:progressbar-stripes 1.5s linear infinite;-moz-animation:progressbar-stripes 1.5s linear infinite;-ms-animation:progressbar-stripes 1.5s linear infinite;-o-animation:progressbar-stripes 1.5s linear infinite;animation:progressbar-stripes 1.5s linear infinite}
\ No newline at end of file
diff --git a/public/css/custom.css b/public/css/custom.css
deleted file mode 100644
index 3cd0e32..0000000
--- a/public/css/custom.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.success {
- background-color: #a0ff80 !important;
-}
-.warning {
- background-color: #ffe050 !important;
-}
diff --git a/public/fonts/FontAwesome.otf b/public/fonts/FontAwesome.otf
deleted file mode 100644
index 401ec0f..0000000
Binary files a/public/fonts/FontAwesome.otf and /dev/null differ
diff --git a/public/fonts/fontawesome-webfont.eot b/public/fonts/fontawesome-webfont.eot
deleted file mode 100644
index e9f60ca..0000000
Binary files a/public/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/public/fonts/fontawesome-webfont.svg b/public/fonts/fontawesome-webfont.svg
deleted file mode 100644
index 855c845..0000000
--- a/public/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,2671 +0,0 @@
-
-
-
diff --git a/public/fonts/fontawesome-webfont.ttf b/public/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index 35acda2..0000000
Binary files a/public/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/public/fonts/fontawesome-webfont.woff b/public/fonts/fontawesome-webfont.woff
deleted file mode 100644
index 400014a..0000000
Binary files a/public/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/public/fonts/fontawesome-webfont.woff2 b/public/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 4d13fc6..0000000
Binary files a/public/fonts/fontawesome-webfont.woff2 and /dev/null differ
diff --git a/public/fonts/glyphicons-halflings-regular.eot b/public/fonts/glyphicons-halflings-regular.eot
deleted file mode 100644
index b93a495..0000000
Binary files a/public/fonts/glyphicons-halflings-regular.eot and /dev/null differ
diff --git a/public/fonts/glyphicons-halflings-regular.svg b/public/fonts/glyphicons-halflings-regular.svg
deleted file mode 100644
index 94fb549..0000000
--- a/public/fonts/glyphicons-halflings-regular.svg
+++ /dev/null
@@ -1,288 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/public/fonts/glyphicons-halflings-regular.ttf b/public/fonts/glyphicons-halflings-regular.ttf
deleted file mode 100644
index 1413fc6..0000000
Binary files a/public/fonts/glyphicons-halflings-regular.ttf and /dev/null differ
diff --git a/public/fonts/glyphicons-halflings-regular.woff b/public/fonts/glyphicons-halflings-regular.woff
deleted file mode 100644
index 9e61285..0000000
Binary files a/public/fonts/glyphicons-halflings-regular.woff and /dev/null differ
diff --git a/public/fonts/glyphicons-halflings-regular.woff2 b/public/fonts/glyphicons-halflings-regular.woff2
deleted file mode 100644
index 64539b5..0000000
Binary files a/public/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ
diff --git a/public/index.php b/public/index.php
deleted file mode 100644
index b99fc7b..0000000
--- a/public/index.php
+++ /dev/null
@@ -1,288 +0,0 @@
-debug and $this->benchmark) {
- $this->time = microtime(true);
- }
- }
-
- public function stop()
- {
- if ($this->debug and $this->benchmark) {
- $this->time = microtime(true) - $this->time;
- }
- }
-
- public function show()
- {
- if ($this->debug and $this->benchmark) {
- $this->logger->debug("Time {$this->time}");
- echo view('benchmark', ['benchmark' => $this->time]);
- }
- }
-}
-
-class Request
-{
- public function __construct()
- {
- sanitize();
- }
-
- protected array $server;
- protected array $headers;
- protected object $uri;
- protected array $query;
- protected object $body;
-
- public function getServerParams(): array
- {
- return $this->server;
- }
- public function getHeaders(): array
- {
- return $this->headers;
- }
- public function getUri(): object
- {
- return $this->uri;
- }
- public function getQueryParams(): array
- {
- return $this->query;
- }
- public function getBody(): object
- {
- return $this->body;
- }
-
- public static function createFromGlobals(): Request
- {
- $request = new Request();
- $request->server = $_SERVER;
- $request->headers = apache_request_headers();
- $request->uri = (object) parse_url($_SERVER['REQUEST_URI']);
- $request->query = $_GET;
- $request->body = new class() {
- public function __construct()
- {
- $this->contents = fopen('php://stdin', 'r');
- }
-
- protected $contents;
-
- public function getContent(): string
- {
- return stream_get_contents($this->contents);
- }
- };
- return $request;
- }
-}
-
-class Container
-{
- public function __construct(array $definitions = [])
- {
- foreach ($definitions as $name => $value)
- {
- $this->set($name, $value);
- }
- if (!isset($definitions[Container::class])) {
- $this->set(Container::class, $this);
- }
- }
-
- protected array $definitions;
-
- public function get(string $name)
- {
- if (!isset($this->definitions[$name]) and class_exists($name)) {
- $this->set($name, $name);
- }
- return $this->eval($this->definitions[$name]);
- }
-
- public function set(string $name, $value): Container
- {
- $this->definitions[$name] = $value;
- return $this;
- }
-
- protected function eval($value)
- {
- if (is_callable($value)) {
- return $this->evalCallable($value);
- }
- if (is_string($value) and class_exists($value)) {
- return $this->evalNewClass($value);
- }
- return $value;
- }
- protected function evalCallable(callable $value)
- {
- $args = $this->getMethodParameters(new ReflectionFunction($value));
- return call_user_func_array($value, $args);
- }
- protected function evalNewClass(string $class)
- {
- $ref = new reflectionClass($class);
- $args = $this->getMethodParameters($ref->getConstructor());
- return $ref->newInstanceArgs($args);
- }
- protected function getMethodParameters(ReflectionFunctionAbstract $function)
- {
- return array_map(function(ReflectionParameter $parameter) {
- return $this->get($parameter->getType()->getName());
- }, $function->getParameters());
- }
-}
-
-class App
-{
- public function __construct(
- protected Auth $authWrapper,
- protected Request $request,
- protected Monolog\Logger $logger,
- protected Benchmark $benchmark,
- ) {}
-
- public function run()
- {
- header("Access-Control-Allow-Origin: *");
-
- Monolog\ErrorHandler::register($this->logger);
-
- $this->benchmark->start();
-
- Carbon::setLocale(config('app.locale'));
- setlocale(LC_TIME, 'es_ES');
-
- try {
- $this->authWrapper->isIn();
- } catch (PDOException $e) {
- $this->logger->error($e);
- header('Location: install');
- die();
- }
-
- $get = $this->request->getQueryParams();
- try {
- if ($this->authWrapper->isIn()) {
- if ((($get['p'] ?? false) !== false or ($get['page'] ?? false) !== false or ($get['m'] ?? false) !== false or ($get['module'] ?? false) !== false)) {
- if (($route = route()) !== false) {
- echo $route;
- } else {
- echo view('construccion');
- }
- } else {
- $proyectos = model(Proyecto::class)->findMany();
- $dias = [];
- $cierres = [];
- $pendientes = 0;
- $hoy = 0;
- foreach ($proyectos as $proyecto) {
- $pendientes += $proyecto->cuotasPendientes();
- $hoy += $proyecto->cuotasHoy();
- foreach ($proyecto->cuotasMes() as $cuota) {
- $f = $cuota->pago()->fecha();
- if ($f->isoWeekday() == 6 or $f->isoWeekDay() == 7) {
- $f = $f->copy()->addDays(2)->startOfWeek();
- }
- $dia = $f->format('Y-m-d');
- if (!isset($dias[$dia])) {
- $dias[$dia] = [$proyecto->descripcion => 0];
- }
- if (!isset($dias[$dia][$proyecto->descripcion])) {
- $dias[$dia][$proyecto->descripcion] = 0;
- }
- $dias[$dia][$proyecto->descripcion] ++;
- }
- if (count($proyecto->cierres()) > 0) {
- $cierres[$proyecto->descripcion] = (object) ['total' => count($proyecto->cierres()),'vigentes' => $proyecto->cierres(3), 'rechazados' => $proyecto->cierres(-1), 'pendientes' => $proyecto->cierres(2)];
- }
- }
- uksort($dias, function($a, $b) {
- return strcmp($a, $b);
- });
- uksort($cierres, function($a, $b) {
- return strcmp($a, $b);
- });
- echo view('home', compact('pendientes', 'hoy', 'dias', 'cierres'));
- }
- } elseif (($get['p'] ?? false) === 'auth' or ($get['page'] ?? false) === 'auth') {
- $route = route();
- if ($route !== false) {
- echo $route;
- } else {
- echo view('guest');
- }
- } else {
- echo view('guest');
- }
- } catch (Exception $e) {
- $this->logger->warning($e);
- die();
- } catch (Error $e) {
- $this->logger->error($e);
- die();
- }
-
- $this->benchmark->stop();
-
- if (($get['ajax'] ?? false) !== '1' and ($get['p'] ?? false) !== 'ajax' and ($get['p'] ?? false) !== 'informes') {
- $this->benchmark->show();
- }
- }
-}
-
-$container = new Container([
- Monolog\Logger::class => function() {
- return (new Monolog\Logger('global'))
- ->pushHandler((new Handler\FilterHandler(
- (new Handler\RotatingFileHandler('/logs/php.log'))
- ->setFormatter(new Formatter\LineFormatter(null, null, true)),
- Level::Debug,
- Level::Notice
- )))
- ->pushHandler((new Handler\FilterHandler(
- (new Handler\NativeMailerHandler('jpvial@incoviba.cl', 'Error - Incoviba', 'alert@incoviba.cl'))
- ->setFormatter(new Formatter\HtmlFormatter()),
- Level::Warning,
- Level::Emergency
- )))
- ->pushProcessor(new Processor\PsrLogMessageProcessor())
- ->pushProcessor(new Processor\IntrospectionProcessor())
- ->pushProcessor(new Processor\HostnameProcessor())
- ->pushProcessor(new Processor\WebProcessor())
- ->pushProcessor(new Processor\MemoryPeakUsageProcessor());
- },
- Request::class => function() {
- return Request::createFromGlobals();
- },
- Auth::class => function() {
- return new Auth();
- },
- Benchmark::class => function(Container $container) {
- return new Benchmark($container->get(Monolog\Logger::class), config('app.debug'), config('app.benchmark'));
- }
-]);
-
-$app = $container->get(App::class);
-$app->run();
diff --git a/public/install/create_admin.php b/public/install/create_admin.php
deleted file mode 100644
index 5d03999..0000000
--- a/public/install/create_admin.php
+++ /dev/null
@@ -1,40 +0,0 @@
-where('name', post('name'))->findOne();
- if ($user === false) {
- $user = Model::factory(\Incoviba\common\User::class)->create();
- $user->name = post('name');
- $user->password(post('password'));
-
- $user->save();
- echo 'Created';
- }
- $role = Model::factory(\Incoviba\common\Role::class)->where('description', 'administrador')->findOne();
- if ($role == false) {
- $role = Model::factory(\Incoviba\common\Role::class)->create(['description' => 'administrador']);
- $role->save();
- }
- $usrRl = Model::factory(\Incoviba\common\UserRole::class)->where('user', $user->id)->where('role', $role->id)->findOne();
- if ($usrRl == false) {
- $usrRl = Model::factory(\Incoviba\common\UserRole::class)->create(['user' => $user->id, 'role' => $role->id]);
- $usrRl->save();
- }
- $perm = Model::factory(\Incoviba\common\Permission::class)->where('type', 2)->where('ext_id', $role->id)->where('all', 1)->where('access', 1)->findOne();
- if ($perm == false) {
- $perm = Model::factory(\Incoviba\common\Permission::class)->create([
- 'type' => 2,
- 'ext_id' => $role->id,
- 'all' => 1,
- 'access' => 1
- ]);
- $perm->save();
- }
- header('Location: next_step.php?step=create_admin');
-} else {
- echo view('install.admin');
-}
-?>
diff --git a/public/install/create_guest.php b/public/install/create_guest.php
deleted file mode 100644
index 53492ba..0000000
--- a/public/install/create_guest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-where('name', 'guest')->findOne();
-if ($user === false) {
- $user = Model::factory(\Incoviba\common\User::class)->create(['name' => 'guest']);
- $user->save();
-}
-$role = Model::factory(\Incoviba\common\Role::class)->where('description', 'guest')->findOne();
-if ($role === false) {
- $role = Model::factory(\Incoviba\common\Role::class)->create(['description' => 'guest']);
- $role->save();
-}
-$usrRl = Model::factory(\Incoviba\common\UserRole::class)->where('user', $user->id)->where('role', $role->id)->findOne();
-if ($usrRl === false) {
- $usrRl = Model::factory(\Incoviba\common\UserRole::class)->create(['user' => $user->id, 'role' => $role->id]);
- $usrRl->save();
-}
-$locations = Model::factory(\Incoviba\common\Location::class)->where('controller', 'auth')->findMany();
-foreach ($locations as $location) {
- $permission = Model::factory(\Incoviba\common\Permission::class)->where('type', 2)->where('ext_id', $role->id)->where('access', 1)->where('location', $location->id)->findOne();
- if ($permission === false) {
- $permission = Model::factory(\Incoviba\common\Permission::class)->create([
- 'type' => 2,
- 'ext_id' => $role->id,
- 'access' => 1,
- 'location' => $location->id
- ]);
- $permission->save();
- }
-}
-
-header('Location: next_step.php?step=create_guest');
-?>
diff --git a/public/install/create_user_base.php b/public/install/create_user_base.php
deleted file mode 100644
index 4fe56d4..0000000
--- a/public/install/create_user_base.php
+++ /dev/null
@@ -1,128 +0,0 @@
- 0) {
- $q .= ', PRIMARY KEY (' . implode(', ', $keys) . ')';
- }
- if (count($foreigns) > 0) {
- $q .= ', CONSTRAINT ' . implode(', CONSTRAINT ', $foreigns);
- }
- $q .= ') ENGINE=InnoDB DEFAULT CHARSET=utf8;';
-
- return $q;
-}
-
-$cnt = 0;
-$queries = [];
-foreach ($models as $model) {
- $class = '\\Incoviba\\common\\' . $model;
- $ref = new ReflectionClass($class);
-
- $table = $ref->getProperty('_table')->getValue();
- $comments = explode(PHP_EOL, $ref->getDocComment());
-
- $columns = [];
- $keys = [];
- $foreigns = [];
- foreach ($comments as $comment) {
- if (strpos($comment, '@property') === false) {
- continue;
- }
- $info = explode(' ', substr($comment, strpos($comment, '@property') + strlen('@property ')));
- $column = extractColumn($table, $info, $keys, $foreigns);
-
- $columns []= columnQuery($column);
- }
-
- $q = tableQuery($table, $columns, $keys, $foreigns);
- $queries []= $q;
-}
-try {
- \ORM::getDb()->beginTransaction();
- foreach ($queries as $q) {
- \ORM::getDb()->query($q);
- }
- \ORM::getDb()->commit();
- header('Location: next_step.php?step=create_user_base');
-} catch (Exception $e) {
- \ORM::getDb()->rollBack();
- throw $e;
-}
-?>
diff --git a/public/install/end_install.php b/public/install/end_install.php
deleted file mode 100644
index 94eafcc..0000000
--- a/public/install/end_install.php
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/public/install/index.php b/public/install/index.php
deleted file mode 100644
index 9a5d75c..0000000
--- a/public/install/index.php
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/public/install/log_locations.php b/public/install/log_locations.php
deleted file mode 100644
index 9de5bc5..0000000
--- a/public/install/log_locations.php
+++ /dev/null
@@ -1,39 +0,0 @@
-underscored();
- $class = '\\App\\Controller\\' . $name;
- $ref = new ReflectionClass($class);
- $methods = $ref->getMethods(ReflectionMethod::IS_STATIC);
-
- try {
- foreach ($methods as $method) {
- $data = [
- 'controller' => $controller,
- 'action' => $method->name
- ];
- $location = Model::factory(\Incoviba\common\Location::class)->where('controller', $controller)->where('action', $method->name)->findOne();
- if ($location !== false) {
- continue;
- }
-
- $location = Model::factory(\Incoviba\common\Location::class)->create($data);
- $location->save();
- $cnt ++;
- }
- } catch (Exception $e) {
- d($e);
- $errors ++;
- }
-}
-
-if ($errors == 0) {
- header('Location: next_step.php?step=log_locations');
-}
-?>
diff --git a/public/install/next_step.php b/public/install/next_step.php
deleted file mode 100644
index c370b67..0000000
--- a/public/install/next_step.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/public/js/admin.js b/public/js/admin.js
deleted file mode 100644
index a5a69bc..0000000
--- a/public/js/admin.js
+++ /dev/null
@@ -1,81 +0,0 @@
-$(document).ready(function() {
- $('#databases').submit(function(e) {
- e.preventDefault();
-
- var db = $("[name='database']").val();
- var models = [];
- var namespaces = [];
- $.post('?p=admin&action=listModels', {"database": db}).done(function(data) {
- //console.debug(data);
- var info = $.parseJSON(data);
- //console.debug(info.models);
-
- models = info.models;
- //console.debug(models);
-
- $.post('?p=admin&action=listNamespaces').done(function(data) {
- //console.debug(data);
- info = $.parseJSON(data);
- //console.debug(info.models);
-
- namespaces = info.namespaces;
- //console.debug(namespaces);
-
- $.each(models, function(i, elem) {
- var div = $('').attr('class', 'row');
- div.append($('').attr('class', 'col-md-2').html(elem.model));
- var div2 = $('').attr('class', 'row');
- $.each(namespaces, function(j, ns) {
- div2.append($('').attr('class', 'col-md-3').append($('').attr('class', 'ns').attr('data-table', elem.table).attr('data-ns', ns).html(ns)));
- });
- div.append($('').attr('class', 'col-md-9').append(div2));
- div.append($('').attr('class', 'col-md-1 remove').append($('').attr('class', 'glyphicon glyphicon-remove')));
- $('#results').append(div);
- });
-
- $('.ns').css('cursor', 'pointer');
- $('.remove').css('cursor', 'pointer');
-
- $('.ns').mouseover(function(e) {
- $(this).parent().addClass('bg-success');
- $(this).parent().parent().parent().parent().addClass('bg-warning');
- }).mouseout(function(e) {
- $(this).parent().removeClass('bg-success');
- $(this).parent().parent().parent().parent().removeClass('bg-warning');
- });
-
- $('.remove').mouseover(function(e) {
- $(this).parent().addClass('bg-danger');
- }).mouseout(function(e) {
- $(this).parent().removeClass('bg-danger');
- });
-
- $('.ns').click(function(e) {
- var table = $(this).attr('data-table');
- var ns = $(this).attr('data-ns');
- execute(table, ns);
- });
- $('.remove').click(function(e) {
- $(this).parent().remove();
- });
- });
- });
-
- return false;
- });
-});
-
-function execute(table, ns) {
- console.debug(table, ns);
- var db = $("[name='database']").val();
- $.post('?p=admin&action=createModel', {"table": table, "namespace": ns, "database": db}).done(function(data) {
- console.debug(data);
- var info = $.parseJSON(data);
- console.debug(info);
- if (info.result) {
- $(".ns[data-table='" + table + "']").parent().parent().parent().parent().remove();
- } else {
- alert('Error');
- }
- });
-}
\ No newline at end of file
diff --git a/public/js/app.js b/public/js/app.js
deleted file mode 100644
index 7e4c9f3..0000000
--- a/public/js/app.js
+++ /dev/null
@@ -1,89 +0,0 @@
-!function(e){var a={};function i(t){if(a[t])return a[t].exports;var n=a[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=e,i.c=a,i.d=function(e,a,t){i.o(e,a)||Object.defineProperty(e,a,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,a){if(1&a&&(e=i(e)),8&a)return e;if(4&a&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&a&&"string"!=typeof e)for(var n in e)i.d(t,n,function(a){return e[a]}.bind(null,n));return t},i.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(a,"a",a),a},i.o=function(e,a){return Object.prototype.hasOwnProperty.call(e,a)},i.p="",i(i.s=219)}([function(e,a,i){(function(e){e.exports=function(){"use strict";var a,t;function n(){return a.apply(null,arguments)}function r(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function s(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function o(e){return void 0===e}function l(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function c(e,a){var i,t=[];for(i=0;i>>0,t=0;t0)for(i=0;i=0;return(r?i?"+":"":"-")+Math.pow(10,Math.max(0,n)).toString().substr(1)+t}var I=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,F=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,N={},R={};function $(e,a,i,t){var n=t;"string"==typeof t&&(n=function(){return this[t]()}),e&&(R[e]=n),a&&(R[a[0]]=function(){return W(n.apply(this,arguments),a[1],a[2])}),i&&(R[i]=function(){return this.localeData().ordinal(n.apply(this,arguments),e)})}function B(e){return e.match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"")}function V(e,a){return e.isValid()?(a=U(a,e.localeData()),N[a]=N[a]||function(e){var a,i,t=e.match(I);for(a=0,i=t.length;a=0&&F.test(e);)e=e.replace(F,t),F.lastIndex=0,i-=1;return e}var J=/\d/,G=/\d\d/,K=/\d{3}/,Z=/\d{4}/,X=/[+-]?\d{6}/,Q=/\d\d?/,ee=/\d\d\d\d?/,ae=/\d\d\d\d\d\d?/,ie=/\d{1,3}/,te=/\d{1,4}/,ne=/[+-]?\d{1,6}/,re=/\d+/,se=/[+-]?\d+/,oe=/Z|[+-]\d\d:?\d\d/gi,le=/Z|[+-]\d\d(?::?\d\d)?/gi,de=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ce={};function ue(e,a,i){ce[e]=T(a)?a:function(e,t){return e&&i?i:a}}function me(e,a){return u(ce,e)?ce[e](a._strict,a._locale):new RegExp(function(e){return he(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,a,i,t,n){return a||i||t||n}))}(e))}function he(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ge={};function pe(e,a){var i,t=a;for("string"==typeof e&&(e=[e]),l(a)&&(t=function(e,i){i[a]=x(e)}),i=0;i68?1900:2e3)};var De,Te=qe("FullYear",!0);function qe(e,a){return function(i){return null!=i?(He(this,e,i),n.updateOffset(this,a),this):Se(this,e)}}function Se(e,a){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+a]():NaN}function He(e,a,i){e.isValid()&&!isNaN(i)&&("FullYear"===a&&Ye(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+a](i,e.month(),Ce(i,e.month())):e._d["set"+(e._isUTC?"UTC":"")+a](i))}function Ce(e,a){if(isNaN(e)||isNaN(a))return NaN;var i=function(e,a){return(e%a+a)%a}(a,12);return e+=(a-i)/12,1===i?Ye(e)?29:28:31-i%7%2}De=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var a;for(a=0;a=0&&isFinite(a.getUTCFullYear())&&a.setUTCFullYear(e),a}function $e(e,a,i){var t=7+a-i,n=(7+Re(e,0,t).getUTCDay()-a)%7;return-n+t-1}function Be(e,a,i,t,n){var r,s,o=(7+i-t)%7,l=$e(e,t,n),d=1+7*(a-1)+o+l;return d<=0?s=Le(r=e-1)+d:d>Le(e)?(r=e+1,s=d-Le(e)):(r=e,s=d),{year:r,dayOfYear:s}}function Ve(e,a,i){var t,n,r=$e(e.year(),a,i),s=Math.floor((e.dayOfYear()-r-1)/7)+1;return s<1?(n=e.year()-1,t=s+Ue(n,a,i)):s>Ue(e.year(),a,i)?(t=s-Ue(e.year(),a,i),n=e.year()+1):(n=e.year(),t=s),{week:t,year:n}}function Ue(e,a,i){var t=$e(e,a,i),n=$e(e+1,a,i);return(Le(e)-t+n)/7}$("w",["ww",2],"wo","week"),$("W",["WW",2],"Wo","isoWeek"),C("week","w"),C("isoWeek","W"),E("week",5),E("isoWeek",5),ue("w",Q),ue("ww",Q,G),ue("W",Q),ue("WW",Q,G),be(["w","ww","W","WW"],function(e,a,i,t){a[t.substr(0,1)]=x(e)}),$("d",0,"do","day"),$("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),$("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),$("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),$("e",0,0,"weekday"),$("E",0,0,"isoWeekday"),C("day","d"),C("weekday","e"),C("isoWeekday","E"),E("day",11),E("weekday",11),E("isoWeekday",11),ue("d",Q),ue("e",Q),ue("E",Q),ue("dd",function(e,a){return a.weekdaysMinRegex(e)}),ue("ddd",function(e,a){return a.weekdaysShortRegex(e)}),ue("dddd",function(e,a){return a.weekdaysRegex(e)}),be(["dd","ddd","dddd"],function(e,a,i,t){var n=i._locale.weekdaysParse(e,t,i._strict);null!=n?a.d=n:g(i).invalidWeekday=e}),be(["d","e","E"],function(e,a,i,t){a[t]=x(e)});var Je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ge="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ke="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ze=de,Xe=de,Qe=de;function ea(){function e(e,a){return a.length-e.length}var a,i,t,n,r,s=[],o=[],l=[],d=[];for(a=0;a<7;a++)i=h([2e3,1]).day(a),t=this.weekdaysMin(i,""),n=this.weekdaysShort(i,""),r=this.weekdays(i,""),s.push(t),o.push(n),l.push(r),d.push(t),d.push(n),d.push(r);for(s.sort(e),o.sort(e),l.sort(e),d.sort(e),a=0;a<7;a++)o[a]=he(o[a]),l[a]=he(l[a]),d[a]=he(d[a]);this._weekdaysRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+s.join("|")+")","i")}function aa(){return this.hours()%12||12}function ia(e,a){$(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function ta(e,a){return a._meridiemParse}$("H",["HH",2],0,"hour"),$("h",["hh",2],0,aa),$("k",["kk",2],0,function(){return this.hours()||24}),$("hmm",0,0,function(){return""+aa.apply(this)+W(this.minutes(),2)}),$("hmmss",0,0,function(){return""+aa.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),$("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),$("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),ia("a",!0),ia("A",!1),C("hour","h"),E("hour",13),ue("a",ta),ue("A",ta),ue("H",Q),ue("h",Q),ue("k",Q),ue("HH",Q,G),ue("hh",Q,G),ue("kk",Q,G),ue("hmm",ee),ue("hmmss",ae),ue("Hmm",ee),ue("Hmmss",ae),pe(["H","HH"],we),pe(["k","kk"],function(e,a,i){var t=x(e);a[we]=24===t?0:t}),pe(["a","A"],function(e,a,i){i._isPm=i._locale.isPM(e),i._meridiem=e}),pe(["h","hh"],function(e,a,i){a[we]=x(e),g(i).bigHour=!0}),pe("hmm",function(e,a,i){var t=e.length-2;a[we]=x(e.substr(0,t)),a[_e]=x(e.substr(t)),g(i).bigHour=!0}),pe("hmmss",function(e,a,i){var t=e.length-4,n=e.length-2;a[we]=x(e.substr(0,t)),a[_e]=x(e.substr(t,2)),a[xe]=x(e.substr(n)),g(i).bigHour=!0}),pe("Hmm",function(e,a,i){var t=e.length-2;a[we]=x(e.substr(0,t)),a[_e]=x(e.substr(t))}),pe("Hmmss",function(e,a,i){var t=e.length-4,n=e.length-2;a[we]=x(e.substr(0,t)),a[_e]=x(e.substr(t,2)),a[xe]=x(e.substr(n))});var na,ra=qe("Hours",!0),sa={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Pe,monthsShort:Oe,week:{dow:0,doy:6},weekdays:Je,weekdaysMin:Ke,weekdaysShort:Ge,meridiemParse:/[ap]\.?m?\.?/i},oa={},la={};function da(e){return e?e.toLowerCase().replace("_","-"):e}function ca(a){var t=null;if(!oa[a]&&void 0!==e&&e&&e.exports)try{t=na._abbr,i(168)("./"+a),ua(t)}catch(e){}return oa[a]}function ua(e,a){var i;return e&&((i=o(a)?ha(e):ma(e,a))?na=i:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),na._abbr}function ma(e,a){if(null!==a){var i,t=sa;if(a.abbr=e,null!=oa[e])D("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=oa[e]._config;else if(null!=a.parentLocale)if(null!=oa[a.parentLocale])t=oa[a.parentLocale]._config;else{if(null==(i=ca(a.parentLocale)))return la[a.parentLocale]||(la[a.parentLocale]=[]),la[a.parentLocale].push({name:e,config:a}),null;t=i._config}return oa[e]=new S(q(t,a)),la[e]&&la[e].forEach(function(e){ma(e.name,e.config)}),ua(e),oa[e]}return delete oa[e],null}function ha(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return na;if(!r(e)){if(a=ca(e))return a;e=[e]}return function(e){for(var a,i,t,n,r=0;r0;){if(t=ca(n.slice(0,a).join("-")))return t;if(i&&i.length>=a&&j(n,i,!0)>=a-1)break;a--}r++}return na}(e)}function ga(e){var a,i=e._a;return i&&-2===g(e).overflow&&(a=i[ke]<0||i[ke]>11?ke:i[ve]<1||i[ve]>Ce(i[ye],i[ke])?ve:i[we]<0||i[we]>24||24===i[we]&&(0!==i[_e]||0!==i[xe]||0!==i[je])?we:i[_e]<0||i[_e]>59?_e:i[xe]<0||i[xe]>59?xe:i[je]<0||i[je]>999?je:-1,g(e)._overflowDayOfYear&&(ave)&&(a=ve),g(e)._overflowWeeks&&-1===a&&(a=ze),g(e)._overflowWeekday&&-1===a&&(a=Me),g(e).overflow=a),e}function pa(e,a,i){return null!=e?e:null!=a?a:i}function ba(e){var a,i,t,r,s,o=[];if(!e._d){for(t=function(e){var a=new Date(n.now());return e._useUTC?[a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()]:[a.getFullYear(),a.getMonth(),a.getDate()]}(e),e._w&&null==e._a[ve]&&null==e._a[ke]&&function(e){var a,i,t,n,r,s,o,l;if(null!=(a=e._w).GG||null!=a.W||null!=a.E)r=1,s=4,i=pa(a.GG,e._a[ye],Ve(qa(),1,4).year),t=pa(a.W,1),((n=pa(a.E,1))<1||n>7)&&(l=!0);else{r=e._locale._week.dow,s=e._locale._week.doy;var d=Ve(qa(),r,s);i=pa(a.gg,e._a[ye],d.year),t=pa(a.w,d.week),null!=a.d?((n=a.d)<0||n>6)&&(l=!0):null!=a.e?(n=a.e+r,(a.e<0||a.e>6)&&(l=!0)):n=r}t<1||t>Ue(i,r,s)?g(e)._overflowWeeks=!0:null!=l?g(e)._overflowWeekday=!0:(o=Be(i,t,n,r,s),e._a[ye]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(s=pa(e._a[ye],t[ye]),(e._dayOfYear>Le(s)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),i=Re(s,0,e._dayOfYear),e._a[ke]=i.getUTCMonth(),e._a[ve]=i.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=o[a]=t[a];for(;a<7;a++)e._a[a]=o[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[we]&&0===e._a[_e]&&0===e._a[xe]&&0===e._a[je]&&(e._nextDay=!0,e._a[we]=0),e._d=(e._useUTC?Re:function(e,a,i,t,n,r,s){var o=new Date(e,a,i,t,n,r,s);return e<100&&e>=0&&isFinite(o.getFullYear())&&o.setFullYear(e),o}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[we]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(g(e).weekdayMismatch=!0)}}var fa=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ya=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ka=/Z|[+-]\d\d(?::?\d\d)?/,va=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],wa=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],_a=/^\/?Date\((\-?\d+)/i;function xa(e){var a,i,t,n,r,s,o=e._i,l=fa.exec(o)||ya.exec(o);if(l){for(g(e).iso=!0,a=0,i=va.length;a0&&g(e).unusedInput.push(s),o=o.slice(o.indexOf(i)+i.length),d+=i.length),R[r]?(i?g(e).empty=!1:g(e).unusedTokens.push(r),fe(r,i,e)):e._strict&&!i&&g(e).unusedTokens.push(r);g(e).charsLeftOver=l-d,o.length>0&&g(e).unusedInput.push(o),e._a[we]<=12&&!0===g(e).bigHour&&e._a[we]>0&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[we]=function(e,a,i){var t;return null==i?a:null!=e.meridiemHour?e.meridiemHour(a,i):null!=e.isPM?((t=e.isPM(i))&&a<12&&(a+=12),t||12!==a||(a=0),a):a}(e._locale,e._a[we],e._meridiem),ba(e),ga(e)}else La(e);else xa(e)}function Da(e){var a=e._i,i=e._f;return e._locale=e._locale||ha(e._l),null===a||void 0===i&&""===a?b({nullInput:!0}):("string"==typeof a&&(e._i=a=e._locale.preparse(a)),w(a)?new v(ga(a)):(d(a)?e._d=a:r(i)?function(e){var a,i,t,n,r;if(0===e._f.length)return g(e).invalidFormat=!0,void(e._d=new Date(NaN));for(n=0;nthis?this:e:b()});function Ca(e,a){var i,t;if(1===a.length&&r(a[0])&&(a=a[0]),!a.length)return qa();for(i=a[0],t=1;tr&&(a=r),function(e,a,i,t,n){var r=Be(e,a,i,t,n),s=Re(r.year,0,r.dayOfYear);return this.year(s.getUTCFullYear()),this.month(s.getUTCMonth()),this.date(s.getUTCDate()),this}.call(this,e,a,i,t,n))}$(0,["gg",2],0,function(){return this.weekYear()%100}),$(0,["GG",2],0,function(){return this.isoWeekYear()%100}),ni("gggg","weekYear"),ni("ggggg","weekYear"),ni("GGGG","isoWeekYear"),ni("GGGGG","isoWeekYear"),C("weekYear","gg"),C("isoWeekYear","GG"),E("weekYear",1),E("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",Q,G),ue("gg",Q,G),ue("GGGG",te,Z),ue("gggg",te,Z),ue("GGGGG",ne,X),ue("ggggg",ne,X),be(["gggg","ggggg","GGGG","GGGGG"],function(e,a,i,t){a[t.substr(0,2)]=x(e)}),be(["gg","GG"],function(e,a,i,t){a[t]=n.parseTwoDigitYear(e)}),$("Q",0,"Qo","quarter"),C("quarter","Q"),E("quarter",7),ue("Q",J),pe("Q",function(e,a){a[ke]=3*(x(e)-1)}),$("D",["DD",2],"Do","date"),C("date","D"),E("date",9),ue("D",Q),ue("DD",Q,G),ue("Do",function(e,a){return e?a._dayOfMonthOrdinalParse||a._ordinalParse:a._dayOfMonthOrdinalParseLenient}),pe(["D","DD"],ve),pe("Do",function(e,a){a[ve]=x(e.match(Q)[0])});var si=qe("Date",!0);$("DDD",["DDDD",3],"DDDo","dayOfYear"),C("dayOfYear","DDD"),E("dayOfYear",4),ue("DDD",ie),ue("DDDD",K),pe(["DDD","DDDD"],function(e,a,i){i._dayOfYear=x(e)}),$("m",["mm",2],0,"minute"),C("minute","m"),E("minute",14),ue("m",Q),ue("mm",Q,G),pe(["m","mm"],_e);var oi=qe("Minutes",!1);$("s",["ss",2],0,"second"),C("second","s"),E("second",15),ue("s",Q),ue("ss",Q,G),pe(["s","ss"],xe);var li,di=qe("Seconds",!1);for($("S",0,0,function(){return~~(this.millisecond()/100)}),$(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),$(0,["SSS",3],0,"millisecond"),$(0,["SSSS",4],0,function(){return 10*this.millisecond()}),$(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),$(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),$(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),$(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),$(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),C("millisecond","ms"),E("millisecond",16),ue("S",ie,J),ue("SS",ie,G),ue("SSS",ie,K),li="SSSS";li.length<=9;li+="S")ue(li,re);function ci(e,a){a[je]=x(1e3*("0."+e))}for(li="S";li.length<=9;li+="S")pe(li,ci);var ui=qe("Milliseconds",!1);$("z",0,0,"zoneAbbr"),$("zz",0,0,"zoneName");var mi=v.prototype;function hi(e){return e}mi.add=Xa,mi.calendar=function(e,a){var i=e||qa(),t=Na(i,this).startOf("day"),r=n.calendarFormat(this,t)||"sameElse",s=a&&(T(a[r])?a[r].call(this,i):a[r]);return this.format(s||this.localeData().calendar(r,this,qa(i)))},mi.clone=function(){return new v(this)},mi.diff=function(e,a,i){var t,n,r;if(!this.isValid())return NaN;if(!(t=Na(e,this)).isValid())return NaN;switch(n=6e4*(t.utcOffset()-this.utcOffset()),a=A(a)){case"year":r=ei(this,t)/12;break;case"month":r=ei(this,t);break;case"quarter":r=ei(this,t)/3;break;case"second":r=(this-t)/1e3;break;case"minute":r=(this-t)/6e4;break;case"hour":r=(this-t)/36e5;break;case"day":r=(this-t-n)/864e5;break;case"week":r=(this-t-n)/6048e5;break;default:r=this-t}return i?r:_(r)},mi.endOf=function(e){return void 0===(e=A(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},mi.format=function(e){e||(e=this.isUtc()?n.defaultFormatUtc:n.defaultFormat);var a=V(this,e);return this.localeData().postformat(a)},mi.from=function(e,a){return this.isValid()&&(w(e)&&e.isValid()||qa(e).isValid())?Ua({to:this,from:e}).locale(this.locale()).humanize(!a):this.localeData().invalidDate()},mi.fromNow=function(e){return this.from(qa(),e)},mi.to=function(e,a){return this.isValid()&&(w(e)&&e.isValid()||qa(e).isValid())?Ua({from:this,to:e}).locale(this.locale()).humanize(!a):this.localeData().invalidDate()},mi.toNow=function(e){return this.to(qa(),e)},mi.get=function(e){return T(this[e=A(e)])?this[e]():this},mi.invalidAt=function(){return g(this).overflow},mi.isAfter=function(e,a){var i=w(e)?e:qa(e);return!(!this.isValid()||!i.isValid())&&("millisecond"===(a=A(o(a)?"millisecond":a))?this.valueOf()>i.valueOf():i.valueOf()9999?V(i,a?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):T(Date.prototype.toISOString)?a?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",V(i,"Z")):V(i,a?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},mi.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",a="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",a="Z");var i="["+e+'("]',t=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=a+'[")]';return this.format(i+t+"-MM-DD[T]HH:mm:ss.SSS"+n)},mi.toJSON=function(){return this.isValid()?this.toISOString():null},mi.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},mi.unix=function(){return Math.floor(this.valueOf()/1e3)},mi.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},mi.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},mi.year=Te,mi.isLeapYear=function(){return Ye(this.year())},mi.weekYear=function(e){return ri.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},mi.isoWeekYear=function(e){return ri.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},mi.quarter=mi.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},mi.month=We,mi.daysInMonth=function(){return Ce(this.year(),this.month())},mi.week=mi.weeks=function(e){var a=this.localeData().week(this);return null==e?a:this.add(7*(e-a),"d")},mi.isoWeek=mi.isoWeeks=function(e){var a=Ve(this,1,4).week;return null==e?a:this.add(7*(e-a),"d")},mi.weeksInYear=function(){var e=this.localeData()._week;return Ue(this.year(),e.dow,e.doy)},mi.isoWeeksInYear=function(){return Ue(this.year(),1,4)},mi.date=si,mi.day=mi.days=function(e){if(!this.isValid())return null!=e?this:NaN;var a=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=function(e,a){return"string"!=typeof e?e:isNaN(e)?"number"==typeof(e=a.weekdaysParse(e))?e:null:parseInt(e,10)}(e,this.localeData()),this.add(e-a,"d")):a},mi.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var a=(this.day()+7-this.localeData()._week.dow)%7;return null==e?a:this.add(e-a,"d")},mi.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var a=function(e,a){return"string"==typeof e?a.weekdaysParse(e)%7||7:isNaN(e)?null:e}(e,this.localeData());return this.day(this.day()%7?a:a-7)}return this.day()||7},mi.dayOfYear=function(e){var a=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?a:this.add(e-a,"d")},mi.hour=mi.hours=ra,mi.minute=mi.minutes=oi,mi.second=mi.seconds=di,mi.millisecond=mi.milliseconds=ui,mi.utcOffset=function(e,a,i){var t,r=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Fa(le,e)))return this}else Math.abs(e)<16&&!i&&(e*=60);return!this._isUTC&&a&&(t=Ra(this)),this._offset=e,this._isUTC=!0,null!=t&&this.add(t,"m"),r!==e&&(!a||this._changeInProgress?Za(this,Ua(e-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,n.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ra(this)},mi.utc=function(e){return this.utcOffset(0,e)},mi.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Ra(this),"m")),this},mi.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Fa(oe,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},mi.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?qa(e).utcOffset():0,(this.utcOffset()-e)%60==0)},mi.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},mi.isLocal=function(){return!!this.isValid()&&!this._isUTC},mi.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},mi.isUtc=$a,mi.isUTC=$a,mi.zoneAbbr=function(){return this._isUTC?"UTC":""},mi.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},mi.dates=M("dates accessor is deprecated. Use date instead.",si),mi.months=M("months accessor is deprecated. Use month instead",We),mi.years=M("years accessor is deprecated. Use year instead",Te),mi.zone=M("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),mi.isDSTShifted=M("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e={};if(y(e,this),(e=Da(e))._a){var a=e._isUTC?h(e._a):qa(e._a);this._isDSTShifted=this.isValid()&&j(e._a,a.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var gi=S.prototype;function pi(e,a,i,t){var n=ha(),r=h().set(t,a);return n[i](r,e)}function bi(e,a,i){if(l(e)&&(a=e,e=void 0),e=e||"",null!=a)return pi(e,a,i,"month");var t,n=[];for(t=0;t<12;t++)n[t]=pi(e,t,i,"month");return n}function fi(e,a,i,t){"boolean"==typeof e?(l(a)&&(i=a,a=void 0),a=a||""):(i=a=e,e=!1,l(a)&&(i=a,a=void 0),a=a||"");var n,r=ha(),s=e?r._week.dow:0;if(null!=i)return pi(a,(i+s)%7,t,"day");var o=[];for(n=0;n<7;n++)o[n]=pi(a,(n+s)%7,t,"day");return o}gi.calendar=function(e,a,i){var t=this._calendar[e]||this._calendar.sameElse;return T(t)?t.call(a,i):t},gi.longDateFormat=function(e){var a=this._longDateFormat[e],i=this._longDateFormat[e.toUpperCase()];return a||!i?a:(this._longDateFormat[e]=i.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},gi.invalidDate=function(){return this._invalidDate},gi.ordinal=function(e){return this._ordinal.replace("%d",e)},gi.preparse=hi,gi.postformat=hi,gi.relativeTime=function(e,a,i,t){var n=this._relativeTime[i];return T(n)?n(e,a,i,t):n.replace(/%d/i,e)},gi.pastFuture=function(e,a){var i=this._relativeTime[e>0?"future":"past"];return T(i)?i(a):i.replace(/%s/i,a)},gi.set=function(e){var a,i;for(i in e)T(a=e[i])?this[i]=a:this["_"+i]=a;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},gi.months=function(e,a){return e?r(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||Ae).test(a)?"format":"standalone"][e.month()]:r(this._months)?this._months:this._months.standalone},gi.monthsShort=function(e,a){return e?r(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[Ae.test(a)?"format":"standalone"][e.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},gi.monthsParse=function(e,a,i){var t,n,r;if(this._monthsParseExact)return function(e,a,i){var t,n,r,s=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],t=0;t<12;++t)r=h([2e3,t]),this._shortMonthsParse[t]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[t]=this.months(r,"").toLocaleLowerCase();return i?"MMM"===a?-1!==(n=De.call(this._shortMonthsParse,s))?n:null:-1!==(n=De.call(this._longMonthsParse,s))?n:null:"MMM"===a?-1!==(n=De.call(this._shortMonthsParse,s))?n:-1!==(n=De.call(this._longMonthsParse,s))?n:null:-1!==(n=De.call(this._longMonthsParse,s))?n:-1!==(n=De.call(this._shortMonthsParse,s))?n:null}.call(this,e,a,i);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),t=0;t<12;t++){if(n=h([2e3,t]),i&&!this._longMonthsParse[t]&&(this._longMonthsParse[t]=new RegExp("^"+this.months(n,"").replace(".","")+"$","i"),this._shortMonthsParse[t]=new RegExp("^"+this.monthsShort(n,"").replace(".","")+"$","i")),i||this._monthsParse[t]||(r="^"+this.months(n,"")+"|^"+this.monthsShort(n,""),this._monthsParse[t]=new RegExp(r.replace(".",""),"i")),i&&"MMMM"===a&&this._longMonthsParse[t].test(e))return t;if(i&&"MMM"===a&&this._shortMonthsParse[t].test(e))return t;if(!i&&this._monthsParse[t].test(e))return t}},gi.monthsRegex=function(e){return this._monthsParseExact?(u(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(u(this,"_monthsRegex")||(this._monthsRegex=Fe),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},gi.monthsShortRegex=function(e){return this._monthsParseExact?(u(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(u(this,"_monthsShortRegex")||(this._monthsShortRegex=Ie),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},gi.week=function(e){return Ve(e,this._week.dow,this._week.doy).week},gi.firstDayOfYear=function(){return this._week.doy},gi.firstDayOfWeek=function(){return this._week.dow},gi.weekdays=function(e,a){return e?r(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(a)?"format":"standalone"][e.day()]:r(this._weekdays)?this._weekdays:this._weekdays.standalone},gi.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},gi.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},gi.weekdaysParse=function(e,a,i){var t,n,r;if(this._weekdaysParseExact)return function(e,a,i){var t,n,r,s=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],t=0;t<7;++t)r=h([2e3,1]).day(t),this._minWeekdaysParse[t]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[t]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[t]=this.weekdays(r,"").toLocaleLowerCase();return i?"dddd"===a?-1!==(n=De.call(this._weekdaysParse,s))?n:null:"ddd"===a?-1!==(n=De.call(this._shortWeekdaysParse,s))?n:null:-1!==(n=De.call(this._minWeekdaysParse,s))?n:null:"dddd"===a?-1!==(n=De.call(this._weekdaysParse,s))?n:-1!==(n=De.call(this._shortWeekdaysParse,s))?n:-1!==(n=De.call(this._minWeekdaysParse,s))?n:null:"ddd"===a?-1!==(n=De.call(this._shortWeekdaysParse,s))?n:-1!==(n=De.call(this._weekdaysParse,s))?n:-1!==(n=De.call(this._minWeekdaysParse,s))?n:null:-1!==(n=De.call(this._minWeekdaysParse,s))?n:-1!==(n=De.call(this._weekdaysParse,s))?n:-1!==(n=De.call(this._shortWeekdaysParse,s))?n:null}.call(this,e,a,i);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),t=0;t<7;t++){if(n=h([2e3,1]).day(t),i&&!this._fullWeekdaysParse[t]&&(this._fullWeekdaysParse[t]=new RegExp("^"+this.weekdays(n,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[t]=new RegExp("^"+this.weekdaysShort(n,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[t]=new RegExp("^"+this.weekdaysMin(n,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[t]||(r="^"+this.weekdays(n,"")+"|^"+this.weekdaysShort(n,"")+"|^"+this.weekdaysMin(n,""),this._weekdaysParse[t]=new RegExp(r.replace(".",""),"i")),i&&"dddd"===a&&this._fullWeekdaysParse[t].test(e))return t;if(i&&"ddd"===a&&this._shortWeekdaysParse[t].test(e))return t;if(i&&"dd"===a&&this._minWeekdaysParse[t].test(e))return t;if(!i&&this._weekdaysParse[t].test(e))return t}},gi.weekdaysRegex=function(e){return this._weekdaysParseExact?(u(this,"_weekdaysRegex")||ea.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(u(this,"_weekdaysRegex")||(this._weekdaysRegex=Ze),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},gi.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(u(this,"_weekdaysRegex")||ea.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(u(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Xe),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},gi.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(u(this,"_weekdaysRegex")||ea.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(u(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Qe),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},gi.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},gi.meridiem=function(e,a,i){return e>11?i?"pm":"PM":i?"am":"AM"},ua("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var a=e%10,i=1===x(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+i}}),n.lang=M("moment.lang is deprecated. Use moment.locale instead.",ua),n.langData=M("moment.langData is deprecated. Use moment.localeData instead.",ha);var yi=Math.abs;function ki(e,a,i,t){var n=Ua(a,i);return e._milliseconds+=t*n._milliseconds,e._days+=t*n._days,e._months+=t*n._months,e._bubble()}function vi(e){return e<0?Math.floor(e):Math.ceil(e)}function wi(e){return 4800*e/146097}function _i(e){return 146097*e/4800}function xi(e){return function(){return this.as(e)}}var ji=xi("ms"),zi=xi("s"),Mi=xi("m"),Li=xi("h"),Yi=xi("d"),Di=xi("w"),Ti=xi("M"),qi=xi("y");function Si(e){return function(){return this.isValid()?this._data[e]:NaN}}var Hi=Si("milliseconds"),Ci=Si("seconds"),Ai=Si("minutes"),Pi=Si("hours"),Oi=Si("days"),Ei=Si("months"),Wi=Si("years"),Ii=Math.round,Fi={ss:44,s:45,m:45,h:22,d:26,M:11},Ni=Math.abs;function Ri(e){return(e>0)-(e<0)||+e}function $i(){if(!this.isValid())return this.localeData().invalidDate();var e,a,i=Ni(this._milliseconds)/1e3,t=Ni(this._days),n=Ni(this._months);e=_(i/60),a=_(e/60),i%=60,e%=60;var r=_(n/12),s=n%=12,o=t,l=a,d=e,c=i?i.toFixed(3).replace(/\.?0+$/,""):"",u=this.asSeconds();if(!u)return"P0D";var m=u<0?"-":"",h=Ri(this._months)!==Ri(u)?"-":"",g=Ri(this._days)!==Ri(u)?"-":"",p=Ri(this._milliseconds)!==Ri(u)?"-":"";return m+"P"+(r?h+r+"Y":"")+(s?h+s+"M":"")+(o?g+o+"D":"")+(l||d||c?"T":"")+(l?p+l+"H":"")+(d?p+d+"M":"")+(c?p+c+"S":"")}var Bi=Pa.prototype;return Bi.isValid=function(){return this._isValid},Bi.abs=function(){var e=this._data;return this._milliseconds=yi(this._milliseconds),this._days=yi(this._days),this._months=yi(this._months),e.milliseconds=yi(e.milliseconds),e.seconds=yi(e.seconds),e.minutes=yi(e.minutes),e.hours=yi(e.hours),e.months=yi(e.months),e.years=yi(e.years),this},Bi.add=function(e,a){return ki(this,e,a,1)},Bi.subtract=function(e,a){return ki(this,e,a,-1)},Bi.as=function(e){if(!this.isValid())return NaN;var a,i,t=this._milliseconds;if("month"===(e=A(e))||"year"===e)return a=this._days+t/864e5,i=this._months+wi(a),"month"===e?i:i/12;switch(a=this._days+Math.round(_i(this._months)),e){case"week":return a/7+t/6048e5;case"day":return a+t/864e5;case"hour":return 24*a+t/36e5;case"minute":return 1440*a+t/6e4;case"second":return 86400*a+t/1e3;case"millisecond":return Math.floor(864e5*a)+t;default:throw new Error("Unknown unit "+e)}},Bi.asMilliseconds=ji,Bi.asSeconds=zi,Bi.asMinutes=Mi,Bi.asHours=Li,Bi.asDays=Yi,Bi.asWeeks=Di,Bi.asMonths=Ti,Bi.asYears=qi,Bi.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*x(this._months/12):NaN},Bi._bubble=function(){var e,a,i,t,n,r=this._milliseconds,s=this._days,o=this._months,l=this._data;return r>=0&&s>=0&&o>=0||r<=0&&s<=0&&o<=0||(r+=864e5*vi(_i(o)+s),s=0,o=0),l.milliseconds=r%1e3,e=_(r/1e3),l.seconds=e%60,a=_(e/60),l.minutes=a%60,i=_(a/60),l.hours=i%24,s+=_(i/24),n=_(wi(s)),o+=n,s-=vi(_i(n)),t=_(o/12),o%=12,l.days=s,l.months=o,l.years=t,this},Bi.clone=function(){return Ua(this)},Bi.get=function(e){return e=A(e),this.isValid()?this[e+"s"]():NaN},Bi.milliseconds=Hi,Bi.seconds=Ci,Bi.minutes=Ai,Bi.hours=Pi,Bi.days=Oi,Bi.weeks=function(){return _(this.days()/7)},Bi.months=Ei,Bi.years=Wi,Bi.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var a=this.localeData(),i=function(e,a,i){var t=Ua(e).abs(),n=Ii(t.as("s")),r=Ii(t.as("m")),s=Ii(t.as("h")),o=Ii(t.as("d")),l=Ii(t.as("M")),d=Ii(t.as("y")),c=n<=Fi.ss&&["s",n]||n0,c[4]=i,function(e,a,i,t,n){return n.relativeTime(a||1,!!i,e,t)}.apply(null,c)}(this,!e,a);return e&&(i=a.pastFuture(+this,i)),a.postformat(i)},Bi.toISOString=$i,Bi.toString=$i,Bi.toJSON=$i,Bi.locale=ai,Bi.localeData=ti,Bi.toIsoString=M("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",$i),Bi.lang=ii,$("X",0,0,"unix"),$("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),pe("X",function(e,a,i){i._d=new Date(1e3*parseFloat(e,10))}),pe("x",function(e,a,i){i._d=new Date(x(e))}),n.version="2.22.2",function(e){a=e}(qa),n.fn=mi,n.min=function(){return Ca("isBefore",[].slice.call(arguments,0))},n.max=function(){return Ca("isAfter",[].slice.call(arguments,0))},n.now=function(){return Date.now?Date.now():+new Date},n.utc=h,n.unix=function(e){return qa(1e3*e)},n.months=function(e,a){return bi(e,a,"months")},n.isDate=d,n.locale=ua,n.invalid=b,n.duration=Ua,n.isMoment=w,n.weekdays=function(e,a,i){return fi(e,a,i,"weekdays")},n.parseZone=function(){return qa.apply(null,arguments).parseZone()},n.localeData=ha,n.isDuration=Oa,n.monthsShort=function(e,a){return bi(e,a,"monthsShort")},n.weekdaysMin=function(e,a,i){return fi(e,a,i,"weekdaysMin")},n.defineLocale=ma,n.updateLocale=function(e,a){if(null!=a){var i,t,n=sa;null!=(t=ca(e))&&(n=t._config),a=q(n,a),(i=new S(a)).parentLocale=oa[e],oa[e]=i,ua(e)}else null!=oa[e]&&(null!=oa[e].parentLocale?oa[e]=oa[e].parentLocale:null!=oa[e]&&delete oa[e]);return oa[e]},n.locales=function(){return L(oa)},n.weekdaysShort=function(e,a,i){return fi(e,a,i,"weekdaysShort")},n.normalizeUnits=A,n.relativeTimeRounding=function(e){return void 0===e?Ii:"function"==typeof e&&(Ii=e,!0)},n.relativeTimeThreshold=function(e,a){return void 0!==Fi[e]&&(void 0===a?Fi[e]:(Fi[e]=a,"s"===e&&(Fi.ss=a-1),!0))},n.calendarFormat=function(e,a){var i=e.diff(a,"days",!0);return i<-6?"sameElse":i<-1?"lastWeek":i<0?"lastDay":i<1?"sameDay":i<2?"nextDay":i<7?"nextWeek":"sameElse"},n.prototype=mi,n.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},n}()}).call(this,i(169)(e))},function(e,a,i){"use strict";e.exports=i(9),e.exports.easing=i(195),e.exports.canvas=i(194),e.exports.options=i(193)},function(e,a,i){"use strict";var t=i(1);e.exports={_set:function(e,a){return t.merge(this[e]||(this[e]={}),a)}}},function(e,a,i){var t;
-/*!
- * jQuery JavaScript Library v3.3.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2018-01-20T17:24Z
- */
-/*!
- * jQuery JavaScript Library v3.3.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2018-01-20T17:24Z
- */
-!function(a,i){"use strict";"object"==typeof e&&"object"==typeof e.exports?e.exports=a.document?i(a,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return i(e)}:i(a)}("undefined"!=typeof window?window:this,function(i,n){"use strict";var r=[],s=i.document,o=Object.getPrototypeOf,l=r.slice,d=r.concat,c=r.push,u=r.indexOf,m={},h=m.toString,g=m.hasOwnProperty,p=g.toString,b=p.call(Object),f={},y=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},k=function(e){return null!=e&&e===e.window},v={type:!0,src:!0,noModule:!0};function w(e,a,i){var t,n=(a=a||s).createElement("script");if(n.text=e,i)for(t in v)i[t]&&(n[t]=i[t]);a.head.appendChild(n).parentNode.removeChild(n)}function _(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?m[h.call(e)]||"object":typeof e}var x=function(e,a){return new x.fn.init(e,a)},j=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function z(e){var a=!!e&&"length"in e&&e.length,i=_(e);return!y(e)&&!k(e)&&("array"===i||0===a||"number"==typeof a&&a>0&&a-1 in e)}x.fn=x.prototype={jquery:"3.3.1",constructor:x,length:0,toArray:function(){return l.call(this)},get:function(e){return null==e?l.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var a=x.merge(this.constructor(),e);return a.prevObject=this,a},each:function(e){return x.each(this,e)},map:function(e){return this.pushStack(x.map(this,function(a,i){return e.call(a,i,a)}))},slice:function(){return this.pushStack(l.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var a=this.length,i=+e+(e<0?a:0);return this.pushStack(i>=0&&i+~]|"+P+")"+P+"*"),$=new RegExp("="+P+"*([^\\]'\"]*?)"+P+"*\\]","g"),B=new RegExp(W),V=new RegExp("^"+O+"$"),U={ID:new RegExp("^#("+O+")"),CLASS:new RegExp("^\\.("+O+")"),TAG:new RegExp("^("+O+"|[*])"),ATTR:new RegExp("^"+E),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:new RegExp("^(?:"+A+")$","i"),needsContext:new RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},J=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,X=/[+~]/,Q=new RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),ee=function(e,a,i){var t="0x"+a-65536;return t!=t||i?a:t<0?String.fromCharCode(t+65536):String.fromCharCode(t>>10|55296,1023&t|56320)},ae=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,a){return a?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},te=function(){m()},ne=ye(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{S.apply(D=H.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(e){S={apply:D.length?function(e,a){q.apply(e,H.call(a))}:function(e,a){for(var i=e.length,t=0;e[i++]=a[t++];);e.length=i-1}}}function re(e,a,t,n){var r,o,d,c,u,g,f,y=a&&a.ownerDocument,_=a?a.nodeType:9;if(t=t||[],"string"!=typeof e||!e||1!==_&&9!==_&&11!==_)return t;if(!n&&((a?a.ownerDocument||a:w)!==h&&m(a),a=a||h,p)){if(11!==_&&(u=Z.exec(e)))if(r=u[1]){if(9===_){if(!(d=a.getElementById(r)))return t;if(d.id===r)return t.push(d),t}else if(y&&(d=y.getElementById(r))&&k(a,d)&&d.id===r)return t.push(d),t}else{if(u[2])return S.apply(t,a.getElementsByTagName(e)),t;if((r=u[3])&&i.getElementsByClassName&&a.getElementsByClassName)return S.apply(t,a.getElementsByClassName(r)),t}if(i.qsa&&!M[e+" "]&&(!b||!b.test(e))){if(1!==_)y=a,f=e;else if("object"!==a.nodeName.toLowerCase()){for((c=a.getAttribute("id"))?c=c.replace(ae,ie):a.setAttribute("id",c=v),o=(g=s(e)).length;o--;)g[o]="#"+c+" "+fe(g[o]);f=g.join(","),y=X.test(e)&&pe(a.parentNode)||a}if(f)try{return S.apply(t,y.querySelectorAll(f)),t}catch(e){}finally{c===v&&a.removeAttribute("id")}}}return l(e.replace(F,"$1"),a,t,n)}function se(){var e=[];return function a(i,n){return e.push(i+" ")>t.cacheLength&&delete a[e.shift()],a[i+" "]=n}}function oe(e){return e[v]=!0,e}function le(e){var a=h.createElement("fieldset");try{return!!e(a)}catch(e){return!1}finally{a.parentNode&&a.parentNode.removeChild(a),a=null}}function de(e,a){for(var i=e.split("|"),n=i.length;n--;)t.attrHandle[i[n]]=a}function ce(e,a){var i=a&&e,t=i&&1===e.nodeType&&1===a.nodeType&&e.sourceIndex-a.sourceIndex;if(t)return t;if(i)for(;i=i.nextSibling;)if(i===a)return-1;return e?1:-1}function ue(e){return function(a){return"input"===a.nodeName.toLowerCase()&&a.type===e}}function me(e){return function(a){var i=a.nodeName.toLowerCase();return("input"===i||"button"===i)&&a.type===e}}function he(e){return function(a){return"form"in a?a.parentNode&&!1===a.disabled?"label"in a?"label"in a.parentNode?a.parentNode.disabled===e:a.disabled===e:a.isDisabled===e||a.isDisabled!==!e&&ne(a)===e:a.disabled===e:"label"in a&&a.disabled===e}}function ge(e){return oe(function(a){return a=+a,oe(function(i,t){for(var n,r=e([],i.length,a),s=r.length;s--;)i[n=r[s]]&&(i[n]=!(t[n]=i[n]))})})}function pe(e){return e&&void 0!==e.getElementsByTagName&&e}for(a in i=re.support={},r=re.isXML=function(e){var a=e&&(e.ownerDocument||e).documentElement;return!!a&&"HTML"!==a.nodeName},m=re.setDocument=function(e){var a,n,s=e?e.ownerDocument||e:w;return s!==h&&9===s.nodeType&&s.documentElement?(g=(h=s).documentElement,p=!r(h),w!==h&&(n=h.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",te,!1):n.attachEvent&&n.attachEvent("onunload",te)),i.attributes=le(function(e){return e.className="i",!e.getAttribute("className")}),i.getElementsByTagName=le(function(e){return e.appendChild(h.createComment("")),!e.getElementsByTagName("*").length}),i.getElementsByClassName=K.test(h.getElementsByClassName),i.getById=le(function(e){return g.appendChild(e).id=v,!h.getElementsByName||!h.getElementsByName(v).length}),i.getById?(t.filter.ID=function(e){var a=e.replace(Q,ee);return function(e){return e.getAttribute("id")===a}},t.find.ID=function(e,a){if(void 0!==a.getElementById&&p){var i=a.getElementById(e);return i?[i]:[]}}):(t.filter.ID=function(e){var a=e.replace(Q,ee);return function(e){var i=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return i&&i.value===a}},t.find.ID=function(e,a){if(void 0!==a.getElementById&&p){var i,t,n,r=a.getElementById(e);if(r){if((i=r.getAttributeNode("id"))&&i.value===e)return[r];for(n=a.getElementsByName(e),t=0;r=n[t++];)if((i=r.getAttributeNode("id"))&&i.value===e)return[r]}return[]}}),t.find.TAG=i.getElementsByTagName?function(e,a){return void 0!==a.getElementsByTagName?a.getElementsByTagName(e):i.qsa?a.querySelectorAll(e):void 0}:function(e,a){var i,t=[],n=0,r=a.getElementsByTagName(e);if("*"===e){for(;i=r[n++];)1===i.nodeType&&t.push(i);return t}return r},t.find.CLASS=i.getElementsByClassName&&function(e,a){if(void 0!==a.getElementsByClassName&&p)return a.getElementsByClassName(e)},f=[],b=[],(i.qsa=K.test(h.querySelectorAll))&&(le(function(e){g.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&b.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||b.push("\\["+P+"*(?:value|"+A+")"),e.querySelectorAll("[id~="+v+"-]").length||b.push("~="),e.querySelectorAll(":checked").length||b.push(":checked"),e.querySelectorAll("a#"+v+"+*").length||b.push(".#.+[+~]")}),le(function(e){e.innerHTML="";var a=h.createElement("input");a.setAttribute("type","hidden"),e.appendChild(a).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&b.push("name"+P+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&b.push(":enabled",":disabled"),g.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&b.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),b.push(",.*:")})),(i.matchesSelector=K.test(y=g.matches||g.webkitMatchesSelector||g.mozMatchesSelector||g.oMatchesSelector||g.msMatchesSelector))&&le(function(e){i.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),f.push("!=",W)}),b=b.length&&new RegExp(b.join("|")),f=f.length&&new RegExp(f.join("|")),a=K.test(g.compareDocumentPosition),k=a||K.test(g.contains)?function(e,a){var i=9===e.nodeType?e.documentElement:e,t=a&&a.parentNode;return e===t||!(!t||1!==t.nodeType||!(i.contains?i.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,a){if(a)for(;a=a.parentNode;)if(a===e)return!0;return!1},L=a?function(e,a){if(e===a)return u=!0,0;var t=!e.compareDocumentPosition-!a.compareDocumentPosition;return t||(1&(t=(e.ownerDocument||e)===(a.ownerDocument||a)?e.compareDocumentPosition(a):1)||!i.sortDetached&&a.compareDocumentPosition(e)===t?e===h||e.ownerDocument===w&&k(w,e)?-1:a===h||a.ownerDocument===w&&k(w,a)?1:c?C(c,e)-C(c,a):0:4&t?-1:1)}:function(e,a){if(e===a)return u=!0,0;var i,t=0,n=e.parentNode,r=a.parentNode,s=[e],o=[a];if(!n||!r)return e===h?-1:a===h?1:n?-1:r?1:c?C(c,e)-C(c,a):0;if(n===r)return ce(e,a);for(i=e;i=i.parentNode;)s.unshift(i);for(i=a;i=i.parentNode;)o.unshift(i);for(;s[t]===o[t];)t++;return t?ce(s[t],o[t]):s[t]===w?-1:o[t]===w?1:0},h):h},re.matches=function(e,a){return re(e,null,null,a)},re.matchesSelector=function(e,a){if((e.ownerDocument||e)!==h&&m(e),a=a.replace($,"='$1']"),i.matchesSelector&&p&&!M[a+" "]&&(!f||!f.test(a))&&(!b||!b.test(a)))try{var t=y.call(e,a);if(t||i.disconnectedMatch||e.document&&11!==e.document.nodeType)return t}catch(e){}return re(a,h,null,[e]).length>0},re.contains=function(e,a){return(e.ownerDocument||e)!==h&&m(e),k(e,a)},re.attr=function(e,a){(e.ownerDocument||e)!==h&&m(e);var n=t.attrHandle[a.toLowerCase()],r=n&&Y.call(t.attrHandle,a.toLowerCase())?n(e,a,!p):void 0;return void 0!==r?r:i.attributes||!p?e.getAttribute(a):(r=e.getAttributeNode(a))&&r.specified?r.value:null},re.escape=function(e){return(e+"").replace(ae,ie)},re.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},re.uniqueSort=function(e){var a,t=[],n=0,r=0;if(u=!i.detectDuplicates,c=!i.sortStable&&e.slice(0),e.sort(L),u){for(;a=e[r++];)a===e[r]&&(n=t.push(r));for(;n--;)e.splice(t[n],1)}return c=null,e},n=re.getText=function(e){var a,i="",t=0,r=e.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)i+=n(e)}else if(3===r||4===r)return e.nodeValue}else for(;a=e[t++];)i+=n(a);return i},(t=re.selectors={cacheLength:50,createPseudo:oe,match:U,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Q,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Q,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var a,i=!e[6]&&e[2];return U.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":i&&B.test(i)&&(a=s(i,!0))&&(a=i.indexOf(")",i.length-a)-i.length)&&(e[0]=e[0].slice(0,a),e[2]=i.slice(0,a)),e.slice(0,3))}},filter:{TAG:function(e){var a=e.replace(Q,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===a}},CLASS:function(e){var a=j[e+" "];return a||(a=new RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&j(e,function(e){return a.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,a,i){return function(t){var n=re.attr(t,e);return null==n?"!="===a:!a||(n+="","="===a?n===i:"!="===a?n!==i:"^="===a?i&&0===n.indexOf(i):"*="===a?i&&n.indexOf(i)>-1:"$="===a?i&&n.slice(-i.length)===i:"~="===a?(" "+n.replace(I," ")+" ").indexOf(i)>-1:"|="===a&&(n===i||n.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,a,i,t,n){var r="nth"!==e.slice(0,3),s="last"!==e.slice(-4),o="of-type"===a;return 1===t&&0===n?function(e){return!!e.parentNode}:function(a,i,l){var d,c,u,m,h,g,p=r!==s?"nextSibling":"previousSibling",b=a.parentNode,f=o&&a.nodeName.toLowerCase(),y=!l&&!o,k=!1;if(b){if(r){for(;p;){for(m=a;m=m[p];)if(o?m.nodeName.toLowerCase()===f:1===m.nodeType)return!1;g=p="only"===e&&!g&&"nextSibling"}return!0}if(g=[s?b.firstChild:b.lastChild],s&&y){for(k=(h=(d=(c=(u=(m=b)[v]||(m[v]={}))[m.uniqueID]||(u[m.uniqueID]={}))[e]||[])[0]===_&&d[1])&&d[2],m=h&&b.childNodes[h];m=++h&&m&&m[p]||(k=h=0)||g.pop();)if(1===m.nodeType&&++k&&m===a){c[e]=[_,h,k];break}}else if(y&&(k=h=(d=(c=(u=(m=a)[v]||(m[v]={}))[m.uniqueID]||(u[m.uniqueID]={}))[e]||[])[0]===_&&d[1]),!1===k)for(;(m=++h&&m&&m[p]||(k=h=0)||g.pop())&&((o?m.nodeName.toLowerCase()!==f:1!==m.nodeType)||!++k||(y&&((c=(u=m[v]||(m[v]={}))[m.uniqueID]||(u[m.uniqueID]={}))[e]=[_,k]),m!==a)););return(k-=n)===t||k%t==0&&k/t>=0}}},PSEUDO:function(e,a){var i,n=t.pseudos[e]||t.setFilters[e.toLowerCase()]||re.error("unsupported pseudo: "+e);return n[v]?n(a):n.length>1?(i=[e,e,"",a],t.setFilters.hasOwnProperty(e.toLowerCase())?oe(function(e,i){for(var t,r=n(e,a),s=r.length;s--;)e[t=C(e,r[s])]=!(i[t]=r[s])}):function(e){return n(e,0,i)}):n}},pseudos:{not:oe(function(e){var a=[],i=[],t=o(e.replace(F,"$1"));return t[v]?oe(function(e,a,i,n){for(var r,s=t(e,null,n,[]),o=e.length;o--;)(r=s[o])&&(e[o]=!(a[o]=r))}):function(e,n,r){return a[0]=e,t(a,null,r,i),a[0]=null,!i.pop()}}),has:oe(function(e){return function(a){return re(e,a).length>0}}),contains:oe(function(e){return e=e.replace(Q,ee),function(a){return(a.textContent||a.innerText||n(a)).indexOf(e)>-1}}),lang:oe(function(e){return V.test(e||"")||re.error("unsupported lang: "+e),e=e.replace(Q,ee).toLowerCase(),function(a){var i;do{if(i=p?a.lang:a.getAttribute("xml:lang")||a.getAttribute("lang"))return(i=i.toLowerCase())===e||0===i.indexOf(e+"-")}while((a=a.parentNode)&&1===a.nodeType);return!1}}),target:function(a){var i=e.location&&e.location.hash;return i&&i.slice(1)===a.id},root:function(e){return e===g},focus:function(e){return e===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:he(!1),disabled:he(!0),checked:function(e){var a=e.nodeName.toLowerCase();return"input"===a&&!!e.checked||"option"===a&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!t.pseudos.empty(e)},header:function(e){return G.test(e.nodeName)},input:function(e){return J.test(e.nodeName)},button:function(e){var a=e.nodeName.toLowerCase();return"input"===a&&"button"===e.type||"button"===a},text:function(e){var a;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(a=e.getAttribute("type"))||"text"===a.toLowerCase())},first:ge(function(){return[0]}),last:ge(function(e,a){return[a-1]}),eq:ge(function(e,a,i){return[i<0?i+a:i]}),even:ge(function(e,a){for(var i=0;i=0;)e.push(t);return e}),gt:ge(function(e,a,i){for(var t=i<0?i+a:i;++t1?function(a,i,t){for(var n=e.length;n--;)if(!e[n](a,i,t))return!1;return!0}:e[0]}function ve(e,a,i,t,n){for(var r,s=[],o=0,l=e.length,d=null!=a;o-1&&(r[d]=!(s[d]=u))}}else f=ve(f===s?f.splice(g,f.length):f),n?n(null,s,f,l):S.apply(s,f)})}function _e(e){for(var a,i,n,r=e.length,s=t.relative[e[0].type],o=s||t.relative[" "],l=s?1:0,c=ye(function(e){return e===a},o,!0),u=ye(function(e){return C(a,e)>-1},o,!0),m=[function(e,i,t){var n=!s&&(t||i!==d)||((a=i).nodeType?c(e,i,t):u(e,i,t));return a=null,n}];l1&&ke(m),l>1&&fe(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(F,"$1"),i,l0,n=e.length>0,r=function(r,s,o,l,c){var u,g,b,f=0,y="0",k=r&&[],v=[],w=d,x=r||n&&t.find.TAG("*",c),j=_+=null==w?1:Math.random()||.1,z=x.length;for(c&&(d=s===h||s||c);y!==z&&null!=(u=x[y]);y++){if(n&&u){for(g=0,s||u.ownerDocument===h||(m(u),o=!p);b=e[g++];)if(b(u,s||h,o)){l.push(u);break}c&&(_=j)}i&&((u=!b&&u)&&f--,r&&k.push(u))}if(f+=y,i&&y!==f){for(g=0;b=a[g++];)b(k,v,s,o);if(r){if(f>0)for(;y--;)k[y]||v[y]||(v[y]=T.call(l));v=ve(v)}S.apply(l,v),c&&!r&&v.length>0&&f+a.length>1&&re.uniqueSort(l)}return c&&(_=j,d=w),k};return i?oe(r):r}(r,n))).selector=e}return o},l=re.select=function(e,a,i,n){var r,l,d,c,u,m="function"==typeof e&&e,h=!n&&s(e=m.selector||e);if(i=i||[],1===h.length){if((l=h[0]=h[0].slice(0)).length>2&&"ID"===(d=l[0]).type&&9===a.nodeType&&p&&t.relative[l[1].type]){if(!(a=(t.find.ID(d.matches[0].replace(Q,ee),a)||[])[0]))return i;m&&(a=a.parentNode),e=e.slice(l.shift().value.length)}for(r=U.needsContext.test(e)?0:l.length;r--&&(d=l[r],!t.relative[c=d.type]);)if((u=t.find[c])&&(n=u(d.matches[0].replace(Q,ee),X.test(l[0].type)&&pe(a.parentNode)||a))){if(l.splice(r,1),!(e=n.length&&fe(l)))return S.apply(i,n),i;break}}return(m||o(e,h))(n,a,!p,i,!a||X.test(e)&&pe(a.parentNode)||a),i},i.sortStable=v.split("").sort(L).join("")===v,i.detectDuplicates=!!u,m(),i.sortDetached=le(function(e){return 1&e.compareDocumentPosition(h.createElement("fieldset"))}),le(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||de("type|href|height|width",function(e,a,i){if(!i)return e.getAttribute(a,"type"===a.toLowerCase()?1:2)}),i.attributes&&le(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||de("value",function(e,a,i){if(!i&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),le(function(e){return null==e.getAttribute("disabled")})||de(A,function(e,a,i){var t;if(!i)return!0===e[a]?a.toLowerCase():(t=e.getAttributeNode(a))&&t.specified?t.value:null}),re}(i);x.find=M,x.expr=M.selectors,x.expr[":"]=x.expr.pseudos,x.uniqueSort=x.unique=M.uniqueSort,x.text=M.getText,x.isXMLDoc=M.isXML,x.contains=M.contains,x.escapeSelector=M.escape;var L=function(e,a,i){for(var t=[],n=void 0!==i;(e=e[a])&&9!==e.nodeType;)if(1===e.nodeType){if(n&&x(e).is(i))break;t.push(e)}return t},Y=function(e,a){for(var i=[];e;e=e.nextSibling)1===e.nodeType&&e!==a&&i.push(e);return i},D=x.expr.match.needsContext;function T(e,a){return e.nodeName&&e.nodeName.toLowerCase()===a.toLowerCase()}var q=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function S(e,a,i){return y(a)?x.grep(e,function(e,t){return!!a.call(e,t,e)!==i}):a.nodeType?x.grep(e,function(e){return e===a!==i}):"string"!=typeof a?x.grep(e,function(e){return u.call(a,e)>-1!==i}):x.filter(a,e,i)}x.filter=function(e,a,i){var t=a[0];return i&&(e=":not("+e+")"),1===a.length&&1===t.nodeType?x.find.matchesSelector(t,e)?[t]:[]:x.find.matches(e,x.grep(a,function(e){return 1===e.nodeType}))},x.fn.extend({find:function(e){var a,i,t=this.length,n=this;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(a=0;a1?x.uniqueSort(i):i},filter:function(e){return this.pushStack(S(this,e||[],!1))},not:function(e){return this.pushStack(S(this,e||[],!0))},is:function(e){return!!S(this,"string"==typeof e&&D.test(e)?x(e):e||[],!1).length}});var H,C=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(x.fn.init=function(e,a,i){var t,n;if(!e)return this;if(i=i||H,"string"==typeof e){if(!(t="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:C.exec(e))||!t[1]&&a)return!a||a.jquery?(a||i).find(e):this.constructor(a).find(e);if(t[1]){if(a=a instanceof x?a[0]:a,x.merge(this,x.parseHTML(t[1],a&&a.nodeType?a.ownerDocument||a:s,!0)),q.test(t[1])&&x.isPlainObject(a))for(t in a)y(this[t])?this[t](a[t]):this.attr(t,a[t]);return this}return(n=s.getElementById(t[2]))&&(this[0]=n,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):y(e)?void 0!==i.ready?i.ready(e):e(x):x.makeArray(e,this)}).prototype=x.fn,H=x(s);var A=/^(?:parents|prev(?:Until|All))/,P={children:!0,contents:!0,next:!0,prev:!0};function O(e,a){for(;(e=e[a])&&1!==e.nodeType;);return e}x.fn.extend({has:function(e){var a=x(e,this),i=a.length;return this.filter(function(){for(var e=0;e-1:1===i.nodeType&&x.find.matchesSelector(i,e))){r.push(i);break}return this.pushStack(r.length>1?x.uniqueSort(r):r)},index:function(e){return e?"string"==typeof e?u.call(x(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,a){return this.pushStack(x.uniqueSort(x.merge(this.get(),x(e,a))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),x.each({parent:function(e){var a=e.parentNode;return a&&11!==a.nodeType?a:null},parents:function(e){return L(e,"parentNode")},parentsUntil:function(e,a,i){return L(e,"parentNode",i)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return L(e,"nextSibling")},prevAll:function(e){return L(e,"previousSibling")},nextUntil:function(e,a,i){return L(e,"nextSibling",i)},prevUntil:function(e,a,i){return L(e,"previousSibling",i)},siblings:function(e){return Y((e.parentNode||{}).firstChild,e)},children:function(e){return Y(e.firstChild)},contents:function(e){return T(e,"iframe")?e.contentDocument:(T(e,"template")&&(e=e.content||e),x.merge([],e.childNodes))}},function(e,a){x.fn[e]=function(i,t){var n=x.map(this,a,i);return"Until"!==e.slice(-5)&&(t=i),t&&"string"==typeof t&&(n=x.filter(t,n)),this.length>1&&(P[e]||x.uniqueSort(n),A.test(e)&&n.reverse()),this.pushStack(n)}});var E=/[^\x20\t\r\n\f]+/g;function W(e){return e}function I(e){throw e}function F(e,a,i,t){var n;try{e&&y(n=e.promise)?n.call(e).done(a).fail(i):e&&y(n=e.then)?n.call(e,a,i):a.apply(void 0,[e].slice(t))}catch(e){i.apply(void 0,[e])}}x.Callbacks=function(e){e="string"==typeof e?function(e){var a={};return x.each(e.match(E)||[],function(e,i){a[i]=!0}),a}(e):x.extend({},e);var a,i,t,n,r=[],s=[],o=-1,l=function(){for(n=n||e.once,t=a=!0;s.length;o=-1)for(i=s.shift();++o-1;)r.splice(i,1),i<=o&&o--}),this},has:function(e){return e?x.inArray(e,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return n=s=[],r=i="",this},disabled:function(){return!r},lock:function(){return n=s=[],i||a||(r=i=""),this},locked:function(){return!!n},fireWith:function(e,i){return n||(i=[e,(i=i||[]).slice?i.slice():i],s.push(i),a||l()),this},fire:function(){return d.fireWith(this,arguments),this},fired:function(){return!!t}};return d},x.extend({Deferred:function(e){var a=[["notify","progress",x.Callbacks("memory"),x.Callbacks("memory"),2],["resolve","done",x.Callbacks("once memory"),x.Callbacks("once memory"),0,"resolved"],["reject","fail",x.Callbacks("once memory"),x.Callbacks("once memory"),1,"rejected"]],t="pending",n={state:function(){return t},always:function(){return r.done(arguments).fail(arguments),this},catch:function(e){return n.then(null,e)},pipe:function(){var e=arguments;return x.Deferred(function(i){x.each(a,function(a,t){var n=y(e[t[4]])&&e[t[4]];r[t[1]](function(){var e=n&&n.apply(this,arguments);e&&y(e.promise)?e.promise().progress(i.notify).done(i.resolve).fail(i.reject):i[t[0]+"With"](this,n?[e]:arguments)})}),e=null}).promise()},then:function(e,t,n){var r=0;function s(e,a,t,n){return function(){var o=this,l=arguments,d=function(){var i,d;if(!(e=r&&(t!==I&&(o=void 0,l=[i]),a.rejectWith(o,l))}};e?c():(x.Deferred.getStackHook&&(c.stackTrace=x.Deferred.getStackHook()),i.setTimeout(c))}}return x.Deferred(function(i){a[0][3].add(s(0,i,y(n)?n:W,i.notifyWith)),a[1][3].add(s(0,i,y(e)?e:W)),a[2][3].add(s(0,i,y(t)?t:I))}).promise()},promise:function(e){return null!=e?x.extend(e,n):n}},r={};return x.each(a,function(e,i){var s=i[2],o=i[5];n[i[1]]=s.add,o&&s.add(function(){t=o},a[3-e][2].disable,a[3-e][3].disable,a[0][2].lock,a[0][3].lock),s.add(i[3].fire),r[i[0]]=function(){return r[i[0]+"With"](this===r?void 0:this,arguments),this},r[i[0]+"With"]=s.fireWith}),n.promise(r),e&&e.call(r,r),r},when:function(e){var a=arguments.length,i=a,t=Array(i),n=l.call(arguments),r=x.Deferred(),s=function(e){return function(i){t[e]=this,n[e]=arguments.length>1?l.call(arguments):i,--a||r.resolveWith(t,n)}};if(a<=1&&(F(e,r.done(s(i)).resolve,r.reject,!a),"pending"===r.state()||y(n[i]&&n[i].then)))return r.then();for(;i--;)F(n[i],s(i),r.reject);return r.promise()}});var N=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;x.Deferred.exceptionHook=function(e,a){i.console&&i.console.warn&&e&&N.test(e.name)&&i.console.warn("jQuery.Deferred exception: "+e.message,e.stack,a)},x.readyException=function(e){i.setTimeout(function(){throw e})};var R=x.Deferred();function $(){s.removeEventListener("DOMContentLoaded",$),i.removeEventListener("load",$),x.ready()}x.fn.ready=function(e){return R.then(e).catch(function(e){x.readyException(e)}),this},x.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--x.readyWait:x.isReady)||(x.isReady=!0,!0!==e&&--x.readyWait>0||R.resolveWith(s,[x]))}}),x.ready.then=R.then,"complete"===s.readyState||"loading"!==s.readyState&&!s.documentElement.doScroll?i.setTimeout(x.ready):(s.addEventListener("DOMContentLoaded",$),i.addEventListener("load",$));var B=function(e,a,i,t,n,r,s){var o=0,l=e.length,d=null==i;if("object"===_(i))for(o in n=!0,i)B(e,a,o,i[o],!0,r,s);else if(void 0!==t&&(n=!0,y(t)||(s=!0),d&&(s?(a.call(e,t),a=null):(d=a,a=function(e,a,i){return d.call(x(e),i)})),a))for(;o1,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),x.extend({queue:function(e,a,i){var t;if(e)return a=(a||"fx")+"queue",t=X.get(e,a),i&&(!t||Array.isArray(i)?t=X.access(e,a,x.makeArray(i)):t.push(i)),t||[]},dequeue:function(e,a){a=a||"fx";var i=x.queue(e,a),t=i.length,n=i.shift(),r=x._queueHooks(e,a);"inprogress"===n&&(n=i.shift(),t--),n&&("fx"===a&&i.unshift("inprogress"),delete r.stop,n.call(e,function(){x.dequeue(e,a)},r)),!t&&r&&r.empty.fire()},_queueHooks:function(e,a){var i=a+"queueHooks";return X.get(e,i)||X.access(e,i,{empty:x.Callbacks("once memory").add(function(){X.remove(e,[a+"queue",i])})})}}),x.fn.extend({queue:function(e,a){var i=2;return"string"!=typeof e&&(a=e,e="fx",i--),arguments.length\x20\t\r\n\f]+)/i,ge=/^$|^module$|\/(?:java|ecma)script/i,pe={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function be(e,a){var i;return i=void 0!==e.getElementsByTagName?e.getElementsByTagName(a||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(a||"*"):[],void 0===a||a&&T(e,a)?x.merge([e],i):i}function fe(e,a){for(var i=0,t=e.length;i-1)n&&n.push(r);else if(d=x.contains(r.ownerDocument,r),s=be(u.appendChild(r),"script"),d&&fe(s),i)for(c=0;r=s[c++];)ge.test(r.type||"")&&i.push(r);return u}!function(){var e=s.createDocumentFragment().appendChild(s.createElement("div")),a=s.createElement("input");a.setAttribute("type","radio"),a.setAttribute("checked","checked"),a.setAttribute("name","t"),e.appendChild(a),f.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",f.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var ve=s.documentElement,we=/^key/,_e=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,xe=/^([^.]*)(?:\.(.+)|)/;function je(){return!0}function ze(){return!1}function Me(){try{return s.activeElement}catch(e){}}function Le(e,a,i,t,n,r){var s,o;if("object"==typeof a){for(o in"string"!=typeof i&&(t=t||i,i=void 0),a)Le(e,o,i,t,a[o],r);return e}if(null==t&&null==n?(n=i,t=i=void 0):null==n&&("string"==typeof i?(n=t,t=void 0):(n=t,t=i,i=void 0)),!1===n)n=ze;else if(!n)return e;return 1===r&&(s=n,(n=function(e){return x().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=x.guid++)),e.each(function(){x.event.add(this,a,n,t,i)})}x.event={global:{},add:function(e,a,i,t,n){var r,s,o,l,d,c,u,m,h,g,p,b=X.get(e);if(b)for(i.handler&&(i=(r=i).handler,n=r.selector),n&&x.find.matchesSelector(ve,n),i.guid||(i.guid=x.guid++),(l=b.events)||(l=b.events={}),(s=b.handle)||(s=b.handle=function(a){return void 0!==x&&x.event.triggered!==a.type?x.event.dispatch.apply(e,arguments):void 0}),d=(a=(a||"").match(E)||[""]).length;d--;)h=p=(o=xe.exec(a[d])||[])[1],g=(o[2]||"").split(".").sort(),h&&(u=x.event.special[h]||{},h=(n?u.delegateType:u.bindType)||h,u=x.event.special[h]||{},c=x.extend({type:h,origType:p,data:t,handler:i,guid:i.guid,selector:n,needsContext:n&&x.expr.match.needsContext.test(n),namespace:g.join(".")},r),(m=l[h])||((m=l[h]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,t,g,s)||e.addEventListener&&e.addEventListener(h,s)),u.add&&(u.add.call(e,c),c.handler.guid||(c.handler.guid=i.guid)),n?m.splice(m.delegateCount++,0,c):m.push(c),x.event.global[h]=!0)},remove:function(e,a,i,t,n){var r,s,o,l,d,c,u,m,h,g,p,b=X.hasData(e)&&X.get(e);if(b&&(l=b.events)){for(d=(a=(a||"").match(E)||[""]).length;d--;)if(h=p=(o=xe.exec(a[d])||[])[1],g=(o[2]||"").split(".").sort(),h){for(u=x.event.special[h]||{},m=l[h=(t?u.delegateType:u.bindType)||h]||[],o=o[2]&&new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=m.length;r--;)c=m[r],!n&&p!==c.origType||i&&i.guid!==c.guid||o&&!o.test(c.namespace)||t&&t!==c.selector&&("**"!==t||!c.selector)||(m.splice(r,1),c.selector&&m.delegateCount--,u.remove&&u.remove.call(e,c));s&&!m.length&&(u.teardown&&!1!==u.teardown.call(e,g,b.handle)||x.removeEvent(e,h,b.handle),delete l[h])}else for(h in l)x.event.remove(e,h+a[d],i,t,!0);x.isEmptyObject(l)&&X.remove(e,"handle events")}},dispatch:function(e){var a,i,t,n,r,s,o=x.event.fix(e),l=new Array(arguments.length),d=(X.get(this,"events")||{})[o.type]||[],c=x.event.special[o.type]||{};for(l[0]=o,a=1;a=1))for(;d!==this;d=d.parentNode||this)if(1===d.nodeType&&("click"!==e.type||!0!==d.disabled)){for(r=[],s={},i=0;i-1:x.find(n,this,null,[d]).length),s[n]&&r.push(t);r.length&&o.push({elem:d,handlers:r})}return d=this,l\x20\t\r\n\f]*)[^>]*)\/>/gi,De=/
-
- @stack('styles')
-
-
-
-
-
-
-
-

-
-
-
-
-
- @include('admin.menu')
-
-
-
-
-
-
-
- @yield('content')
-
-
-
-@include('layout.footer')
-@stack('scripts')
-
-