Compare commits
No commits in common. "master" and "v0.1.0" have entirely different histories.
|
@ -2,37 +2,23 @@
|
|||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
Pipfile*
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
conf.py
|
||||
main.ini
|
||||
source/fixtures
|
||||
source/media
|
||||
|
||||
# Sphinx documentation
|
||||
docs/
|
||||
*.ods
|
||||
*.xlsx
|
||||
|
||||
bk/
|
||||
source/docs/
|
||||
site/
|
||||
vedev/
|
||||
|
||||
# Virtualenv
|
||||
.env/
|
||||
virtual/
|
||||
env
|
||||
|
||||
docs/build
|
||||
cache/
|
||||
credenciales.conf
|
||||
*.sqlite
|
||||
*.sql
|
||||
*.service
|
||||
*.orig
|
||||
rfc.db
|
||||
Dockerfile
|
||||
chuletas/
|
||||
configpac.py
|
||||
|
||||
|
||||
|
|
837
CHANGELOG.md
|
@ -1,840 +1,3 @@
|
|||
v 2.3.3 [27-Jun-2024]
|
||||
---------------------
|
||||
- Fix: Retención de RESICOS para Personas Morales.
|
||||
|
||||
|
||||
v 2.3.2 [10-Abr-2024]
|
||||
---------------------
|
||||
- Fix: En las mercancías en la Carta Porte al generar el PDF.
|
||||
|
||||
|
||||
v 2.3.1 [02-Abr-2024]
|
||||
---------------------
|
||||
- Fix: En la cantidad de la mercancia en la Carta Porte.
|
||||
|
||||
|
||||
v 2.3.0 [01-Abr-2024]
|
||||
---------------------
|
||||
- Mejora: Soporte para complemento Carta Porte 3.0
|
||||
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
|
||||
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
|
||||
|
||||
|
||||
v 2.2.0 [24-Ene-2024]
|
||||
---------------------
|
||||
- Mejora: Soporte para complemento Comercio Exterior 2.0
|
||||
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
|
||||
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
|
||||
|
||||
|
||||
v 2.1.0 [26-Dic-2023]
|
||||
---------------------
|
||||
- Mejora: Se agrega filtro por día en facturas.
|
||||
|
||||
|
||||
v 2.0.9 [20-Dic-2023]
|
||||
---------------------
|
||||
- Fix: Issue 98 y 107
|
||||
|
||||
|
||||
v 2.0.8 [30-Oct-2023]
|
||||
---------------------
|
||||
- Fix: Permitir generar CFDI de egreso para facturas globales sin datos globales.
|
||||
- Fix: Permitir cambiar la zona horaria para cuando se usa en servidor.
|
||||
|
||||
Es necesario hacer una migración:
|
||||
```
|
||||
cd /opt/empresa-libre
|
||||
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
|
||||
v 2.0.7 [06-Ju1-2023]
|
||||
---------------------
|
||||
- Fix: En tasa de retención de un Resico a una Persona Moral.
|
||||
|
||||
|
||||
v 2.0.6 [14-Jun-2023]
|
||||
---------------------
|
||||
- Fix: Al generar complementos de pago con facturas con retención de impuestos.
|
||||
|
||||
|
||||
v 2.0.5 [05-Jun-2023]
|
||||
---------------------
|
||||
- Fix: Al generar complementos de pago con facturas con varios impuestos.
|
||||
- Fix: ticket #103, hay que usar {receptor.correo_facturas} y {receptor.telefonos}
|
||||
|
||||
|
||||
v 2.0.2 [01-Abr-2023]
|
||||
---------------------
|
||||
- Fix: Obtener la clave del sat al facturar por lote.
|
||||
|
||||
|
||||
v 2.0.1 [29-Mar-2023]
|
||||
---------------------
|
||||
- Fix ticket #97
|
||||
|
||||
Es necesario hacer una migración:
|
||||
```
|
||||
cd /opt/empresa-libre
|
||||
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
|
||||
v 2.0.0 [08-Ene-2023]
|
||||
----------------------
|
||||
- Liberamos para todos la versión CFDI 4.0
|
||||
- **IMPORTANTE** NO intentes timbrar si **antes** no has validado en nuestro demo que puedes timbrar tus CFDIs habituales.
|
||||
|
||||
* IMPORTANTE:
|
||||
|
||||
Es necesario hacer una migración:
|
||||
|
||||
```
|
||||
cd /opt/empresa-libre
|
||||
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
Y reiniciar todo. IMPORTANTE: dependiendo desde que versión actualices, tal vez debas de hacer algún prodecimiento extra. Siempre revisa este historial.
|
||||
|
||||
|
||||
v 2.0.0 [31-Mar-2022]
|
||||
----------------------
|
||||
- Primera versión de timbrado con CFDI4
|
||||
- **IMPORTANTE** NO intentes timbrar si **antes** no has validado en nuestro demo que puedes timbrar tus CFDIs habituales.
|
||||
|
||||
|
||||
v 1.47.0 [28-Mar-2022]
|
||||
----------------------
|
||||
- Mejora: Soporte basico para complemento Comercio Exterior.
|
||||
|
||||
|
||||
v 1.46.5 [10-Mar-2022]
|
||||
----------------------
|
||||
- Error: Al timbrar nómina con Comercio Digital
|
||||
|
||||
|
||||
v 1.46.4 [18-Feb-2022]
|
||||
----------------------
|
||||
- Error: Issue #54
|
||||
|
||||
|
||||
v 1.46.3 [15-Feb-2022]
|
||||
----------------------
|
||||
- Error: Issue #53
|
||||
|
||||
|
||||
v 1.46.2 [31-Ene-2022]
|
||||
----------------------
|
||||
- Error: Al generar Carta Porte sin remolque.
|
||||
- Error: Al cancelar con Finkok.
|
||||
|
||||
|
||||
v 1.46.1 [29-Ene-2022]
|
||||
----------------------
|
||||
- Error: Issue #49
|
||||
- Mejora: Agregar validación para distancia en origen de Carta Porte.
|
||||
|
||||
|
||||
v 1.46.0 [27-Ene-2022]
|
||||
----------------------
|
||||
- Mejora: Issue #45
|
||||
- Mejora: Agregar tipos de persimos SCT para Carta Porte
|
||||
- Mejora: Buscar estado y municipio por CP en Carta Porte
|
||||
|
||||
|
||||
v 1.45.4 [25-Ene-2022]
|
||||
----------------------
|
||||
- Error: Al timbrar carta porte.
|
||||
- Error: Al cancelar con Comercio Digital.
|
||||
- Error: Issue #42
|
||||
- Mejora: Issue #44
|
||||
|
||||
* IMPORTANTE: Es necesario subir de nuevo tus certificados de sello, **solo** si timbras con Comercio Digital.
|
||||
|
||||
|
||||
v 1.45.3 [23-Ene-2022]
|
||||
----------------------
|
||||
- Error: El enviar por correo CFDI de pago. Ticket #40
|
||||
|
||||
|
||||
v 1.45.2 [21-Ene-2022]
|
||||
----------------------
|
||||
- Error: Al cancelar un CFDI
|
||||
|
||||
|
||||
v 1.45.1 [20-Ene-2022]
|
||||
----------------------
|
||||
- Error: Al enviar correos con la nueva configuración
|
||||
|
||||
|
||||
* IMPORTANTE: Revisa tu configuración de correo para verificar que todo funcione.
|
||||
|
||||
|
||||
v 1.45.0 [20-Ene-2022]
|
||||
----------------------
|
||||
- Importar Carta Porte desde archivo JSON
|
||||
|
||||
|
||||
v 1.44.2 [19-Ene-2022]
|
||||
----------------------
|
||||
- Agregar opción STARTTLS que requieren algunos servidores de correo
|
||||
|
||||
* IMPORTANTE: Revisa tu configuración de correo para verificar si tienes que usar esta opción.
|
||||
|
||||
|
||||
v 1.44.1 [19-Ene-2022]
|
||||
----------------------
|
||||
- Correciones en generación de Carta Porte v2.0
|
||||
- Plantilla para representación impresa de Carta Porte v2.0
|
||||
|
||||
|
||||
v 1.44.0 [10-Ene-2022]
|
||||
----------------------
|
||||
- Soporte para Carta Porte v2 con CFDI 3.3
|
||||
- Soporte para el nuevo esquema de cancelación del SAT
|
||||
|
||||
* IMPORTANTE:
|
||||
|
||||
Es necesario hacer una migración:
|
||||
|
||||
```
|
||||
cd /opt/empresa-libre
|
||||
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
|
||||
v 1.43.0 [12-Dic-2021]
|
||||
----------------------
|
||||
- Soporte para entradas de almacen.
|
||||
- Soporte para multi almacen.
|
||||
- Soporte para regenerar un ticket.
|
||||
- Soporte para movimientos entre almacenes
|
||||
- Consulta en SAT para estatus de nómina
|
||||
|
||||
* IMPORTANTE:
|
||||
|
||||
Instalar nuevo requerimiento:
|
||||
|
||||
```
|
||||
pip install segno
|
||||
```
|
||||
|
||||
Es necesario hacer una migración:
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
v 1.42.2 [14-Sep-2021]
|
||||
----------------------
|
||||
- Los productos pueden no llevar ningún impuesto.
|
||||
|
||||
|
||||
v 1.42.1 [01-Jun-2021]
|
||||
----------------------
|
||||
- Error - Ticket #5
|
||||
|
||||
|
||||
v 1.42.0 [24-May-2021]
|
||||
----------------------
|
||||
- Opción para que solo un admin pueda cancelar.
|
||||
|
||||
|
||||
v 1.41.4 [13-Abr-2021]
|
||||
----------------------
|
||||
- Error - Ticket #4
|
||||
|
||||
|
||||
v 1.41.3 [12-Feb-2021]
|
||||
----------------------
|
||||
- Error - Ticket #3
|
||||
|
||||
|
||||
v 1.41.2 [12-Feb-2021]
|
||||
----------------------
|
||||
- Error - Ticket #2
|
||||
|
||||
|
||||
v 1.41.1 [11-Feb-2021]
|
||||
----------------------
|
||||
- Error - Ticket #1
|
||||
|
||||
|
||||
v 1.41.0 [10-Feb-2021]
|
||||
----------------------
|
||||
- Importar clientes desde archivo CSV
|
||||
|
||||
|
||||
v 1.40.1 [09-Feb-2021]
|
||||
----------------------
|
||||
- Fix #422
|
||||
|
||||
|
||||
v 1.40.0 [05-ene-2021]
|
||||
----------------------
|
||||
- Error: Al parsear XML en Python 3.9+
|
||||
- Mejora: Agregar versión de Empresa Libre a plantilla.
|
||||
- Mejora: Sellado en memoria
|
||||
- Mejora: Se agrega un segundo PAC y se refactoriza el timbrado.
|
||||
|
||||
* **IMPORTANTE**
|
||||
|
||||
Es necesario seguir una serie de pasos **obligatorios** para migrar a esta
|
||||
versión, **no continues hasta seguir paso a paso** estas instrucciones.
|
||||
**Antes** de comenzar ten a la mano tus certificados de sello para timbrar, es
|
||||
necesario subirlos de nuevo. **NO actualices si no tienes tus certificados**
|
||||
con su respectiva contraseña, te quedarás sin poder timbrar.
|
||||
|
||||
Estas instrucciones solamente aplican para la maquina virtual con Ubuntu Server,
|
||||
la ultima y única versión sobre la que se dará soporte.
|
||||
|
||||
1. Entra a la parte administrativa y toma de tus credenciales de timbrado en el
|
||||
menú "Emisor" ficha "Otros Datos", usuario y token de timbrado.
|
||||
1. Agregar nuevos requerimientos `sudo apt install pkgconf libxml2-dev libxmlsec1-dev libxmlsec1-openssl`
|
||||
1. Agregar nuevo requerimiento `pip install --user xmlsec`
|
||||
1. Entrar a la carpeta del sistema: `/opt/empresa-libre`
|
||||
1. Actualizar `git pull origin master`
|
||||
1. Entrar a `source/app/controllers/pacs/comerciodigital` y copiar `conf.py.example` a `conf.py`
|
||||
1. Entrar a `source/app/controllers/pacs/finkok` y copiar `conf.py.example` a `conf.py`
|
||||
1. Agregar la variable `TOKEN = ''` al archivo `source/app/conf.py` mira el archivo de ejemplo en el mismo directorio.
|
||||
1. Reiniciar el servicio: `sudo systemctl restart empresalibre`
|
||||
1. Si no ves los cambios descritos a continuación, fuerza el refresco de tu navegador, generalmente con **CTRL+F5**
|
||||
1. Sube de nuevo tus certificados en el menú "Emisor" ficha "Certificado".
|
||||
1. Ve al menú "Opciones", ficha "Otros".
|
||||
1. Selecciona tu PAC, si tu usuario es un correo electrónico, invariablemente
|
||||
debes seleccionar Finkok. Si tienes duda ponte en contacto con nosotros.
|
||||
1. Establece las credenciales del punto 1.
|
||||
1. Guarda los datos.
|
||||
|
||||
|
||||
v 1.39.1 [17-sep-2020]
|
||||
----------------------
|
||||
- Error: Esquema para complemento IEDU
|
||||
|
||||
|
||||
v 1.39.0 [25-ago-2020]
|
||||
----------------------
|
||||
- Mejora: Consulta de las facturas de pago en el SAT
|
||||
- Mejora: Mostrar totales en nómina
|
||||
- Mejora: Mostrar totales por cantidad al facturar
|
||||
- Mejora: Validar líneas con importe cero antes de facturar
|
||||
- Error: Validaciones de namespace en CFDI de nómina por parte del PAC
|
||||
|
||||
|
||||
v 1.38.1 [30-mar-2020]
|
||||
----------------------
|
||||
- Error: En nómina al timbrar asimilados
|
||||
|
||||
|
||||
v 1.38.0 [08-mar-2020]
|
||||
----------------------
|
||||
- Mejora: Factura global por ticket o nota
|
||||
- Error: Al generar algunos PDFs
|
||||
|
||||
|
||||
v 1.37.0 [02-mar-2020]
|
||||
----------------------
|
||||
- Mejora: Soporte para complemento Leyendas Fiscales
|
||||
|
||||
* IMPORTANTE:
|
||||
|
||||
Es necesario hacer una migración, y agregar los campos necesarios para mostrar
|
||||
las leyendas, mira la carpeta pública con la plantilla de ejemplo.
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
|
||||
v 1.36.0 [25-feb-2020]
|
||||
----------------------
|
||||
- Mejora: Permitir ver a usuarios todos los documentos
|
||||
|
||||
|
||||
v 1.35.0 [24-feb-2020]
|
||||
----------------------
|
||||
- Mejora: Filtrado de documentos por sucursal
|
||||
|
||||
|
||||
v 1.34.1 [09-feb-2020]
|
||||
----------------------
|
||||
- Error: Al timbrar nómina de asimilados
|
||||
|
||||
|
||||
v 1.34.0 [29-ene-2020]
|
||||
----------------------
|
||||
- Error: Al timbrar nómina
|
||||
|
||||
|
||||
v 1.33.2 [27-ene-2020]
|
||||
----------------------
|
||||
- Se actualizan métodos de pago en catálogos del SAT
|
||||
|
||||
* IMPORTANTE:
|
||||
Es necesario actualizar los catálogos del SAT
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -us
|
||||
```
|
||||
|
||||
|
||||
v 1.33.0 [22-ene-2020]
|
||||
----------------------
|
||||
- Mejora: Cambio del mensaje para cuando se intenta dar de alta un cliente ya existente.
|
||||
- Mejora: Solo los admins pueden ver la nómina.
|
||||
- Se agrega un segundo PAC
|
||||
- Se actualizan los catálogos del SAT
|
||||
|
||||
* IMPORTANTE:
|
||||
Es necesario actualizar los catálogos del SAT
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -us
|
||||
```
|
||||
|
||||
|
||||
v 1.32.0 [05-ene-2020]
|
||||
----------------------
|
||||
- Mejora: Recuperar facturas no aceptadas para cancelación por el receptor
|
||||
|
||||
|
||||
v 1.31.2 [28-oct-2019]
|
||||
----------------------
|
||||
- Error: Al generar PDF con tags en las series
|
||||
|
||||
|
||||
v 1.31.1 [28-ago-2019]
|
||||
----------------------
|
||||
- Error: Al agregar nuevo impuesto #369
|
||||
|
||||
|
||||
v 1.31.0 [23-abr-2019]
|
||||
----------------------
|
||||
- Error: Validar cantidad o valor unitario cero en tickets
|
||||
- Mejora: Envío de nómina por correo al empleado
|
||||
|
||||
|
||||
v 1.30.0 [24-mar-2019]
|
||||
----------------------
|
||||
- Mejora: Se actualizan los catálogos de Nómina
|
||||
|
||||
* IMPORTANTE:
|
||||
Es necesario realizar una migración, después de actualizar.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
|
||||
v 1.29.0 [08-mar-2019]
|
||||
----------------------
|
||||
- Error: Al mostrar detalle en facturas importadas #343
|
||||
- Mejora: Editar la descripción de un movimiento bancario.
|
||||
|
||||
|
||||
v 1.28.2 [04-mar-2019]
|
||||
----------------------
|
||||
- Error: Al enviar facturas de pago
|
||||
|
||||
|
||||
v 1.28.1 [04-mar-2019]
|
||||
----------------------
|
||||
- Error: Al buscar facturas por fechas
|
||||
|
||||
|
||||
v 1.28.0 [17-feb-2019]
|
||||
----------------------
|
||||
- Mejora: Manejo de empaques para mensajeria
|
||||
- Mejora: Usar concepto personalizado en deducciones de nómina 004 Otros
|
||||
- Mejora: Búsqueda en notas
|
||||
- Mejora: Soporte para el complemento de Divisas
|
||||
- Mejora: Descarga de nómina en lote
|
||||
|
||||
* IMPORTANTE:
|
||||
Es necesario realizar una migración, después de actualizar.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
Es necesario agregar un nuevo requerimiento.
|
||||
|
||||
```
|
||||
sudo pip install cryptography
|
||||
```
|
||||
|
||||
**IMPORTANTE** Si envias tus facturas por correo directamente, es necesario
|
||||
volver a capturar la contraseña de tu servidor de correo y guardar los datos
|
||||
nuevamente.
|
||||
|
||||
|
||||
v 1.27.1 [23-ene-2019]
|
||||
----------------------
|
||||
- Error: Al cancelar nómina
|
||||
|
||||
|
||||
v 1.27.0 [17-ene-2019]
|
||||
----------------------
|
||||
- Mejora: Permitir capturar folio manualmente
|
||||
|
||||
|
||||
v 1.26.1 [16-ene-2019]
|
||||
----------------------
|
||||
- Error: Guardar logos de emisor
|
||||
|
||||
|
||||
v 1.26.0 [15-ene-2019]
|
||||
----------------------
|
||||
- Mejora: Generar PDF desde plantilla JSON
|
||||
|
||||
|
||||
v 1.25.0 [07-nov-2018]
|
||||
----------------------
|
||||
- Fix: Al importar días de pago en nómina
|
||||
- Fix: Al importar descripción en factura en lote
|
||||
|
||||
|
||||
v 1.24.0 [06-nov-2018]
|
||||
----------------------
|
||||
- Fix: Consulta estatus SAT
|
||||
|
||||
|
||||
v 1.23.0 [30-oct-2018]
|
||||
----------------------
|
||||
- Mejora: Permitir importar CFDI 3.2
|
||||
|
||||
|
||||
v 1.22.0 [25-oct-2018]
|
||||
----------------------
|
||||
- Mejora: Permitir cambiar descripción al facturar en lote
|
||||
|
||||
|
||||
v 1.21.2 [23-oct-2018]
|
||||
----------------------
|
||||
- Error unicode
|
||||
|
||||
|
||||
v 1.21.1 [14-oct-2018]
|
||||
----------------------
|
||||
- Error #307
|
||||
|
||||
|
||||
v 1.21.0 [12-oct-2018]
|
||||
----------------------
|
||||
- Error #287
|
||||
- Mejora: Complemento de pago con datos de cuentas
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
|
||||
|
||||
|
||||
v 1.20.0 [08-oct-2018]
|
||||
----------------------
|
||||
- Error #295
|
||||
- Mejora: Cuentas de banco para clientes
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
|
||||
|
||||
|
||||
v 1.19.1 [03-oct-2018]
|
||||
----------------------
|
||||
- Error #291
|
||||
- Error al generar PDF de factura de pago con relacionados sin serie
|
||||
- Error al relacionar facturas versión 3.2
|
||||
|
||||
v 1.19.0 [28-sep-2018]
|
||||
----------------------
|
||||
- Mejora #280
|
||||
- Mejora #288
|
||||
- Error #290
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
|
||||
v 1.18.0 [27-sep-2018]
|
||||
----------------------
|
||||
- Fix #282 Factura de pago en otras monedas
|
||||
|
||||
|
||||
v 1.17.0 [25-sep-2018]
|
||||
----------------------
|
||||
- Fix - Al generar factura de pago con documentos relacionados en otras monedas
|
||||
- Fix - Al generar factura de pago sin serie en documentos relacionados
|
||||
- Fix #278
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
|
||||
v 1.16.1 [18-sep-2018]
|
||||
----------------------
|
||||
- Error https://gitlab.com/mauriciobaeza/empresa-libre/issues/268
|
||||
- IMPORTANTE: Actualizar si usas cuatro decimales en impuestos
|
||||
|
||||
|
||||
v 1.16.0 [16-sep-2018]
|
||||
----------------------
|
||||
- Se puede editar el saldo de un cliente
|
||||
- Se muestra la cantidad de facturas de pago en los movimientos
|
||||
|
||||
|
||||
v 1.15.0 [12-sep-2018]
|
||||
----------------------
|
||||
- Se pueden mover las facturas con doble clic en los movimientos de banco.
|
||||
- Fix - Al sumar las facturas en los depósitos
|
||||
- Fix - Al importar los pedimentos en facturas por lotes
|
||||
- Fix - Al guardar los datos del emisor
|
||||
|
||||
|
||||
v 1.14.0 [10-sep-2018]
|
||||
----------------------
|
||||
- Personalizar plantilla para factura de pago
|
||||
- Fix - Mostrar serie y folio capturado para factura de pago
|
||||
- Fix - Agregar nueva cuenta de banco
|
||||
|
||||
|
||||
v 1.13.0 [10-sep-2018]
|
||||
----------------------
|
||||
- Cancelar factura de pago
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
|
||||
v 1.12.0 [31-ago-2018]
|
||||
----------------------
|
||||
- Soporte para facturas (complemento) de pago.
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
v 1.11.1 [21-ago-2018]
|
||||
----------------------
|
||||
- Fix - Quitar columna en tabla facturaspagos.
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
|
||||
v 1.11.0 [25-jul-2018]
|
||||
----------------------
|
||||
- Se cambia la forma de consultar los folios restantes. Es indispensable actualizar a esta versión para ver tus timbres restantes.
|
||||
|
||||
|
||||
v 1.10.0 [10-jul-2018]
|
||||
----------------------
|
||||
- Ahora se pueden manejar precios con cuatro decimales.
|
||||
|
||||
|
||||
v 1.9.3 [08-jul-2018]
|
||||
---------------------
|
||||
- Fix: Al refacturar conceptos con descuento
|
||||
|
||||
|
||||
v 1.9.2 [05-jul-2018]
|
||||
---------------------
|
||||
- Fix: Al generar el reporte de facturas en PDF
|
||||
|
||||
|
||||
v 1.9.1 [25-jun-2018]
|
||||
---------------------
|
||||
- Fix: Al mostrar el título de la aplicación
|
||||
- Se agrega el registro de acción al borrar una factura
|
||||
|
||||
|
||||
v 1.9.0 [18-jun-2018]
|
||||
---------------------
|
||||
- Se agrega la vista del detalle de facturas
|
||||
- Fix: Al timbrar nómina
|
||||
|
||||
|
||||
v 1.8.1 [14-jun-2018]
|
||||
---------------------
|
||||
- Fix: Se agrega una barra de desplazamiento al buscar productos o clientes
|
||||
- Se cambia el servidor de consulta de timbres
|
||||
|
||||
|
||||
v 1.8.0 [03-jun-2018]
|
||||
---------------------
|
||||
- Se permiten 4 decimales en Tipo de cambio
|
||||
- Se agrega el campo {total_cantidades} al generar el PDF
|
||||
- Se agrega opción para generar respaldos de la BD en MV
|
||||
- Fix: Al generar con complemento EDU
|
||||
|
||||
|
||||
v 1.7.0 [23-may-2018]
|
||||
---------------------
|
||||
- Se agrega soporte para truncar impuestos locales, para las estulticias de los "ingenieros" de las dependencias de gobierno
|
||||
|
||||
|
||||
v 1.6.1 [09-abr-2018]
|
||||
---------------------
|
||||
- Fix: Nómina con separación
|
||||
|
||||
|
||||
v 1.6.0 [18-feb-2018]
|
||||
---------------------
|
||||
- Facturacion a extranjeros
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
v 1.5.0 [30-ene-2018]
|
||||
---------------------
|
||||
- Timbrado de Nómina
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
v 1.4.0 [01-ene-2018]
|
||||
---------------------
|
||||
- Impresión de tickets
|
||||
|
||||
v 1.3.0 [27-Dic-2017]
|
||||
---------------------
|
||||
- Punto de venta
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -m
|
||||
```
|
||||
|
||||
v 1.2.0 [18-Dic-2017]
|
||||
---------------------
|
||||
* IMPORTANTE: Es necesario actualizar la base de datos, despues de actualizar la rama principal.
|
||||
|
||||
```
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bd
|
||||
```
|
||||
|
||||
v 0.1.0 [26-Oct-2017]
|
||||
---------------------
|
||||
- Generar y timbrar con CFDI 3.3
|
||||
|
|
|
@ -13,3 +13,9 @@
|
|||
* Propon nuevas funcionalidades
|
||||
* Difunde Empresa Libre
|
||||
|
||||
|
||||
### Prioridades
|
||||
|
||||
1. Darle continuidad a la facturación de los clientes
|
||||
2. Cubrir todas las funcionalidades que cubre ahora Factura Libre
|
||||
3. Agregar nuevas funcionalidades
|
||||
|
|
44
README.md
|
@ -8,53 +8,21 @@
|
|||
|
||||
Este proyecto está en continuo desarrollo, contratar un esquema de soporte,
|
||||
nos ayuda a continuar su desarrollo. Ponte en contacto con nosotros para
|
||||
contratar: administracion ARROBA empresalibre.net
|
||||
contratar.
|
||||
|
||||
#### Ahora también puede aportar con criptomonedas:
|
||||
|
||||
G1: `A5DdXxCKPw3QKWVdDVs7CzkNugNUW1sHu5zDJFWxCU2h`
|
||||
BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
|
||||
|
||||
## Requerimientos:
|
||||
### Requerimientos:
|
||||
|
||||
* Servidor web, recomendado Nginx
|
||||
* uwsgi
|
||||
* python 3.8
|
||||
* xsltproc
|
||||
* openssl
|
||||
* xmlsec
|
||||
|
||||
* Ubuntu 20.04
|
||||
|
||||
```
|
||||
apt install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl xsltproc
|
||||
```
|
||||
* python3
|
||||
|
||||
Debería de funcionar con cualquier combinación servidor-wsgi que soporte
|
||||
aplicaciones Python.
|
||||
|
||||
El sistema tiene soporte solo para PostgreSQL, debes de instalar el servidor de
|
||||
la base de datos y su driver respectivo.
|
||||
El sistema tiene soporte para tres bases de datos: SQLite, MySQL y PostgreSQL
|
||||
(recomendado), debes de instalar el servidor de la base de datos y sus drivers
|
||||
respectivos, excepto SQLite que es nativo en Python.
|
||||
|
||||
## Configuración para desarrollo local
|
||||
|
||||
* Crea un entorno virtual con python 3.8 y actívalo. Por ejemplo con virtualenv:
|
||||
|
||||
virtualenv .venv
|
||||
source .venv/bin/activate
|
||||
|
||||
* Instala las dependencias
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
* Copia y ajusta algunos archivos necesarios.
|
||||
- `source/app/conf.py`
|
||||
- `source/app/controllers/pacs/comerciodigital/conf.py.example`
|
||||
- `source/app/controllers/pacs/finkok/conf.py.example`
|
||||
* Finalmente ejecutamos la aplicación. Para esto vamos a necesitar un servidor
|
||||
wsgi como uwsgi:
|
||||
|
||||
pip install uwsgi
|
||||
cd source/app
|
||||
uwsgi main_debug.ini
|
||||
* Ahora puedes ver la aplicación en http://localhost:8000
|
||||
|
|
3
TODO.md
|
@ -1,3 +0,0 @@
|
|||
[ ] Permitir más de un remolque en la Carta Porte
|
||||
[ ] Campos de captura de Comercio Exterior
|
||||
[ ] Representación impresa de Comercio Exterior
|
|
@ -1,17 +1,14 @@
|
|||
falcon==1.4.1
|
||||
falcon
|
||||
falcon-multipart
|
||||
Beaker
|
||||
Mako
|
||||
peewee==2.10.2
|
||||
peewee
|
||||
Click
|
||||
logbook
|
||||
bcrypt
|
||||
python-dateutil
|
||||
zeep
|
||||
chardet
|
||||
pyqrcode
|
||||
pypng
|
||||
reportlab
|
||||
psycopg2-binary
|
||||
cryptography==3.4.8
|
||||
xmlsec
|
||||
segno
|
||||
|
||||
# python-escpos
|
||||
|
|
|
@ -1,21 +1,10 @@
|
|||
#!/usr/bin/env python
|
||||
from peewee import SqliteDatabase
|
||||
|
||||
|
||||
DEBUG = False
|
||||
MV = False
|
||||
DEBUG = True
|
||||
ID_SUPPORT = ''
|
||||
|
||||
# ~ Es la contraseña predeterminada de los usuarios admin y superadmin al crear
|
||||
# ~ una nueva base de datos, personaliza por la que quieras.
|
||||
DEFAULT_PASSWORD = 'salgueiro3.3'
|
||||
|
||||
TITLE_APP = 'Empresa Libre'
|
||||
|
||||
#~ Establece una ruta accesible para el servidor web
|
||||
LOG_PATH = '/var/log/empresalibre/empresa-libre.log'
|
||||
|
||||
# ~ Establece un token personalizado para encriptar las claves
|
||||
# ~ from secrets import token_hex
|
||||
# ~ token_hex(32)
|
||||
# ~ IMPORTANTE: Cada vez que cambies este valor, debes de subir de nuevo
|
||||
# ~ tus certificados
|
||||
TOKEN = ''
|
||||
DATABASE = None
|
||||
if DEBUG:
|
||||
DATABASE = SqliteDatabase('empresalibre.sqlite')
|
||||
|
|
|
@ -1,47 +1,25 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# ~ Empresa Libre
|
||||
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#!/usr/bin/env python
|
||||
|
||||
import datetime
|
||||
from xml.etree import ElementTree as ET
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
from dateutil import parser
|
||||
from logbook import Logger
|
||||
|
||||
#~ from settings import DEBUG
|
||||
|
||||
|
||||
log = Logger('XML')
|
||||
CFDI_ACTUAL = 'cfdi40'
|
||||
CFDI_ACTUAL = 'cfdi33'
|
||||
NOMINA_ACTUAL = 'nomina12'
|
||||
PUBLIC = 'PUBLICO EN GENERAL'
|
||||
CFDI_EGRESO = 'E'
|
||||
|
||||
DEFAULT = {
|
||||
'exportacion': '01',
|
||||
}
|
||||
|
||||
|
||||
SAT = {
|
||||
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'cfdi40': {
|
||||
'version': '4.0',
|
||||
'cfdi32': {
|
||||
'version': '3.2',
|
||||
'prefix': 'cfdi',
|
||||
'xmlns': 'http://www.sat.gob.mx/cfd/4',
|
||||
'schema': 'http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd',
|
||||
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
||||
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd',
|
||||
},
|
||||
'cfdi33': {
|
||||
'version': '3.3',
|
||||
|
@ -49,79 +27,18 @@ SAT = {
|
|||
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
||||
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd',
|
||||
},
|
||||
'cfdi32': {
|
||||
'version': '3.2',
|
||||
'prefix': 'cfdi',
|
||||
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
||||
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd',
|
||||
},
|
||||
'nomina11': {
|
||||
'version': '1.1',
|
||||
'prefix': 'nomina',
|
||||
'xmlns': 'http://www.sat.gob.mx/nomina',
|
||||
'schema': ' http://www.sat.gob.mx/nomina http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina11.xsd',
|
||||
'schema': 'http://www.sat.gob.mx/nomina http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina11.xsd',
|
||||
},
|
||||
'nomina': {
|
||||
'nomina12': {
|
||||
'version': '1.2',
|
||||
'prefix': 'nomina12',
|
||||
'prefix': 'nomina',
|
||||
'xmlns': 'http://www.sat.gob.mx/nomina12',
|
||||
'schema': ' http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd',
|
||||
'schema': 'http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd',
|
||||
},
|
||||
'locales': {
|
||||
'version': '1.0',
|
||||
'prefix': 'implocal',
|
||||
'xmlns': 'http://www.sat.gob.mx/implocal',
|
||||
'schema': ' http://www.sat.gob.mx/implocal http://www.sat.gob.mx/sitio_internet/cfd/implocal/implocal.xsd',
|
||||
},
|
||||
'donativo': {
|
||||
'version': '1.1',
|
||||
'prefix': 'donat',
|
||||
'xmlns': 'http://www.sat.gob.mx/donat',
|
||||
'schema': ' http://www.sat.gob.mx/donat http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xsd',
|
||||
'leyenda': 'Este comprobante ampara un donativo, el cual será destinado por la donataria a los fines propios de su objeto social. En el caso de que los bienes donados hayan sido deducidos previamente para los efectos del impuesto sobre la renta, este donativo no es deducible. La reproducción no autorizada de este comprobante constituye un delito en los términos de las disposiciones fiscales.',
|
||||
},
|
||||
'ine': {
|
||||
'version': '1.1',
|
||||
'prefix': 'ine',
|
||||
'xmlns': 'http://www.sat.gob.mx/ine',
|
||||
'schema': ' http://www.sat.gob.mx/ine http://www.sat.gob.mx/sitio_internet/cfd/ine/ine11.xsd',
|
||||
},
|
||||
'edu': {
|
||||
'version': '1.0',
|
||||
'prefix': 'iedu',
|
||||
'xmlns': 'http://www.sat.gob.mx/iedu',
|
||||
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/iedu/iedu.xsd',
|
||||
},
|
||||
'pagos': {
|
||||
'version': '2.0',
|
||||
'prefix': 'pago20',
|
||||
'xmlns': 'http://www.sat.gob.mx/Pagos20',
|
||||
'schema': ' http://www.sat.gob.mx/Pagos20 http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd',
|
||||
},
|
||||
'divisas': {
|
||||
'version': '1.0',
|
||||
'prefix': 'divisas',
|
||||
'xmlns': 'http://www.sat.gob.mx/divisas',
|
||||
'schema': ' http://www.sat.gob.mx/divisas http://www.sat.gob.mx/sitio_internet/cfd/divisas/divisas.xsd',
|
||||
},
|
||||
'leyendas': {
|
||||
'version': '1.0',
|
||||
'prefix': 'leyendasFisc',
|
||||
'xmlns': 'http://www.sat.gob.mx/leyendasFiscales',
|
||||
'schema': ' http://www.sat.gob.mx/leyendasFiscales http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd',
|
||||
},
|
||||
'cartaporte': {
|
||||
'version': '3.0',
|
||||
'prefix': 'cartaporte30',
|
||||
'xmlns': 'http://www.sat.gob.mx/CartaPorte30',
|
||||
'schema': ' http://www.sat.gob.mx/CartaPorte30 http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte30.xsd',
|
||||
},
|
||||
'comercioe': {
|
||||
'version': '2.0',
|
||||
'prefix': 'cce20',
|
||||
'xmlns': 'http://www.sat.gob.mx/ComercioExterior20',
|
||||
'schema': ' http://www.sat.gob.mx/ComercioExterior20 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,19 +49,6 @@ class CFDI(object):
|
|||
self._xsi = SAT['xsi']
|
||||
self._pre = self._sat_cfdi['prefix']
|
||||
self._cfdi = None
|
||||
self._complemento = None
|
||||
self._impuestos_locales = False
|
||||
self._donativo = False
|
||||
self._ine = False
|
||||
self._edu = False
|
||||
self._pagos = False
|
||||
self._is_nomina = False
|
||||
self._leyendas = False
|
||||
self._carta_porte = False
|
||||
self._comercio_exterior = False
|
||||
self._divisas = ''
|
||||
self._tipo_de_comprobante = ''
|
||||
self._exportacion = DEFAULT['exportacion']
|
||||
self.error = ''
|
||||
|
||||
def _now(self):
|
||||
|
@ -155,27 +59,18 @@ class CFDI(object):
|
|||
return ''
|
||||
|
||||
self._comprobante(datos['comprobante'])
|
||||
if 'global' in datos:
|
||||
self._informacion_global(datos['global'])
|
||||
self._relacionados(datos['relacionados'])
|
||||
self._emisor(datos['emisor'])
|
||||
self._receptor(datos['receptor'])
|
||||
self._conceptos(datos['conceptos'])
|
||||
self._impuestos(datos['impuestos'])
|
||||
self._locales(datos['impuestos'])
|
||||
self._donatarias(datos['donativo'])
|
||||
self._complementos(datos['complementos'])
|
||||
|
||||
if 'nomina' in datos:
|
||||
self._nomina(datos['nomina'])
|
||||
if 'complementos' in datos:
|
||||
self._complementos(datos['complementos'])
|
||||
return self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
|
||||
xml = self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
|
||||
return xml
|
||||
|
||||
def add_sello(self, sello, cert_txt):
|
||||
def add_sello(self, sello):
|
||||
self._cfdi.attrib['Sello'] = sello
|
||||
self._cfdi.attrib['Certificado'] = cert_txt
|
||||
return self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
|
||||
def _to_pretty_xml(self, source):
|
||||
|
@ -184,169 +79,65 @@ class CFDI(object):
|
|||
return xml
|
||||
|
||||
def _validate(self, datos):
|
||||
if datos['impuestos']:
|
||||
if datos['impuestos']['total_locales_trasladados'] or \
|
||||
datos['impuestos']['total_locales_retenciones']:
|
||||
self._impuestos_locales = True
|
||||
|
||||
if datos['donativo']:
|
||||
self._donativo = True
|
||||
|
||||
self._edu = datos.get('edu', False)
|
||||
|
||||
if datos['complementos']:
|
||||
if 'ine' in datos['complementos']:
|
||||
self._ine = True
|
||||
self._pagos = bool(datos['complementos'].get('pagos', False))
|
||||
self._leyendas = bool(datos['complementos'].get('leyendas', False))
|
||||
self._carta_porte = bool(datos['complementos'].get('cartaporte', False))
|
||||
self._comercio_exterior = bool(datos['complementos'].get('comercioe', False))
|
||||
if self._comercio_exterior:
|
||||
self._exportacion = datos['complementos']['comercioe'].pop('Exportacion')
|
||||
|
||||
self._divisas = datos['comprobante'].pop('divisas', '')
|
||||
|
||||
if 'nomina' in datos:
|
||||
self._is_nomina = True
|
||||
return self._validate_nomina(datos)
|
||||
|
||||
return True
|
||||
|
||||
def _validate_nomina(self, datos):
|
||||
comprobante = datos['comprobante']
|
||||
|
||||
validators = (
|
||||
('MetodoDePago', 'NA'),
|
||||
('TipoCambio', '1'),
|
||||
('Moneda', 'MXN'),
|
||||
('TipoDeComprobante', 'egreso'),
|
||||
)
|
||||
for f, v in validators:
|
||||
if f in comprobante:
|
||||
if v != comprobante[f]:
|
||||
msg = 'El atributo: {}, debe ser: {}'.format(f, v)
|
||||
self.error = msg
|
||||
return False
|
||||
return True
|
||||
|
||||
def _comprobante(self, datos):
|
||||
attributes = {}
|
||||
attributes['xmlns:{}'.format(self._pre)] = self._sat_cfdi['xmlns']
|
||||
attributes['xmlns:xsi'] = self._xsi
|
||||
|
||||
schema_locales = ''
|
||||
if self._impuestos_locales:
|
||||
name = 'xmlns:{}'.format(SAT['locales']['prefix'])
|
||||
attributes[name] = SAT['locales']['xmlns']
|
||||
schema_locales = SAT['locales']['schema']
|
||||
|
||||
schema_donativo = ''
|
||||
if self._donativo:
|
||||
name = 'xmlns:{}'.format(SAT['donativo']['prefix'])
|
||||
attributes[name] = SAT['donativo']['xmlns']
|
||||
schema_donativo = SAT['donativo']['schema']
|
||||
|
||||
schema_ine = ''
|
||||
if self._ine:
|
||||
name = 'xmlns:{}'.format(SAT['ine']['prefix'])
|
||||
attributes[name] = SAT['ine']['xmlns']
|
||||
schema_ine = SAT['ine']['schema']
|
||||
|
||||
schema_edu = ''
|
||||
if self._edu:
|
||||
name = 'xmlns:{}'.format(SAT['edu']['prefix'])
|
||||
attributes[name] = SAT['edu']['xmlns']
|
||||
schema_edu = SAT['edu']['schema']
|
||||
|
||||
schema_divisas = ''
|
||||
if self._divisas:
|
||||
name = 'xmlns:{}'.format(SAT['divisas']['prefix'])
|
||||
attributes[name] = SAT['divisas']['xmlns']
|
||||
schema_divisas = SAT['divisas']['schema']
|
||||
|
||||
schema_nomina = ''
|
||||
if self._is_nomina:
|
||||
name = 'xmlns:{}'.format(SAT['nomina']['prefix'])
|
||||
attributes[name] = SAT['nomina']['xmlns']
|
||||
schema_nomina = SAT['nomina']['schema']
|
||||
|
||||
schema_pagos = ''
|
||||
if self._pagos:
|
||||
name = 'xmlns:{}'.format(SAT['pagos']['prefix'])
|
||||
attributes[name] = SAT['pagos']['xmlns']
|
||||
schema_pagos = SAT['pagos']['schema']
|
||||
|
||||
schema_leyendas = ''
|
||||
if self._leyendas:
|
||||
name = 'xmlns:{}'.format(SAT['leyendas']['prefix'])
|
||||
attributes[name] = SAT['leyendas']['xmlns']
|
||||
schema_leyendas = SAT['leyendas']['schema']
|
||||
|
||||
schema_carta_porte = ''
|
||||
if self._carta_porte:
|
||||
name = 'xmlns:{}'.format(SAT['cartaporte']['prefix'])
|
||||
attributes[name] = SAT['cartaporte']['xmlns']
|
||||
schema_carta_porte = SAT['cartaporte']['schema']
|
||||
|
||||
schema_comercioe = ''
|
||||
if self._comercio_exterior:
|
||||
name = 'xmlns:{}'.format(SAT['comercioe']['prefix'])
|
||||
attributes[name] = SAT['comercioe']['xmlns']
|
||||
schema_carta_porte = SAT['comercioe']['schema']
|
||||
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
||||
schema_locales + schema_donativo + schema_ine + schema_edu + \
|
||||
schema_divisas + schema_nomina + schema_pagos + schema_leyendas + \
|
||||
schema_carta_porte + schema_comercioe
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema']
|
||||
attributes.update(datos)
|
||||
|
||||
#~ if DEBUG:
|
||||
#~ attributes['Fecha'] = self._now()
|
||||
#~ attributes['NoCertificado'] = CERT_NUM
|
||||
|
||||
if not 'Version' in attributes:
|
||||
attributes['Version'] = self._sat_cfdi['version']
|
||||
if not 'Fecha' in attributes:
|
||||
attributes['Fecha'] = self._now()
|
||||
|
||||
# ~ cfdi4
|
||||
if not 'Exportacion' in attributes:
|
||||
attributes['Exportacion'] = self._exportacion
|
||||
|
||||
self._tipo_de_comprobante = attributes['TipoDeComprobante']
|
||||
|
||||
self._cfdi = ET.Element('{}:Comprobante'.format(self._pre), attributes)
|
||||
return
|
||||
|
||||
def _informacion_global(self, datos):
|
||||
if not datos:
|
||||
return
|
||||
|
||||
node_name = '{}:InformacionGlobal'.format(self._pre)
|
||||
node = ET.SubElement(self._cfdi, node_name, datos)
|
||||
return
|
||||
|
||||
def _relacionados(self, datos):
|
||||
if not datos or not datos['tipo'] or not datos['cfdis']:
|
||||
return
|
||||
|
||||
node_name = '{}:CfdiRelacionados'.format(self._pre)
|
||||
value = {'TipoRelacion': datos['tipo']}
|
||||
node = ET.SubElement(self._cfdi, node_name, value)
|
||||
for uuid in datos['cfdis']:
|
||||
node_name = '{}:CfdiRelacionado'.format(self._pre)
|
||||
value = {'UUID': uuid}
|
||||
ET.SubElement(node, node_name, value)
|
||||
return
|
||||
|
||||
def _emisor(self, datos):
|
||||
#~ if DEBUG:
|
||||
#~ datos['Rfc'] = RFC_TEST
|
||||
|
||||
node_name = '{}:Emisor'.format(self._pre)
|
||||
emisor = ET.SubElement(self._cfdi, node_name, datos)
|
||||
return
|
||||
|
||||
def _receptor(self, datos):
|
||||
receptor_name = datos['Nombre'].upper()
|
||||
if receptor_name == PUBLIC and self._tipo_de_comprobante == CFDI_EGRESO:
|
||||
receptor_name = datos['Nombre']
|
||||
datos['Nombre'] = receptor_name
|
||||
node_name = '{}:Receptor'.format(self._pre)
|
||||
emisor = ET.SubElement(self._cfdi, node_name, datos)
|
||||
return
|
||||
|
||||
def _conceptos(self, datos):
|
||||
from xml.sax.saxutils import escape, unescape
|
||||
|
||||
conceptos = ET.SubElement(self._cfdi, '{}:Conceptos'.format(self._pre))
|
||||
# ~ for row in reversed(datos):
|
||||
for row in datos:
|
||||
complemento = {}
|
||||
if 'complemento' in row:
|
||||
complemento = row.pop('complemento')
|
||||
cuenta_predial = row.pop('CuentaPredial', '')
|
||||
pedimento = row.pop('Pedimento', '')
|
||||
student = row.pop('student', '')
|
||||
|
||||
taxes = {}
|
||||
if 'impuestos' in row:
|
||||
|
@ -370,26 +161,36 @@ class CFDI(object):
|
|||
ET.SubElement(
|
||||
retenciones, '{}:Retencion'.format(self._pre), retencion)
|
||||
|
||||
if pedimento:
|
||||
attributes = {'NumeroPedimento': pedimento}
|
||||
node_name = '{}:InformacionAduanera'.format(self._pre)
|
||||
ET.SubElement(concepto, node_name, attributes)
|
||||
if 'InformacionAduanera' in row:
|
||||
for field in fields:
|
||||
if field in row['InformacionAduanera']:
|
||||
attributes[field] = row['InformacionAduanera'][field]
|
||||
if attributes:
|
||||
node_name = '{}:InformacionAduanera'.format(self._pre)
|
||||
ET.SubElement(concepto, node_name, attributes)
|
||||
|
||||
if cuenta_predial:
|
||||
attributes = {'Numero': cuenta_predial}
|
||||
if 'CuentaPredial' in row:
|
||||
attributes = {'numero': row['CuentaPredial']}
|
||||
node_name = '{}:CuentaPredial'.format(self._pre)
|
||||
ET.SubElement(concepto, node_name, attributes)
|
||||
|
||||
if student:
|
||||
if 'autRVOE' in row:
|
||||
fields = (
|
||||
'version',
|
||||
'nombreAlumno',
|
||||
'CURP',
|
||||
'nivelEducativo',
|
||||
'autRVOE',
|
||||
)
|
||||
for field in fields:
|
||||
if field in row['autRVOE']:
|
||||
attributes[field] = row['autRVOE'][field]
|
||||
node_name = '{}:ComplementoConcepto'.format(self._pre)
|
||||
complemento = ET.SubElement(concepto, node_name)
|
||||
ET.SubElement(complemento, 'iedu:instEducativas', student)
|
||||
ET.SubElement(complemento, 'iedu:instEducativas', attributes)
|
||||
return
|
||||
|
||||
def _impuestos(self, datos):
|
||||
if self._is_nomina or not datos:
|
||||
return
|
||||
|
||||
if not datos:
|
||||
node_name = '{}:Impuestos'.format(self._pre)
|
||||
ET.SubElement(self._cfdi, node_name)
|
||||
|
@ -400,10 +201,6 @@ class CFDI(object):
|
|||
for field in fields:
|
||||
if field in datos:
|
||||
attributes[field] = datos[field]
|
||||
|
||||
if not attributes:
|
||||
return
|
||||
|
||||
node_name = '{}:Impuestos'.format(self._pre)
|
||||
impuestos = ET.SubElement(self._cfdi, node_name, attributes)
|
||||
|
||||
|
@ -419,276 +216,93 @@ class CFDI(object):
|
|||
return
|
||||
|
||||
def _nomina(self, datos):
|
||||
pre = SAT['nomina']['prefix']
|
||||
sat_nomina = SAT[NOMINA_ACTUAL]
|
||||
pre = sat_nomina['prefix']
|
||||
complemento = ET.SubElement(self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
|
||||
if self._complemento is None:
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
|
||||
emisor = datos.pop('emisor', None)
|
||||
receptor = datos.pop('receptor', None)
|
||||
percepciones = datos.pop('percepciones', None)
|
||||
deducciones = datos.pop('deducciones', None)
|
||||
otros_pagos = datos.pop('otros_pagos', ())
|
||||
incapacidades = datos.pop('incapacidades', ())
|
||||
|
||||
nomina = ET.SubElement(
|
||||
self._complemento, '{}:Nomina'.format(pre), datos['nomina'])
|
||||
|
||||
if emisor:
|
||||
ET.SubElement(nomina, '{}:Emisor'.format(pre), emisor)
|
||||
|
||||
if receptor:
|
||||
node = ET.SubElement(nomina, '{}:Receptor'.format(pre), receptor)
|
||||
|
||||
if percepciones:
|
||||
details = percepciones.pop('details', None)
|
||||
hours_extra = percepciones.pop('hours_extra', None)
|
||||
separacion = percepciones.pop('separacion', None)
|
||||
if details:
|
||||
node = ET.SubElement(nomina, '{}:Percepciones'.format(pre), percepciones)
|
||||
for row in details:
|
||||
nodep = ET.SubElement(node, '{}:Percepcion'.format(pre), row)
|
||||
if row['TipoPercepcion'] == '019' and hours_extra:
|
||||
for he in hours_extra:
|
||||
ET.SubElement(nodep, '{}:HorasExtra'.format(pre), he)
|
||||
hours_extra = None
|
||||
if separacion:
|
||||
ET.SubElement(node, '{}:SeparacionIndemnizacion'.format(pre), separacion)
|
||||
|
||||
if deducciones:
|
||||
details = deducciones.pop('details', None)
|
||||
if details:
|
||||
deducciones = ET.SubElement(nomina, '{}:Deducciones'.format(pre), deducciones)
|
||||
for row in details:
|
||||
ET.SubElement(deducciones, '{}:Deduccion'.format(pre), row)
|
||||
|
||||
if otros_pagos:
|
||||
node = ET.SubElement(nomina, '{}:OtrosPagos'.format(pre))
|
||||
for row in otros_pagos:
|
||||
subsidio = row.pop('subsidio', None)
|
||||
subnode = ET.SubElement(node, '{}:OtroPago'.format(pre), row)
|
||||
if subsidio:
|
||||
ET.SubElement(subnode, '{}:SubsidioAlEmpleo'.format(pre), subsidio)
|
||||
|
||||
if incapacidades:
|
||||
node = ET.SubElement(nomina, '{}:Incapacidades'.format(pre))
|
||||
for row in incapacidades:
|
||||
ET.SubElement(node, '{}:Incapacidad'.format(pre), row)
|
||||
return
|
||||
|
||||
def _locales(self, datos):
|
||||
if not self._impuestos_locales:
|
||||
return
|
||||
|
||||
if self._complemento is None:
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
emisor = datos.pop('Emisor', None)
|
||||
receptor = datos.pop('Receptor', None)
|
||||
percepciones = datos.pop('Percepciones', None)
|
||||
deducciones = datos.pop('Deducciones', None)
|
||||
|
||||
attributes = {}
|
||||
attributes['version'] = SAT['locales']['version']
|
||||
if not datos['total_locales_trasladados']:
|
||||
datos['total_locales_trasladados'] = '0.00'
|
||||
attributes['TotaldeTraslados'] = datos['total_locales_trasladados']
|
||||
if not datos['total_locales_retenciones']:
|
||||
datos['total_locales_retenciones'] = '0.00'
|
||||
attributes['TotaldeRetenciones'] = datos['total_locales_retenciones']
|
||||
|
||||
node = ET.SubElement(
|
||||
self._complemento, 'implocal:ImpuestosLocales', attributes)
|
||||
|
||||
for retencion in datos['locales_retenciones']:
|
||||
ET.SubElement(node, 'implocal:RetencionesLocales', retencion)
|
||||
for traslado in datos['locales_trasladados']:
|
||||
ET.SubElement(node, 'implocal:TrasladosLocales', traslado)
|
||||
return
|
||||
|
||||
def _donatarias(self, datos):
|
||||
if not datos:
|
||||
return
|
||||
|
||||
if self._complemento is None:
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
|
||||
attributes = {}
|
||||
attributes['version'] = SAT['donativo']['version']
|
||||
attributes['leyenda'] = SAT['donativo']['leyenda']
|
||||
attributes['xmlns:{}'.format(pre)] = sat_nomina['xmlns']
|
||||
attributes['xsi:schemaLocation'] = sat_nomina['schema']
|
||||
attributes.update(datos)
|
||||
|
||||
node = ET.SubElement(self._complemento, 'donat:Donatarias', attributes)
|
||||
|
||||
return
|
||||
|
||||
def _complemento_comercio_exterior(self, datos):
|
||||
prefix = SAT['comercioe']['prefix']
|
||||
|
||||
emisor = datos.pop('emisor')
|
||||
propietarios = datos.pop('propietarios', {})
|
||||
receptor = datos.pop('receptor')
|
||||
destinatario = datos.pop('destinatario', {})
|
||||
mercancias = datos.pop('mercancias')
|
||||
|
||||
attr = {'Version': SAT['comercioe']['version']}
|
||||
attr.update(datos)
|
||||
ce = ET.SubElement(
|
||||
self._complemento, f'{prefix}:ComercioExterior', attr)
|
||||
|
||||
attributes = {}
|
||||
if 'Curp' in emisor:
|
||||
attributes = {'Curp': emisor.pop('Curp')}
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
|
||||
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in receptor:
|
||||
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
|
||||
node = ET.SubElement(ce, '{}:Receptor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), receptor)
|
||||
|
||||
node = ET.SubElement(ce, '{}:Mercancias'.format(prefix))
|
||||
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
|
||||
for row in mercancias:
|
||||
detalle = {}
|
||||
for f in fields:
|
||||
if f in row and row[f]:
|
||||
detalle[f] = row[f]
|
||||
row.pop(f)
|
||||
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
|
||||
if detalle:
|
||||
ET.SubElement(
|
||||
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
|
||||
if not 'Version' in attributes:
|
||||
attributes['Version'] = sat_nomina['version']
|
||||
|
||||
nomina = ET.SubElement(complemento, '{}:Nomina'.format(pre), attributes)
|
||||
if emisor:
|
||||
ET.SubElement(nomina, '{}:Emisor'.format(pre), emisor)
|
||||
if receptor:
|
||||
ET.SubElement(nomina, '{}:Receptor'.format(pre), receptor)
|
||||
if percepciones:
|
||||
detalle = percepciones.pop('detalle', None)
|
||||
percepciones = ET.SubElement(nomina, '{}:Percepciones'.format(pre), percepciones)
|
||||
for row in detalle:
|
||||
ET.SubElement(percepciones, '{}:Percepcion'.format(pre), row)
|
||||
if deducciones:
|
||||
detalle = deducciones.pop('detalle', None)
|
||||
deducciones = ET.SubElement(nomina, '{}:Deducciones'.format(pre), deducciones)
|
||||
for row in detalle:
|
||||
ET.SubElement(deducciones, '{}:Deduccion'.format(pre), row)
|
||||
return
|
||||
|
||||
def _complementos(self, datos):
|
||||
if not datos:
|
||||
return
|
||||
complemento = ET.SubElement(self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
if 'ce' in datos:
|
||||
pre = 'cce11'
|
||||
datos = datos.pop('ce')
|
||||
emisor = datos.pop('emisor')
|
||||
propietario = datos.pop('propietario')
|
||||
receptor = datos.pop('receptor')
|
||||
destinatario = datos.pop('destinatario')
|
||||
conceptos = datos.pop('conceptos')
|
||||
|
||||
if self._complemento is None:
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
attributes = {}
|
||||
attributes['xmlns:{}'.format(pre)] = \
|
||||
'http://www.sat.gob.mx/ComercioExterior11'
|
||||
attributes['xsi:schemaLocation'] = \
|
||||
'http://www.sat.gob.mx/ComercioExterior11 ' \
|
||||
'http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd'
|
||||
attributes.update(datos)
|
||||
ce = ET.SubElement(
|
||||
complemento, '{}:ComercioExterior'.format(pre), attributes)
|
||||
|
||||
if self._carta_porte:
|
||||
datos = datos['cartaporte']
|
||||
ubicaciones = datos.pop('ubicaciones')
|
||||
mercancias = datos.pop('mercancias', ())
|
||||
tiposfigura = datos.pop('tiposfigura', ())
|
||||
attributes = {}
|
||||
if 'Curp' in emisor:
|
||||
attributes = {'Curp': emisor.pop('Curp')}
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), emisor)
|
||||
|
||||
autotransporte = datos.pop('autotransporte', {})
|
||||
identificacion = autotransporte.pop('identificacion')
|
||||
seguros = autotransporte.pop('seguros')
|
||||
remolques = autotransporte.pop('remolques')
|
||||
if propietario:
|
||||
ET.SubElement(ce, '{}:Propietario'.format(pre), propietario)
|
||||
|
||||
atributos = {'Version': SAT['cartaporte']['version']}
|
||||
atributos.update(datos)
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in receptor:
|
||||
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
|
||||
node = ET.SubElement(ce, '{}:Receptor'.format(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), receptor)
|
||||
|
||||
prefix = SAT['cartaporte']['prefix']
|
||||
node_carta = ET.SubElement(self._complemento, f'{prefix}:CartaPorte', atributos)
|
||||
|
||||
node = ET.SubElement(node_carta, f'{prefix}:Ubicaciones')
|
||||
for ubicacion in ubicaciones:
|
||||
domicilio = ubicacion.pop('domicilio', {})
|
||||
dt = parser.parse(ubicacion['FechaHoraSalidaLlegada'])
|
||||
ubicacion['FechaHoraSalidaLlegada'] = dt.isoformat()[:19]
|
||||
sub_node = ET.SubElement(node, f'{prefix}:Ubicacion', ubicacion)
|
||||
if domicilio:
|
||||
ET.SubElement(sub_node, f'{prefix}:Domicilio', domicilio)
|
||||
|
||||
attr = mercancias
|
||||
mercancias = attr.pop('mercancias')
|
||||
|
||||
node = ET.SubElement(node_carta, f'{prefix}:Mercancias', attr)
|
||||
for mercancia in mercancias:
|
||||
ET.SubElement(node, f'{prefix}:Mercancia', mercancia)
|
||||
|
||||
sub_node = ET.SubElement(node, f'{prefix}:Autotransporte', autotransporte)
|
||||
ET.SubElement(sub_node, f'{prefix}:IdentificacionVehicular', identificacion)
|
||||
ET.SubElement(sub_node, f'{prefix}:Seguros', seguros)
|
||||
if remolques:
|
||||
node_remolques = ET.SubElement(sub_node, f'{prefix}:Remolques')
|
||||
for remolque in remolques:
|
||||
ET.SubElement(node_remolques, f'{prefix}:Remolque', remolque)
|
||||
|
||||
if tiposfigura:
|
||||
sub_node = ET.SubElement(node_carta, f'{prefix}:FiguraTransporte')
|
||||
for figura in tiposfigura:
|
||||
ET.SubElement(sub_node, f'{prefix}:TiposFigura', figura)
|
||||
|
||||
if self._divisas:
|
||||
atributos = {
|
||||
'version': SAT['divisas']['version'],
|
||||
'tipoOperacion': self._divisas,
|
||||
}
|
||||
ET.SubElement(self._complemento, 'divisas:Divisas', atributos)
|
||||
|
||||
if 'ine' in datos:
|
||||
atributos = {'Version': SAT['ine']['version']}
|
||||
ine_key_entidad = datos['ine'].pop('ClaveEntidad', '')
|
||||
ine_ambito = datos['ine'].pop('Ambito', '')
|
||||
if ine_key_entidad:
|
||||
ine_id_conta = datos['ine'].pop('IdContabilidad', '')
|
||||
atributos.update(datos['ine'])
|
||||
node_ine = ET.SubElement(self._complemento, 'ine:INE', atributos)
|
||||
if ine_key_entidad:
|
||||
attr = {'ClaveEntidad': ine_key_entidad}
|
||||
if ine_ambito:
|
||||
attr['Ambito'] = ine_ambito
|
||||
node_entidad = ET.SubElement(node_ine, 'ine:Entidad', attr)
|
||||
attr = {'IdContabilidad': ine_id_conta}
|
||||
ET.SubElement(node_entidad, 'ine:Contabilidad', attr)
|
||||
|
||||
if 'pagos' in datos:
|
||||
datos = datos.pop('pagos')
|
||||
totales = datos.pop('totales')
|
||||
relacionados = datos.pop('relacionados')
|
||||
taxes_pay = datos.pop('taxes_pay')
|
||||
pre = SAT['pagos']['prefix']
|
||||
|
||||
attributes = {'Version': SAT['pagos']['version']}
|
||||
pagos = ET.SubElement(
|
||||
self._complemento, '{}:Pagos'.format(pre), attributes)
|
||||
|
||||
ET.SubElement(pagos, '{}:Totales'.format(pre), totales)
|
||||
|
||||
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
||||
for row in relacionados:
|
||||
taxes = row.pop('taxes')
|
||||
node = ET.SubElement(node_pago, f'{pre}:DoctoRelacionado', row)
|
||||
nodex_tax = None
|
||||
if taxes['traslados'] or taxes['retenciones']:
|
||||
node_tax = ET.SubElement(node, f'{pre}:ImpuestosDR')
|
||||
if taxes['retenciones']:
|
||||
node = ET.SubElement(node_tax, f'{pre}:RetencionesDR')
|
||||
for tax in taxes['retenciones']:
|
||||
ET.SubElement(node, f'{pre}:RetencionDR', tax)
|
||||
if taxes['traslados']:
|
||||
node = ET.SubElement(node_tax, f'{pre}:TrasladosDR')
|
||||
for tax in taxes['traslados']:
|
||||
ET.SubElement(node, f'{pre}:TrasladoDR', tax)
|
||||
|
||||
if taxes_pay['traslados'] or taxes_pay['retenciones']:
|
||||
node_tax = ET.SubElement(node_pago, f'{pre}:ImpuestosP')
|
||||
if taxes_pay['retenciones']:
|
||||
node = ET.SubElement(node_tax, f'{pre}:RetencionesP')
|
||||
for key, importe in taxes_pay['retenciones'].items():
|
||||
attr = {'ImpuestoP': key, 'ImporteP': importe}
|
||||
ET.SubElement(node, f'{pre}:RetencionP', attr)
|
||||
if taxes_pay['traslados']:
|
||||
node = ET.SubElement(node_tax, f'{pre}:TrasladosP')
|
||||
for key, tax in taxes_pay['traslados'].items():
|
||||
ET.SubElement(node, f'{pre}:TrasladoP', tax)
|
||||
|
||||
if 'leyendas' in datos:
|
||||
pre = SAT['leyendas']['prefix']
|
||||
attributes = {'version': SAT['leyendas']['version']}
|
||||
node_leyend = ET.SubElement(
|
||||
self._complemento, '{}:LeyendasFiscales'.format(pre), attributes)
|
||||
for leyend in datos['leyendas']:
|
||||
ET.SubElement(node_leyend, '{}:Leyenda'.format(pre), leyend)
|
||||
|
||||
if self._comercio_exterior:
|
||||
datos = datos.pop('comercioe')
|
||||
self._complemento_comercio_exterior(datos)
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in destinatario:
|
||||
attributes = {'NumRegIdTrib': destinatario.pop('NumRegIdTrib')}
|
||||
if 'Nombre' in destinatario:
|
||||
attributes.update({'Nombre': destinatario.pop('Nombre')})
|
||||
node = ET.SubElement(ce, '{}:Destinatario'.format(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), destinatario)
|
||||
|
||||
node = ET.SubElement(ce, '{}:Mercancias'.format(pre))
|
||||
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
|
||||
for row in conceptos:
|
||||
detalle = {}
|
||||
for f in fields:
|
||||
if f in row:
|
||||
detalle[f] = row.pop(f)
|
||||
concepto = ET.SubElement(node, '{}:Mercancia'.format(pre), row)
|
||||
if detalle:
|
||||
ET.SubElement(
|
||||
concepto, '{}:DescripcionesEspecificas'.format(pre), detalle)
|
||||
return
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import io
|
||||
import os
|
||||
#~ import falcon
|
||||
import re
|
||||
import smtplib
|
||||
import ssl
|
||||
import collections
|
||||
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
from collections import OrderedDict
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.base import MIMEBase
|
||||
|
@ -16,12 +12,6 @@ from email.mime.text import MIMEText
|
|||
from email import encoders
|
||||
from email.utils import formatdate
|
||||
|
||||
import requests
|
||||
try:
|
||||
from escpos import printer
|
||||
except ImportError:
|
||||
printer = None
|
||||
|
||||
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Image
|
||||
from reportlab.lib import colors
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
|
@ -32,9 +22,6 @@ from reportlab.platypus import Paragraph, Table, TableStyle, Spacer
|
|||
from reportlab.pdfgen import canvas
|
||||
|
||||
|
||||
CANCEL = False
|
||||
|
||||
|
||||
#~ https://github.com/kennethreitz/requests/blob/v1.2.3/requests/structures.py#L37
|
||||
class CaseInsensitiveDict(collections.MutableMapping):
|
||||
"""A case-insensitive ``dict``-like object.
|
||||
|
@ -114,20 +101,12 @@ class NumLet(object):
|
|||
def letras(self):
|
||||
return self._letras.upper()
|
||||
|
||||
def _letters(self, numero, currency='MXN'):
|
||||
# ~ print (currency)
|
||||
monedas = {
|
||||
'MXN': 'peso',
|
||||
'USD': 'dólar',
|
||||
'EUR': 'euro',
|
||||
}
|
||||
moneda = monedas.get(currency, currency)
|
||||
tf = {
|
||||
'MXN': 'm.n.',
|
||||
}
|
||||
#~ def _letters(self, numero, moneda='peso', texto_inicial='-(',
|
||||
#~ texto_final='/100 m.n.)-', fraccion_letras=False, fraccion=''):
|
||||
def _letters(self, numero, moneda='peso'):
|
||||
|
||||
texto_inicial = '-('
|
||||
texto_final = '/100 {})-'.format(tf.get(currency, currency))
|
||||
texto_final = '/100 m.n.)-'
|
||||
fraccion_letras = False
|
||||
fraccion = ''
|
||||
|
||||
|
@ -269,18 +248,10 @@ class SendMail(object):
|
|||
|
||||
def _login(self):
|
||||
try:
|
||||
if self._config['ssl'] and self._config['starttls']:
|
||||
self._server = smtplib.SMTP(
|
||||
self._config['servidor'],
|
||||
self._config['puerto'], timeout=10)
|
||||
self._server.ehlo()
|
||||
self._server.starttls()
|
||||
self._server.ehlo()
|
||||
elif self._config['ssl']:
|
||||
if self._config['ssl']:
|
||||
self._server = smtplib.SMTP_SSL(
|
||||
self._config['servidor'],
|
||||
self._config['puerto'], timeout=10)
|
||||
self._server.ehlo()
|
||||
else:
|
||||
self._server = smtplib.SMTP(
|
||||
self._config['servidor'],
|
||||
|
@ -291,7 +262,6 @@ class SendMail(object):
|
|||
if '535' in str(e):
|
||||
self._error = 'Nombre de usuario o contraseña inválidos'
|
||||
return False
|
||||
# ~ print (e)
|
||||
if '534' in str(e) and 'gmail' in self._config['servidor']:
|
||||
self._error = 'Necesitas activar el acceso a otras ' \
|
||||
'aplicaciones en tu cuenta de GMail'
|
||||
|
@ -312,15 +282,10 @@ class SendMail(object):
|
|||
message['CC'] = options['copia']
|
||||
message['Subject'] = options['asunto']
|
||||
message['Date'] = formatdate(localtime=True)
|
||||
if options['confirmar']:
|
||||
message['Disposition-Notification-To'] = message['From']
|
||||
message.attach(MIMEText(options['mensaje'], 'html'))
|
||||
for f in options['files']:
|
||||
part = MIMEBase('application', 'octet-stream')
|
||||
if isinstance(f[0], str):
|
||||
part.set_payload(f[0].encode('utf-8'))
|
||||
else:
|
||||
part.set_payload(f[0])
|
||||
part.set_payload(f[0])
|
||||
encoders.encode_base64(part)
|
||||
part.add_header(
|
||||
'Content-Disposition',
|
||||
|
@ -344,7 +309,6 @@ class SendMail(object):
|
|||
|
||||
class NumberedCanvas(canvas.Canvas):
|
||||
X = 20.59 * cm
|
||||
XC = 21.6 * cm / 2 + 1.5 * cm
|
||||
Y = 1.5 * cm
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -362,33 +326,19 @@ class NumberedCanvas(canvas.Canvas):
|
|||
for state in self._saved_page_states:
|
||||
self.__dict__.update(state)
|
||||
self.draw_page_number(page_count)
|
||||
self.draw_cancel()
|
||||
canvas.Canvas.showPage(self)
|
||||
canvas.Canvas.save(self)
|
||||
return
|
||||
|
||||
def draw_page_number(self, page_count):
|
||||
self.setFont('Helvetica', 8)
|
||||
# ~ self.setFillColor(colors.darkred)
|
||||
text = f'Página {self._pageNumber} de {page_count}'
|
||||
self.setFillColor(colors.darkred)
|
||||
text = 'Página {} de {}'.format(self._pageNumber, page_count)
|
||||
self.drawRightString(self.X, self.Y, text)
|
||||
|
||||
text = 'Este documento es una representación impresa de un CFDI'
|
||||
self.drawCentredString(self.XC, self.Y, text)
|
||||
|
||||
text = 'Factura elaborada con software libre'
|
||||
text = 'Factura elaborada con software libre: www.empresalibre.net'
|
||||
self.drawString(1.5 * cm, 1.5 * cm, text)
|
||||
return
|
||||
|
||||
def draw_cancel(self):
|
||||
global CANCEL
|
||||
if CANCEL:
|
||||
self.rotate(45)
|
||||
self.setFont('Helvetica', 100)
|
||||
self.setFillColor(colors.red)
|
||||
text = 'Cancelada'
|
||||
self.drawCentredString(20 * cm, 3 * cm, text)
|
||||
return
|
||||
|
||||
class TemplateInvoice(BaseDocTemplate):
|
||||
|
||||
|
@ -437,9 +387,6 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
def _emisor(self, styles, data):
|
||||
logo_path = data.pop('logo', '')
|
||||
logo_style = styles.pop('logo', {})
|
||||
logo_path2 = data.pop('logo2', '')
|
||||
logo_style2 = styles.pop('logo2', {})
|
||||
sucursales = styles.pop('sucursales', {})
|
||||
|
||||
for k, v in styles.items():
|
||||
self._set_text(styles[k], data.get(k, ''))
|
||||
|
@ -450,28 +397,6 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
for k in keys:
|
||||
rect[k] = rect[k] * cm
|
||||
self.canv.drawImage(logo_path, **rect)
|
||||
|
||||
if logo_path2 and logo_style2:
|
||||
rect = logo_style2['rectangulo']
|
||||
keys = ('x', 'y', 'width', 'height')
|
||||
for k in keys:
|
||||
rect[k] = rect[k] * cm
|
||||
self.canv.drawImage(logo_path2, **rect)
|
||||
|
||||
if sucursales:
|
||||
for k, sucursal in sucursales.items():
|
||||
values = sucursal.pop('textos')
|
||||
x = sucursal['rectangulo']['x']
|
||||
y = sucursal['rectangulo']['y']
|
||||
w = sucursal['rectangulo']['width']
|
||||
h = sucursal['rectangulo']['height']
|
||||
for v in values:
|
||||
self._set_text(sucursal, v)
|
||||
y -= h
|
||||
sucursal['rectangulo']['x'] = x
|
||||
sucursal['rectangulo']['y'] = y
|
||||
sucursal['rectangulo']['width'] = w
|
||||
sucursal['rectangulo']['height'] = h
|
||||
return
|
||||
|
||||
def _receptor(self, styles, data):
|
||||
|
@ -493,7 +418,6 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
|
||||
def _comprobante1(self, styles, data):
|
||||
title = styles.pop('titulo', {})
|
||||
self.canv.setTitle(f"Factura {data.get('seriefolio', '')}")
|
||||
|
||||
for k, v in styles.items():
|
||||
self._set_text(styles[k], data.get(k, ''))
|
||||
|
@ -525,12 +449,6 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
fields = ('valorunitario', 'importe')
|
||||
if field in fields:
|
||||
return self._currency(value)
|
||||
|
||||
if field == 'descripcion':
|
||||
html = '<font color="black" size=7>{}</font>'
|
||||
style_bt = getSampleStyleSheet()['BodyText']
|
||||
return Paragraph(html.format(value), style_bt)
|
||||
|
||||
return value
|
||||
|
||||
def _conceptos(self, conceptos):
|
||||
|
@ -566,8 +484,8 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
('GRID', (0, 0), (-1, -1), 0.05 * cm, colors.white),
|
||||
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
||||
('FONTSIZE', (0, 0), (-1, -1), 8),
|
||||
('BACKGROUND', (1, 0), (-1, -1), colors.lightgrey),
|
||||
('TEXTCOLOR', (1, 0), (-1, -1), colors.black),
|
||||
('BACKGROUND', (1, 0), (-1, -1), colors.linen),
|
||||
('TEXTCOLOR', (1, 0), (-1, -1), colors.darkred),
|
||||
('FACE', (1, 0), (-1, -1), 'Helvetica-Bold'),
|
||||
]
|
||||
table = Table(rows, colWidths=widths, spaceBefore=0.25*cm)
|
||||
|
@ -575,7 +493,7 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
return table
|
||||
|
||||
def _comprobante2(self, styles, data):
|
||||
leyendas = styles.pop('leyendas', {})
|
||||
leyenda = styles.pop('leyenda', {})
|
||||
|
||||
ls = []
|
||||
for k, v in styles.items():
|
||||
|
@ -583,27 +501,17 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
if 'spaceBefore' in v['estilo']:
|
||||
v['estilo']['spaceBefore'] = v['estilo']['spaceBefore'] * cm
|
||||
ps = ParagraphStyle(**v['estilo'])
|
||||
p = Paragraph(escape(data[k]), ps)
|
||||
ls.append(p)
|
||||
elif k=='formametodopago':
|
||||
ps = ParagraphStyle(**v['estilo'])
|
||||
v = f"{data['formadepago']} - {data['metododepago']}"
|
||||
p = Paragraph(v, ps)
|
||||
ls.append(p)
|
||||
elif k=='monedatipocambio':
|
||||
ps = ParagraphStyle(**v['estilo'])
|
||||
v = f"{data['moneda']} - {data['tipocambio']}"
|
||||
p = Paragraph(v, ps)
|
||||
p = Paragraph(data[k], ps)
|
||||
ls.append(p)
|
||||
|
||||
cbb = Image(data['cbb'])
|
||||
cbb = Image(data['path_cbb'])
|
||||
cbb.drawHeight = 4 * cm
|
||||
cbb.drawWidth = 4 * cm
|
||||
|
||||
style_bt = getSampleStyleSheet()['BodyText']
|
||||
style_bt.leading = 8
|
||||
html_t = '<b><font size=6>{}</font></b>'
|
||||
html = '<font color="black" size=5>{}</font>'
|
||||
html = '<font color="darkred" size=5>{}</font>'
|
||||
msg = 'Cadena original del complemento de certificación digital del SAT'
|
||||
rows = [
|
||||
(cbb, Paragraph(html_t.format('Sello Digital del CFDI'), style_bt)),
|
||||
|
@ -619,13 +527,13 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
('FONTSIZE', (0, 0), (-1, -1), 6),
|
||||
('SPAN', (0, 0), (0, -1)),
|
||||
('FACE', (1, 0), (1, 0), 'Helvetica-Bold'),
|
||||
('BACKGROUND', (1, 1), (1, 1), colors.lightgrey),
|
||||
('BACKGROUND', (1, 1), (1, 1), colors.linen),
|
||||
('TEXTCOLOR', (1, 1), (1, 1), colors.darkred),
|
||||
('FACE', (1, 2), (1, 2), 'Helvetica-Bold'),
|
||||
('BACKGROUND', (1, 3), (1, 3), colors.lightgrey),
|
||||
('BACKGROUND', (1, 3), (1, 3), colors.linen),
|
||||
('TEXTCOLOR', (1, 3), (1, 3), colors.darkred),
|
||||
('FACE', (1, 4), (1, 4), 'Helvetica-Bold'),
|
||||
('BACKGROUND', (1, 5), (1, 5), colors.lightgrey),
|
||||
('BACKGROUND', (1, 5), (1, 5), colors.linen),
|
||||
('TEXTCOLOR', (1, 5), (1, 5), colors.darkred),
|
||||
('ALIGN', (0, 0), (0, 0), 'CENTER'),
|
||||
('VALIGN', (0, 0), (0, 0), 'MIDDLE'),
|
||||
|
@ -634,14 +542,14 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
table.setStyle(TableStyle(table_styles))
|
||||
ls.append(table)
|
||||
|
||||
if leyendas:
|
||||
if 'spaceBefore' in leyendas['estilo']:
|
||||
leyendas['estilo']['spaceBefore'] = \
|
||||
leyendas['estilo']['spaceBefore'] * cm
|
||||
for t in leyendas['textos']:
|
||||
ps = ParagraphStyle(**leyendas['estilo'])
|
||||
p = Paragraph(t, ps)
|
||||
ls.append(p)
|
||||
if leyenda:
|
||||
if 'spaceBefore' in leyenda['estilo']:
|
||||
leyenda['estilo']['spaceBefore'] = \
|
||||
leyenda['estilo']['spaceBefore'] * cm
|
||||
msg = 'Este documento es una representación impresa de un CFDI'
|
||||
ps = ParagraphStyle(**leyenda['estilo'])
|
||||
p = Paragraph(msg, ps)
|
||||
ls.append(p)
|
||||
|
||||
return ls
|
||||
|
||||
|
@ -657,10 +565,8 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
return self._data
|
||||
@data.setter
|
||||
def data(self, values):
|
||||
global CANCEL
|
||||
# ~ print (values)
|
||||
#~ print (values)
|
||||
self._data = values
|
||||
CANCEL = self._data['cancelada']
|
||||
|
||||
rows = self._conceptos(self._data['conceptos'])
|
||||
widths = [2 * cm, 9 * cm, 1.5 * cm, 2 * cm, 2 * cm, 3 * cm]
|
||||
|
@ -670,13 +576,13 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
|
||||
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
|
||||
('FACE', (0, 0), (-1, 0), 'Helvetica-Bold'),
|
||||
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
|
||||
('BACKGROUND', (0, 0), (-1, 0), colors.darkred),
|
||||
('FONTSIZE', (0, 1), (-1, -1), 7),
|
||||
('VALIGN', (0, 1), (-1, -1), 'TOP'),
|
||||
('ALIGN', (0, 1), (0, -1), 'CENTER'),
|
||||
('ALIGN', (2, 1), (2, -1), 'CENTER'),
|
||||
('ALIGN', (3, 1), (5, -1), 'RIGHT'),
|
||||
('LINEBELOW', (0, 1), (-1, -1), 0.05 * cm, colors.grey),
|
||||
('LINEBELOW', (0, 1), (-1, -1), 0.05 * cm, colors.darkred),
|
||||
('LINEBEFORE', (0, 1), (-1, -1), 0.05 * cm, colors.white),
|
||||
]
|
||||
table_conceptos = Table(rows, colWidths=widths, repeatRows=1)
|
||||
|
@ -686,7 +592,7 @@ class TemplateInvoice(BaseDocTemplate):
|
|||
comprobante = self._comprobante2(
|
||||
self._custom_styles['comprobante'], self.data['comprobante'])
|
||||
|
||||
self._rows = [Spacer(0, 5.7 * cm), table_conceptos, totales] + comprobante
|
||||
self._rows = [Spacer(0, 6*cm), table_conceptos, totales] + comprobante
|
||||
|
||||
def render(self):
|
||||
frame = Frame(self.leftMargin, self.bottomMargin,
|
||||
|
@ -818,303 +724,3 @@ class ReportTemplate(BaseDocTemplate):
|
|||
return
|
||||
|
||||
|
||||
class SeaFileAPI(object):
|
||||
FILE_DOES_NOT_EXIST = 441
|
||||
|
||||
def __init__(self, url, username, password):
|
||||
self._url = url
|
||||
self._headers = self._get_auth(username, password)
|
||||
|
||||
@property
|
||||
def is_connect(self):
|
||||
return bool(self._headers)
|
||||
|
||||
def _open(self, path):
|
||||
return open(path, 'rb')
|
||||
|
||||
def _get_auth(self, username, password):
|
||||
url = self._url + 'auth-token/'
|
||||
data = {
|
||||
'username': username,
|
||||
'password': password,
|
||||
}
|
||||
resp = requests.post(url, data=data)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Token Error: {}'.format(resp.status_code)
|
||||
print (msg)
|
||||
return {}
|
||||
|
||||
headers = {'Authorization': 'Token {}'.format(resp.json()['token'])}
|
||||
return headers
|
||||
|
||||
def _get_upload_link(self, repo_id):
|
||||
if not self._headers:
|
||||
return ''
|
||||
|
||||
url = '{}repos/{}/upload-link/'.format(self._url, repo_id)
|
||||
resp = requests.get(url, headers=self._headers)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Error: {}'.format(resp.status_code)
|
||||
print (msg)
|
||||
return ''
|
||||
|
||||
return resp.json()
|
||||
|
||||
def _get_update_link(self, repo_id):
|
||||
if not self._headers:
|
||||
return ''
|
||||
|
||||
url = '{}repos/{}/update-link/'.format(self._url, repo_id)
|
||||
data = {'p': '/'}
|
||||
resp = requests.get(url, data=data, headers=self._headers)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Error: {}'.format(resp.status_code)
|
||||
print (msg)
|
||||
return ''
|
||||
|
||||
return resp.json()
|
||||
|
||||
def _decrypt(self, repo_id, password):
|
||||
if not self._headers:
|
||||
return False
|
||||
|
||||
url = '{}repos/{}/'.format(self._url, repo_id)
|
||||
data = {'password': password}
|
||||
resp = requests.post(url, data=data, headers=self._headers)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Error: {}'.format(resp.status_code)
|
||||
print (msg)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def upload_file(self, path_file, repo_id, relative_path, password=''):
|
||||
if not self._headers:
|
||||
return False
|
||||
|
||||
if password:
|
||||
if not self._decrypt(repo_id, password):
|
||||
return False
|
||||
|
||||
upload_link = self._get_upload_link(repo_id)
|
||||
if isinstance(path_file, tuple):
|
||||
obj_file = path_file[0]
|
||||
filename = path_file[1]
|
||||
else:
|
||||
obj_file = self._open(path_file)
|
||||
_, filename = self._info_path(path_file)
|
||||
|
||||
data = {
|
||||
# ~ 'filename': filename,
|
||||
'parent_dir': relative_path,
|
||||
'relative_path': '',
|
||||
}
|
||||
files = {'file': (filename, obj_file)}
|
||||
|
||||
resp = requests.post(
|
||||
upload_link, data=data, files=files, headers=self._headers)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Upload Code: {}\n{}'.format(resp.status_code, resp.text)
|
||||
print (msg)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _info_path(self, path):
|
||||
path, filename = os.path.split(path)
|
||||
return path, filename
|
||||
|
||||
def list_directory(self, repo_id):
|
||||
if not self._headers:
|
||||
return False
|
||||
|
||||
url = '{}repos/{}/dir/'.format(self._url, repo_id)
|
||||
params = {'p': '/', 't': 'd', 'recursive': '1'}
|
||||
try:
|
||||
resp = requests.get(url, params=params, headers=self._headers)
|
||||
return resp.json()
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
def create_dir(self, repo_id, name):
|
||||
url = '{}repos/{}/dir/'.format(self._url, repo_id)
|
||||
data = {'operation': 'mkdir'}
|
||||
params = {'p': name}
|
||||
resp = requests.post(url, data=data, headers=self._headers, params=params)
|
||||
if resp.status_code != requests.codes.created:
|
||||
msg = 'Create Dir Error: {}'.format(resp.status_code)
|
||||
print (msg)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _validate_directory(self, repo_id, target_file):
|
||||
if target_file == '/':
|
||||
return True
|
||||
|
||||
names = target_file.split('/')[:-1]
|
||||
directories = self.list_directory(repo_id)
|
||||
|
||||
if isinstance(directories, bool):
|
||||
return False
|
||||
|
||||
exists = False
|
||||
parent_dir = '/'
|
||||
name_dir = ''
|
||||
for name in names:
|
||||
name_dir += '/' + name
|
||||
for directory in directories:
|
||||
if name == directory['name'] and parent_dir == directory['parent_dir']:
|
||||
exists = True
|
||||
break
|
||||
if exists:
|
||||
exists = False
|
||||
else:
|
||||
self.create_dir(repo_id, name_dir)
|
||||
if parent_dir == '/':
|
||||
parent_dir += name
|
||||
else:
|
||||
parent_dir += '/' + name
|
||||
|
||||
return True
|
||||
|
||||
def update_file(self, path_file, repo_id, target_file, password, create=True):
|
||||
if not self._headers:
|
||||
return False
|
||||
|
||||
if not self._validate_directory(repo_id, target_file):
|
||||
return False
|
||||
|
||||
if password:
|
||||
if not self._decrypt(repo_id, password):
|
||||
return False
|
||||
|
||||
update_link = self._get_update_link(repo_id)
|
||||
if isinstance(path_file, tuple):
|
||||
obj_file = path_file[0]
|
||||
filename = path_file[1]
|
||||
else:
|
||||
obj_file = self._open(path_file)
|
||||
_, filename = self._info_path(path_file)
|
||||
|
||||
files = {
|
||||
'file': (filename, obj_file),
|
||||
'filename': (None, filename),
|
||||
'target_file': (None, '{}{}'.format(target_file, filename))
|
||||
}
|
||||
|
||||
resp = requests.post(update_link, files=files, headers=self._headers)
|
||||
if resp.status_code != requests.codes.ok:
|
||||
msg = 'Update Code: {}\n{}'.format(resp.status_code, resp.text)
|
||||
print (msg)
|
||||
if resp.status_code == self.FILE_DOES_NOT_EXIST and create:
|
||||
relative_path = '/'
|
||||
if target_file != '/':
|
||||
relative_path += target_file
|
||||
return self.upload_file(path_file, repo_id, relative_path, password)
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def ping(self):
|
||||
url = self._url + 'ping/'
|
||||
resp = requests.get(url)
|
||||
return resp.json()
|
||||
|
||||
|
||||
def auth_ping(self):
|
||||
url = self._url + 'auth/ping/'
|
||||
resp = requests.get(url, headers=self._headers)
|
||||
return resp.json()
|
||||
|
||||
|
||||
class PrintTicket(object):
|
||||
LINE = '------------------------------------------------\n'
|
||||
TITLES = 'CANT. U ARTICULO P.U. TOTAL\n'
|
||||
LEYENDA = 'GRACIAS POR SU COMPRA\n\nGuarde este ticket para cualquier ' \
|
||||
'aclaración.\nComprobante simplificado de operación con\npúblico en ' \
|
||||
'general de acuerdo al Art. 37\nFracc II inc. v del Reglamento del\n' \
|
||||
'Código Fiscal de la Federación.\n\n'
|
||||
|
||||
def __init__(self, info):
|
||||
self.p = self._init_printer(info)
|
||||
|
||||
def _init_printer(self, info):
|
||||
try:
|
||||
if info['ip']:
|
||||
p = printer.Network(info['ip'])
|
||||
else:
|
||||
p = printer.Usb(*info['usb'])
|
||||
p.codepage = 'cp850'
|
||||
return p
|
||||
except Exception as e:
|
||||
print (e)
|
||||
return
|
||||
|
||||
def _set(self, *data):
|
||||
self.p.set(*data)
|
||||
return
|
||||
|
||||
def _t(self, text):
|
||||
self.p.text(text)
|
||||
return
|
||||
|
||||
def _l(self):
|
||||
self._t(self.LINE)
|
||||
return
|
||||
|
||||
def printer(self, data):
|
||||
if self.p is None:
|
||||
return False
|
||||
|
||||
self._emisor(data['emisor'])
|
||||
self._receptor(data['receptor'])
|
||||
self._ticket(data['ticket'])
|
||||
self._products(data['products'])
|
||||
self._footer(data['ticket'])
|
||||
self.p.cut()
|
||||
return True
|
||||
|
||||
def _emisor(self, data):
|
||||
self._set('center', 'B', 'B', 2, 2)
|
||||
self._t(data['name'])
|
||||
self._set('center', 'B', 'B', 2)
|
||||
self._t(data['rfc'])
|
||||
self._set('center', 'A')
|
||||
self._t(data['regimen'])
|
||||
self._t(data['address'])
|
||||
return
|
||||
|
||||
def _receptor(self, data):
|
||||
self._set('center', 'B', 'B', 2)
|
||||
self._t(data['name'])
|
||||
return
|
||||
|
||||
def _ticket(self, data):
|
||||
self._set('left', 'B', 'B', 2)
|
||||
self._t(data['title'])
|
||||
self._set('left', 'A')
|
||||
self._t(data['date'])
|
||||
return
|
||||
|
||||
def _products(self, data):
|
||||
self._l()
|
||||
self._t(self.TITLES)
|
||||
self._l()
|
||||
for p in data:
|
||||
self._t(p)
|
||||
self._l()
|
||||
self._t('Total artículos: {}\n'.format(len(data)))
|
||||
self._l()
|
||||
return
|
||||
|
||||
def _footer(self, data):
|
||||
self._set('right', 'B', 'B', 2)
|
||||
self._t(data['total'])
|
||||
self._set('center', 'A')
|
||||
self._t(data['letters'])
|
||||
self._t(self.LEYENDA)
|
||||
self._set('center', 'A', 'B')
|
||||
self._t('empresalibre.net')
|
||||
return
|
||||
|
|
|
@ -2,35 +2,6 @@
|
|||
|
||||
import falcon
|
||||
from middleware import get_template
|
||||
from urllib.parse import unquote
|
||||
|
||||
|
||||
class AppEmpresas(object):
|
||||
template = 'empresas.html'
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
@falcon.after(get_template)
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
opt = values.pop('opt', '1')
|
||||
if opt == '1':
|
||||
req.context['result'] = self._db.empresa_agregar(values)
|
||||
elif opt == '2':
|
||||
req.context['result'] = self._db.respaldar_dbs()
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.empresa_borrar(values):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppLogin(object):
|
||||
|
@ -45,14 +16,11 @@ class AppLogin(object):
|
|||
|
||||
def on_post(self, req, resp):
|
||||
session = req.env['beaker.session']
|
||||
session.invalidate()
|
||||
values = req.params
|
||||
values['rfc'] = values['rfc'].upper()
|
||||
values['ip'] = req.remote_addr
|
||||
result, user = self._db.authenticate(values)
|
||||
result = self._db.authenticate(values)
|
||||
if result['login']:
|
||||
session.save()
|
||||
session['userobj'] = user
|
||||
session['user'] = result['user']
|
||||
session['rfc'] = values['rfc']
|
||||
req.context['result'] = result
|
||||
|
@ -94,101 +62,24 @@ class AppMain(object):
|
|||
|
||||
|
||||
class AppValues(object):
|
||||
TABLES = ('allusuarios', 'usuario', 'usuarioupdate', 'editusuario',
|
||||
'addusuario')
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def _valid_user(self, table, user):
|
||||
if table in self.TABLES:
|
||||
if user.es_admin or user.es_superusuario:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def on_get(self, req, resp, table):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
|
||||
if table == 'product':
|
||||
original = values['name']
|
||||
try:
|
||||
values['name'] = unquote(req.query_string.split('=')[1])
|
||||
except Exception as e:
|
||||
values['name'] = original
|
||||
|
||||
if req.path in ('/values/titlelogin', '/values/empresas'):
|
||||
req.context['result'] = self._db.get_values(table, values, session)
|
||||
resp.status = falcon.HTTP_200
|
||||
return
|
||||
|
||||
if not 'userobj' in session and req.path != '/values/empresas':
|
||||
session.invalidate()
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
|
||||
if table == 'admin':
|
||||
req.context['result'] = session['userobj'].es_superusuario \
|
||||
or session['userobj'].es_admin
|
||||
else:
|
||||
if not self._valid_user(table, session['userobj']):
|
||||
resp.status = falcon.HTTP_403
|
||||
return
|
||||
|
||||
req.context['result'] = self._db.get_values(table, values, session)
|
||||
req.context['result'] = self._db.get_values(table, values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp, table):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
|
||||
if table == 'usuario' and (session['userobj'].id == int(values['id'])):
|
||||
resp.status = falcon.HTTP_204
|
||||
return
|
||||
|
||||
if not self._valid_user(table, session['userobj']):
|
||||
resp.status = falcon.HTTP_403
|
||||
return
|
||||
|
||||
if self._db.delete(table, values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
def on_post(self, req, resp, table):
|
||||
file_object = req.get_param('upload')
|
||||
if file_object is None:
|
||||
session = req.env['beaker.session']
|
||||
values = req.params
|
||||
|
||||
if not self._valid_user(table, session['userobj']):
|
||||
resp.status = falcon.HTTP_403
|
||||
return
|
||||
|
||||
if table == 'correo':
|
||||
req.context['result'] = self._db.validate_email(values)
|
||||
elif table == 'sendmail':
|
||||
req.context['result'] = self._db.send_email(values, session)
|
||||
elif table == 'enviarprefac':
|
||||
req.context['result'] = self._db.enviar_prefac(values)
|
||||
elif table == 'addmoneda':
|
||||
req.context['result'] = self._db.add_moneda(values)
|
||||
elif table == 'addunidad':
|
||||
req.context['result'] = self._db.add_unidad(values)
|
||||
elif table == 'addimpuesto':
|
||||
req.context['result'] = self._db.add_impuesto(values)
|
||||
elif table == 'addusuario':
|
||||
req.context['result'] = self._db.add_usuario(values)
|
||||
elif table == 'editusuario':
|
||||
req.context['result'] = self._db.edit_usuario(values)
|
||||
elif table == 'bdfl':
|
||||
req.context['result'] = self._db.importar_bdfl()
|
||||
elif table == 'invoicenotes':
|
||||
req.context['result'] = self._db.save_invoice_notes(values)
|
||||
elif table == 'nivedu':
|
||||
req.context['result'] = self._db.add_nivel_educativo(values)
|
||||
else:
|
||||
req.context['result'] = self._db.validate_cert(values, session)
|
||||
else:
|
||||
|
@ -196,22 +87,6 @@ class AppValues(object):
|
|||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppFiles(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp, table):
|
||||
values = req.params
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp, table):
|
||||
session = req.env['beaker.session']
|
||||
file_object = req.get_param('upload')
|
||||
req.context['result'] = self._db.upload_file(session, table, file_object)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppConfig(object):
|
||||
|
||||
def __init__(self, db):
|
||||
|
@ -227,12 +102,6 @@ class AppConfig(object):
|
|||
req.context['result'] = self._db.add_config(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('config', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppPartners(object):
|
||||
|
@ -258,29 +127,6 @@ class AppPartners(object):
|
|||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppStudents(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_students(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.students(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('students', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppProducts(object):
|
||||
|
||||
def __init__(self, db):
|
||||
|
@ -288,17 +134,12 @@ class AppProducts(object):
|
|||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
|
||||
if 'opt' in values:
|
||||
req.context['result'] = self._db.products_get(values, user)
|
||||
else:
|
||||
req.context['result'] = self._db.get_products(values)
|
||||
req.context['result'] = self._db.get_products(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.products(values)
|
||||
req.context['result'] = self._db.product(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
|
@ -316,72 +157,22 @@ class AppInvoices(object):
|
|||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.get_invoices(values, session['userobj'])
|
||||
req.context['result'] = self._db.get_invoices(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.invoice(values, session['userobj'])
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_put(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.invoice_put(values, session['userobj'])
|
||||
req.context['result'] = self._db.invoice(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
if self._db.delete('invoice', values['id'], session['userobj']):
|
||||
if self._db.delete('invoice', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppPreInvoices(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_preinvoices(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.preinvoice(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('preinvoice', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppTickets(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.get_tickets(values, session['userobj'])
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.tickets(values, session['userobj'])
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppEmisor(object):
|
||||
|
||||
def __init__(self, db):
|
||||
|
@ -406,55 +197,6 @@ class AppEmisor(object):
|
|||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppCuentasBanco(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.get_cuentasbanco(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.cuentasbanco(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('cuentasbanco', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppMovimientosBanco(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.get_movimientosbanco(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
# ~ req.context['result'] = self._db.add_movbanco(values)
|
||||
req.context['result'] = self._db.bankmovement(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('movbanco', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppFolios(object):
|
||||
|
||||
def __init__(self, db):
|
||||
|
@ -478,350 +220,17 @@ class AppFolios(object):
|
|||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppEmployees(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_employees(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.employees(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('employee', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppNomina(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
if 'opt' in values:
|
||||
req.context['result'] = self._db.nomina_get(values, user)
|
||||
else:
|
||||
by = values.get('by', '')
|
||||
req.context['result'] = self._db.get_nomina(values)
|
||||
if 'download' in by:
|
||||
name = req.context['result']['name']
|
||||
req.context['blob'] = req.context['result']['data']
|
||||
resp.content_type = 'application/octet-stream'
|
||||
resp.append_header(
|
||||
'Content-Disposition', f'attachment; filename={name}')
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'] = self._db.nomina(values, session['userobj'])
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('nomina', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppDocumentos(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
#~ self._not_json = True
|
||||
|
||||
def on_get(self, req, resp, type_doc, id_doc):
|
||||
# ~ print('TD', type_doc)
|
||||
session = req.env['beaker.session']
|
||||
req.context['result'], file_name, content_type = \
|
||||
self._db.get_doc(type_doc, id_doc, session['rfc'])
|
||||
if not type_doc in ('pdf', 'pre', 'tpdf', 'pdfpago', 'html', 'nompdf'):
|
||||
resp.append_header('Content-Disposition',
|
||||
'attachment; filename={}'.format(file_name))
|
||||
if type_doc in ('pdf', 'nompdf', 'pdfpago'):
|
||||
resp.append_header('Content-Disposition',
|
||||
'inline; filename={}'.format(file_name))
|
||||
resp.append_header('Content-Disposition',
|
||||
'attachment; filename={}'.format(file_name))
|
||||
resp.content_type = content_type
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
# ~ Revisado
|
||||
class AppInvoicePay(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_invoicepay(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppCfdiPay(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_cfdipay(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.cfdipay(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATBancos(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_sat_bancos(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sat_bancos(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATFormaPago(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_sat_forma_pago(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sat_forma_pago(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATLeyendaFiscales(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sat_leyendas_fiscales_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sat_leyendas_fiscales_post(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.sat_leyendas_fiscales_delete(values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppSociosCuentasBanco(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_partners_accounts_bank(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.partners_accounts_bank(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppCert(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.cert_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.cert_post(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSucursales(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sucursales_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.sucursales_post(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppPartnerProducts(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.partner_products_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.partner_products_post(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppInventoryEntries(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.inventory_entries_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.inventory_entries_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppWareHouse(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.warehouse_get(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.warehouse_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppWareHouseProduct(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.warehouseproduct_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.warehouseproduct_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppTicketsDetails(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.ticketsdetails_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppUsers(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.users_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.users_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATUnidadesPeso(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.sat_unidades_peso_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.sat_unidades_peso_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATRegimenes(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.sat_regimenes_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSociosRegimenes(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.socios_regimenes_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
|
|
@ -0,0 +1,622 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
#~ import re
|
||||
#~ from xml.etree import ElementTree as ET
|
||||
#~ from requests import Request, Session, exceptions
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
import requests
|
||||
import time
|
||||
from lxml import etree
|
||||
from xml.dom.minidom import parseString
|
||||
from xml.sax.saxutils import escape, unescape
|
||||
from uuid import UUID
|
||||
|
||||
from logbook import Logger
|
||||
from zeep import Client
|
||||
from zeep.plugins import HistoryPlugin
|
||||
from zeep.cache import SqliteCache
|
||||
from zeep.transports import Transport
|
||||
from zeep.exceptions import Fault, TransportError
|
||||
|
||||
if __name__ == '__main__':
|
||||
from configpac import DEBUG, TIMEOUT, AUTH, URL
|
||||
else:
|
||||
from .configpac import DEBUG, TIMEOUT, AUTH, URL
|
||||
|
||||
|
||||
log = Logger('PAC')
|
||||
#~ node = client.create_message(client.service, SERVICE, **args)
|
||||
#~ print(etree.tostring(node, pretty_print=True).decode())
|
||||
|
||||
|
||||
class Ecodex(object):
|
||||
|
||||
def __init__(self):
|
||||
self.codes = URL['codes']
|
||||
self.error = ''
|
||||
self.message = ''
|
||||
self._transport = Transport(cache=SqliteCache(), timeout=TIMEOUT)
|
||||
self._plugins = None
|
||||
self._history = None
|
||||
if DEBUG:
|
||||
self._history = HistoryPlugin()
|
||||
self._plugins = [self._history]
|
||||
|
||||
def _get_token(self, rfc):
|
||||
client = Client(URL['seguridad'],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.ObtenerToken(rfc, self._get_epoch())
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
s = '{}|{}'.format(AUTH['ID'], result.Token)
|
||||
return hashlib.sha1(s.encode()).hexdigest()
|
||||
|
||||
def _get_token_rest(self, rfc):
|
||||
data = {
|
||||
'rfc': rfc,
|
||||
'grant_type': 'authorization_token',
|
||||
}
|
||||
headers = {'Content-type': 'application/x-www-form-urlencoded'}
|
||||
result = requests.post(URL['token'], data=data, headers=headers)
|
||||
data = result.json()
|
||||
s = '{}|{}'.format(AUTH['ID'], data['service_token'])
|
||||
return hashlib.sha1(s.encode()).hexdigest(), data['access_token']
|
||||
|
||||
def _validate_xml(self, xml):
|
||||
NS_CFDI = {'cfdi': 'http://www.sat.gob.mx/cfd/3'}
|
||||
if os.path.isfile(xml):
|
||||
tree = etree.parse(xml).getroot()
|
||||
else:
|
||||
tree = etree.fromstring(xml.encode())
|
||||
|
||||
fecha = tree.get('Fecha')
|
||||
rfc = tree.xpath('string(//cfdi:Emisor/@Rfc)', namespaces=NS_CFDI)
|
||||
data = {
|
||||
'ComprobanteXML': etree.tostring(tree).decode(),
|
||||
'RFC': rfc,
|
||||
'Token': self._get_token(rfc),
|
||||
'TransaccionID': self._get_epoch(fecha),
|
||||
}
|
||||
return data
|
||||
|
||||
def _get_by_hash(self, sh, rfc):
|
||||
token, access_token = self._get_token_rest(rfc)
|
||||
url = URL['hash'].format(sh)
|
||||
headers = {
|
||||
'Authorization': 'Bearer {}'.format(access_token),
|
||||
'X-Auth-Token': token,
|
||||
}
|
||||
result = requests.get(url, headers=headers)
|
||||
if result.status_code == 200:
|
||||
print (result.json())
|
||||
return
|
||||
|
||||
def timbra_xml(self, xml):
|
||||
data = self._validate_xml(xml)
|
||||
client = Client(URL['timbra'],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.TimbraXML(**data)
|
||||
except Fault as e:
|
||||
error = str(e)
|
||||
if self.codes['HASH'] in error:
|
||||
sh = error.split(' ')[3]
|
||||
return self._get_by_hash(sh[:40], data['RFC'])
|
||||
self.error = error
|
||||
return ''
|
||||
|
||||
tree = parseString(result.ComprobanteXML.DatosXML)
|
||||
xml = tree.toprettyxml(encoding='utf-8').decode('utf-8')
|
||||
return xml
|
||||
|
||||
def _get_epoch(self, date=None):
|
||||
if isinstance(date, str):
|
||||
f = '%Y-%m-%dT%H:%M:%S'
|
||||
e = int(time.mktime(time.strptime(date, f)))
|
||||
else:
|
||||
date = datetime.datetime.now()
|
||||
e = int(time.mktime(date.timetuple()))
|
||||
return e
|
||||
|
||||
def estatus_cuenta(self, rfc):
|
||||
#~ Codigos:
|
||||
#~ 100 = Cuenta encontrada
|
||||
#~ 101 = RFC no dado de alta en el sistema ECODEX
|
||||
token = self._get_token(rfc)
|
||||
if not token:
|
||||
return {}
|
||||
|
||||
data = {
|
||||
'RFC': rfc,
|
||||
'Token': token,
|
||||
'TransaccionID': self._get_epoch()
|
||||
}
|
||||
client = Client(URL['clients'],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.EstatusCuenta(**data)
|
||||
except Fault as e:
|
||||
log.error(str(e))
|
||||
return
|
||||
#~ print (result)
|
||||
return result.Estatus
|
||||
|
||||
|
||||
class Finkok(object):
|
||||
|
||||
def __init__(self, auth={}):
|
||||
self.codes = URL['codes']
|
||||
self.error = ''
|
||||
self.message = ''
|
||||
self._transport = Transport(cache=SqliteCache(), timeout=TIMEOUT)
|
||||
self._plugins = None
|
||||
self._history = None
|
||||
self.uuid = ''
|
||||
self.fecha = None
|
||||
if DEBUG:
|
||||
self._history = HistoryPlugin()
|
||||
self._plugins = [self._history]
|
||||
self._auth = AUTH
|
||||
else:
|
||||
self._auth = auth
|
||||
|
||||
def _debug(self):
|
||||
if not DEBUG:
|
||||
return
|
||||
print('SEND', self._history.last_sent)
|
||||
print('RESULT', self._history.last_received)
|
||||
return
|
||||
|
||||
def _check_result(self, method, result):
|
||||
#~ print ('CODE', result.CodEstatus)
|
||||
#~ print ('INCIDENCIAS', result.Incidencias)
|
||||
self.message = ''
|
||||
MSG = {
|
||||
'OK': 'Comprobante timbrado satisfactoriamente',
|
||||
'307': 'Comprobante timbrado previamente',
|
||||
}
|
||||
status = result.CodEstatus
|
||||
if status is None and result.Incidencias:
|
||||
for i in result.Incidencias['Incidencia']:
|
||||
self.error += 'Error: {}\n{}'.format(
|
||||
i['CodigoError'], i['MensajeIncidencia'])
|
||||
return ''
|
||||
|
||||
if method == 'timbra' and status in (MSG['OK'], MSG['307']):
|
||||
#~ print ('UUID', result.UUID)
|
||||
#~ print ('FECHA', result.Fecha)
|
||||
if status == MSG['307']:
|
||||
self.message = MSG['307']
|
||||
tree = parseString(result.xml)
|
||||
response = tree.toprettyxml(encoding='utf-8').decode('utf-8')
|
||||
self.uuid = result.UUID
|
||||
self.fecha = result.Fecha
|
||||
|
||||
return response
|
||||
|
||||
def _load_file(self, path):
|
||||
try:
|
||||
with open(path, 'rb') as f:
|
||||
data = f.read()
|
||||
except Exception as e:
|
||||
self.error = str(e)
|
||||
return
|
||||
return data
|
||||
|
||||
def _validate_xml(self, file_xml):
|
||||
if os.path.isfile(file_xml):
|
||||
try:
|
||||
with open(file_xml, 'rb') as f:
|
||||
xml = f.read()
|
||||
except Exception as e:
|
||||
self.error = str(e)
|
||||
return False, ''
|
||||
else:
|
||||
xml = file_xml.encode('utf-8')
|
||||
return True, xml
|
||||
|
||||
def _validate_uuid(self, uuid):
|
||||
try:
|
||||
UUID(uuid)
|
||||
return True
|
||||
except ValueError:
|
||||
self.error = 'UUID no válido: {}'.format(uuid)
|
||||
return False
|
||||
|
||||
def timbra_xml(self, file_xml):
|
||||
self.error = ''
|
||||
|
||||
if not DEBUG and not self._auth:
|
||||
self.error = 'Sin datos para timbrar'
|
||||
return
|
||||
|
||||
method = 'timbra'
|
||||
ok, xml = self._validate_xml(file_xml)
|
||||
if not ok:
|
||||
return ''
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'xml': xml,
|
||||
}
|
||||
if URL['quick_stamp']:
|
||||
try:
|
||||
result = client.service.quick_stamp(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return
|
||||
else:
|
||||
try:
|
||||
result = client.service.stamp(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return
|
||||
|
||||
return self._check_result(method, result)
|
||||
|
||||
def _get_xml(self, uuid):
|
||||
if not self._validate_uuid(uuid):
|
||||
return ''
|
||||
|
||||
method = 'util'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'uuid': uuid,
|
||||
'taxpayer_id': self.rfc,
|
||||
'invoice_type': 'I',
|
||||
}
|
||||
try:
|
||||
result = client.service.get_xml(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
except TransportError as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
if result.error:
|
||||
self.error = result.error
|
||||
return ''
|
||||
|
||||
tree = parseString(result.xml)
|
||||
xml = tree.toprettyxml(encoding='utf-8').decode('utf-8')
|
||||
return xml
|
||||
|
||||
def recupera_xml(self, file_xml='', uuid=''):
|
||||
self.error = ''
|
||||
if uuid:
|
||||
return self._get_xml(uuid)
|
||||
|
||||
method = 'timbra'
|
||||
ok, xml = self._validate_xml(file_xml)
|
||||
if not ok:
|
||||
return ''
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.stamped(
|
||||
xml, self._auth['user'], self._auth['pass'])
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return self._check_result(method, result)
|
||||
|
||||
def estatus_xml(self, uuid):
|
||||
method = 'timbra'
|
||||
if not self._validate_uuid(uuid):
|
||||
return ''
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.query_pending(
|
||||
self._auth['USER'], self._auth['PASS'], uuid)
|
||||
#~ print (result.date)
|
||||
#~ tree = parseString(unescape(result.xml))
|
||||
#~ response = tree.toprettyxml(encoding='utf-8').decode('utf-8')
|
||||
return result.status
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
def cancel_xml(self, rfc, uuids, path_cer, path_key):
|
||||
for u in uuids:
|
||||
if not self._validate_uuid(u):
|
||||
return ''
|
||||
|
||||
cer = self._load_file(path_cer)
|
||||
key = self._load_file(path_key)
|
||||
method = 'cancel'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
uuid_type = client.get_type('ns1:UUIDS')
|
||||
sa = client.get_type('ns0:stringArray')
|
||||
|
||||
args = {
|
||||
'UUIDS': uuid_type(uuids=sa(string=uuids)),
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
'cer': cer,
|
||||
'key': key,
|
||||
'store_pending': True,
|
||||
}
|
||||
try:
|
||||
result = client.service.cancel(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
if result.CodEstatus and self.codes['205'] in result.CodEstatus:
|
||||
self.error = result.CodEstatus
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def cancel_signature(self, file_xml):
|
||||
method = 'cancel'
|
||||
if os.path.isfile(file_xml):
|
||||
root = etree.parse(file_xml).getroot()
|
||||
else:
|
||||
root = etree.fromstring(file_xml)
|
||||
|
||||
xml = etree.tostring(root)
|
||||
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'xml': xml,
|
||||
'store_pending': True,
|
||||
}
|
||||
|
||||
result = client.service.cancel_signature(**args)
|
||||
return result
|
||||
|
||||
def get_acuse(self, rfc, uuids, type_acuse='C'):
|
||||
for u in uuids:
|
||||
if not self._validate_uuid(u):
|
||||
return ''
|
||||
|
||||
method = 'cancel'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
'uuid': '',
|
||||
'type': type_acuse,
|
||||
}
|
||||
try:
|
||||
result = []
|
||||
for u in uuids:
|
||||
args['uuid'] = u
|
||||
r = client.service.get_receipt(**args)
|
||||
result.append(r)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def estatus_cancel(self, uuids):
|
||||
for u in uuids:
|
||||
if not self._validate_uuid(u):
|
||||
return ''
|
||||
|
||||
method = 'cancel'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': self._auth['USER'],
|
||||
'password': self._auth['PASS'],
|
||||
'uuid': '',
|
||||
}
|
||||
try:
|
||||
result = []
|
||||
for u in uuids:
|
||||
args['uuid'] = u
|
||||
r = client.service.query_pending_cancellation(**args)
|
||||
result.append(r)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def add_token(self, rfc, email):
|
||||
"""
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
"""
|
||||
method = 'util'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'username': AUTH['USER'],
|
||||
'password': AUTH['PASS'],
|
||||
'name': rfc,
|
||||
'token_username': email,
|
||||
'taxpayer_id': rfc,
|
||||
'status': True,
|
||||
}
|
||||
result = client.service.add_token(**args)
|
||||
return result
|
||||
|
||||
def get_date(self):
|
||||
method = 'util'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
try:
|
||||
result = client.service.datetime(AUTH['USER'], AUTH['PASS'])
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
if result.error:
|
||||
self.error = result.error
|
||||
return
|
||||
|
||||
return result.datetime
|
||||
|
||||
def add_client(self, rfc, type_user=False):
|
||||
"""
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
type_user: False == 'P' == Prepago or True == 'O' == On demand
|
||||
"""
|
||||
tu = {False: 'P', True: 'O'}
|
||||
method = 'client'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'reseller_username': AUTH['USER'],
|
||||
'reseller_password': AUTH['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
'type_user': tu[type_user],
|
||||
'added': datetime.datetime.now().isoformat()[:19],
|
||||
}
|
||||
try:
|
||||
result = client.service.add(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def edit_client(self, rfc, status=True):
|
||||
"""
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
status = 'A' or 'S'
|
||||
"""
|
||||
sv = {False: 'S', True: 'A'}
|
||||
method = 'client'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'reseller_username': AUTH['USER'],
|
||||
'reseller_password': AUTH['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
'status': sv[status],
|
||||
}
|
||||
try:
|
||||
result = client.service.edit(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def get_client(self, rfc):
|
||||
"""
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
"""
|
||||
method = 'client'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'reseller_username': AUTH['USER'],
|
||||
'reseller_password': AUTH['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
}
|
||||
|
||||
try:
|
||||
result = client.service.get(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
except TransportError as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
def assign_client(self, rfc, credit):
|
||||
"""
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
"""
|
||||
method = 'client'
|
||||
client = Client(
|
||||
URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'username': AUTH['USER'],
|
||||
'password': AUTH['PASS'],
|
||||
'taxpayer_id': rfc,
|
||||
'credit': credit,
|
||||
}
|
||||
try:
|
||||
result = client.service.assign(**args)
|
||||
except Fault as e:
|
||||
self.error = str(e)
|
||||
return ''
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _get_data_sat(path):
|
||||
BF = 'string(//*[local-name()="{}"]/@{})'
|
||||
NS_CFDI = {'cfdi': 'http://www.sat.gob.mx/cfd/3'}
|
||||
|
||||
try:
|
||||
if os.path.isfile(path):
|
||||
tree = etree.parse(path).getroot()
|
||||
else:
|
||||
tree = etree.fromstring(path)
|
||||
|
||||
data = {}
|
||||
emisor = escape(
|
||||
tree.xpath('string(//cfdi:Emisor/@rfc)', namespaces=NS_CFDI) or
|
||||
tree.xpath('string(//cfdi:Emisor/@Rfc)', namespaces=NS_CFDI)
|
||||
)
|
||||
receptor = escape(
|
||||
tree.xpath('string(//cfdi:Receptor/@rfc)', namespaces=NS_CFDI) or
|
||||
tree.xpath('string(//cfdi:Receptor/@Rfc)', namespaces=NS_CFDI)
|
||||
)
|
||||
data['total'] = tree.get('total') or tree.get('Total')
|
||||
data['emisor'] = emisor
|
||||
data['receptor'] = receptor
|
||||
data['uuid'] = tree.xpath(BF.format('TimbreFiscalDigital', 'UUID'))
|
||||
except Exception as e:
|
||||
print (e)
|
||||
return {}
|
||||
|
||||
return '?re={emisor}&rr={receptor}&tt={total}&id={uuid}'.format(**data)
|
||||
|
||||
|
||||
def get_status_sat(xml):
|
||||
data = _get_data_sat(xml)
|
||||
if not data:
|
||||
return
|
||||
|
||||
URL = 'https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc?wsdl'
|
||||
client = Client(URL, transport=Transport(cache=SqliteCache()))
|
||||
try:
|
||||
result = client.service.Consulta(expresionImpresa=data)
|
||||
except Exception as e:
|
||||
return 'Error: {}'.format(str(e))
|
||||
|
||||
return result.Estado
|
||||
|
||||
|
||||
def main():
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from .comerciodigital import PACComercioDigital
|
||||
from .finkok import PACFinkok
|
|
@ -1,350 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import datetime
|
||||
import getpass
|
||||
import hashlib
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import lxml.etree as ET
|
||||
import xmlsec
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography import x509
|
||||
from cryptography.x509.oid import NameOID
|
||||
from cryptography.x509.oid import ExtensionOID
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
|
||||
from conf import TOKEN
|
||||
|
||||
|
||||
class SATCertificate(object):
|
||||
|
||||
def __init__(self, cer=b'', key=b'', password=''):
|
||||
self._error = ''
|
||||
self._init_values()
|
||||
self._get_data_cer(cer)
|
||||
self._get_data_key(key, password)
|
||||
# ~ if not password:
|
||||
# ~ self._test()
|
||||
|
||||
# ~ def _test(self):
|
||||
# ~ key = self._get_key('')
|
||||
# ~ self._p = ''
|
||||
# ~ self._key_der = key.private_bytes(
|
||||
# ~ encoding=serialization.Encoding.DER,
|
||||
# ~ format=serialization.PrivateFormat.PKCS8,
|
||||
# ~ encryption_algorithm=serialization.BestAvailableEncryption(self._p.encode())
|
||||
# ~ )
|
||||
# ~ return
|
||||
|
||||
def _init_values(self):
|
||||
self._rfc = ''
|
||||
self._serial_number = ''
|
||||
self._serial_number2 = ''
|
||||
self._subject = ''
|
||||
self._issuer = ''
|
||||
self._not_before = None
|
||||
self._not_after = None
|
||||
self._is_fiel = False
|
||||
self._are_couple = False
|
||||
self._is_valid_time = False
|
||||
self._key = b''
|
||||
self._cer = b''
|
||||
self._cer_pem = ''
|
||||
self._cer_txt = ''
|
||||
self._key_enc = b''
|
||||
self._key_der = b''
|
||||
self._p12 = b''
|
||||
self._cer_modulus = 0
|
||||
self._key_modulus = 0
|
||||
return
|
||||
|
||||
def __str__(self):
|
||||
msg = '\tRFC: {}\n'.format(self.rfc)
|
||||
msg += '\tNo de Serie: {}\n'.format(self.serial_number)
|
||||
msg += '\tVálido desde: {}\n'.format(self.not_before)
|
||||
msg += '\tVálido hasta: {}\n'.format(self.not_after)
|
||||
msg += '\tEs vigente: {}\n'.format(self.is_valid_time)
|
||||
msg += '\tSon pareja: {}\n'.format(self.are_couple)
|
||||
msg += '\tEs FIEL: {}\n'.format(self.is_fiel)
|
||||
return msg
|
||||
|
||||
def __bool__(self):
|
||||
return self.is_valid
|
||||
|
||||
def _get_hash(self):
|
||||
digest = hashes.Hash(hashes.SHA512(), default_backend())
|
||||
digest.update(self._rfc.encode())
|
||||
digest.update(self._serial_number.encode())
|
||||
digest.update(TOKEN.encode())
|
||||
return digest.finalize()
|
||||
|
||||
def _get_data_cer(self, cer):
|
||||
self._cer = cer
|
||||
obj = x509.load_der_x509_certificate(cer, default_backend())
|
||||
|
||||
self._issuer = obj.issuer.rfc4514_string()
|
||||
self._subject = obj.subject.rfc4514_string()
|
||||
|
||||
self._rfc = obj.subject.get_attributes_for_oid(
|
||||
NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0]
|
||||
self._serial_number2 = '{0:x}'.format(obj.serial_number)
|
||||
self._serial_number = self._serial_number2[1::2]
|
||||
self._not_before = obj.not_valid_before
|
||||
self._not_after = obj.not_valid_after
|
||||
now = datetime.datetime.utcnow()
|
||||
self._is_valid_time = (now > self.not_before) and (now < self.not_after)
|
||||
if not self._is_valid_time:
|
||||
msg = 'El certificado no es vigente'
|
||||
self._error = msg
|
||||
|
||||
self._is_fiel = obj.extensions.get_extension_for_oid(
|
||||
ExtensionOID.KEY_USAGE).value.key_agreement
|
||||
|
||||
self._cer_pem = obj.public_bytes(serialization.Encoding.PEM).decode()
|
||||
self._cer_txt = ''.join(self._cer_pem.split('\n')[1:-2])
|
||||
self._cer_modulus = obj.public_key().public_numbers().n
|
||||
return
|
||||
|
||||
def _get_data_key(self, key, password):
|
||||
self._key = key
|
||||
self._keyp = password
|
||||
self._key_enc = key
|
||||
if not key or not password:
|
||||
return
|
||||
|
||||
try:
|
||||
obj = serialization.load_der_private_key(
|
||||
key, password.encode(), default_backend())
|
||||
except ValueError:
|
||||
msg = 'La contraseña es incorrecta'
|
||||
self._error = msg
|
||||
return
|
||||
|
||||
p = self._get_hash()
|
||||
self._key_enc = obj.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.BestAvailableEncryption(p)
|
||||
)
|
||||
|
||||
self._key_modulus = obj.public_key().public_numbers().n
|
||||
self._are_couple = self._cer_modulus == self._key_modulus
|
||||
if not self._are_couple:
|
||||
msg = 'El CER y el KEY no son pareja'
|
||||
self._error = msg
|
||||
return
|
||||
|
||||
def _get_key(self, password):
|
||||
if not password:
|
||||
password = self._get_hash()
|
||||
private_key = serialization.load_pem_private_key(
|
||||
self._key_enc, password=password, backend=default_backend())
|
||||
return private_key
|
||||
|
||||
def _get_key_pem(self):
|
||||
obj = self._get_key('')
|
||||
key_pem = obj.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
return key_pem
|
||||
|
||||
# Not work
|
||||
def _get_p12(self):
|
||||
obj = serialization.pkcs12.serialize_key_and_certificates('test',
|
||||
self.key_pem, self.cer_pem, None,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
return obj
|
||||
|
||||
def sign(self, data, password=''):
|
||||
private_key = self._get_key(password)
|
||||
firma = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
|
||||
return base64.b64encode(firma).decode()
|
||||
|
||||
def sign_xml(self, tree):
|
||||
node = xmlsec.tree.find_node(tree, xmlsec.constants.NodeSignature)
|
||||
ctx = xmlsec.SignatureContext()
|
||||
key = xmlsec.Key.from_memory(
|
||||
self.key_pem, xmlsec.constants.KeyDataFormatPem)
|
||||
ctx.key = key
|
||||
ctx.sign(node)
|
||||
|
||||
node = xmlsec.tree.find_node(tree, 'X509Certificate')
|
||||
node.text = self.cer_txt
|
||||
node = xmlsec.tree.find_node(tree, 'X509IssuerName')
|
||||
node.text = self.issuer
|
||||
node = xmlsec.tree.find_node(tree, 'X509SerialNumber')
|
||||
node.text = self.serial_number
|
||||
node = xmlsec.tree.find_node(tree, 'SignatureValue')
|
||||
node.text = node.text.replace('\n', '')
|
||||
node = xmlsec.tree.find_node(tree, 'Modulus')
|
||||
node.text = node.text.replace('\n', '')
|
||||
|
||||
# ~ xml_signed = ET.tostring(tree,
|
||||
# ~ xml_declaration=True, encoding='UTF-8').decode()
|
||||
xml_signed = ET.tostring(tree, encoding='UTF-8').decode().replace('\n', '')
|
||||
|
||||
return xml_signed
|
||||
|
||||
@property
|
||||
def rfc(self):
|
||||
return self._rfc
|
||||
|
||||
@property
|
||||
def serial_number(self):
|
||||
return self._serial_number
|
||||
|
||||
@property
|
||||
def serial_number2(self):
|
||||
return self._serial_number2
|
||||
|
||||
@property
|
||||
def issuer(self):
|
||||
return self._issuer
|
||||
|
||||
@property
|
||||
def subject(self):
|
||||
return self._subject
|
||||
|
||||
@property
|
||||
def not_before(self):
|
||||
return self._not_before
|
||||
|
||||
@property
|
||||
def not_after(self):
|
||||
return self._not_after
|
||||
|
||||
@property
|
||||
def is_fiel(self):
|
||||
return self._is_fiel
|
||||
|
||||
@property
|
||||
def are_couple(self):
|
||||
return self._are_couple
|
||||
|
||||
@property
|
||||
def is_valid(self):
|
||||
return not bool(self.error)
|
||||
|
||||
@property
|
||||
def is_valid_time(self):
|
||||
return self._is_valid_time
|
||||
|
||||
@property
|
||||
def cer(self):
|
||||
return self._cer
|
||||
|
||||
@property
|
||||
def cer_pem(self):
|
||||
return self._cer_pem.encode()
|
||||
|
||||
@property
|
||||
def cer_txt(self):
|
||||
return self._cer_txt
|
||||
|
||||
@property
|
||||
def key_pem(self):
|
||||
return self._get_key_pem()
|
||||
|
||||
@property
|
||||
def key_enc(self):
|
||||
return self._key_enc
|
||||
|
||||
@property
|
||||
def p12(self):
|
||||
return self._get_p12()
|
||||
|
||||
@property
|
||||
def error(self):
|
||||
return self._error
|
||||
|
||||
@classmethod
|
||||
def save_cert(cls, obj):
|
||||
import hashlib
|
||||
|
||||
cer = x509.load_pem_x509_certificate(obj.cer_pem.encode(), default_backend())
|
||||
cer_der = cer.public_bytes(serialization.Encoding.DER)
|
||||
token = hashlib.md5(obj.rfc.encode()).hexdigest()
|
||||
path = Path(f'/tmp/{obj.rfc}.key')
|
||||
path.write_text(obj.key_enc)
|
||||
args = f'openssl rsa -inform PEM -outform PEM -in "{str(path)}" -passin pass:{token}'
|
||||
pem = subprocess.check_output(args, shell=True).decode()
|
||||
key = serialization.load_pem_private_key(
|
||||
pem.encode(), password=None, backend=default_backend())
|
||||
|
||||
digest = hashes.Hash(hashes.SHA512(), default_backend())
|
||||
digest.update(obj.rfc.encode())
|
||||
digest.update(obj.serie.encode())
|
||||
digest.update(TOKEN.encode())
|
||||
p = digest.finalize()
|
||||
|
||||
key_enc = key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.BestAvailableEncryption(p)
|
||||
)
|
||||
|
||||
cert = SATCertificate(cer_der, key_enc)
|
||||
obj.key_enc = cert.key_enc
|
||||
obj.cer = cert.cer
|
||||
obj.serie = cert.serial_number
|
||||
obj.desde = cert.not_before
|
||||
obj.hasta = cert.not_after
|
||||
obj.save()
|
||||
return
|
||||
|
||||
|
||||
def main(args):
|
||||
# ~ contra = getpass.getpass('Introduce la contraseña del archivo KEY: ')
|
||||
contra = '12345678a'
|
||||
if not contra.strip():
|
||||
msg = 'La contraseña es requerida'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
path_cer = Path(args.cer)
|
||||
path_key = Path(args.key)
|
||||
|
||||
if not path_cer.is_file():
|
||||
msg = 'El archivo CER es necesario'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
if not path_key.is_file():
|
||||
msg = 'El archivo KEY es necesario'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
cer = path_cer.read_bytes()
|
||||
key = path_key.read_bytes()
|
||||
cert = SATCertificate(cer, key, contra)
|
||||
|
||||
if cert.error:
|
||||
print(cert.error)
|
||||
else:
|
||||
print(cert)
|
||||
return
|
||||
|
||||
|
||||
def _process_command_line_arguments():
|
||||
parser = argparse.ArgumentParser(description='CFDI Certificados')
|
||||
|
||||
help = 'Archivo CER'
|
||||
parser.add_argument('-c', '--cer', help=help, default='')
|
||||
help = 'Archivo KEY'
|
||||
parser.add_argument('-k', '--key', help=help, default='')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = _process_command_line_arguments()
|
||||
main(args)
|
|
@ -1,3 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from .comercio import PACComercioDigital
|
|
@ -1,431 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# ~
|
||||
# ~ PAC
|
||||
# ~ Copyright (C) 2018-2019 Mauricio Baeza Servin - public [AT] elmau [DOT] net
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import base64
|
||||
import logging
|
||||
|
||||
import lxml.etree as ET
|
||||
import requests
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from .conf import DEBUG
|
||||
# ~ , AUTH
|
||||
|
||||
|
||||
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
||||
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
||||
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
||||
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
logging.getLogger('requests').setLevel(logging.ERROR)
|
||||
|
||||
|
||||
TIMEOUT = 10
|
||||
|
||||
NAMESPACES = {
|
||||
'3.3': 'http://www.sat.gob.mx/cfd/3',
|
||||
'4.0': 'http://www.sat.gob.mx/cfd/4',
|
||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
}
|
||||
|
||||
|
||||
def pretty_print_POST(req):
|
||||
"""
|
||||
At this point it is completely built and ready
|
||||
to be fired; it is "prepared".
|
||||
|
||||
However pay attention at the formatting used in
|
||||
this function because it is programmed to be pretty
|
||||
printed and may differ from the actual request.
|
||||
"""
|
||||
print('{}\n{}\r\n{}\r\n\r\n{}'.format(
|
||||
'-----------START-----------',
|
||||
req.method + ' ' + req.url,
|
||||
'\r\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
|
||||
req.body,
|
||||
))
|
||||
|
||||
|
||||
class PACComercioDigital(object):
|
||||
ws = 'https://{}.comercio-digital.mx/{}'
|
||||
api = 'https://app2.comercio-digital.mx/{}'
|
||||
URL = {
|
||||
'timbra': ws.format('ws', 'timbre4/timbrarV5'),
|
||||
'cancel': ws.format('cancela', 'cancela4/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela', 'cancela4/cancelarXml'),
|
||||
'status': ws.format('cancela', 'arws/consultaEstatus'),
|
||||
'client': api.format('x3/altaEmpresa'),
|
||||
'saldo': api.format('x3/saldo'),
|
||||
'timbres': api.format('x3/altaTimbres'),
|
||||
}
|
||||
CODES = {
|
||||
'000': '000 Exitoso',
|
||||
'004': '004 RFC {} ya esta dado de alta con Estatus=A',
|
||||
'704': '704 Usuario Invalido',
|
||||
'702': '702 Error rfc/empresa invalido',
|
||||
}
|
||||
NS_CFDI = {
|
||||
'cfdi': 'http://www.sat.gob.mx/cfd/4',
|
||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
}
|
||||
|
||||
if DEBUG:
|
||||
ws = 'https://pruebas.comercio-digital.mx/{}'
|
||||
ws6 = 'https://pruebas6.comercio-digital.mx/arws/{}'
|
||||
URL = {
|
||||
'timbra': ws.format('timbre4/timbrarV5'),
|
||||
'cancel': ws.format('cancela4/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela4/cancelarXml'),
|
||||
'status': ws6.format('consultaEstatus'),
|
||||
'client': api.format('x3/altaEmpresa'),
|
||||
'saldo': api.format('x3/saldo'),
|
||||
'timbres': api.format('x3/altaTimbres'),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.error = ''
|
||||
|
||||
def _error(self, msg):
|
||||
self.error = str(msg)
|
||||
log.error(msg)
|
||||
return
|
||||
|
||||
def _post(self, url, data, headers={}):
|
||||
result = None
|
||||
headers['host'] = url.split('/')[2]
|
||||
headers['Content-type'] = 'text/plain'
|
||||
headers['Connection'] = 'Keep-Alive'
|
||||
headers['Expect'] = '100-continue'
|
||||
|
||||
if DEBUG:
|
||||
req = requests.Request('POST', url, headers=headers, data=data)
|
||||
prepared = req.prepare()
|
||||
pretty_print_POST(prepared)
|
||||
|
||||
try:
|
||||
result = requests.post(url, data=data, headers=headers, timeout=TIMEOUT)
|
||||
except ConnectionError as e:
|
||||
self._error(e)
|
||||
|
||||
return result
|
||||
|
||||
def _validate_cfdi(self, xml):
|
||||
"""
|
||||
Comercio Digital solo soporta la declaración con doble comilla
|
||||
"""
|
||||
# ~ tree = ET.fromstring(xml.encode())
|
||||
# ~ xml = ET.tostring(tree,
|
||||
# ~ pretty_print=True, doctype='<?xml version="1.0" encoding="utf-8"?>')
|
||||
return xml.encode('utf-8')
|
||||
|
||||
def stamp(self, cfdi, auth):
|
||||
# ~ if DEBUG or not auth:
|
||||
# ~ auth = AUTH
|
||||
|
||||
url = self.URL['timbra']
|
||||
headers = {
|
||||
'usrws': auth['user'],
|
||||
'pwdws': auth['pass'],
|
||||
'tipo': 'XML',
|
||||
}
|
||||
cfdi = self._validate_cfdi(cfdi)
|
||||
result = self._post(url, cfdi, headers)
|
||||
|
||||
if result is None:
|
||||
return ''
|
||||
|
||||
if result.status_code != 200:
|
||||
return ''
|
||||
|
||||
if 'errmsg' in result.headers:
|
||||
self._error(result.headers['errmsg'])
|
||||
return ''
|
||||
|
||||
xml = result.content
|
||||
tree = ET.fromstring(xml)
|
||||
cfdi_uuid = tree.xpath(
|
||||
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@UUID)',
|
||||
namespaces=self.NS_CFDI)
|
||||
date_stamped = tree.xpath(
|
||||
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@FechaTimbrado)',
|
||||
namespaces=self.NS_CFDI)
|
||||
|
||||
data = {
|
||||
'xml': xml.decode(),
|
||||
'uuid': cfdi_uuid,
|
||||
'date': date_stamped,
|
||||
}
|
||||
return data
|
||||
|
||||
def _get_data_cancel(self, cfdi, info, auth):
|
||||
info['tipo'] = 'cfdi'
|
||||
info['key'] = base64.b64encode(info['key_enc']).decode()
|
||||
info['cer'] = base64.b64encode(info['cer_ori']).decode()
|
||||
|
||||
tree = ET.fromstring(cfdi.encode())
|
||||
version = tree.attrib['Version']
|
||||
|
||||
namespaces = {
|
||||
'cfdi': NAMESPACES[version],
|
||||
'tdf': NAMESPACES['tdf'],
|
||||
}
|
||||
|
||||
tipo = tree.xpath(
|
||||
'string(//cfdi:Comprobante/@TipoDeComprobante)',
|
||||
namespaces=namespaces)
|
||||
total = tree.xpath(
|
||||
'string(//cfdi:Comprobante/@Total)',
|
||||
namespaces=namespaces)
|
||||
rfc_emisor = tree.xpath(
|
||||
'string(//cfdi:Comprobante/cfdi:Emisor/@Rfc)',
|
||||
namespaces=namespaces)
|
||||
rfc_receptor = tree.xpath(
|
||||
'string(//cfdi:Comprobante/cfdi:Receptor/@Rfc)',
|
||||
namespaces=namespaces)
|
||||
uid = tree.xpath(
|
||||
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@UUID)',
|
||||
namespaces=namespaces)
|
||||
data = (
|
||||
f"USER={auth['user']}",
|
||||
f"PWDW={auth['pass']}",
|
||||
f"RFCE={rfc_emisor}",
|
||||
f"UUID={uid}",
|
||||
f"PWDK={info['pass']}",
|
||||
f"KEYF={info['key']}",
|
||||
f"CERT={info['cer']}",
|
||||
f"TIPO1={info['tipo']}",
|
||||
f"ACUS=SI",
|
||||
f"RFCR={rfc_receptor}",
|
||||
f"TIPOC={tipo}",
|
||||
f"TOTAL={total}",
|
||||
f"UUIDREL={info['args']['uuid']}",
|
||||
f"MOTIVO={info['args']['reason']}",
|
||||
)
|
||||
return '\n'.join(data)
|
||||
|
||||
def cancel(self, cfdi, info, auth):
|
||||
# ~ if DEBUG or not auth:
|
||||
# ~ auth = AUTH
|
||||
url = self.URL['cancel']
|
||||
data = self._get_data_cancel(cfdi, info, auth)
|
||||
|
||||
result = self._post(url, data)
|
||||
|
||||
if result is None:
|
||||
return ''
|
||||
|
||||
if result.status_code != 200:
|
||||
return ''
|
||||
|
||||
if result.headers['codigo'] != '000':
|
||||
self._error(result.headers['errmsg'])
|
||||
return ''
|
||||
|
||||
tree = ET.fromstring(result.text)
|
||||
date_cancel = tree.xpath('string(//Acuse/@Fecha)')[:19]
|
||||
|
||||
data = {
|
||||
'acuse': result.text,
|
||||
'date': date_cancel,
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
def _get_headers_cancel_xml(self, cfdi, info, auth):
|
||||
NS_CFDI = {
|
||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
}
|
||||
tree = ET.fromstring(cfdi.encode())
|
||||
tipocfdi = tree.xpath(
|
||||
'string(//cfdi:Comprobante/@TipoDeComprobante)',
|
||||
namespaces=NS_CFDI)
|
||||
total = tree.xpath(
|
||||
'string(//cfdi:Comprobante/@Total)',
|
||||
namespaces=NS_CFDI)
|
||||
rfc_receptor = tree.xpath(
|
||||
'string(//cfdi:Comprobante/cfdi:Receptor/@Rfc)',
|
||||
namespaces=NS_CFDI)
|
||||
|
||||
headers = {
|
||||
'usrws': auth['user'],
|
||||
'pwdws': auth['pass'],
|
||||
'rfcr': rfc_receptor,
|
||||
'total': total,
|
||||
'tipocfdi': tipocfdi,
|
||||
}
|
||||
headers.update(info)
|
||||
|
||||
return headers
|
||||
|
||||
def cancel_xml(self, xml, auth, cfdi='', info={'tipo': 'cfdi'}):
|
||||
# ~ if DEBUG or not auth:
|
||||
# ~ auth = AUTH
|
||||
|
||||
url = self.URL['cancelxml']
|
||||
headers = self._get_headers_cancel_xml(cfdi, info, auth)
|
||||
result = self._post(url, xml, headers)
|
||||
|
||||
if result is None:
|
||||
return ''
|
||||
|
||||
if result.status_code != 200:
|
||||
return ''
|
||||
|
||||
if result.headers['codigo'] != '000':
|
||||
self._error(result.headers['errmsg'])
|
||||
return ''
|
||||
|
||||
tree = ET.fromstring(result.text)
|
||||
date_cancel = tree.xpath('string(//Acuse/@Fecha)')[:19]
|
||||
|
||||
data = {
|
||||
'acuse': result.text,
|
||||
'date': date_cancel,
|
||||
}
|
||||
return data
|
||||
|
||||
def status(self, data, auth):
|
||||
# ~ if not auth:
|
||||
# ~ auth = AUTH
|
||||
url = self.URL['status']
|
||||
|
||||
data = (
|
||||
f"USER={auth['user']}",
|
||||
f"PWDW={auth['pass']}",
|
||||
f"RFCR={data['rfc_receptor']}",
|
||||
f"RFCE={data['rfc_emisor']}",
|
||||
f"TOTAL={data['total']}",
|
||||
f"UUID={data['uuid']}",
|
||||
)
|
||||
data = '\n'.join(data)
|
||||
result = self._post(url, data)
|
||||
|
||||
if result is None:
|
||||
return ''
|
||||
|
||||
if result.status_code != 200:
|
||||
self._error(result.status_code)
|
||||
return self.error
|
||||
|
||||
return result.text
|
||||
|
||||
def _get_data_client(self, auth, values):
|
||||
data = [f"usr_ws={auth['user']}", f"pwd_ws={auth['pass']}"]
|
||||
fields = (
|
||||
'rfc_contribuyente',
|
||||
'nombre_contribuyente',
|
||||
'calle',
|
||||
'noExterior',
|
||||
'noInterior',
|
||||
'colonia',
|
||||
'localidad',
|
||||
'municipio',
|
||||
'estado',
|
||||
'pais',
|
||||
'cp',
|
||||
'contacto',
|
||||
'telefono',
|
||||
'email',
|
||||
'rep_nom',
|
||||
'rep_rfc',
|
||||
'email_fact',
|
||||
'pwd_asignado',
|
||||
)
|
||||
data += [f"{k}={values[k]}" for k in fields]
|
||||
|
||||
return '\n'.join(data)
|
||||
|
||||
def client_add(self, data, auth):
|
||||
# ~ auth = AUTH
|
||||
url = self.URL['client']
|
||||
data = self._get_data_client(auth, data)
|
||||
|
||||
result = self._post(url, data)
|
||||
|
||||
if result is None:
|
||||
return False
|
||||
|
||||
if result.status_code != 200:
|
||||
self._error(f'Code: {result.status_code}')
|
||||
return False
|
||||
|
||||
if result.text != self.CODES['000']:
|
||||
self._error(result.text)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def client_balance(self, data, rfc=''):
|
||||
url = self.URL['saldo']
|
||||
host = url.split('/')[2]
|
||||
headers = {
|
||||
'Content-type': 'text/plain',
|
||||
'Host': host,
|
||||
'Connection' : 'Keep-Alive',
|
||||
}
|
||||
data = {'usr': data['user'], 'pwd': data['pass']}
|
||||
try:
|
||||
result = requests.get(url, params=data, headers=headers, timeout=TIMEOUT)
|
||||
except ConnectionError as e:
|
||||
self._error(e)
|
||||
return ''
|
||||
|
||||
if result.status_code != 200:
|
||||
return ''
|
||||
|
||||
if result.text == self.CODES['704']:
|
||||
self._error(result.text)
|
||||
return ''
|
||||
|
||||
if result.text == self.CODES['702']:
|
||||
self._error(result.text)
|
||||
return ''
|
||||
|
||||
return result.text
|
||||
|
||||
def client_add_timbres(self, data, auth):
|
||||
# ~ if not auth:
|
||||
# ~ auth = AUTH
|
||||
url = self.URL['timbres']
|
||||
data = '\n'.join((
|
||||
f"usr_ws={auth['user']}",
|
||||
f"pwd_ws={auth['pass']}",
|
||||
f"rfc_recibir={data['rfc']}",
|
||||
f"num_timbres={data['timbres']}"
|
||||
))
|
||||
|
||||
result = self._post(url, data)
|
||||
|
||||
if result is None:
|
||||
return False
|
||||
|
||||
if result.status_code != 200:
|
||||
self._error(f'Code: {result.status_code}')
|
||||
return False
|
||||
|
||||
if result.text != self.CODES['000']:
|
||||
self._error(result.text)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# ~
|
||||
# ~ PAC
|
||||
# ~ Copyright (C) 2018-2019 Mauricio Baeza Servin - public [AT] elmau [DOT] net
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# ~ Siempre consulta la documentación de PAC
|
||||
# ~ AUTH = Las credenciales de timbrado proporcionadas por el PAC
|
||||
# ~ NO cambies las credenciales de prueba
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
AUTH = {
|
||||
'user': '',
|
||||
'pass': '',
|
||||
}
|
||||
|
||||
|
||||
if DEBUG:
|
||||
AUTH = {
|
||||
'user': 'AAA010101AAA',
|
||||
'pass': 'PWD',
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from .finkok import PACFinkok
|
|
@ -1,46 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# ~
|
||||
# ~ PAC
|
||||
# ~ Copyright (C) 2018-2019 Mauricio Baeza Servin - public [AT] elmau [DOT] net
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# ~ Siempre consulta la documentación de PAC
|
||||
# ~ AUTH = Las credenciales de timbrado proporcionadas por el PAC
|
||||
# ~ NO cambies las credenciales de prueba
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
AUTH = {
|
||||
'user': '',
|
||||
'pass': '',
|
||||
'RESELLER': {
|
||||
'user': '',
|
||||
'pass': ''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if DEBUG:
|
||||
AUTH = {
|
||||
'user': 'pruebas-finkok@correolibre.net',
|
||||
'pass': '5c9a88da105bff9a8c430cb713f6d35269f51674bdc5963c1501b7316366',
|
||||
'RESELLER': {
|
||||
'user': '',
|
||||
'pass': ''
|
||||
}
|
||||
}
|
|
@ -1,580 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# ~
|
||||
# ~ PAC
|
||||
# ~ Copyright (C) 2018-2019 Mauricio Baeza Servin - public [AT] elmau [DOT] net
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# ~ import base64
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
from xml.sax.saxutils import unescape
|
||||
|
||||
import lxml.etree as ET
|
||||
from zeep import Client
|
||||
from zeep.plugins import Plugin
|
||||
from zeep.cache import SqliteCache
|
||||
from zeep.transports import Transport
|
||||
from zeep.exceptions import Fault, TransportError
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from .conf import DEBUG, AUTH
|
||||
|
||||
|
||||
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
||||
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
||||
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
||||
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
||||
log = logging.getLogger(__name__)
|
||||
logging.getLogger('requests').setLevel(logging.ERROR)
|
||||
logging.getLogger('zeep').setLevel(logging.ERROR)
|
||||
|
||||
|
||||
TIMEOUT = 10
|
||||
DEBUG_SOAP = False
|
||||
|
||||
|
||||
class DebugPlugin(Plugin):
|
||||
|
||||
def _to_string(self, envelope, name):
|
||||
if DEBUG_SOAP:
|
||||
data = ET.tostring(envelope, pretty_print=True, encoding='utf-8').decode()
|
||||
path = f'/tmp/soap_{name}.xml'
|
||||
with open(path, 'w') as f:
|
||||
f.write(data)
|
||||
# ~ print(data)
|
||||
return
|
||||
|
||||
def egress(self, envelope, http_headers, operation, binding_options):
|
||||
self._to_string(envelope, 'request')
|
||||
return envelope, http_headers
|
||||
|
||||
def ingress(self, envelope, http_headers, operation):
|
||||
self._to_string(envelope, 'response')
|
||||
return envelope, http_headers
|
||||
|
||||
|
||||
class PACFinkok(object):
|
||||
WS = 'https://facturacion.finkok.com/servicios/soap/{}.wsdl'
|
||||
NS_TYPE = 'ns1'
|
||||
if DEBUG:
|
||||
WS = 'https://demo-facturacion.finkok.com/servicios/soap/{}.wsdl'
|
||||
NS_TYPE = 'ns0'
|
||||
URL = {
|
||||
'quick_stamp': False,
|
||||
'timbra': WS.format('stamp'),
|
||||
'cancel': WS.format('cancel'),
|
||||
'client': WS.format('registration'),
|
||||
'util': WS.format('utilities'),
|
||||
}
|
||||
CODE = {
|
||||
'200': 'Comprobante timbrado satisfactoriamente',
|
||||
'205': 'No Encontrado',
|
||||
'307': 'Comprobante timbrado previamente',
|
||||
'702': 'No se encontro el RFC del emisor',
|
||||
'IP': 'Invalid Passphrase',
|
||||
'IPMSG': 'Frase de paso inválida',
|
||||
'NE': 'No Encontrado',
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self._error = ''
|
||||
self._transport = Transport(cache=SqliteCache(), timeout=TIMEOUT)
|
||||
self._plugins = [DebugPlugin()]
|
||||
|
||||
@property
|
||||
def error(self):
|
||||
return self._error
|
||||
|
||||
def _validate_result(self, result):
|
||||
if hasattr(result, 'Incidencias') and not result.Incidencias is None:
|
||||
fault = result.Incidencias.Incidencia[0]
|
||||
cod_error = fault.CodigoError.encode('utf-8').decode()
|
||||
msg_error = fault.MensajeIncidencia.encode('utf-8').decode()
|
||||
error = 'Error: {}\n{}'.format(cod_error, msg_error)
|
||||
if cod_error == '307':
|
||||
return result
|
||||
|
||||
self._error = self.CODE.get(cod_error, error)
|
||||
return {}
|
||||
|
||||
if hasattr(result, 'CodEstatus'):
|
||||
ce = result.CodEstatus
|
||||
if ce is None:
|
||||
return result
|
||||
|
||||
if ce == self.CODE['IP']:
|
||||
self._error = self.CODE['IPMSG']
|
||||
return {}
|
||||
|
||||
if self.CODE['NE'] in ce:
|
||||
self._error = 'UUID ' + self.CODE['NE']
|
||||
return {}
|
||||
|
||||
if ce == 'UUID Not Found':
|
||||
self._error = 'UUID ' + self.CODE['NE']
|
||||
return {}
|
||||
|
||||
if self.CODE['200'] != ce:
|
||||
self._error = ce
|
||||
return {}
|
||||
|
||||
return result
|
||||
|
||||
return result
|
||||
|
||||
def _get_result(self, client, method, args):
|
||||
self._error = ''
|
||||
try:
|
||||
result = getattr(client.service, method)(**args)
|
||||
except Fault as e:
|
||||
self._error = str(e)
|
||||
return {}
|
||||
except TransportError as e:
|
||||
if '413' in str(e):
|
||||
self._error = '413<BR><BR><b>Documento muy grande para timbrar</b>'
|
||||
else:
|
||||
self._error = str(e)
|
||||
return {}
|
||||
except ConnectionError as e:
|
||||
msg = '502 - Error de conexión'
|
||||
self._error = msg
|
||||
return {}
|
||||
|
||||
return self._validate_result(result)
|
||||
|
||||
def _to_string(self, data):
|
||||
root = ET.parse(BytesIO(data.encode('utf-8'))).getroot()
|
||||
xml = ET.tostring(root,
|
||||
pretty_print=True, xml_declaration=True, encoding='utf-8')
|
||||
return xml.decode('utf-8')
|
||||
|
||||
def stamp(self, cfdi, auth={}):
|
||||
if DEBUG or not auth:
|
||||
auth = AUTH
|
||||
|
||||
method = 'timbra'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'xml': cfdi.encode('utf-8'),
|
||||
}
|
||||
result = self._get_result(client, 'stamp', args)
|
||||
if self.error:
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
data = {
|
||||
'xml': self._to_string(result.xml),
|
||||
'uuid': result.UUID,
|
||||
'date': result.Fecha,
|
||||
}
|
||||
return data
|
||||
|
||||
def _get_data_cancel(self, cfdi):
|
||||
VERSIONS = {
|
||||
'3.3': 'http://www.sat.gob.mx/cfd/3',
|
||||
'4.0': 'http://www.sat.gob.mx/cfd/4',
|
||||
}
|
||||
NS_CFDI = {
|
||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
}
|
||||
tree = ET.fromstring(cfdi.encode())
|
||||
|
||||
version = tree.attrib['Version']
|
||||
NS_CFDI['cfdi'] = VERSIONS[version]
|
||||
|
||||
rfc_emisor = tree.xpath(
|
||||
'string(//cfdi:Comprobante/cfdi:Emisor/@Rfc)',
|
||||
namespaces=NS_CFDI)
|
||||
cfdi_uuid = tree.xpath(
|
||||
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@UUID)',
|
||||
namespaces=NS_CFDI)
|
||||
return rfc_emisor, cfdi_uuid
|
||||
|
||||
def cancel(self, cfdi, info, auth={}):
|
||||
if DEBUG or not auth:
|
||||
auth = AUTH
|
||||
|
||||
rfc_emisor, cfdi_uuid = self._get_data_cancel(cfdi)
|
||||
method = 'cancel'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
|
||||
uuid_type = client.get_type(f'{self.NS_TYPE}:UUIDS')
|
||||
ns1_uuid = client.get_type(f'{self.NS_TYPE}:UUID')
|
||||
|
||||
# ~ sa = client.get_type('ns0:stringArray')
|
||||
|
||||
data_uuid = {
|
||||
'UUID': cfdi_uuid,
|
||||
'FolioSustitucion': info['args']['uuid'],
|
||||
'Motivo': info['args']['reason'],
|
||||
}
|
||||
# ~ 'UUIDS': uuid_type(uuids=sa(string=cfdi_uuid)),
|
||||
|
||||
args = {
|
||||
'UUIDS': uuid_type(ns1_uuid(**data_uuid)),
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'taxpayer_id': rfc_emisor,
|
||||
'cer': info['cer'],
|
||||
'key': info['key'],
|
||||
'store_pending': False,
|
||||
}
|
||||
|
||||
result = self._get_result(client, 'cancel', args)
|
||||
if self.error:
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
folio = result['Folios']['Folio'][0]
|
||||
status = folio['EstatusUUID']
|
||||
if status != '201':
|
||||
log.debug(f'Cancel status: {status} - {cfdi_uuid}')
|
||||
|
||||
data = {
|
||||
'acuse': result['Acuse'],
|
||||
'date': result['Fecha'],
|
||||
}
|
||||
return data
|
||||
|
||||
def cancel_xml(self, xml, auth={}, cfdi=''):
|
||||
if DEBUG or not auth:
|
||||
auth = AUTH
|
||||
|
||||
method = 'cancel'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
client.set_ns_prefix('can', 'http://facturacion.finkok.com/cancel')
|
||||
args = {
|
||||
'xml': xml.encode(),
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'store_pending': False,
|
||||
}
|
||||
result = self._get_result(client, 'cancel_signature', args)
|
||||
if self.error:
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
folio = result['Folios']['Folio'][0]
|
||||
status = folio['EstatusUUID']
|
||||
|
||||
if status == '708':
|
||||
self._error = 'Error 708 del SAT, intenta más tarde.'
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
if status != '201':
|
||||
log.debug(f'Cancel status: {status} -')
|
||||
|
||||
data = {
|
||||
'acuse': result['Acuse'],
|
||||
'date': result['Fecha'],
|
||||
}
|
||||
return data
|
||||
|
||||
def client_add(self, rfc, type_user=False):
|
||||
"""Agrega un nuevo cliente para timbrado.
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
|
||||
Args:
|
||||
rfc (str): El RFC del nuevo cliente
|
||||
|
||||
Kwargs:
|
||||
type_user (bool):
|
||||
False == 'P' == Prepago
|
||||
True == 'O' == On demand
|
||||
|
||||
Returns:
|
||||
True or False
|
||||
|
||||
origin PAC
|
||||
'message':
|
||||
'Account Created successfully'
|
||||
'Account Already exists'
|
||||
'success': True or False
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
tu = {True: 'O', False: 'P'}
|
||||
|
||||
method = 'client'
|
||||
client = Client(
|
||||
self.URL[method], transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'reseller_username': auth['user'],
|
||||
'reseller_password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
'type_user': tu[type_user],
|
||||
'added': datetime.datetime.now().isoformat()[:19],
|
||||
}
|
||||
|
||||
result = self._get_result(client, 'add', args)
|
||||
if self.error:
|
||||
return False
|
||||
|
||||
if not result.success:
|
||||
self.error = result.message
|
||||
return False
|
||||
|
||||
# ~ PAC success debería ser False
|
||||
msg = 'Account Already exists'
|
||||
if result.message == msg:
|
||||
self.error = msg
|
||||
return True
|
||||
|
||||
return result.success
|
||||
|
||||
def client_get_token(self, rfc, email):
|
||||
"""Genera un nuevo token al cliente para timbrado.
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
|
||||
Args:
|
||||
rfc (str): El RFC del cliente, ya debe existir
|
||||
email (str): El correo del cliente, funciona como USER al timbrar
|
||||
|
||||
Returns:
|
||||
token (str): Es la contraseña para timbrar
|
||||
|
||||
origin PAC
|
||||
dict
|
||||
'username': 'username',
|
||||
'status': True or False
|
||||
'name': 'name',
|
||||
'success': True or False
|
||||
'token': 'Token de timbrado',
|
||||
'message': None
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
method = 'util'
|
||||
client = Client(
|
||||
self.URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'name': rfc,
|
||||
'token_username': email,
|
||||
'taxpayer_id': rfc,
|
||||
'status': True,
|
||||
}
|
||||
|
||||
result = self._get_result(client, 'add_token', args)
|
||||
if self.error:
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
if not result.success:
|
||||
self.error = result.message
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
return result.token
|
||||
|
||||
def client_add_timbres(self, rfc, credit):
|
||||
"""Agregar credito a un emisor
|
||||
|
||||
Se requiere cuenta de reseller
|
||||
|
||||
Args:
|
||||
rfc (str): El RFC del emisor, debe existir
|
||||
credit (int): Cantidad de folios a agregar
|
||||
|
||||
Returns:
|
||||
dict
|
||||
'success': True or False,
|
||||
'credit': nuevo credito despues de agregar or None
|
||||
'message':
|
||||
'Success, added {credit} of credit to {RFC}.'
|
||||
'RFC no encontrado'
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
|
||||
method = 'client'
|
||||
client = Client(
|
||||
self.URL[method], transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
'credit': credit,
|
||||
}
|
||||
|
||||
result = self._get_result(client, 'assign', args)
|
||||
if self.error:
|
||||
log.error(error)
|
||||
return ''
|
||||
|
||||
if not result.success:
|
||||
self.error = result.message
|
||||
return 0
|
||||
|
||||
return result.credit
|
||||
|
||||
def client_balance(self, auth={}, rfc=''):
|
||||
"""Regresa los timbres restantes del cliente
|
||||
Se pueden usar las credenciales de relleser o las credenciales del emisor
|
||||
|
||||
Args:
|
||||
auth (dict): Credenciales del emisor
|
||||
rfc (str): El RFC del emisor
|
||||
|
||||
Returns:
|
||||
int Cantidad de timbres restantes
|
||||
"""
|
||||
if not auth:
|
||||
auth = AUTH['RESELLER']
|
||||
|
||||
method = 'client'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
args = {
|
||||
'reseller_username': auth['user'],
|
||||
'reseller_password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
}
|
||||
result = self._get_result(client, 'get', args)
|
||||
|
||||
if self.error:
|
||||
log.error(self.error)
|
||||
return ''
|
||||
|
||||
success = bool(result.users)
|
||||
if not success:
|
||||
self._error = result.message or 'RFC no existe'
|
||||
log.error(self.error)
|
||||
return 0
|
||||
|
||||
return result.users.ResellerUser[0].credit
|
||||
|
||||
def client_set_status(self, rfc, status):
|
||||
"""Edita el estatus (Activo o Suspendido) de un cliente
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
|
||||
Args:
|
||||
rfc (str): El RFC del cliente
|
||||
|
||||
Kwargs:
|
||||
status (bool):
|
||||
True == 'A' == Activo
|
||||
False == 'S' == Suspendido
|
||||
|
||||
Returns:
|
||||
dict
|
||||
'message':
|
||||
'Account Created successfully'
|
||||
'Account Already exists'
|
||||
'success': True or False
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
ts = {True: 'A', False: 'S'}
|
||||
method = 'client'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'reseller_username': auth['user'],
|
||||
'reseller_password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
'status': ts[status],
|
||||
}
|
||||
result = self._get_result(client, 'edit', args)
|
||||
|
||||
if self.error:
|
||||
return False
|
||||
|
||||
if not result.success:
|
||||
self.error = result.message
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def client_switch(self, rfc, type_user):
|
||||
"""Edita el tipo de timbrado (OnDemand o Prepago) de un cliente
|
||||
Se requiere cuenta de reseller para usar este método
|
||||
|
||||
Args:
|
||||
rfc (str): El RFC del cliente
|
||||
|
||||
Kwargs:
|
||||
status (bool):
|
||||
True == 'O' == OnDemand
|
||||
False == 'P' == Prepago
|
||||
|
||||
Returns:
|
||||
dict
|
||||
'message':
|
||||
'Account Created successfully'
|
||||
'Account Already exists'
|
||||
'success': True or False
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
tu = {True: 'O', False: 'P'}
|
||||
method = 'client'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
|
||||
args = {
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
'type_user': tu[type_user],
|
||||
}
|
||||
result = self._get_result(client, 'switch', args)
|
||||
|
||||
if self.error:
|
||||
return False
|
||||
|
||||
if not result.success:
|
||||
self.error = result.message
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def client_report_folios(self, rfc, date_from, date_to, invoice_type='I'):
|
||||
"""Obtiene un reporte del total de facturas timbradas
|
||||
"""
|
||||
auth = AUTH['RESELLER']
|
||||
|
||||
args = {
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'taxpayer_id': rfc,
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'invoice_type': invoice_type,
|
||||
}
|
||||
|
||||
method = 'util'
|
||||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
|
||||
result = self._get_result(client, 'report_total', args)
|
||||
|
||||
if result.result is None:
|
||||
# ~ PAC - Debería regresar RFC inexistente o sin registros
|
||||
self.error = 'RFC no existe o no tiene registros'
|
||||
return 0
|
||||
|
||||
total = result.result.ReportTotal[0].total
|
||||
|
||||
return total
|
|
@ -1,87 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from decimal import Decimal, getcontext
|
||||
# ~ getcontext().prec = 6
|
||||
|
||||
import lxml.etree as ET
|
||||
from requests.structures import CaseInsensitiveDict as CIDict
|
||||
|
||||
|
||||
NS_CFDI = {
|
||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
||||
'tfd': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
'nomina12': 'http://www.sat.gob.mx/nomina12',
|
||||
}
|
||||
PRE = '/cfdi:Comprobante'
|
||||
|
||||
|
||||
class CfdiRead(object):
|
||||
|
||||
def __init__(self, source):
|
||||
self._source = source
|
||||
self._data = {}
|
||||
self._error = ''
|
||||
self._rfc_emisor = ''
|
||||
self._rfc_receptor = ''
|
||||
self._parse()
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._source
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
return self._data
|
||||
|
||||
@property
|
||||
def rfc_emisor(self):
|
||||
return self._rfc_emisor
|
||||
|
||||
@property
|
||||
def rfc_receptor(self):
|
||||
return self._rfc_receptor
|
||||
|
||||
@property
|
||||
def error(self):
|
||||
return self._error
|
||||
|
||||
def _parse(self):
|
||||
self._tree = ET.fromstring(self.source)
|
||||
self._data['cfdi'] = dict(self._tree.attrib)
|
||||
|
||||
node_name = f'{PRE}/cfdi:Emisor'
|
||||
self._data['emisor'] = self._get_attr(node_name)
|
||||
self._rfc_emisor = self._data['emisor']['Rfc']
|
||||
|
||||
node_name = f'{PRE}/cfdi:Receptor'
|
||||
self._data['receptor'] = self._get_attr(node_name)
|
||||
self._rfc_receptor = self._data['receptor']['Rfc']
|
||||
|
||||
node_name = f'{PRE}/cfdi:Complemento/tfd:TimbreFiscalDigital'
|
||||
self._data['timbre'] = self._get_attr(node_name)
|
||||
|
||||
self._parse_details()
|
||||
return
|
||||
|
||||
def _get_attr(self, node_name):
|
||||
node = self._tree.xpath(node_name, namespaces=NS_CFDI)[0]
|
||||
attr = dict(node.attrib)
|
||||
return attr
|
||||
|
||||
def _parse_details(self):
|
||||
node_name = f'{PRE}/cfdi:Conceptos/cfdi:Concepto'
|
||||
details = self._tree.xpath(node_name, namespaces=NS_CFDI)
|
||||
rows = []
|
||||
for detail in details:
|
||||
row = dict(detail.attrib)
|
||||
for k, v in row.items():
|
||||
if k in ('Cantidad', 'ValorUnitario', 'Descuento', 'Importe'):
|
||||
row[k] = Decimal(v)
|
||||
# ~ row['taxes'] = self._get_taxes(detail)
|
||||
rows.append(row)
|
||||
self._data['conceptos'] = rows
|
||||
return
|
||||
|
||||
|
||||
class CfdiWrite(object):
|
||||
pass
|
|
@ -1,33 +0,0 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name cfdi.empresalibre.net;
|
||||
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass 127.0.0.1:3033;
|
||||
|
||||
access_log /var/log/nginx/empresa-libre.access.log;
|
||||
error_log /var/log/nginx/empresa-libre.error.log;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
# redirect server error pages to the static page /50x.html
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
location /static {
|
||||
alias /opt/empresa-libre/static;
|
||||
}
|
||||
|
||||
if ($http_user_agent ~* (python|curl) ) {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Necesario para Let's Encrypt
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
default_type "text/plain";
|
||||
root /opt/www;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
[Unit]
|
||||
Description=uWSGI instance to serve Empresa Libre
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/uwsgi /opt/empresa-libre/app/main.ini
|
||||
KillSignal=SIGQUIT
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,13 @@
|
|||
[uwsgi]
|
||||
socket = 127.0.0.1:3033
|
||||
uid = nginx
|
||||
gid = nginx
|
||||
chdir = /srv/app/empresa-libre/app
|
||||
wsgi-file = main.py
|
||||
callable = app
|
||||
master = true
|
||||
processes = 4
|
||||
threads = 4
|
||||
thunder-lock = true
|
||||
#~ stats = 127.0.0.1:9191
|
||||
logger = file:/srv/log/empresalibre-uwsgi.log
|
|
@ -1,19 +0,0 @@
|
|||
[uwsgi]
|
||||
#~ Debe de corresponder con tu configuracion proxi en tu servidor web
|
||||
socket = 127.0.0.1:3033
|
||||
uid = nginx
|
||||
gid = nginx
|
||||
#~ Establece una ruta accesible para el servidor web
|
||||
chdir = /srv/app/empresa-libre/app
|
||||
wsgi-file = main.py
|
||||
callable = app
|
||||
master = true
|
||||
#~ Puedes configurar de acuerdo a los recursos de tu servidor
|
||||
processes = 4
|
||||
threads = 4
|
||||
thunder-lock = true
|
||||
#~ stats = 127.0.0.1:9191
|
||||
#~ Establece una ruta accesible para el servidor web
|
||||
logger = file:/srv/log/empresalibre-uwsgi.log
|
||||
log-maxsize = 1000000
|
||||
http-timeout = 180
|
|
@ -8,29 +8,16 @@ from middleware import (
|
|||
AuthMiddleware,
|
||||
JSONTranslator,
|
||||
ConnectionMiddleware,
|
||||
static,
|
||||
handle_404
|
||||
)
|
||||
from models.db import StorageEngine
|
||||
from controllers.main import (AppEmpresas,
|
||||
from controllers.main import (
|
||||
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
||||
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
||||
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
||||
AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina,
|
||||
AppInvoicePay, AppCfdiPay, AppSATBancos, AppSociosCuentasBanco,
|
||||
AppSATFormaPago, AppSATLeyendaFiscales, AppCert, AppSucursales,
|
||||
AppPartnerProducts,
|
||||
AppInventoryEntries,
|
||||
AppTicketsDetails,
|
||||
AppUsers,
|
||||
AppWareHouse,
|
||||
AppWareHouseProduct,
|
||||
AppSATUnidadesPeso,
|
||||
AppSATRegimenes,
|
||||
AppSociosRegimenes,
|
||||
AppDocumentos
|
||||
)
|
||||
|
||||
|
||||
from settings import DEBUG, MV, NO_HTTPS, PATH_SESSIONS
|
||||
from settings import DEBUG
|
||||
|
||||
|
||||
db = StorageEngine()
|
||||
|
@ -44,7 +31,6 @@ api = falcon.API(middleware=[
|
|||
api.req_options.auto_parse_form_urlencoded = True
|
||||
api.add_sink(handle_404, '')
|
||||
|
||||
api.add_route('/empresas', AppEmpresas(db))
|
||||
api.add_route('/', AppLogin(db))
|
||||
api.add_route('/logout', AppLogout(db))
|
||||
api.add_route('/admin', AppAdmin(db))
|
||||
|
@ -52,49 +38,23 @@ api.add_route('/emisor', AppEmisor(db))
|
|||
api.add_route('/folios', AppFolios(db))
|
||||
api.add_route('/main', AppMain(db))
|
||||
api.add_route('/values/{table}', AppValues(db))
|
||||
api.add_route('/files/{table}', AppFiles(db))
|
||||
api.add_route('/config', AppConfig(db))
|
||||
api.add_route('/doc/{type_doc}/{id_doc}', AppDocumentos(db))
|
||||
api.add_route('/partners', AppPartners(db))
|
||||
api.add_route('/products', AppProducts(db))
|
||||
api.add_route('/invoices', AppInvoices(db))
|
||||
api.add_route('/preinvoices', AppPreInvoices(db))
|
||||
api.add_route('/tickets', AppTickets(db))
|
||||
api.add_route('/cuentasbanco', AppCuentasBanco(db))
|
||||
api.add_route('/movbanco', AppMovimientosBanco(db))
|
||||
api.add_route('/students', AppStudents(db))
|
||||
api.add_route('/employees', AppEmployees(db))
|
||||
api.add_route('/nomina', AppNomina(db))
|
||||
api.add_route('/invoicepay', AppInvoicePay(db))
|
||||
api.add_route('/cfdipay', AppCfdiPay(db))
|
||||
api.add_route('/satbancos', AppSATBancos(db))
|
||||
api.add_route('/satformapago', AppSATFormaPago(db))
|
||||
api.add_route('/socioscb', AppSociosCuentasBanco(db))
|
||||
api.add_route('/leyendasfiscales', AppSATLeyendaFiscales(db))
|
||||
api.add_route('/cert', AppCert(db))
|
||||
api.add_route('/sucursales', AppSucursales(db))
|
||||
api.add_route('/partnerproducts', AppPartnerProducts(db))
|
||||
api.add_route('/inventoryentries', AppInventoryEntries(db))
|
||||
api.add_route('/warehouse', AppWareHouse(db))
|
||||
api.add_route('/warehouseproduct', AppWareHouseProduct(db))
|
||||
api.add_route('/ticketsdetails', AppTicketsDetails(db))
|
||||
api.add_route('/users', AppUsers(db))
|
||||
api.add_route('/satunidadespeso', AppSATUnidadesPeso(db))
|
||||
api.add_route('/satregimenes', AppSATRegimenes(db))
|
||||
api.add_route('/sociosregimenes', AppSociosRegimenes(db))
|
||||
|
||||
|
||||
|
||||
if DEBUG:
|
||||
api.add_sink(static, '/static')
|
||||
|
||||
|
||||
session_options = {
|
||||
'session.type': 'file',
|
||||
'session.cookie_expires': True,
|
||||
'session.httponly': True,
|
||||
'session.secure': True,
|
||||
'session.data_dir': PATH_SESSIONS['data'],
|
||||
'session.lock_dir': PATH_SESSIONS['lock'],
|
||||
'session.data_dir': '/tmp/cache/data',
|
||||
'session.lock_dir': '/tmp/cache/lock',
|
||||
}
|
||||
# ~ Si no usas (NO deberías) certificados en tu servidor, ponla siempre en False
|
||||
if DEBUG or MV or NO_HTTPS:
|
||||
session_options['session.secure'] = False
|
||||
|
||||
app = SessionMiddleware(api, session_options)
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
[uwsgi]
|
||||
http = 127.0.0.1:8000
|
||||
#~ http = 37.228.132.181:9000
|
||||
wsgi-file = main.py
|
||||
callable = app
|
||||
master = true
|
||||
processes = 4
|
||||
threads = 4
|
||||
py-autoreload = 1
|
||||
thunder-lock = true
|
||||
static-map = /static=../static
|
||||
http-timeout = 300
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
[uwsgi]
|
||||
http = :8000
|
||||
uid = empresa
|
||||
gid = empresa
|
||||
chdir = /home/empresa/.opt/empresa-libre/source/app
|
||||
wsgi-file = main.py
|
||||
callable = app
|
||||
master = true
|
||||
processes = 4
|
||||
threads = 4
|
||||
thunder-lock = true
|
||||
static-map = /static=../static
|
||||
logger = file:../../../empresa-libre-uwsgi.log
|
|
@ -3,7 +3,7 @@
|
|||
import falcon
|
||||
from controllers import util
|
||||
from models import main
|
||||
from settings import MV
|
||||
from settings import PATH_STATIC
|
||||
|
||||
|
||||
def handle_404(req, resp):
|
||||
|
@ -20,44 +20,22 @@ def get_template(req, resp, resource):
|
|||
resp.body = util.get_template(resource.template, data)
|
||||
|
||||
|
||||
# ~ def static(req, res):
|
||||
# ~ path = PATH_STATIC + req.path
|
||||
# ~ if util.is_file(path):
|
||||
# ~ res.content_type = util.get_mimetype(path)
|
||||
# ~ res.stream, res.stream_len = util.get_stream(path)
|
||||
# ~ res.status = falcon.HTTP_200
|
||||
# ~ else:
|
||||
# ~ res.status = falcon.HTTP_404
|
||||
def static(req, res):
|
||||
path = PATH_STATIC + req.path
|
||||
if util.is_file(path):
|
||||
res.content_type = util.get_mimetype(path)
|
||||
res.stream, res.stream_len = util.get_stream(path)
|
||||
res.status = falcon.HTTP_200
|
||||
else:
|
||||
res.status = falcon.HTTP_404
|
||||
|
||||
|
||||
class AuthMiddleware(object):
|
||||
|
||||
def process_response(self, req, resp, resource):
|
||||
pass
|
||||
|
||||
def process_resource(self, req, resp, resource, params):
|
||||
session = req.env['beaker.session']
|
||||
user = session.get('userobj', None)
|
||||
id_session = req.cookies.get('beaker.session.id', '')
|
||||
|
||||
if req.path == '/values/titlelogin':
|
||||
pass
|
||||
elif req.path == '/empresas' or req.path == '/values/empresas':
|
||||
if MV:
|
||||
pass
|
||||
else:
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
elif id_session and req.path == '/admin':
|
||||
if user is None:
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
elif not user.es_admin and not user.es_superusuario:
|
||||
raise falcon.HTTPTemporaryRedirect('/main')
|
||||
elif not id_session and req.path != '/':
|
||||
if not id_session and req.path != '/':
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
elif id_session and user is None:
|
||||
session.delete()
|
||||
if req.path == '/main':
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
|
||||
|
||||
class JSONTranslator(object):
|
||||
|
@ -68,15 +46,9 @@ class JSONTranslator(object):
|
|||
def process_response(self, req, resp, resource):
|
||||
if 'result' not in req.context:
|
||||
return
|
||||
|
||||
if '/doc/' in req.path:
|
||||
resp.body = req.context['result']
|
||||
return
|
||||
|
||||
if 'blob' in req.context:
|
||||
resp.body = req.context['blob']
|
||||
return
|
||||
|
||||
resp.body = util.dumps(req.context['result'])
|
||||
|
||||
|
||||
|
@ -89,10 +61,7 @@ class ConnectionMiddleware(object):
|
|||
rfc = session.get('rfc', '')
|
||||
if id_session and rfc:
|
||||
opt = util.get_con(rfc)
|
||||
if opt:
|
||||
main.conectar(opt)
|
||||
else:
|
||||
raise falcon.HTTPTemporaryRedirect('/')
|
||||
main.conectar(opt)
|
||||
|
||||
def process_response(self, req, resp, resource):
|
||||
main.desconectar()
|
||||
|
|
|
@ -1,21 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# ~ Empresa Libre
|
||||
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import main
|
||||
|
||||
|
||||
|
@ -27,89 +11,17 @@ class StorageEngine(object):
|
|||
def authenticate(self, args):
|
||||
return main.authenticate(args)
|
||||
|
||||
def get_employees(self, values):
|
||||
return main.Empleados.get_by(values)
|
||||
|
||||
def get_nomina(self, values):
|
||||
return main.CfdiNomina.get_by(values)
|
||||
|
||||
def empresa_agregar(self, values):
|
||||
# ~ return main.empresa_agregar(values['alta_rfc'], False)
|
||||
return main._new_client(values['alta_rfc'], False)
|
||||
|
||||
def empresa_borrar(self, values):
|
||||
# ~ return main.empresa_borrar(values['rfc'])
|
||||
return main._delete_client(values['rfc'], False, False)
|
||||
|
||||
def respaldar_dbs(self):
|
||||
return main.respaldar_dbs()
|
||||
|
||||
def get_values(self, table, values=None, session=None):
|
||||
if table in ('allusuarios', 'usuarioupdate', 'main'):
|
||||
return getattr(self, '_get_{}'.format(table))(values, session)
|
||||
def get_values(self, table, values=None):
|
||||
return getattr(self, '_get_{}'.format(table))(values)
|
||||
|
||||
def _get_timbres(self, values):
|
||||
return main.Emisor.get_timbres()
|
||||
|
||||
def _get_schoolgroups(self, values):
|
||||
return main.Grupos.get_by(values)
|
||||
|
||||
def _get_nivedusat(self, values):
|
||||
return main.SATNivelesEducativos.get_by()
|
||||
|
||||
def _get_niveduall(self, values):
|
||||
return main.NivelesEducativos.get_all()
|
||||
|
||||
def _get_titlelogin(self, values):
|
||||
return main.get_title_app(2)
|
||||
|
||||
def _get_canopenpre(self, values):
|
||||
return main.PreFacturasDetalle.can_open(values['id'])
|
||||
|
||||
def _get_importinvoice(self, values):
|
||||
return main.import_invoice()
|
||||
|
||||
def _get_importceods(self, values):
|
||||
return main.import_ceods()
|
||||
|
||||
def _get_main(self, values, session):
|
||||
return main.config_main(session['userobj'])
|
||||
|
||||
def _get_configtimbrar(self, values):
|
||||
return main.config_timbrar()
|
||||
|
||||
def _get_invoicenotes(self, values):
|
||||
return main.Facturas.get_notes(values['id'])
|
||||
|
||||
def save_invoice_notes(self, values):
|
||||
return main.Facturas.save_notes(values)
|
||||
|
||||
def _get_configticket(self, values):
|
||||
return main.config_ticket()
|
||||
|
||||
def _get_saldocuenta(self, values):
|
||||
return main.CuentasBanco.get_saldo(values['id'])
|
||||
|
||||
def _get_validartimbrar(self, values):
|
||||
return main.validar_timbrar()
|
||||
|
||||
def _get_preproductos(self, values):
|
||||
return main.PreFacturasDetalle.facturar(values['id'])
|
||||
|
||||
def upload_file(self, session, table, file_obj):
|
||||
if not 'rfc' in session:
|
||||
return {'status': 'error'}
|
||||
return main.upload_file(session['rfc'], table, file_obj)
|
||||
|
||||
def get_config(self, values):
|
||||
return main.Configuracion.get_(values)
|
||||
|
||||
def add_config(self, values):
|
||||
return main.Configuracion.add(values)
|
||||
|
||||
def add_cert(self, file_obj):
|
||||
return main.Certificado.add(file_obj)
|
||||
def add_cert(self, file_object):
|
||||
return main.Certificado.add(file_object)
|
||||
|
||||
def validate_cert(self, values, session):
|
||||
return main.Certificado.validate(values, session)
|
||||
|
@ -120,26 +32,6 @@ class StorageEngine(object):
|
|||
def send_email(self, values, session):
|
||||
return main.Facturas.send(values['id'], session['rfc'])
|
||||
|
||||
def enviar_prefac(self, values):
|
||||
return main.PreFacturas.enviar(values['id'])
|
||||
|
||||
def _get_verifysat(self, values):
|
||||
return main.Facturas.get_verify_sat(values['id'])
|
||||
|
||||
def _get_filteryears(self, values):
|
||||
years1 = main.Facturas.filter_years()
|
||||
years2 = main.PreFacturas.filter_years()
|
||||
return [years1, years2]
|
||||
|
||||
def _get_filteryearsticket(self, values):
|
||||
return main.Tickets.filter_years()
|
||||
|
||||
def _get_filteryearsnomina(self, values):
|
||||
return main.CfdiNomina.filter_years()
|
||||
|
||||
def _get_cuentayears(self, values):
|
||||
return main.CuentasBanco.get_years()
|
||||
|
||||
def _get_cert(self, values):
|
||||
return main.Certificado.get_data()
|
||||
|
||||
|
@ -149,12 +41,6 @@ class StorageEngine(object):
|
|||
def _get_formapago(self, values):
|
||||
return main.SATFormaPago.get_activos(values)
|
||||
|
||||
def _get_tiporelacion(self, values):
|
||||
return main.SATTipoRelacion.get_activos(values)
|
||||
|
||||
def _get_condicionespago(self, values):
|
||||
return main.CondicionesPago.get_()
|
||||
|
||||
def _get_categorias(self, values):
|
||||
return main.Categorias.get_all()
|
||||
|
||||
|
@ -164,246 +50,70 @@ class StorageEngine(object):
|
|||
def _get_unidades(self, values):
|
||||
return main.SATUnidades.get_activos()
|
||||
|
||||
def _get_unitbykey(self, values):
|
||||
return main.SATUnidades.get_activos_by_key()
|
||||
|
||||
def add_moneda(self, values):
|
||||
return main.SATMonedas.add(values)
|
||||
|
||||
def add_unidad(self, values):
|
||||
return main.SATUnidades.add(values)
|
||||
|
||||
def add_impuesto(self, values):
|
||||
return main.SATImpuestos.add(values)
|
||||
|
||||
def add_usuario(self, values):
|
||||
return main.Usuarios.add(values)
|
||||
|
||||
def edit_usuario(self, values):
|
||||
return main.Usuarios.edit(values)
|
||||
|
||||
def _get_taxes(self, values):
|
||||
return main.SATImpuestos.get_activos()
|
||||
|
||||
def _get_alltaxes(self, values):
|
||||
return main.SATImpuestos.get_()
|
||||
|
||||
def _get_allcurrencies(self, values):
|
||||
return main.SATMonedas.get_()
|
||||
|
||||
def _get_allbancos(self, values):
|
||||
return main.SATBancos.get_()
|
||||
|
||||
def _get_allunidades(self, values):
|
||||
return main.SATUnidades.get_()
|
||||
|
||||
def _get_allformasdepago(self, values):
|
||||
return main.SATFormaPago.get_()
|
||||
|
||||
def _get_allusoscfdi(self, values):
|
||||
return main.SATUsoCfdi.get_all()
|
||||
|
||||
def _get_allregimenes(self, values):
|
||||
filters = {'opt': 'all'}
|
||||
return main.SATRegimenes.get_data(filters, None)
|
||||
|
||||
def _get_allusuarios(self, values, session):
|
||||
return main.Usuarios.get_(session['userobj'])
|
||||
|
||||
def _get_usuarioupdate(self, values, session):
|
||||
return main.Usuarios.actualizar(values, session['userobj'])
|
||||
|
||||
def _get_taxupdate(self, values):
|
||||
return main.SATImpuestos.actualizar(values)
|
||||
|
||||
def _get_currencyupdate(self, values):
|
||||
return main.SATMonedas.actualizar(values)
|
||||
|
||||
def _get_bancoupdate(self, values):
|
||||
return main.SATBancos.actualizar(values)
|
||||
|
||||
def _get_emisorbancoupdate(self, values):
|
||||
return main.CuentasBanco.activate(values)
|
||||
|
||||
def _get_unidadupdate(self, values):
|
||||
return main.SATUnidades.actualizar(values)
|
||||
|
||||
def _get_formasdepagoupdate(self, values):
|
||||
return main.SATFormaPago.actualizar(values)
|
||||
|
||||
def _get_usocfdiupdate(self, values):
|
||||
return main.SATUsoCfdi.actualizar(values)
|
||||
|
||||
def _get_regimenesupdate(self, values):
|
||||
return main.SATRegimenes.actualizar(values)
|
||||
|
||||
def _get_emisorcuentasbanco(self, values):
|
||||
return main.CuentasBanco.emisor()
|
||||
|
||||
def _get_satkey(self, values):
|
||||
return main.get_sat_key(values['key'])
|
||||
|
||||
def _get_satmonedas(self, values):
|
||||
return main.get_sat_monedas(values['key'])
|
||||
|
||||
def _get_satunidades(self, values):
|
||||
return main.get_sat_unidades(values['key'])
|
||||
|
||||
def _get_satunidadespeso(self, values):
|
||||
return main.get_sat_unidadespeso(values['key'])
|
||||
|
||||
def _get_satproductos(self, values):
|
||||
return main.get_sat_productos(values['key'])
|
||||
|
||||
def _get_series(self, values):
|
||||
return main.Folios.get_all()
|
||||
|
||||
def _get_monedas(self, values):
|
||||
return main.SATMonedas.get_activos()
|
||||
|
||||
def _get_monedasid(self, values):
|
||||
return main.SATMonedas.get_activos_by_id()
|
||||
|
||||
def _get_bancosid(self, values):
|
||||
return main.SATBancos.get_activos_by_id()
|
||||
|
||||
def _get_regimenes(self, values):
|
||||
return main.Emisor.get_regimenes()
|
||||
|
||||
def _get_usocfdi(self, values):
|
||||
return main.SATUsoCfdi.get_activos()
|
||||
return main.SATUsoCfdi.get_activos(values)
|
||||
|
||||
def _get_ebancomov(self, values):
|
||||
return main.MovimientosBanco.con(values['id'])
|
||||
|
||||
def delete(self, table, id, user=None):
|
||||
def delete(self, table, id):
|
||||
if table == 'partner':
|
||||
return main.Socios.remove(id)
|
||||
if table == 'product':
|
||||
return main.Productos.remove(id)
|
||||
if table == 'invoice':
|
||||
return main.Facturas.remove(id, user)
|
||||
return main.Facturas.remove(id)
|
||||
if table == 'folios':
|
||||
return main.Folios.remove(id)
|
||||
if table == 'preinvoice':
|
||||
return main.PreFacturas.remove(id)
|
||||
if table == 'satimpuesto':
|
||||
return main.SATImpuestos.remove(id)
|
||||
if table == 'satunit':
|
||||
return main.SATUnidades.remove(id)
|
||||
if table == 'cuentasbanco':
|
||||
return main.CuentasBanco.remove(id)
|
||||
if table == 'movbanco':
|
||||
return main.MovimientosBanco.remove(id)
|
||||
if table == 'usuario':
|
||||
return main.Usuarios.remove(id)
|
||||
if table == 'config':
|
||||
return main.Configuracion.remove(id)
|
||||
if table == 'nivedu':
|
||||
return main.NivelesEducativos.remove(id)
|
||||
if table == 'students':
|
||||
return main.Alumnos.remove(id)
|
||||
if table == 'employee':
|
||||
return main.Empleados.remove(id)
|
||||
if table == 'nomina':
|
||||
return main.CfdiNomina.remove(id)
|
||||
return False
|
||||
|
||||
def _get_client(self, values):
|
||||
return main.Socios.get_by_client(values)
|
||||
|
||||
def _get_student(self, values):
|
||||
return main.Alumnos.get_by_name(values)
|
||||
|
||||
def _get_product(self, values):
|
||||
return main.Productos.get_by(values)
|
||||
|
||||
def _get_productokey(self, values):
|
||||
return main.Productos.get_by_key(values)
|
||||
|
||||
def get_partners(self, values):
|
||||
return main.Socios.get_(values)
|
||||
|
||||
def partner(self, values):
|
||||
if 'opt' in values:
|
||||
return main.Socios.opt(values)
|
||||
|
||||
id = int(values.pop('id', '0'))
|
||||
if id:
|
||||
return main.Socios.actualizar(values, id)
|
||||
|
||||
return main.Socios.add(values)
|
||||
|
||||
def get_products(self, values):
|
||||
return main.Productos.get_(values)
|
||||
|
||||
def products(self, values):
|
||||
def product(self, values):
|
||||
id = int(values.pop('id', '0'))
|
||||
if id:
|
||||
return main.Productos.actualizar(values, id)
|
||||
|
||||
opt = values.get('opt', '')
|
||||
if opt:
|
||||
return main.Productos.opt(values)
|
||||
|
||||
return main.Productos.add(values)
|
||||
|
||||
def invoice(self, values, user):
|
||||
if 'opt' in values:
|
||||
return main.Facturas.opt(values, user)
|
||||
|
||||
def invoice(self, values):
|
||||
id = int(values.pop('id', '0'))
|
||||
if id:
|
||||
return main.Facturas.actualizar(values, id)
|
||||
return main.Facturas.add(values)
|
||||
|
||||
return main.Facturas.add(values, user)
|
||||
def get_invoices(self, values):
|
||||
return main.Facturas.get_(values)
|
||||
|
||||
def invoice_put(self, values, user):
|
||||
return main.Facturas.put(values, user)
|
||||
|
||||
def preinvoice(self, values):
|
||||
id = int(values.pop('id', '0'))
|
||||
#~ if id:
|
||||
#~ return main.PreFacturas.actualizar(values, id)
|
||||
return main.PreFacturas.add(values)
|
||||
|
||||
def get_students(self, values):
|
||||
return main.Alumnos.get_by(values)
|
||||
|
||||
def students(self, values):
|
||||
opt = values.pop('opt')
|
||||
if opt == 'add':
|
||||
return main.Alumnos.add(values['values'])
|
||||
if opt == 'edit':
|
||||
return main.Alumnos.actualizar(values['values'])
|
||||
|
||||
def tickets(self, values, user):
|
||||
opt = values.pop('opt')
|
||||
if opt == 'add':
|
||||
return main.Tickets.add(values, user)
|
||||
if opt == 'cancel':
|
||||
return main.Tickets.cancel(values, user)
|
||||
if opt == 'invoice':
|
||||
return main.Tickets.invoice(values, user)
|
||||
if opt == 'print':
|
||||
return main.Tickets.printer(values)
|
||||
|
||||
def get_tickets(self, values, user):
|
||||
return main.Tickets.get_by(values, user)
|
||||
|
||||
def get_invoices(self, filters, user):
|
||||
if filters.get('by', ''):
|
||||
return main.Facturas.get_by(filters, user)
|
||||
return main.Facturas.get_(filters)
|
||||
|
||||
def get_preinvoices(self, values):
|
||||
return main.PreFacturas.get_(values)
|
||||
|
||||
# ~ def _get_timbrar(self, values):
|
||||
# ~ return main.Facturas.timbrar(values)
|
||||
|
||||
def _get_anticipoegreso(self, values):
|
||||
return main.Facturas.anticipo_egreso(int(values['id']))
|
||||
def _get_timbrar(self, values):
|
||||
return main.Facturas.timbrar(int(values['id']))
|
||||
|
||||
def get_emisor(self, rfc):
|
||||
return main.Emisor.get_(rfc)
|
||||
|
@ -411,138 +121,21 @@ class StorageEngine(object):
|
|||
def emisor(self, values):
|
||||
return main.Emisor.add(values)
|
||||
|
||||
def cuentasbanco(self, values):
|
||||
return main.CuentasBanco.add(values)
|
||||
|
||||
# ~ def add_movbanco(self, values):
|
||||
# ~ return main.MovimientosBanco.add(values)
|
||||
|
||||
def get_cuentasbanco(self, values):
|
||||
return main.CuentasBanco.get_(values)
|
||||
|
||||
def get_folios(self):
|
||||
return main.Folios.get_()
|
||||
|
||||
def add_folios(self, values):
|
||||
return main.Folios.add(values)
|
||||
|
||||
def add_nivel_educativo(self, values):
|
||||
return main.NivelesEducativos.add(values)
|
||||
|
||||
def get_doc(self, type_doc, id, rfc):
|
||||
return main.get_doc(type_doc, id, rfc)
|
||||
|
||||
def get_movimientosbanco(self, values):
|
||||
return main.MovimientosBanco.get_(values)
|
||||
|
||||
def importar_bdfl(self):
|
||||
return main.importar_bdfl()
|
||||
|
||||
# ~ Revisado
|
||||
def get_invoicepay(self, values):
|
||||
return main.FacturasPagos.get_values(values)
|
||||
|
||||
def get_cfdipay(self, values):
|
||||
return main.CfdiPagos.get_values(values)
|
||||
|
||||
def get_sat_bancos(self, values):
|
||||
return main.SATBancos.get_values(values)
|
||||
|
||||
def get_sat_forma_pago(self, values):
|
||||
return main.SATFormaPago.get_values(values)
|
||||
|
||||
def get_partners_accounts_bank(self, values):
|
||||
return main.SociosCuentasBanco.get_values(values)
|
||||
|
||||
def cfdipay(self, values):
|
||||
return main.CfdiPagos.post(values)
|
||||
|
||||
def bankmovement(self, values):
|
||||
return main.MovimientosBanco.post(values)
|
||||
|
||||
def sat_bancos(self, values):
|
||||
return main.SATBancos.post(values)
|
||||
|
||||
def sat_forma_pago(self, values):
|
||||
return main.SATFormaPago.post(values)
|
||||
|
||||
def partners_accounts_bank(self, values):
|
||||
return main.SociosCuentasBanco.post(values)
|
||||
|
||||
def nomina(self, values, user):
|
||||
return main.CfdiNomina.post(values, user)
|
||||
|
||||
def sat_leyendas_fiscales_get(self, values):
|
||||
return main.SATLeyendasFiscales.get_values(values)
|
||||
|
||||
def sat_leyendas_fiscales_post(self, values):
|
||||
return main.SATLeyendasFiscales.post(values)
|
||||
|
||||
def sat_leyendas_fiscales_delete(self, values):
|
||||
return main.SATLeyendasFiscales.remove(values)
|
||||
|
||||
# ~ v2
|
||||
def cert_get(self, filters):
|
||||
return main.Certificado.get_data(filters)
|
||||
|
||||
def cert_post(self, filters):
|
||||
return main.Certificado.post(filters)
|
||||
|
||||
def sucursales_get(self, filters):
|
||||
return main.Sucursales.get_data(filters)
|
||||
|
||||
def sucursales_post(self, filters):
|
||||
return main.Sucursales.post(filters)
|
||||
|
||||
def partner_products_get(self, filters):
|
||||
return main.PartnerProducts.get_data(filters)
|
||||
|
||||
def inventory_entries_get(self, filters):
|
||||
return main.InventoryEntries.get_data(filters)
|
||||
|
||||
def inventory_entries_post(self, filters, user):
|
||||
return main.InventoryEntries.post(filters, user)
|
||||
|
||||
def warehouse_get(self, filters):
|
||||
return main.Almacenes.get_data(filters)
|
||||
|
||||
def warehouse_post(self, values, user):
|
||||
return main.Almacenes.post(values, user)
|
||||
|
||||
def warehouseproduct_get(self, filters, user):
|
||||
return main.WareHouseProduct.get_data(filters, user)
|
||||
|
||||
def warehouseproduct_post(self, filters, user):
|
||||
return main.WareHouseProduct.post(filters, user)
|
||||
|
||||
def users_get(self, filters, user):
|
||||
return main.Usuarios.get_data(filters, user)
|
||||
|
||||
def users_post(self, args, user):
|
||||
return main.Usuarios.post(args, user)
|
||||
|
||||
def ticketsdetails_get(self, filters, user):
|
||||
return main.TicketsDetalle.get_data(filters, user)
|
||||
|
||||
def products_get(self, filters, user):
|
||||
return main.Productos.get_data(filters, user)
|
||||
|
||||
def nomina_get(self, filters, user):
|
||||
return main.CfdiNomina.get_data(filters, user)
|
||||
|
||||
def sat_unidades_peso_get(self, filters, user):
|
||||
return main.SATUnidadesPeso.get_data(filters, user)
|
||||
|
||||
def sat_unidades_peso_post(self, args, user):
|
||||
return main.SATUnidadesPeso.post(args, user)
|
||||
|
||||
def sat_regimenes_get(self, filters, user):
|
||||
return main.SATRegimenes.get_data(filters, user)
|
||||
|
||||
def socios_regimenes_get(self, filters, user):
|
||||
return main.SociosRegimenes.get_data(filters, user)
|
||||
|
||||
# Companies only in MV
|
||||
def _get_empresas(self, values):
|
||||
return main.companies_get()
|
||||
if type_doc == 'xml':
|
||||
data, file_name = main.Facturas.get_xml(id)
|
||||
content_type = 'application/xml'
|
||||
if type_doc == 'pdf':
|
||||
data, file_name = main.Facturas.get_pdf(id, rfc)
|
||||
content_type = 'application/pdf'
|
||||
if type_doc == 'zip':
|
||||
data, file_name = main.Facturas.get_zip(id, rfc)
|
||||
content_type = 'application/octet-stream'
|
||||
return data, file_name, content_type
|
||||
|
||||
|
|
|
@ -1,20 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# ~ Empresa Libre
|
||||
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (publico@cuates.net)
|
||||
# ~
|
||||
# ~ This program is free software: you can redistribute it and/or modify
|
||||
# ~ it under the terms of the GNU General Public License as published by
|
||||
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||
# ~ (at your option) any later version.
|
||||
# ~
|
||||
# ~ This program is distributed in the hope that it will be useful,
|
||||
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# ~ GNU General Public License for more details.
|
||||
# ~
|
||||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#!/usr/bin/env python
|
||||
|
||||
import logbook
|
||||
import os
|
||||
|
@ -23,40 +7,15 @@ from mako.lookup import TemplateLookup
|
|||
from logbook import Logger, StreamHandler, RotatingFileHandler
|
||||
logbook.set_datetime_format('local')
|
||||
|
||||
from conf import DEBUG, MV, LOG_PATH
|
||||
|
||||
try:
|
||||
from conf import DEFAULT_PASSWORD
|
||||
except ImportError:
|
||||
DEFAULT_PASSWORD = 'salgueiro4.0'
|
||||
|
||||
TITLE_APP = 'Empresa Libre'
|
||||
|
||||
try:
|
||||
from conf import NO_HTTPS
|
||||
except ImportError:
|
||||
NO_HTTPS = True
|
||||
from conf import DEBUG
|
||||
|
||||
|
||||
DEBUG = DEBUG
|
||||
VERSION = '2.3.3'
|
||||
|
||||
VERSION = '0.1.0'
|
||||
EMAIL_SUPPORT = ('soporte@empresalibre.net',)
|
||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||
|
||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
||||
|
||||
path_static = os.path.abspath(os.path.join(BASE_DIR, '..', 'static'))
|
||||
path_docs = os.path.abspath(os.path.join(BASE_DIR, '..', 'docs'))
|
||||
|
||||
path_css = os.path.join(path_static, 'css')
|
||||
path_img = os.path.join(path_static, 'img')
|
||||
path_user_template = os.path.join(path_docs, 'templates')
|
||||
path_user_logos = os.path.join(path_docs, 'logos')
|
||||
|
||||
# ~ PATH_STATIC = os.path.abspath(os.path.join(BASE_DIR, '..'))
|
||||
|
||||
PATH_STATIC = os.path.abspath(os.path.join(BASE_DIR, '..'))
|
||||
PATH_TEMPLATES = os.path.abspath(os.path.join(BASE_DIR, '..', 'templates'))
|
||||
PATH_MEDIA = os.path.abspath(os.path.join(BASE_DIR, '..', 'docs'))
|
||||
|
||||
|
@ -64,26 +23,17 @@ PATH_CP = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'cp.db'))
|
|||
COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
||||
DB_SAT = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'sat.db'))
|
||||
|
||||
PATH_SESSIONS = {
|
||||
'data': os.path.abspath(os.path.join(BASE_DIR, '..', 'cache', 'data')),
|
||||
'lock': os.path.abspath(os.path.join(BASE_DIR, '..', 'cache', 'lock')),
|
||||
}
|
||||
|
||||
IV = 'valores_iniciales.json'
|
||||
INIT_VALUES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', IV))
|
||||
# ~ CT = 'cancel_template.xml'
|
||||
# ~ TEMPLATE_CANCEL = os.path.abspath(os.path.join(PATH_TEMPLATES, CT))
|
||||
|
||||
PATH_XSLT = os.path.abspath(os.path.join(BASE_DIR, '..', 'xslt'))
|
||||
PATH_BIN = os.path.abspath(os.path.join(BASE_DIR, '..', 'bin'))
|
||||
|
||||
PATH_TEMPLATES_USER = os.path.abspath(os.path.join(
|
||||
BASE_DIR, '..', 'docs', 'templates'))
|
||||
directories=[PATH_TEMPLATES, PATH_TEMPLATES_USER]
|
||||
template_lookup = TemplateLookup(directories=directories,
|
||||
template_lookup = TemplateLookup(directories=[PATH_TEMPLATES],
|
||||
input_encoding='utf-8',
|
||||
output_encoding='utf-8')
|
||||
|
||||
LOG_PATH = 'empresalibre.log'
|
||||
LOG_NAME = 'API'
|
||||
LOG_LEVEL = 'INFO'
|
||||
|
||||
|
@ -100,6 +50,7 @@ if DEBUG:
|
|||
level=LOG_LEVEL,
|
||||
format_string=format_string).push_application()
|
||||
else:
|
||||
LOG_PATH = '/srv/log/empresalibre.log'
|
||||
RotatingFileHandler(
|
||||
LOG_PATH,
|
||||
backup_count=10,
|
||||
|
@ -118,202 +69,22 @@ log = Logger(LOG_NAME)
|
|||
|
||||
PATH_XSLTPROC = 'xsltproc'
|
||||
PATH_OPENSSL = 'openssl'
|
||||
PATH_XMLSEC = 'xmlsec1'
|
||||
if 'win' in sys.platform:
|
||||
PATH_XSLTPROC = os.path.join(PATH_BIN, 'xsltproc.exe')
|
||||
PATH_OPENSSL = os.path.join(PATH_BIN, 'openssl.exe')
|
||||
PATH_XMLSEC = os.path.join(PATH_BIN, 'xmlsec.exe')
|
||||
|
||||
|
||||
PRE_DEFAULT = {
|
||||
'CFDI': {'VERSION': '4.0', 'PRE': '{http://www.sat.gob.mx/cfd/4}'},
|
||||
'NOMINA': {'VERSION': '1.2', 'PRE': '{http://www.sat.gob.mx/nomina12}'},
|
||||
'PAGOS': {'VERSION': '2.0', 'PRE': '{http://www.sat.gob.mx/Pagos20}'},
|
||||
'TIBRE': {'VERSION': '1.1', 'PRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}'},
|
||||
}
|
||||
|
||||
pre2 ='{http://www.sat.gob.mx/cfd/2}'
|
||||
pre3 ='{http://www.sat.gob.mx/cfd/3}'
|
||||
PRE_HISTORY = {
|
||||
'CFDI': {'2.0': pre2, '2.2': pre2,
|
||||
'3.0': pre3, '3.2': pre3, '3.3': pre3},
|
||||
'NOMINA': {'1.1': '{http://www.sat.gob.mx/nomina}'},
|
||||
'PAGOS': {'1.0': '{http://www.sat.gob.mx/Pagos}'},
|
||||
}
|
||||
|
||||
PRE = {
|
||||
'2.0': '{http://www.sat.gob.mx/cfd/2}',
|
||||
'2.2': '{http://www.sat.gob.mx/cfd/2}',
|
||||
'3.0': '{http://www.sat.gob.mx/cfd/3}',
|
||||
'3.2': '{http://www.sat.gob.mx/cfd/3}',
|
||||
'3.3': '{http://www.sat.gob.mx/cfd/3}',
|
||||
'4.0': '{http://www.sat.gob.mx/cfd/4}',
|
||||
'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}',
|
||||
'DONATARIA': '{http://www.sat.gob.mx/donat}',
|
||||
'INE': '{http://www.sat.gob.mx/ine}',
|
||||
'LOCALES': '{http://www.sat.gob.mx/implocal}',
|
||||
'NOMINA': {
|
||||
'1.1': '{http://www.sat.gob.mx/nomina}',
|
||||
'1.2': '{http://www.sat.gob.mx/nomina12}',
|
||||
},
|
||||
'PAGOS': {
|
||||
'1.0': '{http://www.sat.gob.mx/Pagos}',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To delete
|
||||
# ~ CURRENT_CFDI = '4.0'
|
||||
# ~ CURRENT_CFDI_NOMINA = '1.2'
|
||||
|
||||
DECIMALES = 2
|
||||
DECIMALES_TAX = 4
|
||||
DECIMALES_PRECIOS = 4
|
||||
IMPUESTOS = {
|
||||
'ISR': '001',
|
||||
'IVA': '002',
|
||||
'IEPS': '003',
|
||||
'EXENTO': '000',
|
||||
'ISH': '000',
|
||||
'INSPECCION DE OBRA': '000',
|
||||
'ICIC': '000',
|
||||
'CEDULAR': '000',
|
||||
'CMIC': '000',
|
||||
'SUPERVISION': '000',
|
||||
}
|
||||
DEFAULT_SAT_PRODUCTO = '01010101'
|
||||
DEFAULT_SERIE_TICKET = 'T'
|
||||
DEFAULT_CFDIPAY = {
|
||||
'SERIE': 'FP',
|
||||
'TYPE': 'P',
|
||||
'WAYPAY': 'PPD',
|
||||
'CURRENCY': 'XXX',
|
||||
'TC': '1',
|
||||
'USED': 'CP01',
|
||||
'KEYSAT': '84111506',
|
||||
'UNITKEY': 'ACT',
|
||||
'DESCRIPTION': 'Pago',
|
||||
'TYPE_RELATION': '04',
|
||||
}
|
||||
DIR_FACTURAS = 'facturas'
|
||||
USAR_TOKEN = False
|
||||
CANCEL_SIGNATURE = False
|
||||
PUBLIC = 'Público en general'
|
||||
DEFAULT_SAT_NOMINA = {
|
||||
'SERIE': 'N',
|
||||
'FORMA_PAGO': '99',
|
||||
'USO_CFDI': 'CN01',
|
||||
'CLAVE': '84111505',
|
||||
'UNIDAD': 'ACT',
|
||||
'DESCRIPCION': 'Pago de nómina',
|
||||
}
|
||||
|
||||
API = 'https://api.empresalibre.net{}'
|
||||
|
||||
CURRENCY_MN = 'MXN'
|
||||
|
||||
# ~ v2
|
||||
CANCEL_VERSION = ('3.3', '4.0')
|
||||
CFDI_VERSIONS = CANCEL_VERSION
|
||||
|
||||
IS_MV = MV
|
||||
DB_COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
||||
path_bk = os.path.join(path_docs, 'tmp')
|
||||
path_local = 'facturas'
|
||||
path_sat = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'valores_iniciales.json'))
|
||||
|
||||
EXT = {
|
||||
'CSS': 'css',
|
||||
'HTML': 'html',
|
||||
'ODS': 'ods',
|
||||
'PNG': 'png',
|
||||
'JSON': 'json',
|
||||
}
|
||||
MXN = 'MXN'
|
||||
|
||||
CARTA_PORTE = {
|
||||
'MONEDA': 'XXX',
|
||||
}
|
||||
|
||||
PATHS = {
|
||||
'STATIC': path_static,
|
||||
'CSS': path_css,
|
||||
'IMG': path_img,
|
||||
'DOCS': path_docs,
|
||||
'USER': path_user_template,
|
||||
'LOGOS': path_user_logos,
|
||||
'BK': path_bk,
|
||||
'LOCAL': path_local,
|
||||
'SAT': path_sat,
|
||||
'xslt': PATH_XSLT,
|
||||
}
|
||||
|
||||
VALUES_PDF = {
|
||||
'CANCEL': {True: 'inline', False: 'none'},
|
||||
'TYPE': {'I': 'Ingreso', 'E': 'Egreso', 'T': 'Traslado'},
|
||||
'TAX': {'001': 'ISR', '002': 'IVA', '003': 'IEPS'},
|
||||
'METHOD': {
|
||||
'PUE': 'Pago en una sola exhibición',
|
||||
'PPD': 'Pago en parcialidades o diferido',
|
||||
},
|
||||
}
|
||||
|
||||
RESICO = '626'
|
||||
|
||||
RFCS = {
|
||||
'PUBLIC': 'XAXX010101000',
|
||||
'FOREIGN': 'XEXX010101000',
|
||||
'CVD110412TF6': 'finkok',
|
||||
'SCD110105654': 'comercio',
|
||||
'AAA010101AAA': 'comercio',
|
||||
'SPR190613I52': 'comercio',
|
||||
}
|
||||
|
||||
URL = {
|
||||
'SEAFILE': 'https://seafile.cuates.net',
|
||||
}
|
||||
|
||||
DEFAULT_GLOBAL = {
|
||||
'cantidad': 1.00,
|
||||
'unidad': 'ACT',
|
||||
'descripcion': 'Venta',
|
||||
'clave_sat': '01010101',
|
||||
}
|
||||
|
||||
# ~ TEMPLATE_CANCEL = """<CancelaCFD xmlns="http://cancelacfd.sat.gob.mx">
|
||||
# ~ <Cancelacion xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" RfcEmisor="{rfc}" Fecha="{fecha}">
|
||||
# ~ <Folios>
|
||||
# ~ <Folio UUID="{uuid}" Motivo="{motivo}"{folio}/>
|
||||
# ~ </Folios>
|
||||
# ~ <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
# ~ <SignedInfo>
|
||||
# ~ <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
|
||||
# ~ <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
|
||||
# ~ <Reference URI="">
|
||||
# ~ <Transforms>
|
||||
# ~ <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
||||
# ~ </Transforms>
|
||||
# ~ <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
|
||||
# ~ <DigestValue/>
|
||||
# ~ </Reference>
|
||||
# ~ </SignedInfo>
|
||||
# ~ <SignatureValue/>
|
||||
# ~ <KeyInfo>
|
||||
# ~ <X509Data>
|
||||
# ~ <X509IssuerSerial>
|
||||
# ~ <X509IssuerName/>
|
||||
# ~ <X509SerialNumber/>
|
||||
# ~ </X509IssuerSerial>
|
||||
# ~ <X509Certificate/>
|
||||
# ~ </X509Data>
|
||||
# ~ <KeyValue>
|
||||
# ~ <RSAKeyValue>
|
||||
# ~ <Modulus/>
|
||||
# ~ <Exponent/>
|
||||
# ~ </RSAKeyValue>
|
||||
# ~ </KeyValue>
|
||||
# ~ </KeyInfo>
|
||||
# ~ </Signature>
|
||||
# ~ </Cancelacion>
|
||||
# ~ </CancelaCFD>"""
|
||||
|
||||
TEMPLATE_CANCEL = """<CancelaCFD xmlns="http://cancelacfd.sat.gob.mx"><Cancelacion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Fecha="{fecha}" RfcEmisor="{rfc}" xmlns="http://cancelacfd.sat.gob.mx"><Folios><Folio UUID="{uuid}" Motivo="{motivo}"{folio}/></Folios><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue/></Reference></SignedInfo><SignatureValue/><KeyInfo><X509Data><X509IssuerSerial><X509IssuerName/><X509SerialNumber/></X509IssuerSerial><X509Certificate/></X509Data><KeyValue><RSAKeyValue><Modulus/><Exponent/></RSAKeyValue></KeyValue></KeyInfo></Signature></Cancelacion></CancelaCFD>"""
|
||||
CURRENT_CFDI = '3.3'
|
||||
|
|
BIN
source/db/cp.db
BIN
source/db/sat.db
|
@ -1,473 +0,0 @@
|
|||
id key name
|
||||
1 Tu Contenedor externo
|
||||
2 X1A Tambor de acero
|
||||
3 X1B Tambor de aluminio
|
||||
4 X1D Tambor contrachapado
|
||||
5 X1F Contenedor flexible
|
||||
6 X1G Tambor de fibra
|
||||
7 X1w Tambor de madera
|
||||
8 X2C Barril de madera
|
||||
9 X3A Bidón de acero
|
||||
10 X3H Bidón de plástico
|
||||
11 X43 Bolsa de gran tamaño
|
||||
12 X44 Bolsa de plástico
|
||||
13 X4A Caja de acero
|
||||
14 X4B Caja de aluminio
|
||||
15 X4C Caja de madera natural
|
||||
16 X4D Caja de contrachapado
|
||||
17 X4F Caja de madera reconstituida
|
||||
18 X4G Caja de cartón
|
||||
19 X4H Caja de plástico
|
||||
20 X5H Bolsa de plástico tejido
|
||||
21 X5L Bolsa textil
|
||||
22 X5M Bolsa de papel
|
||||
23 X6H Recipiente de plástico, Contenedor compuesto.
|
||||
24 X6P Recipiente de vidrio, Contenedor compuesto.
|
||||
25 X7A Estuche para carro
|
||||
26 X7B Estuche de madera
|
||||
27 X8A Pallet de madera
|
||||
28 X8B Cajón de madera
|
||||
29 X8C Madera flejada
|
||||
30 XAA Contenedor intermedio para gráneles de plástico rígido
|
||||
31 XAB Contenedor de fibra
|
||||
32 XAC Contenedor de papel
|
||||
33 XAD Contenedor de madera
|
||||
34 XAE Aerosol
|
||||
35 XAF Pallet modular con collares, 80cms * 60cms
|
||||
36 XAG Pallet o empaquetado
|
||||
37 XAH Pallet, 100cms X 110cms
|
||||
38 XAI Contenedor tipo concha
|
||||
39 XAJ Cono
|
||||
40 XAL Esfera
|
||||
41 XAM Ampolleta no protegida
|
||||
42 XAP Ampolleta protegida
|
||||
43 XAT Atomizador
|
||||
44 XAV Cápsula
|
||||
45 XB4 Cinturón
|
||||
46 XBA Barril
|
||||
47 XBB Bobina
|
||||
48 XBC Cajón para botellas / Estante para botellas
|
||||
49 XBD Tablero
|
||||
50 XBE Flejado
|
||||
51 XBF Globo no protegido
|
||||
52 XBG Bolso
|
||||
53 XBH Manojo
|
||||
54 XBI Compartimiento
|
||||
55 XBJ Cubeta
|
||||
56 XBK Cesta
|
||||
57 XBL Paca comprimida
|
||||
58 XBM Cuenco
|
||||
59 XBN Paca no comprimida
|
||||
60 XBO Botella no-protegida y cilíndrica
|
||||
61 XBP Globo protegido
|
||||
62 XBQ Botella cilíndrica protegida
|
||||
63 XBR Barra
|
||||
64 XBS Botella, no-protegida en forma de bulbo
|
||||
65 XBT Rollo de tela
|
||||
66 XBU Butt
|
||||
67 XBV Botella de bulbo protegido
|
||||
68 XBW Caja para líquidos
|
||||
69 XBX Caja
|
||||
70 XBY Tablero, con fleje/ agrupados/ armados
|
||||
71 XBZ Barras, con fleje/ agrupados/ armados
|
||||
72 XCA Lata rectangular
|
||||
73 XCB Cajón para cerveza
|
||||
74 XCC Mantequera
|
||||
75 XCD Lata con mango y boquilla
|
||||
76 XCE Cesto tejido
|
||||
77 XCF Cofre
|
||||
78 XCG Contenedor tipo Jaula
|
||||
79 XCH Cajonera
|
||||
80 XCI Frasco
|
||||
81 XCJ Ataúd
|
||||
82 XCK Barrica
|
||||
83 XCL Espiral
|
||||
84 XCM Paquete de tarjetas
|
||||
85 XCN Contenedor, no especificado como equipo de transporte
|
||||
86 XCO Garrafón no protegido
|
||||
87 XCP Garrafón protegido
|
||||
88 XCQ Cartucho
|
||||
89 XCR Cajón
|
||||
90 XCS Estuche
|
||||
91 XCT Cartón
|
||||
92 XCU Vaso
|
||||
93 XCV Cubierta
|
||||
94 XCW Jaula estilo rodillo
|
||||
95 XCX Lata cilíndrica
|
||||
96 XCY Cilindro
|
||||
97 XCZ Lona
|
||||
98 XDA Cajón multicapa de plástico
|
||||
99 XDB Cajón de varias capas de madera
|
||||
100 XDC Cajón multicapa de cartón
|
||||
101 XDG Jaula, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP))
|
||||
102 XDH Caja, Según la clasificación de la compañía (CHEP), Eurobox
|
||||
103 XDI Tambor de hierro
|
||||
104 XDJ damajuana o garrafa, no protegido
|
||||
105 XDK Cajón a granel, cartón
|
||||
106 XDL Cajas de plástico
|
||||
107 XDM Cajones a granel de madera
|
||||
108 XDN Dispensador
|
||||
109 XDP damajuana o garrafa, protegido
|
||||
110 XDR Tambor
|
||||
111 XDS Bandeja de una capa sin cubierta y de plástico
|
||||
112 XDT Bandeja de una capa sin cubierta y de madera
|
||||
113 XDU Bandeja de una capa sin cubierta y poliestireno
|
||||
114 XDV Bandeja de una capa sin cubierta y de cartón
|
||||
115 XDW Bandeja de dos capas sin tapa y con bandeja de plástico
|
||||
116 XDX Bandeja de dos capas sin cubierta y de madera
|
||||
117 XDY Bandeja de dos capas sin cubierta y de cartón
|
||||
118 XEC Bolsa de plástico
|
||||
119 XED Estuche, con pallet de base
|
||||
120 XEE Estuche, con pallet base de madera
|
||||
121 XEF Estuche, con pallet base de cartón
|
||||
122 XEG Estuche, con pallet base de plástico
|
||||
123 XEH Estuche, con pallet base de metal
|
||||
124 XEI Estuche isotérmico
|
||||
125 XEN Sobre
|
||||
126 XFB Bolsa flexible
|
||||
127 XFC Cajón para fruta
|
||||
128 XFD Cajón enmarcado
|
||||
129 XFE Tanque flexible
|
||||
130 XFI Firkin
|
||||
131 XFL Matraz
|
||||
132 XFO Cajón para zapatos
|
||||
133 XFP Caja auxiliar para película fotográfica
|
||||
134 XFR Marco
|
||||
135 XFT Contenedor para alimentos
|
||||
136 XFW Carro de cama plana
|
||||
137 XFX Bolsa flexible tipo contenedor
|
||||
138 XGB Botella para gas
|
||||
139 XGI Viga
|
||||
140 XGL Contenedor tipo galón
|
||||
141 XGR Recipiente de vidrio
|
||||
142 XGU Bandeja contenedor para apilar horizontalmente objetos planos
|
||||
143 XGY Costal de Yute
|
||||
144 XGZ Vigas con correas o agrupadas
|
||||
145 XHA Cesta con mango y de plástico
|
||||
146 XHB Cesta con mango y de madera
|
||||
147 XHC Cesta con asa y de cartón
|
||||
148 XHG Hogshead
|
||||
149 XHN Gancho
|
||||
150 XHR Cesto
|
||||
151 XIA Paquete con pantalla y de madera
|
||||
152 XIB Paquete con pantalla y de cartón
|
||||
153 XIC Paquete con pantalla y de plástico
|
||||
154 XID Paquete con pantalla y de metal
|
||||
155 XIE Paquete de mostrador.
|
||||
156 XIF Envase para alimentos
|
||||
157 XIG Paquete envuelto en papel
|
||||
158 XIH Tambor de plástico
|
||||
159 XIK Paquete de cartón con los agujeros para botellas
|
||||
160 XIL Bandeja rígida con tapa y apilable (CEN TS 14482: 2002)
|
||||
161 XIN Lingote
|
||||
162 XIZ Lingotes con correas/ agrupados
|
||||
163 XJB Bolsa jumbo
|
||||
164 XJC Bidón rectangular
|
||||
165 XJG Jarra
|
||||
166 XJR Tarro
|
||||
167 XJT Bolsa de yute
|
||||
168 XJY Bidón, cilíndrico
|
||||
169 XKG Barrilete
|
||||
170 XKI Kit (Conjunto de piezas)
|
||||
171 XLE Valijas
|
||||
172 XLG Bitácora
|
||||
173 XLT Lote
|
||||
174 XLU Caja de arrastre
|
||||
175 XLV Contenedor pequeño
|
||||
176 XLZ Registros con fleje/ agrupados/ armados
|
||||
177 XMA Cajón metálico
|
||||
178 XMB Múltiplo de bolsas
|
||||
179 XMC Cajón para leche
|
||||
180 XME Contenedor de metal
|
||||
181 XMR Recipiente de metal
|
||||
182 XMS Saco milti-pared
|
||||
183 XMT Tapete
|
||||
184 XMW Contenedor envuelto en plástico
|
||||
185 XMX Caja pequeña de cerillos
|
||||
186 XNA No disponible
|
||||
187 XNE Sin empaque o no empaquetado
|
||||
188 XNF Sin empaque o no empaquetado, unidad simple
|
||||
189 XNG Sin empaque o no empaquetado, unidades múltiples
|
||||
190 XNS Caja nido
|
||||
191 XNT Red
|
||||
192 XNU Red de plástico con tubo
|
||||
193 XNV Red textil con tubo
|
||||
194 XOA Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 40 cm x 60 cm
|
||||
195 XOB Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 80 cm x 120 cm
|
||||
196 XOC Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 100 cm x 120 cm
|
||||
197 XOD Pallet, AS 4068-1993
|
||||
198 XOE Pallet, ISO T11
|
||||
199 XOF Plataforma, peso o dimensión no especificada
|
||||
200 XOK Bloque
|
||||
201 XOT Octabin
|
||||
202 XP2 Charola
|
||||
203 XPA Cajetilla
|
||||
204 XPB Pallet, Caja combinada y abierta con caja y pallet.
|
||||
205 XPC Paquete postal
|
||||
206 XPD Pallet modular con collares (80cms * 100cms)
|
||||
207 XPE Pallet modular con collares (80cms * 120cms)
|
||||
208 XPF Corral
|
||||
209 XPG Placa
|
||||
210 XPH Cantaro
|
||||
211 XPI Pleca
|
||||
212 XPJ Canastilla
|
||||
213 XPK Paquete
|
||||
214 XPL Balde
|
||||
215 XPN Tablón
|
||||
216 XPO Bolsa pequeña
|
||||
217 XPR Contenedor de plástico
|
||||
218 XPT Maceta
|
||||
219 XPU Cacerola
|
||||
220 XPV Tubos, con fleje/ agrupados/ armados
|
||||
221 XPX Pallet
|
||||
222 XPY Placas con fleje/ agrupados/ armados
|
||||
223 XPZ Tablones con fleje/ agrupados/ armados
|
||||
224 XQA Tambor de acero con cabeza no desmontable
|
||||
225 XQB Tambor de acero con cabeza extraíble
|
||||
226 XQC Tambor de aluminio con cabeza no extraíble
|
||||
227 XQD Tambor de aluminio con cabeza extraíble
|
||||
228 XQF Tambor, plástico con cabeza no desmontable
|
||||
229 XQG Tambor, plástico, cabeza extraíble
|
||||
230 XQH Barril de madera con tapón
|
||||
231 XQJ Barril de madera con cabeza desprendible
|
||||
232 XQK Bidón de acero con cabeza no desmontable
|
||||
233 XQL Bidón de acero con cabeza desmontable
|
||||
234 XQM Bidón de plástico con cabeza no desmontable
|
||||
235 XQN Bidón de plástico con cabeza extraíble
|
||||
236 XQP Caja de madera natural estándar
|
||||
237 XQQ Caja de madera natural con muros a prueba de filtraciones
|
||||
238 XQR Caja de plástico expandida
|
||||
239 XQS Caja de plástico sólida
|
||||
240 XRD Rod
|
||||
241 XRG Anillo
|
||||
242 XRJ Estante, Perchero para ropa
|
||||
243 XRK Estante
|
||||
244 XRL Carrete
|
||||
245 XRO Rollo
|
||||
246 XRT Red Roja
|
||||
247 XRZ Varillas con fleje/ agrupados/ armados
|
||||
248 XSA Saco
|
||||
249 XSB Losa
|
||||
250 XSC Cajón poco profundo
|
||||
251 XSD Huso
|
||||
252 XSE Baúl
|
||||
253 XSH Bolsa pequeña hermética
|
||||
254 XSI Patín
|
||||
255 XSK Carcasa esqueleto
|
||||
256 XSL Hoja de deslizamiento
|
||||
257 XSM Hoja de metal
|
||||
258 XSO Carrete pequeño
|
||||
259 XSP Hoja de empaque de plástico
|
||||
260 XSS Cajón de acero
|
||||
261 XSU Maleta
|
||||
262 XSV Sobre de acero
|
||||
263 XSW Envoltorio
|
||||
264 XSY Manga
|
||||
265 XSZ Hojas con fleje/ agrupados/ armados
|
||||
266 XT1 Tableta
|
||||
267 XTB Tina
|
||||
268 XTC Caja para té
|
||||
269 XTD Tubo plegable
|
||||
270 XTG Contenedor de tanque genérico
|
||||
271 XTI Tierce
|
||||
272 XTK Tanque rectangular
|
||||
273 XTL Tina con tapa
|
||||
274 XTN Hojalata
|
||||
275 XTO Tonel
|
||||
276 XTR Maletero
|
||||
277 XTS Estructura
|
||||
278 XTT Bolsa de mano
|
||||
279 XTU Tubo
|
||||
280 XTV Tubo con boquilla
|
||||
281 XTW Pallet tricapa
|
||||
282 XTY Tanque cilíndrico
|
||||
283 XTZ Tubos con fleje/ agrupados/ armados
|
||||
284 XUC Sin empaque
|
||||
285 XUN Unidad
|
||||
286 XVA Tanque
|
||||
287 XVG Tanque de gas (a 1,031 mbar y 15° C)
|
||||
288 XVI Frasco pequeño
|
||||
289 XVK Paquete transportable
|
||||
290 XVL Contenedor para líquidos a granel
|
||||
291 XVN Vehículo
|
||||
292 XVO "Contenedor para sólido de partículas grandes a granel (""nódulos"")"
|
||||
293 XVP Envasado al vacío
|
||||
294 XVQ Tanque para Gas licuado (a temperatura / presión anormal)
|
||||
295 XVR Contenedor para sólidos de partículas granulares a granel (Granos)
|
||||
296 XVS Contenedor de chatarra a granel
|
||||
297 XVY "Contenedor para sólido de partículas finas a granel (""polvos"")"
|
||||
298 XWA Contenedor de granel intermedio
|
||||
299 XWB Botella de mimbre
|
||||
300 XWC Contenedor intermedio para gráneles y de acero
|
||||
301 XWD Contenedor intermedio para gráneles y de aluminio
|
||||
302 XWF Contenedor intermedio para gráneles y de metal
|
||||
303 XWG Contenedor intermedio para gráneles y de acero presurizado menor a 10 kpa
|
||||
304 XWH Contenedor intermedio para gráneles y de aluminio, presurizado menor a 10 kpa
|
||||
305 XWJ Contenedor intermedio para gráneles y de metal con una presión de 10 kpa
|
||||
306 XWK Contenedor intermedio para gráneles y de acero para líquido
|
||||
307 XWL Contenedor intermedio para gráneles y de aluminio para líquido
|
||||
308 XWM Contenedor intermedio para gráneles y de metal para líquido
|
||||
309 XWN Contenedor intermedio para gráneles con tejido plástico sin capa con revestimiento
|
||||
310 XWP Contenedor intermedio para gráneles con tejido plástico y recubierto
|
||||
311 XWQ Contenedor intermedio para gráneles con tejido plástico con revestimiento
|
||||
312 XWR Contenedor intermedio para gráneles con tejido plástico, revestido y con forro
|
||||
313 XWS Contenedor intermedio para gráneles con película de plástico
|
||||
314 XWT Contenedor intermedio para gráneles textil sin capa / forro
|
||||
315 XWU Contenedor intermedio para gráneles de madera natural con forro interior
|
||||
316 XWV Contenedor intermedio para gráneles textil recubierto
|
||||
317 XWW Contenedor intermedio para gráneles textil con revestimiento
|
||||
318 XWX Contenedor intermedio para gráneles textil recubierto y con forro
|
||||
319 XWY Contenedor intermedio para gráneles contrachapado con revestimiento interior
|
||||
320 XWZ Contenedor intermedio para gráneles de madera reconstituida con revestimiento interior
|
||||
321 XXA Bolsa de tejido plástico, sin abrigo interior ni forro
|
||||
322 XXB Bolsa de tejido plástico a prueba de filtraciones
|
||||
323 XXC Bolsa de tejido plástico resistente al agua
|
||||
324 XXD Bolsa con película de plástico
|
||||
325 XXF Bolsa textil sin capa ni forro interior
|
||||
326 XXG Bolsa textil a prueba de filtraciones
|
||||
327 XXH Bolsa textil resistente al agua
|
||||
328 XXJ Bolsa de papel multi-pared
|
||||
329 XXK Bolsa de papel multi-pared, resistente al agua
|
||||
330 XYA Empaque compuesto, recipiente de plástico en tambor de acero
|
||||
331 XYB Empaque compuesto, recipiente de plástico en cajas de acero
|
||||
332 XYC Empaque compuesto, recipiente de plástico en tambor de aluminio
|
||||
333 XYD Empaque compuesto, recipiente de plástico en cajón de aluminio
|
||||
334 XYF Empaque compuesto, recipiente de plástico en caja de madera
|
||||
335 XYG Empaque compuesto, recipiente de plástico en tambor de madera contrachapada
|
||||
336 XYH Empaque compuesto, recipiente de plástico en caja de madera contrachapada
|
||||
337 XYJ Empaque compuesto, recipiente de plástico en tambor de fibra
|
||||
338 XYK Empaque compuesto, recipiente de plástico en caja de cartón
|
||||
339 XYL Empaque compuesto, recipiente de plástico en el tambor de plástico
|
||||
340 XYM Empaque compuesto, recipiente de plástico en caja de plástico sólido
|
||||
341 XYN Empaque compuesto, receptáculo de vidrio en tambor de acero
|
||||
342 XYP Empaque compuesto, receptáculo de vidrio en caja de cajas de acero
|
||||
343 XYQ Empaque compuesto, recipiente de vidrio en tambor de aluminio
|
||||
344 XYR Empaque compuesto, receptáculo de vidrio en caja de aluminio
|
||||
345 XYS Empaque compuesto, recipiente de vidrio en caja de madera
|
||||
346 XYT Empaque compuesto, recipiente de vidrio en tambor de madera contrachapada
|
||||
347 Xyv Empaque compuesto, recipiente de vidrio en el cesto de mimbre
|
||||
348 XYW Empaque compuesto, recipiente de vidrio en tambor de fibra
|
||||
349 XYX Empaque compuesto, recipiente de vidrio en caja de cartón
|
||||
350 XYY Empaque compuesto, recipiente de vidrio en paquete de plástico expandible
|
||||
351 XYZ Empaque compuesto, recipiente de vidrio en paquete de plástico sólido
|
||||
352 XZA Contenedor de granel intermedio, papel, multi-pared
|
||||
353 XZB Bolsa grande
|
||||
354 XZC Contenedor intermedio para gráneles de papel, multi-pared y resistente al agua
|
||||
355 XZD Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para sólidos
|
||||
356 XZF Contenedor intermedio para gráneles de plástico rígido, autoportante para sólidos
|
||||
357 XZG Contenedor intermedio para gráneles de plástico rígido, con equipo estructural, presurizado
|
||||
358 XZH Contenedor intermedio para gráneles de plástico rígido, autoportante y presurizado
|
||||
359 XZJ Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para líquidos
|
||||
360 XZK Contenedor intermedio para gráneles de plástico rígido, autoportante, líquidos
|
||||
361 XZL Contenedor intermedio para gráneles, compuesto y de plástico rígido, sólidos
|
||||
362 XZM Contenedor intermedio para gráneles, compuesto y de plástico flexible, sólidos
|
||||
363 XZN Contenedor intermedio para gráneles, compuesto y de plástico rígido, presurizado
|
||||
364 XZP Contenedor intermedio para gráneles, compuesto y de plástico flexible, presurizado
|
||||
365 XZQ Contenedor intermedio para gráneles, compuesto y de plástico rígido, líquidos
|
||||
366 XZR Contenedor intermedio para gráneles, compuesto y de plástico flexible para líquidos
|
||||
367 XZS Contenedor intermedio para gráneles, compuesto
|
||||
368 XZT Contenedor intermedio para gráneles con tablero de fibras
|
||||
369 XZU Contenedor intermedio para gráneles flexible
|
||||
370 XZV Contenedor intermedio para gráneles de metal, distinto del acero
|
||||
371 XZW Contenedor intermedio para gráneles, de madera natural
|
||||
372 XZX Contenedor intermedio para gráneles, de contrachapado
|
||||
373 XZY Contenedor intermedio para gráneles, de madera reconstituida
|
||||
374 KGM Kilogramo
|
||||
375 MC Microgramo
|
||||
376 DJ Decagramo
|
||||
377 DG Decigramo
|
||||
378 GRM Gramo
|
||||
379 CGM Centigramo
|
||||
380 TNE Tonelada (tonelada métrica)
|
||||
381 DTN Decitonelada métrica
|
||||
382 MGM Miligramo
|
||||
383 HGM Hectogramo
|
||||
384 KTN Kilotonelada Métrica
|
||||
385 2U Megagramo
|
||||
386 LBR Libra
|
||||
387 GRN Grano
|
||||
388 ONZ Onza (avoirdupois)
|
||||
389 CWI Hundredweight
|
||||
390 CWA Hundred pound
|
||||
391 LTN Tonelada (UK) o tonelada larga (estados unidos)
|
||||
392 STI Estone (UK)
|
||||
393 STN Tonelada (estados unidos) o tonelada corta (UK y estados unidos)
|
||||
394 APZ Onza troy u onza farmacéutica
|
||||
395 F13 Slug
|
||||
396 K64 Libra (avoirdupois) por grado fahrenheit
|
||||
397 L69 Tonelada por kelvin
|
||||
398 L87 Tonelada corta por grado fahrenheit
|
||||
399 M85 Tonelada, ensayo
|
||||
400 M86 Libra Alemana
|
||||
401 J33 Microgramo por kilogramo
|
||||
402 L32 Nanogramo por kilogramo
|
||||
403 NA Miligramo por kilogramo
|
||||
404 M29 Kilogramo por kilogramo
|
||||
405 M91 Libra por libra
|
||||
406 Q29 Microgramo por hectogramo
|
||||
407 MTQ Metro cúbico
|
||||
408 MAL Megalitro
|
||||
409 LTR Litro
|
||||
410 MMQ Milímetro cúbico
|
||||
411 CMQ Centímetro cúbico
|
||||
412 DMQ Decímetro cúbico
|
||||
413 MLT Mililitro
|
||||
414 HLT Hectolitro
|
||||
415 CLT Centilitro
|
||||
416 DMA Decámetro cúbico
|
||||
417 H19 Hectómetro cúbico
|
||||
418 H20 Kilómetro cúbico
|
||||
419 M71 Metro cúbico por pascal (joules)
|
||||
420 DLT Decilitro
|
||||
421 4G Microlitro
|
||||
422 K6 Kilolitro
|
||||
423 A44 Decalitro
|
||||
424 G94 Centímetro cúbico por bar
|
||||
425 G95 Litro por bar
|
||||
426 G96 Metro cúbico por bar
|
||||
427 G97 Mililitro por bar
|
||||
428 5I Pies cúbicos estándar
|
||||
429 INQ Pulgada cúbica
|
||||
430 FTQ Pie cúbico
|
||||
431 YDQ Yarda cúbica
|
||||
432 GLI Galón (UK)
|
||||
433 GLL Galón (EUA)
|
||||
434 PT Pinta (US)
|
||||
435 PTI Pint (uk)
|
||||
436 QTI Cuarto (UK)
|
||||
437 PTL Pinta líquida (estados unidos)
|
||||
438 QTL Cuarto de líquido (estadis unidos)
|
||||
439 PTD Pinta seca (estados unidos)
|
||||
440 OZI Onza líquida (UK)
|
||||
441 QT Cuarto (EUA)
|
||||
442 J57 Barril (uk petróleo)
|
||||
443 K21 Pie cúbico por grado fahrenheit
|
||||
444 K23 Pie cúbico por psi (libra por pulgada cuadrada)
|
||||
445 L43 Peck (UK)
|
||||
446 L61 Pinta (US seco)
|
||||
447 L62 Cuarto de galón (seco de los EUA)
|
||||
448 L84 Tonelada (flota UK)
|
||||
449 L86 Tonelada (flota estados unidos)
|
||||
450 M11 Yarda cúbica por grado fahrenheit
|
||||
451 M14 Yarda cúbica por psi (libra por pulgada cuadrada)
|
||||
452 OZA Onza líquida (estados unidos)
|
||||
453 BUI Bushel (UK)
|
||||
454 BUA Bushel (EUA)
|
||||
455 BLL Barril (EUA)
|
||||
456 BLD Barril seco (EUA)
|
||||
457 GLD Galón seco (EUA)
|
||||
458 QTD Cuarto seco (estados unidos)
|
||||
459 G26 Estere
|
||||
460 G21 Taza (unidad de volumen)
|
||||
461 G24 Cucharada (estados unidos)
|
||||
462 G25 Cucharilla (estados unidos)
|
||||
463 G23 Peck
|
||||
464 M67 Acre-pie
|
||||
465 M68 Cordón
|
||||
466 M69 Milla cúbica (reino unido)
|
||||
467 M70 Unidad tradicional de capacidad de carga
|
||||
468 Q32 Femtolitro
|
||||
469 Q33 Picolitro
|
||||
470 Q34 Nanolitro
|
||||
471 NM3 Metro cúbico normalizado
|
||||
472 SM3 Metro cúbico estándar
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
@license
|
||||
webix UI v.5.4.3
|
||||
webix UI v.5.0.0
|
||||
This software is covered by Webix Commercial License.
|
||||
Usage without proper license is prohibited.
|
||||
(c) XB Software Ltd.
|
||||
|
@ -9,12 +9,12 @@ Usage without proper license is prohibited.
|
|||
.webix_view.webix_form{background-color:#fff}
|
||||
body{-webkit-tap-highlight-color:transparent!important}
|
||||
.webix_abslayout{position:relative}
|
||||
.webix_abslayout>.webix_view{position:absolute!important}
|
||||
.webix_abslayout>.webix_view{position:absolute}
|
||||
.webix_layout_space,.webix_layout_wide{background-color:#ebebeb}
|
||||
.webix_layout_accordion,.webix_layout_clean,.webix_layout_line,.webix_multiview{background:0 0}
|
||||
.webix_overlay{width:100%;height:100%;position:absolute;z-index:10;text-align:center;padding-top:10px}
|
||||
.webix_view>.webix_disabled{width:100%;height:100%;position:absolute;top:0;left:0;background-color:#ddd;opacity:.4;filter:alpha(opacity=40);z-index:1}
|
||||
.webix_disabled_view{overflow:hidden!important;position:relative}
|
||||
.webix_disabled_view{overflow:hidden!important}
|
||||
body.webix_full_screen{margin:0;padding:0;overflow:hidden}
|
||||
.webix_noselect,.webix_noselect div{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.webix_selectable{-moz-user-select:text;-webkit-user-select:text;user-select:text}
|
||||
|
@ -25,38 +25,38 @@ body.webix_full_screen{margin:0;padding:0;overflow:hidden}
|
|||
.webix_section>.webix_template{padding:0 8px;background-color:#fff;display:inline}
|
||||
.webix_layout_space>.webix_section>.webix_template,.webix_layout_wide>.webix_section>.webix_template{padding:0 8px;background-color:#ebebeb}
|
||||
.webix_layout_clean>.webix_section>.webix_template,.webix_layout_line>.webix_section>.webix_template{padding:0 8px;background-color:#fff}
|
||||
.webix_header>div{padding-left:10px;font-family:Helvetica,Verdana;color:#1e2022;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;line-height:32px;line-height:34px;padding-top:0;padding-bottom:0}
|
||||
.webix_header>div{padding-left:10px;font-family:Helvetica,Verdana;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);line-height:32px;line-height:34px;padding-top:0;padding-bottom:0}
|
||||
.webix_header>div .webix_el_label,.webix_header>div .webix_inp_label{color:#1e2022}
|
||||
.webix_spacer{background:0 0}
|
||||
.webix_view_animate{position:relative;width:100%;height:100%}
|
||||
x\:ui{display:none}
|
||||
.webix_view.webix_flexlayout{display:flex!important;flex-wrap:wrap;flex-direction:row;overflow:hidden;box-sizing:border-box}
|
||||
.webix_flexlayout{display:flex!important;flex-wrap:wrap;flex-direction:row;overflow:hidden;box-sizing:border-box}
|
||||
.webix_flexlayout>div{display:block!important}
|
||||
.webix_view_align{background:0 0}
|
||||
.webix_view a.webix_list_item,.webix_view div,.webix_view span{outline:0}
|
||||
.webix_view a.webix_list_item:focus,.webix_view div:focus,.webix_view span:focus,.webix_view.webix_window:focus{outline-color:#727981;outline-style:dotted;outline-width:1px}
|
||||
.webix_view a.webix_list_item:focus,.webix_view div:focus,.webix_view span:focus,.webix_view.webix_window:focus{outline:#727981 dotted 1px}
|
||||
.webix_view div.webix_inp_static:focus,button,input,select,textarea{outline:0}
|
||||
.webix_resize_area{position:absolute;top:0;left:0;width:100%;height:100%}
|
||||
.webix_resize_handle_x .webix_handle_content,.webix_resize_handle_y .webix_handle_content{width:100%;height:100%;background:rgba(100,100,100,.1);border:1px dotted #9fa5aa}
|
||||
.webix_resize_handle_x{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:ew-resize;width:1px;height:100%;position:absolute;z-index:2;top:0}
|
||||
.webix_resize_handle_x{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:e-resize;width:1px;height:100%;position:absolute;z-index:2;top:0}
|
||||
.webix_resize_handle_x .webix_handle_content{border-width:0 1px}
|
||||
.webix_resize_origin_x{cursor:ew-resize;width:3px;height:100%;position:absolute;z-index:2;top:0}
|
||||
.webix_resize_handle_y{cursor:ns-resize;height:1px;width:100%;position:absolute;z-index:2;left:0}
|
||||
.webix_resize_origin_x{cursor:e-resize;width:3px;height:100%;position:absolute;z-index:2;top:0}
|
||||
.webix_resize_handle_y{cursor:n-resize;height:1px;width:100%;position:absolute;z-index:2;left:0}
|
||||
.webix_resize_handle_y .webix_handle_content{border-width:1px 0}
|
||||
.webix_resize_origin_y{cursor:ns-resize;height:3px;width:100%;position:absolute;z-index:2;left:0}
|
||||
.webix_resize_origin_y{cursor:n-resize;height:3px;width:100%;position:absolute;z-index:2;left:0}
|
||||
.webix_resizer.webix_disabled_view{cursor:default}
|
||||
.webix_resizer_vy{cursor:ns-resize;margin-top:0!important;border:0!important;padding:0!important;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAADAQMAAABCowZuAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA9JREFUCB1jXMUABoxAGgAJaAFXPIkJqAAAAABJRU5ErkJggg==) no-repeat center center}
|
||||
.webix_resizer_vx{cursor:ew-resize;margin-left:0!important;border:0!important;padding:0!important;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAXAQMAAAD0oWdxAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA5JREFUeF5jWMDAQDwGAKyuB4FpGQdzAAAAAElFTkSuQmCC) no-repeat center center}
|
||||
.webix_resizer_y{cursor:ns-resize;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAADAQMAAABCowZuAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA9JREFUCB1jXMUABoxAGgAJaAFXPIkJqAAAAABJRU5ErkJggg==) no-repeat center center;background-color:#fff}
|
||||
.webix_resizer_x{cursor:ew-resize;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAXAQMAAAD0oWdxAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA5JREFUeF5jWMDAQDwGAKyuB4FpGQdzAAAAAElFTkSuQmCC) no-repeat center center;background-color:#fff}
|
||||
.webix_resizer_vy{cursor:n-resize;margin-top:0!important;border:0!important;padding:0!important;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAADAQMAAABCowZuAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA9JREFUCB1jXMUABoxAGgAJaAFXPIkJqAAAAABJRU5ErkJggg==) center center no-repeat}
|
||||
.webix_resizer_vx{cursor:e-resize;margin-left:0!important;border:0!important;padding:0!important;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAXAQMAAAD0oWdxAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA5JREFUeF5jWMDAQDwGAKyuB4FpGQdzAAAAAElFTkSuQmCC) center center no-repeat}
|
||||
.webix_resizer_y{cursor:n-resize;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAADAQMAAABCowZuAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA9JREFUCB1jXMUABoxAGgAJaAFXPIkJqAAAAABJRU5ErkJggg==) center center no-repeat #fff}
|
||||
.webix_resizer_x{cursor:e-resize;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAXAQMAAAD0oWdxAAAABlBMVEUAAACkvtSA7tmIAAAAAXRSTlMAQObYZgAAAA5JREFUeF5jWMDAQDwGAKyuB4FpGQdzAAAAAElFTkSuQmCC) center center no-repeat #fff}
|
||||
.webix_accordionitem_body{position:relative}
|
||||
.webix_accordionitem_header{border-bottom:1px solid #a4bed4;position:relative;z-index:2;font-family:Helvetica,Verdana;color:#1e2022;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;line-height:32px;cursor:pointer;overflow:hidden}
|
||||
.webix_accordionitem_header{border-bottom:1px solid #a4bed4;position:relative;z-index:2;font-family:Helvetica,Verdana;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);line-height:32px;cursor:pointer;overflow:hidden}
|
||||
.webix_accordionitem_header .webix_el_label,.webix_accordionitem_header .webix_inp_label{color:#1e2022}
|
||||
.webix_ie.horizontal>.webix_accordionitem_header.collapsed{-ms-writing-mode:tb-lr}
|
||||
.webix_ie.horizontal>.webix_accordionitem_header.collapsed .webix_accordionitem_label{padding-left:0;padding-top:10px}
|
||||
.webix_ie.horizontal>.webix_accordionitem_header.collapsed .webix_accordionitem_button{margin:0}
|
||||
.webix_accordionitem_label{height:100%;padding-left:10px}
|
||||
.webix_accordionitem_button{float:right;position:relative;height:11px;width:11px;margin:14px 14px}
|
||||
.webix_accordionitem_button{float:right;position:relative;height:11px;width:11px;margin:14px}
|
||||
.webix_carousel{position:relative}
|
||||
.webix_nav_panel{bottom:15px;height:auto;line-height:8px;overflow:hidden;position:absolute;text-align:center}
|
||||
.webix_nav_item{display:inline-block;height:8px;padding:6px 5px 6px 4px;width:8px;cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||
|
@ -89,10 +89,10 @@ x\:ui{display:none}
|
|||
.webix_dark .webix_nav_button_side.webix_nav_button_next .webix_nav_button_inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAiCAYAAACwaJKDAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gcdCSE1IU5u4gAAAW1JREFUSMet1rtOwzAUgOG/5jbBwsQD8BAwIAa2TggegjmRgELbuFeo1GRlQEJMMDN264CUiYdgg0dolzIkFUEk9nHSbLGtT76cc+xaMA53gUegDnwCgfa9Vyp8CngCToFNYB940WF0WRWt57SPqsAK+C7oG+kwuiqLdg3992Xgtelk8jGN4w3gqGDMyTSOZ8eHB+8uM0X7XhMYGMbd6TC6dkIzcH8VsMr+aN9rCeCGEyqEhzZY5TWmcM8C3zihKdy2wIMiWJmWURZWtk1P4a4FvnVCUziwwP0srKQBLYSbALXFYuGU1zqMNBAYhrRUiSI0s/RvKcdZNoChcQt8Tz5TKSg/fQdQFqdJcJvAXha0Z1QCDixgW577drCbBxZXKRkYyOtpkm6lwf+VPwH7VcC/d5Qd7EjA39s0KQQ2UIvvfbZ3zoEHU2Rp3+u4vlDGqwSX6N4qwSX6ltMelAUB1oELYA6cAV/poTxXeZ/+AOFqn1e/Gh7yAAAAAElFTkSuQmCC)}
|
||||
.webix_list_item{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2px 10px;line-height:23px;cursor:pointer;border-bottom:1px solid #ebebeb;text-align:left}
|
||||
.webix_list_item.webix_invalid{background-color:#fee}
|
||||
.webix_list_item.webix_selected{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_list_item.webix_selected{color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_list .webix_list_item.webix_selected{border-bottom:1px solid #ffd47b;box-shadow:0 1px #ffe3a9 inset;padding:2px 10px}
|
||||
.webix_group{position:relative}
|
||||
.webix_group_back,.webix_group_back.webix_selected{position:relative;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_group_back,.webix_group_back.webix_selected{position:relative;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webix_arrow_icon{position:absolute;top:50%;bottom:50%;margin-top:-12px;right:15px;width:9px;height:22px;line-height:22px;color:#1e2022;font-size:18px;font-family:FontAwesome}
|
||||
.webix_arrow_icon:before{content:'\f105'}
|
||||
.webix_group_back{padding-left:29px}
|
||||
|
@ -103,19 +103,18 @@ x\:ui{display:none}
|
|||
.webix_unit_header{padding:0 10px;line-height:19px;text-align:left;background-color:#d6e8ff}
|
||||
.webix_list-x .webix_list_item{display:inline-block;vertical-align:top;border-right:1px solid #ebebeb;border-bottom:none}
|
||||
.webix_list-x .webix_list_item.webix_selected{border-right:1px solid #ffd47b;border-left:1px solid #ffd47b;padding-left:9px}
|
||||
.webix_list-x .webix_scroll_cont{display:inline-block;overflow:visible}
|
||||
.webix_list-x .webix_scroll_cont{display:inline}
|
||||
.webix_view.webix_list-x{white-space:nowrap}
|
||||
.webix_list_item.webix_disabled{color:#8b949e}
|
||||
.webix_list_item.webix_disabled .webix_submenu_icon{visibility:hidden}
|
||||
.webix_view.webix_pager{padding:2px 0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:transparent}
|
||||
.webix_pager_item,.webix_pager_item_selected{padding:0 6px;text-align:center;height:100%;width:auto;min-width:32px;border:1px solid #a4bed4;margin:0 2px;cursor:pointer;background-color:#fff;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana;font-size:13px}
|
||||
.webix_pager_item,.webix_pager_item_selected{padding:0 6px;text-align:center;height:100%;width:32px;border:1px solid #a4bed4;margin:0 2px;cursor:pointer;background-color:#fff;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana;font-size:13px}
|
||||
.webix_pager_item_selected{cursor:default;background-color:#ffdb8f;border:1px solid #ffd47b}
|
||||
.webix_animation .webix_ss_header{position:relative;z-index:10}
|
||||
.webix_animation .webix_ss_footer,.webix_animation .webix_vscroll_x{position:absolute;bottom:0;z-index:10}
|
||||
.webix_allow_selection{-moz-user-select:text;-webkit-user-select:text;user-select:text}
|
||||
.webix_dataview_item{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2px 10px;line-height:23px;cursor:pointer;border-bottom:1px solid #ebebeb;text-align:left;border-right:1px solid #ebebeb}
|
||||
.webix_dataview_item.webix_selected{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f);border-bottom:1px solid #ffd47b;border-right:1px solid #ffd47b}
|
||||
.webix_dataview_item.webix_invalid{background-color:#fee}
|
||||
.webix_dataview_item.webix_selected{color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f);border-bottom:1px solid #ffd47b;border-right:1px solid #ffd47b}
|
||||
.webix_chart{position:relative;font-family:Helvetica,Verdana;font-size:13px;color:#1e2022;overflow:hidden;z-index:1}
|
||||
.webix_chart canvas{position:absolute}
|
||||
.webix_canvas_text{position:absolute;text-align:center;overflow:hidden;white-space:nowrap;font-size:12px;z-index:100}
|
||||
|
@ -156,11 +155,11 @@ x\:ui{display:none}
|
|||
.webix_dt_editor select{padding-right:0;padding-left:5px}
|
||||
.webix_clipbuffer{width:2000px;height:1px;padding:0;margin:0;border:0;left:0;top:0;white-space:pre-wrap;position:fixed;filter:alpha(opacity=0);opacity:0;pointer-events:none;cursor:default}
|
||||
.webix_message_area{position:fixed;right:5px;width:250px;z-index:1000}
|
||||
.webix_info{min-width:120px;font-family:Tahoma,Arial;z-index:10000;overflow:hidden;margin:5px;margin-bottom:10px;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease}
|
||||
.webix_info{min-width:120px;font-family:Tahoma,Arial;z-index:10000;overflow:hidden;margin:5px 5px 10px;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease}
|
||||
.webix_no_transition{-webkit-transition:none;-moz-transition:none;transition:none}
|
||||
.webix_info.hidden{height:0;min-height:0;padding-top:0;padding-bottom:0;border-width:0;margin-top:0;margin-bottom:0;overflow:hidden}
|
||||
.webix_modal_box{overflow:hidden;display:inline-block;min-width:250px;width:250px;text-align:center;position:fixed;background-color:#fff;box-shadow:0 3px 6px #c8c8c8;font-family:Helvetica,Verdana;z-index:20000;border-radius:0;outline:0}
|
||||
.webix_popup_title{border-top-left-radius:-1px;border-top-right-radius:-1px;border-width:0;background-image:-webkit-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%);background-image:-moz-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%)}
|
||||
.webix_popup_title{border-top-left-radius:-1px;border-top-right-radius:-1px;border-width:0}
|
||||
.webix_button,.webix_info,.webix_popup_button{cursor:pointer}
|
||||
.webix_popup_text{overflow:hidden}
|
||||
.webix_popup_controls{border-radius:6px;padding:5px 10px 10px}
|
||||
|
@ -172,12 +171,12 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_alert_error .webix_popup_title,.webix_confirm_error .webix_popup_title{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAsCAIAAAArRUU2AAAATklEQVR4nIWLuw2AMBBDjVuQiBT2oWbRDATrnB0KQOJoqPzRe3BrHI6dcBASYREKovtK6/6DsDOX+stN+3H1YX9ciRgnYq5EWYhS2dftBIuLT4JyIrPCAAAAAElFTkSuQmCC)}
|
||||
.webix_alert_error,.webix_confirm_error{border:1px solid red}
|
||||
.webix_button,.webix_popup_button{border:1px solid #a4bed4}
|
||||
.webix_button input,.webix_popup_button div{font-size:13px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);height:28px;line-height:28px}
|
||||
.webix_popup_button.confirm div{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_button input,.webix_popup_button div{font-size:13px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);height:28px;line-height:28px}
|
||||
.webix_popup_button.confirm div{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webix_popup_title{color:#fff;height:40px;line-height:40px}
|
||||
.webix_popup_text{margin:0 0 5px 0;padding-top:25px;font-size:13px;color:#1e2022;min-height:60px}
|
||||
.webix_popup_text{margin:0 0 5px;padding-top:25px;font-size:13px;color:#1e2022;min-height:60px}
|
||||
.webix_error,.webix_info{font-size:13px;color:#333;box-shadow:0 0 10px #888;padding:0;background-color:#FFF;border-radius:3px;border:1px solid #fff}
|
||||
.webix_info div{padding:5px 10px 5px 10px;background-color:#fff;border-radius:3px;border:1px solid #B8B8B8}
|
||||
.webix_info div{padding:5px 10px;background-color:#fff;border-radius:3px;border:1px solid #B8B8B8}
|
||||
.webix_error{background-color:#d81b1b;border:1px solid #ff3c3c;box-shadow:0 0 10px #000}
|
||||
.webix_error div{background-color:#d81b1b;border:1px solid #940000;color:#FFF}
|
||||
.webix_drag_zone{position:absolute;box-shadow:1px 1px 5px #a4bed4;background-color:#fff;font-family:Helvetica,Verdana;font-size:13px;color:#1e2022;pointer-events:none}
|
||||
|
@ -202,13 +201,13 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_block_selection,.webix_cell,.webix_hcell,.webix_ss_footer td,.webix_ss_header td,.webix_table_cell,.webix_view.webix_table_cell{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_block_selection{position:absolute}
|
||||
.webix_ss_sort_asc,.webix_ss_sort_desc{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.webix_hcell.webix_ss_filter{padding:2px 5px 2px 5px}
|
||||
.webix_hcell.webix_ss_filter{padding:2px 5px}
|
||||
.webix_ss_filter input,.webix_ss_filter select{width:100%;font-size:inherit;color:#1e2022!important;height:30px;margin-top:-2px;padding:0 3px;vertical-align:top;border:1px solid #a4bed4;line-height:30px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana}
|
||||
.webix_richfilter{margin-top:1px;line-height:30px}
|
||||
.webix_ss_filter select{padding:3px}
|
||||
.webix_dd_drag_column,.webix_ss_header,.webix_ss_header TD,.webix_ss_vscroll_header{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_dd_drag_column,.webix_ss_header,.webix_ss_header TD,.webix_ss_vscroll_header{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webix_ss_footer TD,.webix_ss_vscroll_footer{background:#fafafa}
|
||||
.webix_hcell{padding:0 10px 0 10px;text-align:left}
|
||||
.webix_hcell{padding:0 10px;text-align:left}
|
||||
.webix_ss_header td{border-right:1px solid #a4bed4;border-bottom:1px solid #a4bed4}
|
||||
.webix_ss_footer td{border-right:1px solid #ebebeb;border-top:1px solid #ebebeb}
|
||||
.webix_size_row td{border:none}
|
||||
|
@ -223,32 +222,31 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_block_selection{background:rgba(0,0,0,.1);border:2px solid #ffd47b}
|
||||
.webix_dd_drag{white-space:nowrap;overflow:hidden;border-left:1px solid #ebebeb;height:34px}
|
||||
.webix_dd_drag>div{display:inline-block;vertical-align:top;background:#fff;border-top:1px solid #ebebeb;border-right:1px solid #ebebeb;border-bottom:1px solid #ebebeb;padding:5px 10px;height:34px;line-height:26px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_dd_drag_column{padding:5px 10px 5px 10px}
|
||||
.webix_dd_drag_column{padding:5px 10px}
|
||||
.webix_column>.webix_drag_over.webix_cell{background-color:#e6e6e6;color:#1e2022}
|
||||
.webix_ss_header table,.webix_ss_header td{padding:0;margin:0}
|
||||
.webix_cell.webix_invalid,.webix_column>.webix_cell.webix_invalid:nth-child(even){background-color:#fee}
|
||||
.webix_invalid_cell{position:relative}
|
||||
.webix_invalid_cell:after{content:"";position:absolute;top:0;right:0;width:0;height:1px;border-top:8px solid #f44;border-left:8px solid transparent}
|
||||
.webix_column>div.webix_cell_select,.webix_column>div.webix_column_select,.webix_column>div.webix_row_select{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_column>div.webix_cell_select,.webix_column>div.webix_column_select,.webix_column>div.webix_row_select{color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_column>div.webix_cell_select{border-bottom:1px solid #ffd47b;box-shadow:0 1px #ffe3a9 inset;border-right:1px solid #ffd47b;border-left:1px solid #ffd47b;padding-top:0;padding-left:9px}
|
||||
.webix_ss_right .webix_column.webix_first>div.webix_cell_select{padding-left:10px}
|
||||
.webix_column>div.webix_invalid.webix_row_select:nth-child(even),.webix_column>div.webix_row_select{border-bottom:1px solid #ffd47b;box-shadow:0 1px #ffe3a9 inset;padding-top:0}
|
||||
.webix_column>div.webix_column_select{border-right:1px solid #ffd47b;border-left:1px solid #ffd47b;padding-left:9px}
|
||||
.webix_column>.webix_cell.webix_invalid.webix_cell_select:nth-child(even){background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_cell.webix_dtable_colrow,.webix_cell.webix_dtable_subrow,.webix_dtable_subview{position:absolute;left:0;top:0;background-color:#fff;width:100%;padding-right:28px;padding-left:10px;padding-top:1px;border-bottom:1px solid #ebebeb}
|
||||
.webix_cell.webix_dtable_colrow.webix_selected{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_column>.webix_cell.webix_invalid.webix_cell_select:nth-child(even){color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_cell.webix_dtable_colrow,.webix_cell.webix_dtable_subrow,.webix_cell.webix_dtable_subview{position:absolute;left:0;top:0;background-color:#fff;width:100%;padding-right:28px;padding-left:10px;padding-top:1px;border-bottom:1px solid #ebebeb}
|
||||
.webix_dtable_subrow{border-top:1px solid #ebebeb;text-align:right}
|
||||
.webix_dtable_subview{background:#ebebeb;border-top:1px solid #ebebeb;padding:0;padding-left:10px;box-sizing:border-box}
|
||||
.webix_dtable_subview{background:#ebebeb;border-top:1px solid #ebebeb;padding:0 0 0 10px;box-sizing:border-box}
|
||||
.number .webix_cell{text-align:right}
|
||||
.webix_rotate{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);line-height:normal}
|
||||
.webix_measure_rotate{line-height:normal;white-space:normal;padding:10px}
|
||||
.webix_span_layer,.webix_span_layer_top{background:0 0;position:absolute;left:0;top:0;height:0;width:0;overflow:visible}
|
||||
.webix_span_layer_top{z-index:1}
|
||||
.webix_span_layer_top{z-index:1;overflow:hidden}
|
||||
.webix_ss_right .webix_span_layer,.webix_ss_right .webix_span_layer_top{border-left:1px solid #a4bed4}
|
||||
.webix_dtable_span{position:absolute;background:#fff;text-align:left}
|
||||
.webix_dtable_span.webix_selected{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_dtable_span.webix_selected{color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_hcell span.webix_input_icon{background-color:#a4bed4}
|
||||
.webix_area_selection_layer{position:absolute;z-index:2}
|
||||
.webix_area_selection_layer{position:absolute;z-index:1}
|
||||
.webix_area_selection{position:absolute;background:#1e2022}
|
||||
.webix_area_selection_bottom,.webix_area_selection_top{height:2px}
|
||||
.webix_area_selection_left,.webix_area_selection_right{width:2px}
|
||||
|
@ -258,7 +256,7 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_win_body{overflow:hidden}
|
||||
.webix_win_body,.webix_win_body>.webix_view,.webix_win_body>.webix_view .webix_cal_month,.webix_win_content,.webix_window{border-radius:0}
|
||||
.webix_win_head{border-bottom:1px solid silver}
|
||||
.webix_win_head>.webix_view>.webix_template{font-family:Helvetica,Verdana;color:#1e2022;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;padding:0;text-align:center;line-height:34px}
|
||||
.webix_win_head>.webix_view>.webix_template{font-family:Helvetica,Verdana;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);padding:0;text-align:center;line-height:34px}
|
||||
.webix_win_head>.webix_view>.webix_template .webix_el_label,.webix_win_head>.webix_view>.webix_template .webix_inp_label{color:#1e2022}
|
||||
.webix_win_content{height:auto;width:auto;overflow:hidden}
|
||||
.webix_modal{width:100%;height:100%;position:fixed;top:0;left:0;background-color:#000;filter:alpha(opacity=20);opacity:.2}
|
||||
|
@ -270,19 +268,18 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_point_bottom{background-position:0 0}
|
||||
.webix_point_right{background-position:0 -22px}
|
||||
.webix_point_left{background-position:0 -9px}
|
||||
.webix_resize_handle{position:absolute;z-index:2;width:15px;height:15px;bottom:0;line-height:15px;right:-1px;text-align:center;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAABZJREFUeAFjIAUwUshlpJDLSIhLGAAACQ4AFk79JaMAAAAASUVORK5CYII=);cursor:nw-resize}
|
||||
.webix_resize_handle{position:absolute;width:15px;height:15px;bottom:0;line-height:15px;right:-1px;text-align:center;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAABZJREFUeAFjIAUwUshlpJDLSIhLGAAACQ4AFk79JaMAAAAASUVORK5CYII=);cursor:nw-resize}
|
||||
.webix_resize_frame{position:absolute;filter:alpha(opacity=10);opacity:.1;background:#d6e8ff;display:block;border:1px solid #70afff;box-shadow:1px 3px 6px #000}
|
||||
.webix_resize_cursor{cursor:nw-resize}
|
||||
.webix_tree .webix_scroll_cont>.webix_tree_leaves{padding:9px 10px 9px 9px}
|
||||
.webix_tree_item{clear:both;height:22px;line-height:22px;white-space:nowrap}
|
||||
.webix_tree_item.webix_selected{background:0 0}
|
||||
.webix_tree_item.webix_selected span{padding:4px 10px 4px 4px;margin-left:-4px;background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_tree_item.webix_invalid{background-color:#fee}
|
||||
.webix_tree_item.webix_selected span{padding:4px 10px 4px 4px;margin-left:-4px;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_tree_checkbox{margin:1px 0 0;padding:0;float:left;vertical-align:middle;height:100%;width:13px}
|
||||
.webix_indeterminate{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gcCCSwfRyGesAAAAAxpVFh0Q29tbWVudAAAAAAAvK6ymQAAAExJREFUKM9jLCgo+M9AAmBhYGBgaGtrY+Tk5MSrsLCwkIGBgeE/EwOJgGQNLMgcJSUlBgYGBnQ/Md67d498G+jsB6hbGQfWSYykJg0AUMsPVoNrFX0AAAAASUVORK5CYII=);background-repeat:no-repeat;background-position:left center;height:100%;width:13px;margin-top:0!important}
|
||||
.webix_measure_size input,.webix_measure_size select,.webix_measure_size textarea{width:5px}
|
||||
.webix_measure_size div{margin-left:-5px;float:none}
|
||||
.webix_measure_size a,.webix_measure_size div{display:inline-block!important;position:static!important}
|
||||
.webix_measure_size a,.webix_measure_size div{display:inline-block!important}
|
||||
.webix_tree_close,.webix_tree_file,.webix_tree_folder,.webix_tree_folder_open,.webix_tree_none,.webix_tree_open{float:left;width:20px;height:100%;cursor:pointer;margin:0;background-repeat:no-repeat}
|
||||
.webix_tree_close,.webix_tree_none,.webix_tree_open{background-position:center center}
|
||||
.webix_cell .webix_tree_close,.webix_cell .webix_tree_none,.webix_cell .webix_tree_open{background-color:transparent}
|
||||
|
@ -294,7 +291,7 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_tree_file{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQVAPv7+2RkZPf39/r6+vj4+Pn5+fT09Pb29vX19fHx8fDw8Onp6fLy8u7u7uzs7PPz8+vr6+rq6uXl5ejo6O/v7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABUALAAAAAASABIAAAV4YCWOZGkGaKqaVSAMQCwLQnAOj6ErzUTXpQDgQDgcGJTFDzgSEp4HRCKytDUBMKzAoIAsJACrSCjTGhINR5hELg8ECEZifS3HCgQEgj62xwZPAnwtbgMDBQU0g21Yh4iIi3aGkzBihH52lgEEmDIEli0qoigspSYhADs=)}
|
||||
.webix_tree_folder{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQfAPvjpP/24fPHVvnUdvzotdSiKv/23vvrw/LCS/C+RfnelvPMaf/88/nbi/rsyerYq/TLYv7y1v7wzeCsLO+8P86dJfvv0MuaIsydKPPOc+SqGKGEPe/AS+zVneWwLf///yH5BAEAAB8ALAAAAAASABIAAAWZ4CdeZGleYvpdA+O+zNUBqHoZOB4EceHUqVtuF+n9VCtdQCI5BC6FA3BkCEQkBALAACVMV9eDVhGJQGnIixigaAwiG6jie2G7BxDLpVJozG13EAICPxUeGRleQQMLgggJUhiHC3pBggKPFJETGZRAF5gJCRSaFxgTC55BCByioz+nEKojGgmtHBwPJAUCELo2J8FfSMTFxsUhADs=)}
|
||||
.webix_tree_folder_open{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQfAPXMWPK9N/fipOzLbPrVaP/89frqwv3tuvvprfLES+7PdP7xyP7z0vPAQfvtyMuaIv/32/735OSqFv3de+7ReP7lmf7gh/nv0v/67unFXfb29vK/PenFSaGEPfLnyv///yH5BAEAAB8ALAAAAAASABIAAAWS4Cc+ZGk+YvqZRVtgGiag6sNBThlFWnTQqQcE4sqRFj/VashsYR6HZI0JWSAjDwQCOGIgERULg/EQzJRQsGVCYHTK51qYTQDkFPj4iA4AJHIUgQoGQA8EdX4NhHgKAxeFfQkJGwGLeI6Fkg2UlQ8Dn5hBCZuchKChIxKkGw05Ga8DHlwkqg2tJ1xBtDlKvTUkviEAOw==)}
|
||||
.webix_tree_img{background:0 0;float:left;width:18px;height:22px;background-position:0 0}
|
||||
.webix_tree_img{background:0 0;float:left;width:18px;height:22px}
|
||||
.webix_tree_plus2{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQfAFSWrmi52FCPplORqVmet8HBwfn//02KoE+NpEyIn2a21E2Jn2u/3mzB4Vqguk6LomGtyWGuy27E5VqivG/H51OUrE+OpVyhu1eXr2CqxV6lwFaas06LoXHJ6lKTqgAAACH5BAEAAB8ALAAAAAASABIAAAVZ4CeOYkGeaJmuKpuaLgrHX7IcD2IJrs0hAk8FAGAlDoiBYUNwTIyPAcagyUAirAXCwOUGAoVwmHSwVAiGSIDRYB0EgIthLaG44RN1g9JxwR0QdDSDhIWGKyEAOw==);background-repeat:no-repeat}
|
||||
.webix_tree_plus3{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQfAFSWrmi52FCPplORqVmet8HBwfn//02KoE+NpEyIn2a21E2Jn2u/3mzB4Vqguk6LomGtyWGuy27E5VqivG/H51OUrE+OpVyhu1eXr2CqxV6lwFaas06LoXHJ6lKTqgAAACH5BAEAAB8ALAAAAAASABIAAAVb4CeOYkGeaJmuKpuaLgrHX7IcD2IJrs0hAk8FAGAlDoiBYUNwTIyPAcagyUAirAXCwOUGAoVwmHSwVAiGSIDRYB0EgIthLaG44RN1g9JxwR0QdDQtg4SFM4csIQA7)}
|
||||
.webix_tree_plus4{background-image:url(data:image/gif;base64,R0lGODlhEgASAMQfAFSWrmi52FCPplORqVmet/n//8HBwU2KoE+NpEyIn2a21E2Jn2u/3mzB4VqgumGtyWGuy27E5VqivE6Lom/H51OUrE+OpVyhu1eXr2CqxV6lwFaas06LoVKTqnHJ6gAAACH5BAEAAB8ALAAAAAASABIAAAVY4CeOZGmeaKqubEsmyzEhlqDCHCJ0FQCkiQNiUNgQHBLgZIApaDIPSGqBKFitgYBhuyUdLBVCARJgNFIHAeBSKEcoaLWE3KB4VGrHw+0yuEZ+fx+Bf4QmIQA7)}
|
||||
|
@ -311,9 +308,9 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_cal_next_button,.webix_cal_prev_button{cursor:pointer;position:absolute;top:17px;width:30px;height:28px;background-position:11.5px 4px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.webix_cal_prev_button{left:17px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAASUlEQVR42p2QMQoAQQgD79EZ0Mqn5xCu2cPdYgUbJ0rMMxXgLeiuKq8gsJAz8weQ0QiwJEfECnr4wdlEnwJ68+yyhReC+c85oRecj0Um+pmo9wAAAABJRU5ErkJggg==);background-repeat:no-repeat}
|
||||
.webix_cal_next_button{right:17px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAARElEQVR42qXPsQoAIAhF0T76PdDJT7cUmtQhcmk4N8QVQ9JXN2bmgWOgqp+BiCRG2AYAMoi3/LxYdyagAnhA6G93TrABZaJFJjrFY8IAAAAASUVORK5CYII=);background-repeat:no-repeat}
|
||||
.webix_view>.webix_cal_header{margin:0 17px 10px 17px;height:auto}
|
||||
.webix_view>.webix_cal_header{margin:0 17px 10px;height:auto}
|
||||
.webix_view>.webix_cal_header div{float:left;text-align:center;height:19px;font-size:11px;color:#1e2022;border-bottom:#cecece 1px solid;margin-bottom:7px}
|
||||
.webix_cal_body{margin:0 17px 0 17px}
|
||||
.webix_cal_body{margin:0 17px}
|
||||
.webix_cal_body .webix_cal_row{clear:both}
|
||||
.webix_cal_body .webix_cal_row>div{float:left;text-align:center;height:100%}
|
||||
.webix_cal_body .webix_cal_select,.webix_cal_body .webix_cal_select.webix_cal_today,.webix_cal_body .webix_selected{color:#1e2022;background:#ffdb8f}
|
||||
|
@ -328,30 +325,30 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_cal_block{float:left;text-align:center;cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.webix_selected{background:#ffdb8f;color:#1e2022}
|
||||
.webix_cal_footer{text-align:center;font-size:12px;color:#444;margin:4px 17px;padding-top:2px;cursor:pointer}
|
||||
.webix_cal_icons{float:right;padding:4px 4px}
|
||||
.webix_cal_icons{float:right;padding:4px}
|
||||
.webix_cal_time{padding:2px 4px}
|
||||
.webix_cal_time_icons{float:left}
|
||||
.webix_cal_icons .webix_cal_icon{text-align:center;padding:2px 4px}
|
||||
.webix_cal_icon:hover,.webix_cal_month_name:hover,.webix_cal_time:hover{text-decoration:underline;color:#d6e8ff}
|
||||
.webix_cal_month_name.webix_readonly:hover{text-decoration:none;color:#1e2022;cursor:default}
|
||||
.webix_time_header{padding:17px 17px 1px 17px}
|
||||
.webix_time_header{padding:17px 17px 1px}
|
||||
.webix_time_header .webix_cal_hours,.webix_time_header .webix_cal_minutes{display:inline-block;font-size:14px;text-align:center;height:26px;line-height:22px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:1px solid #a4bed4}
|
||||
.webix_time_header .webix_cal_minutes{padding-left:1px;border-left:none}
|
||||
.webix_time_header .webix_cal_hours{border-right:none!important}
|
||||
.webix_cal_body .webix_hours{float:left;border-right:1px solid #cecece;padding-right:1px}
|
||||
.webix_cal_body .webix_minutes{float:left;padding-left:1px}
|
||||
.webix_cal_block_empty{float:left;text-align:center}
|
||||
.webix_time_footer{text-align:center;font-size:12px;padding:7px 17px 0 17px;cursor:pointer}
|
||||
.webix_cal_done{margin-top:3px;padding:2px 7px;font-size:12px;border-radius:6px;border:1px solid #a4bed4;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;float:right}
|
||||
.webix_time_footer{text-align:center;font-size:12px;padding:7px 17px 0;cursor:pointer}
|
||||
.webix_cal_done{margin-top:3px;padding:2px 7px;font-size:12px;border-radius:6px;border:1px solid #a4bed4;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);float:right}
|
||||
.webix_cal_blurred_hours{background-color:#f7f7f7}
|
||||
.webix_property_line{clear:both;width:100%;min-height:24px;height:auto}
|
||||
.webix_property_line:nth-child(odd){background-color:#f7f7f7}
|
||||
.webix_property_label,.webix_property_value{height:24px;line-height:24px;padding-left:10px;float:left;border-bottom:1px solid #a4bed4;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}
|
||||
.webix_property_label{border-right:1px solid #a4bed4}
|
||||
.webix_property_label_line{padding-left:10px;font-family:Helvetica,Verdana;color:#1e2022;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;line-height:32px;line-height:23px;border-bottom:1px solid #ebebeb}
|
||||
.webix_property_label_line{padding-left:10px;font-family:Helvetica,Verdana;font-size:13px;font-weight:700;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);line-height:32px;line-height:23px;border-bottom:1px solid #ebebeb}
|
||||
.webix_property_label_line .webix_el_label,.webix_property_label_line .webix_inp_label{color:#1e2022}
|
||||
.webix_property_col_val{width:100%;height:100%;-moz-user-select:text;-webkit-user-select:text;user-select:text}
|
||||
.webix_property_col_ind{float:right;border:1px solid #a4bed4;border-radius:3px;width:16px;cursor:pointer;height:16px;margin:4px 10px 3px 0}
|
||||
.webix_property_col_ind{float:right;border:1px solid #a4bed4;border-radius:2px;width:30px;cursor:pointer;height:13px;margin:3px 10px 3px 0}
|
||||
.webix_property_value{text-overflow:ellipsis;white-space:nowrap}
|
||||
.webix_property_check{margin-top:5px}
|
||||
.webix_tooltip{display:none;position:absolute;z-index:10000;background-color:#fff;padding:5px 10px;border:1px solid #a4bed4;font-family:Helvetica,Verdana;font-size:13px;color:#1e2022;border-radius:0;box-shadow:1px 1px 0 0 #CCC}
|
||||
|
@ -380,16 +377,16 @@ div.webix_modal_cover{background-color:#000;cursor:default;filter:alpha(opacity=
|
|||
.webix_el_button button,.webix_el_button input,.webix_el_toggle button,.webix_el_toggle input,.webixbutton{border-radius:6px;border:1px solid #a4bed4;height:100%;width:100%;cursor:pointer;font-size:13px;font-family:Helvetica,Verdana;-webkit-appearance:none}
|
||||
.webix_el_button .webix_img_btn,.webix_el_button .webix_img_btn .webix_img_btn_text,.webix_el_button .webix_img_btn_top,.webix_el_button .webix_img_btn_top .webix_img_btn_text,.webix_el_toggle .webix_img_btn,.webix_el_toggle .webix_img_btn .webix_img_btn_text,.webix_el_toggle .webix_img_btn_top,.webix_el_toggle .webix_img_btn_top .webix_img_btn_text{color:#1e2022}
|
||||
.webix_el_button .webix_img_btn,.webix_el_button .webix_img_btn_top,.webix_el_toggle .webix_img_btn,.webix_el_toggle .webix_img_btn_top{border:0}
|
||||
.webixbutton,.webixtype_base,.webixtype_next,.webixtype_prev{color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);font-size:13px;font-family:Helvetica,Verdana;padding:0;border:0}
|
||||
.webixtype_form{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webixtype_form:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background:#d6e8ff;background-repeat:no-repeat}
|
||||
.webix_el_button .webixtype_danger{background:#c10;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#e7877e),color-stop(100%,#c10));background-image:-webkit-linear-gradient(#e7877e,#c10);background-image:-moz-linear-gradient(#e7877e,#c10);background-image:-ms-linear-gradient(top,#e7877e,#c10);background-image:-o-linear-gradient(top,#e7877e,#c10);border:none!important;color:#fff}
|
||||
.webixbutton,.webixtype_base,.webixtype_next,.webixtype_prev{color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);font-size:13px;font-family:Helvetica,Verdana;padding:0;border:0}
|
||||
.webixtype_form{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webixtype_form:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background:no-repeat #d6e8ff}
|
||||
.webix_el_button .webixtype_danger{background:#c10;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#e7877e),color-stop(100%,#c10));background:-webkit-linear-gradient(#e7877e,#c10);background:-moz-linear-gradient(#e7877e,#c10);background:-ms-linear-gradient(top,#e7877e,#c10);background:-o-linear-gradient(top,#e7877e,#c10);border:none!important;color:#fff}
|
||||
.webix_el_button .webix_el_box,.webix_el_toggle .webix_el_box{position:relative}
|
||||
.webix_el_button .webix_el_arrow,.webix_el_toggle .webix_el_arrow{position:absolute}
|
||||
.webixtype_next,.webixtype_prev{position:absolute;z-index:1;top:0}
|
||||
input.webixtype_prev{border-left-width:0;border-radius:0;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:6px;border-bottom-right-radius:6px}
|
||||
input.webixtype_next{border-right-width:0;border-radius:0;-webkit-border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-top-left-radius:6px;border-bottom-left-radius:6px;border-top-right-radius:0;border-bottom-right-radius:0}
|
||||
.webix_el_arrow{width:18px;height:18px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);border:1px solid #a4bed4}
|
||||
.webix_el_button .webix_el_arrow,.webix_el_toggle .webix_el_arrow{position:absolute;z-index:1}
|
||||
.webixtype_next,.webixtype_prev{position:absolute;z-index:2;top:0}
|
||||
input.webixtype_prev{border-left-width:0;border-radius:0 6px 6px 0;-webkit-border-radius:0 6px 6px 0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}
|
||||
input.webixtype_next{border-right-width:0;border-radius:6px 0 0 6px;-webkit-border-radius:6px 0 0 6px;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0}
|
||||
.webix_el_arrow{width:18px;height:18px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);border:1px solid #a4bed4}
|
||||
.webixtype_prev_arrow{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg)}
|
||||
.webixtype_next_arrow{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg)}
|
||||
.webix_img_btn_abs_top .webix_icon,.webix_img_btn_top .webix_icon{font-size:22px;position:absolute;top:8px;left:50%}
|
||||
|
@ -408,7 +405,7 @@ input.webixtype_next{border-right-width:0;border-radius:0;-webkit-border-top-lef
|
|||
.webix_img_btn_top{background-position:center top;vertical-align:top}
|
||||
.webix_img_btn_abs .webix_img_btn_text{bottom:8px}
|
||||
.webix_pressed .webix_img_btn,.webix_pressed .webix_img_btn_top{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-color:rgba(0,0,0,.05)}
|
||||
.webix_control .webix_disabled_box .webix_el_arrow,.webix_control .webix_disabled_box .webix_img_btn,.webix_control .webix_disabled_box .webixtype_base,.webix_control .webix_disabled_box .webixtype_danger,.webix_control .webix_disabled_box .webixtype_form,.webix_control .webix_disabled_box .webixtype_next,.webix_control .webix_disabled_box .webixtype_prev{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background-image:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background-image:-moz-linear-gradient(#fbfbfb,#e9e9e9);background-image:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background-image:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_control .webix_disabled_box .webix_el_arrow,.webix_control .webix_disabled_box .webix_img_btn,.webix_control .webix_disabled_box .webixtype_base,.webix_control .webix_disabled_box .webixtype_danger,.webix_control .webix_disabled_box .webixtype_form,.webix_control .webix_disabled_box .webixtype_next,.webix_control .webix_disabled_box .webixtype_prev{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background:-moz-linear-gradient(#fbfbfb,#e9e9e9);background:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_control .webix_disabled_box .webix_img_btn_text{color:#aaa}
|
||||
.webix_control .webix_disabled_box .webix_image{opacity:.4}
|
||||
.webix_disabled_view.webix_control .webix_icon,.webix_disabled_view.webix_control .webix_icon_btn,.webix_layout_toolbar.webix_toolbar .webix_disabled_view.webix_control .webix_disabled_box .webix_img_btn_text,.webix_layout_toolbar.webix_toolbar .webix_disabled_view.webix_control .webix_icon,.webix_layout_toolbar.webix_toolbar .webix_disabled_view.webix_control .webix_icon_btn{color:#aaa}
|
||||
|
@ -418,31 +415,31 @@ input.webixtype_next{border-right-width:0;border-radius:0;-webkit-border-top-lef
|
|||
.webix_richtext_container .webix_template{padding:10px;overflow-x:auto;border:solid #ccc;border-width:0 1px 1px;border-radius:0 0 6px 6px}
|
||||
.webix_control{background:0 0}
|
||||
.webix_control button,.webix_control input,.webix_control textarea,.webix_el_label,.webix_inp_bottom_label,.webix_inp_label,.webix_inp_top_label{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana}
|
||||
.webix_el_box{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2px 2px;height:100%;width:100%;font-size:13px;overflow:hidden}
|
||||
.webix_el_box{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2px;height:100%;width:100%;font-size:13px;overflow:hidden}
|
||||
.webix_el_colorpicker input,.webix_el_combo input,.webix_el_datepicker input,.webix_el_search input,.webix_el_text input{height:100%;padding:0 10px;border:1px solid #a4bed4;color:#1e2022;font-size:13px;font-family:Helvetica,Verdana;-webkit-appearance:none;border-radius:0}
|
||||
.webix_inp_label,.webix_inp_top_label,.webix_label_right{color:#1e2022;text-transform:none;font-size:13px}
|
||||
.webix_inp_label{float:left;padding-top:1px;padding-left:2px;padding-right:7.5px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}
|
||||
.webix_inp_top_label{float:none;padding:2px 2px;padding-bottom:0}
|
||||
.webix_inp_top_label{float:none;padding:2px 2px 0}
|
||||
.webix_inp_bottom_label{font-size:11px;color:#2a2d30}
|
||||
.webix_label_right{padding-left:7.5px}
|
||||
.webix_el_checkbox .webix_label_right{display:inline-block;padding-top:2px}
|
||||
.webix_el_label{color:#1e2022;line-height:30px;padding:2px 2px}
|
||||
.webix_el_label{color:#1e2022;line-height:30px;padding:2px}
|
||||
.webix_toolbar .webix_el_label{padding-left:10px;text-transform:none}
|
||||
.webix_el_select select{height:100%;font-size:13px;font-family:Helvetica,Verdana;border:1px solid #a4bed4}
|
||||
body:not(:-moz-handler-blocked) .webix_el_select select{padding:.2em}
|
||||
.webix_all_segments,.webix_el_group{height:100%;white-space:nowrap}
|
||||
.webix_inp_counter_next,.webix_inp_counter_prev,.webix_inp_counter_value{border:1px solid #a4bed4;cursor:pointer;-webkit-appearance:none;width:20px;height:100%;vertical-align:top}
|
||||
.webix_inp_counter_value{font-size:13px;width:50px;color:#1e2022;text-align:center;border-left-width:0;border-right-width:0;-webkit-appearance:none;border-radius:0}
|
||||
.webix_inp_counter_prev{padding-left:6px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);-webkit-border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-top-left-radius:6px;border-bottom-left-radius:6px;border-top-right-radius:0;border-bottom-right-radius:0}
|
||||
.webix_inp_counter_next{padding-left:6px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:6px;border-bottom-right-radius:6px}
|
||||
.webix_el_textarea textarea{border:1px solid #a4bed4;height:100%;margin:0;padding:5px;color:#1e2022;resize:none;font-size:13px;font-family:Helvetica,Verdana;padding-left:10px;padding-right:10px}
|
||||
.webix_inp_counter_prev{padding-left:6px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);-webkit-border-radius:6px 0 0 6px;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-radius:6px 0 0 6px}
|
||||
.webix_inp_counter_next{padding-left:6px;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);-webkit-border-radius:0 6px 6px 0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-radius:0 6px 6px 0}
|
||||
.webix_el_textarea textarea{border:1px solid #a4bed4;height:100%;margin:0;padding:5px 10px;color:#1e2022;resize:none;font-size:13px;font-family:Helvetica,Verdana}
|
||||
.webix_el_textarea .webix_inp_label{padding-top:8.5px}
|
||||
.webix_segment_0,.webix_segment_1{border:1px solid #a4bed4;border-right-width:0;height:100%}
|
||||
.webix_segment_0{-webkit-border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-top-left-radius:6px;border-bottom-left-radius:6px;border-top-right-radius:0;border-bottom-right-radius:0}
|
||||
.webix_segment_N{border:1px solid #a4bed4;height:100%;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:6px;border-bottom-right-radius:6px}
|
||||
.webix_segment_N:first-child{-webkit-border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-top-left-radius:6px;border-bottom-left-radius:6px;border-top-right-radius:6px;border-bottom-right-radius:6px}
|
||||
.webix_segment_0,.webix_segment_1,.webix_segment_N{-webkit-appearance:none;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background-image:-webkit-linear-gradient(#fff,#e6e6e6);background-image:-moz-linear-gradient(#fff,#e6e6e6);background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);font-size:13px;font-family:Helvetica,Verdana;cursor:pointer;padding:0}
|
||||
.webix_segment_0.webix_selected,.webix_segment_1.webix_selected,.webix_segment_N.webix_selected{background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_segment_0{-webkit-border-radius:6px 0 0 6px;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-radius:6px 0 0 6px}
|
||||
.webix_segment_N{border:1px solid #a4bed4;height:100%;-webkit-border-radius:0 6px 6px 0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-radius:0 6px 6px 0}
|
||||
.webix_segment_N:first-child{-webkit-border-radius:6px;-moz-border-radius-topleft:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px;border-radius:6px}
|
||||
.webix_segment_0,.webix_segment_1,.webix_segment_N{-webkit-appearance:none;color:#1e2022;background:#e6e6e6;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(100%,#e6e6e6));background:-webkit-linear-gradient(#fff,#e6e6e6);background:-moz-linear-gradient(#fff,#e6e6e6);background:-ms-linear-gradient(top,#fff,#e6e6e6);background:-o-linear-gradient(top,#fff,#e6e6e6);font-size:13px;font-family:Helvetica,Verdana;cursor:pointer;padding:0}
|
||||
.webix_segment_0.webix_selected,.webix_segment_1.webix_selected,.webix_segment_N.webix_selected{color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_inp_static{border:1px solid #a4bed4;background:#fff;overflow:hidden;padding:0 10px;height:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;float:left}
|
||||
.webix_inp_static .webix_placeholder{color:#666d73}
|
||||
.webix_el_colorpicker,.webix_el_combo,.webix_el_datepicker,.webix_el_richselect,.webix_el_search{font-size:13px}
|
||||
|
@ -468,15 +465,15 @@ body:not(:-moz-handler-blocked) .webix_el_select select{padding:.2em}
|
|||
.webix_disabled_view.webix_control .webix_image{-webkit-filter:grayscale(100%);filter:grayscale(100%)}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_input_icon,.webix_view.webix_control .webix_disabled_box button,.webix_view.webix_control .webix_disabled_box label{color:#aaa}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_inp_static,.webix_view.webix_control .webix_disabled_box input,.webix_view.webix_control .webix_disabled_box select,.webix_view.webix_control .webix_disabled_box textarea{color:#aaa;background:#eee}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_inp_counter_next,.webix_view.webix_control .webix_disabled_box .webix_inp_counter_prev,.webix_view.webix_control .webix_disabled_box .webix_segment_0,.webix_view.webix_control .webix_disabled_box .webix_segment_1,.webix_view.webix_control .webix_disabled_box .webix_segment_N{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background-image:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background-image:-moz-linear-gradient(#fbfbfb,#e9e9e9);background-image:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background-image:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_inp_counter_next,.webix_view.webix_control .webix_disabled_box .webix_inp_counter_prev,.webix_view.webix_control .webix_disabled_box .webix_segment_0,.webix_view.webix_control .webix_disabled_box .webix_segment_1,.webix_view.webix_control .webix_disabled_box .webix_segment_N{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background:-moz-linear-gradient(#fbfbfb,#e9e9e9);background:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_disabled_top_label{color:#aaa}
|
||||
label.webix_required:after,legend.webix_required:after{padding-left:4px;content:"*";color:red}
|
||||
label.webix_required:after{padding-left:4px;content:"*";color:red}
|
||||
.webix_multicombo .webix_inp_static{padding:0 3px}
|
||||
.webix_el_text .webix_multicombo_input{background-color:transparent;border:0;float:left;vertical-align:middle;padding:0;color:#1e2022;font-size:13px;font-family:Helvetica,Verdana;margin-left:7px}
|
||||
.webix_el_text .webix_multicombo_input:focus{border:0;box-shadow:none}
|
||||
.webix_multicombo_listbox{width:auto;line-height:1;margin:0;padding:0;list-style:none}
|
||||
.webix_multicombo_tag,.webix_multicombo_value{padding:0 5px 0 7px;background-color:#f2f2f2;display:inline-block;margin:3px;float:left;border-radius:6px}
|
||||
.webix_multicombo_tag{min-width:15px;text-align:center;padding:0 5px 0 5px}
|
||||
.webix_multicombo_tag{min-width:15px;text-align:center;padding:0 5px}
|
||||
.webix_multicombo_delete{margin-left:10px;padding:0 5px;color:#000;cursor:pointer}
|
||||
.webix_multilist .webix_selected{background:#f2f2f2;color:#1e2022}
|
||||
.webix_checksuggest_select_all{border:none;border-bottom:1px solid #ebebeb;border-color:#ebebeb;margin-bottom:1px}
|
||||
|
@ -488,13 +485,13 @@ label.webix_required:after,legend.webix_required:after{padding-left:4px;content:
|
|||
.webix_tab_filler{display:table-cell;background:0 0;font-size:1px;border-bottom:1px solid #a4bed4;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_tab_filler:first-child{border-right:1px solid #a4bed4}
|
||||
.webix_item_tab:first-child{border-left:1px solid #a4bed4}
|
||||
.webix_item_tab{display:table-cell;text-align:center;vertical-align:middle;overflow:hidden;cursor:pointer;border:1px solid #a4bed4;border-left-width:0;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_item_tab{display:table-cell;text-align:center;vertical-align:middle;overflow:hidden;cursor:pointer;border:1px solid #a4bed4;border-left-width:0;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);-webkit-border-radius:0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-radius:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webixtype_bottom .webix_item_tab{border-radius:0}
|
||||
.webix_item_tab.webix_selected{border-bottom-width:0;background:#fff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#e5f1ff),color-stop(100%,#fff));background-image:-webkit-linear-gradient(#e5f1ff,#fff);background-image:-moz-linear-gradient(#e5f1ff,#fff);background-image:-ms-linear-gradient(top,#e5f1ff,#fff);background-image:-o-linear-gradient(top,#e5f1ff,#fff)}
|
||||
.webixtype_bottom .webix_item_tab.webix_selected{border-bottom-width:1px;background-size:100% 100%;background-position:0 0;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background-image:-webkit-linear-gradient(#ffebc2,#ffdb8f);background-image:-moz-linear-gradient(#ffebc2,#ffdb8f);background-image:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background-image:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_item_tab.webix_selected{border-bottom-width:0;background:#fff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#e5f1ff),color-stop(100%,#fff));background:-webkit-linear-gradient(#e5f1ff,#fff);background:-moz-linear-gradient(#e5f1ff,#fff);background:-ms-linear-gradient(top,#e5f1ff,#fff);background:-o-linear-gradient(top,#e5f1ff,#fff)}
|
||||
.webixtype_bottom .webix_item_tab.webix_selected{border-bottom-width:1px;color:#1e2022;background:#ffdb8f;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ffebc2),color-stop(100%,#ffdb8f));background:-webkit-linear-gradient(#ffebc2,#ffdb8f);background:-moz-linear-gradient(#ffebc2,#ffdb8f);background:-ms-linear-gradient(top,#ffebc2,#ffdb8f);background:-o-linear-gradient(top,#ffebc2,#ffdb8f)}
|
||||
.webix_before_all_tabs{width:100%}
|
||||
.webix_after_all_tabs{width:100%;border-left:1px solid #a4bed4;border-right:1px solid #a4bed4;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_item_tab{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background-image:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background-image:-moz-linear-gradient(#fbfbfb,#e9e9e9);background-image:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background-image:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_view.webix_control .webix_disabled_box .webix_item_tab{color:#aaa!important;background:#e9e9e9;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fbfbfb),color-stop(100%,#e9e9e9));background:-webkit-linear-gradient(#fbfbfb,#e9e9e9);background:-moz-linear-gradient(#fbfbfb,#e9e9e9);background:-ms-linear-gradient(top,#fbfbfb,#e9e9e9);background:-o-linear-gradient(top,#fbfbfb,#e9e9e9);border-color:#d5d5d5!important}
|
||||
.webix_el_tabbar .webixtype_icon .webix_img_btn{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0 auto;text-align:center}
|
||||
.webix_el_tabbar .webixtype_icon .webix_img_btn .webix_icon_btn{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0 3px}
|
||||
.webix_el_tabbar .webixtype_icon .webix_item_tab,.webix_el_tabbar .webixtype_iconTop .webix_item_tab,.webix_el_tabbar .webixtype_image .webix_item_tab{padding:2px 0;border-radius:0}
|
||||
|
@ -508,17 +505,17 @@ label.webix_required:after,legend.webix_required:after{padding-left:4px;content:
|
|||
.webix_menu .webix_list_item .webix_submenu_icon,.webix_menu-x .webix_list_item .webix_submenu_icon{float:right;text-align:right;position:relative;margin-left:4px}
|
||||
.webix_menu-x .webix_list_item:first-child{margin-left:0}
|
||||
.webix_menu-x .webix_submenu_icon{top:13px}
|
||||
.webix_menu-x{background-color:#fff;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_menu-x{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webix_menu-x .webix_list_item{display:inline-block;line-height:30px;-moz-background-size:1px 100%,100% 100%,1px 100%;background-size:1px 100%,100% 100%,1px 100%;background-color:transparent;margin:1px 0;background-position:0 0,1px 0,100% 0;background-repeat:no-repeat;background-image:-webkit-gradient(linear,left top,left bottom,#f0f6ff,#fff,#f0f6ff),-webkit-gradient(linear,left top,left bottom,transparent,transparent),-webkit-gradient(linear,left top,left bottom,#f0f6ff,#a4bed4,#f0f6ff);background-image:-webkit-linear-gradient(#f0f6ff,#fff,#f0f6ff),-webkit-linear-gradient(transparent,transparent),-webkit-linear-gradient(#f0f6ff,#a4bed4,#f0f6ff);background-image:-moz-linear-gradient(#f0f6ff,#fff,#f0f6ff),-moz-linear-gradient(transparent,transparent),-moz-linear-gradient(#f0f6ff,#a4bed4,#f0f6ff);background-image:-ms-linear-gradient(top,#f0f6ff,#fff,#f0f6ff),-ms-linear-gradient(transparent,transparent),-ms-linear-gradient(top,#f0f6ff,#a4bed4,#f0f6ff);background-image:-o-linear-gradient(top,#f0f6ff,#fff,#f0f6ff),-o-linear-gradient(transparent,transparent),-o-linear-gradient(top,#f0f6ff,#a4bed4,#f0f6ff)}
|
||||
.webix_menu-x .webix_list_item:last-child{background-size:1px 100%,100% 100%,1px 100%;background-repeat:no-repeat;background-image:-webkit-gradient(linear,left top,left bottom,#f0f6ff,#fff,#f0f6ff),-webkit-gradient(linear,left top,left bottom,transparent,transparent),-webkit-gradient(linear,left top,left bottom,transparent,transparent);background-image:-webkit-linear-gradient(#f0f6ff,#fff,#f0f6ff),-webkit-linear-gradient(transparent,transparent),-webkit-linear-gradient(transparent,transparent);background-image:-moz-linear-gradient(#f0f6ff,#fff,#f0f6ff),-moz-linear-gradient(transparent,transparent),-moz-linear-gradient(transparent,transparent);background-image:-ms-linear-gradient(top,#f0f6ff,#fff,#f0f6ff),-ms-linear-gradient(transparent,transparent),-ms-linear-gradient(transparent,transparent);background-image:-o-linear-gradient(top,#f0f6ff,#fff,#f0f6ff),-o-linear-gradient(transparent,transparent),-o-linear-gradient(transparent,transparent);border-right:0}
|
||||
.webix_menu{background:#fff;border:1px solid #a4bed4;border-radius:0}
|
||||
.webix_menu .webix_list_item{display:block}
|
||||
.webix_menu .webix_context_separator{height:3px;padding:1px 3px 0 3px}
|
||||
.webix_menu .webix_context_separator{height:3px;padding:1px 3px 0}
|
||||
.webix_menu .webix_context_separator .sep_line{height:1px;border-top:1px solid #a4bed4}
|
||||
.webix_menu .webix_submenu_icon{top:11px}
|
||||
.webix_menu .webix_context_spacer{height:28px}
|
||||
.webix_menu_link{color:inherit;text-decoration:none;display:block;height:100%}
|
||||
.webix_layout_toolbar,.webix_toolbar.webix_layout_subbar{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_layout_toolbar,.webix_toolbar.webix_layout_subbar{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.webix_toolbar .webix_layout_clean,.webix_toolbar .webix_layout_line,.webix_toolbar .webix_layout_toolbar{background:0 0}
|
||||
.webix_el_button .webix_hidden_upload,.webix_hidden_upload{height:1px;width:1px;border:0!important;font-size:1px;position:absolute;top:0;left:0;z-index:-1}
|
||||
.webix_upload_client,.webix_upload_error,.webix_upload_server{width:60px;text-align:center;float:right}
|
||||
|
@ -533,42 +530,29 @@ label.webix_required:after,legend.webix_required:after{padding-left:4px;content:
|
|||
.webix_fieldset fieldset{border:1px solid #81a5c4;margin:0;padding:5px 8px}
|
||||
.webix_fieldset legend{color:#1e2022;font-size:12px}
|
||||
.webix_forminput fieldset{border:none;margin:0;padding:0}
|
||||
.webix_forminput legend{color:#1e2022;line-height:30px;padding:2px 5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana;float:left;padding-right:7.5px}
|
||||
.webix_slider_box{position:relative;padding:0 10px;height:100%;padding-top:13px;float:left;border-radius:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:-11px}
|
||||
.webix_slider_box .webix_slider_left{height:10px;float:left;width:100px;border:1px solid #b5cadc;-webkit-border-top-left-radius:5px;-webkit-border-bottom-left-radius:5px;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-top-left-radius:5px;border-bottom-left-radius:5px;border-top-right-radius:0;border-bottom-right-radius:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_slider_box .webix_slider_right{height:10px;float:left;width:100px;background:#fff;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:5px;-webkit-border-bottom-right-radius:5px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:5px;-moz-border-radius-bottomright:5px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:5px;border-bottom-right-radius:5px;border:1px solid #b5cadc;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_forminput legend{color:#1e2022;line-height:30px;padding:2px 7.5px 2px 2px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Verdana;float:left}
|
||||
.webix_slider_box{position:relative;padding:13px 10px 0;height:100%;float:left;border-radius:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:-11px}
|
||||
.webix_slider_box .webix_slider_left{height:10px;float:left;width:100px;border:1px solid #b5cadc;-webkit-border-radius:5px 0 0 5px;-moz-border-radius-topleft:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;border-radius:5px 0 0 5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_slider_box .webix_slider_right{height:10px;float:left;width:100px;background:#fff;-webkit-border-radius:0 5px 5px 0;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:5px;-moz-border-radius-bottomright:5px;border-radius:0 5px 5px 0;border:1px solid #b5cadc;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.webix_slider_box .webix_slider_handle{z-index:1;position:absolute;width:14px;height:14px;border-radius:8px}
|
||||
.webix_slider_box .webix_slider_left{background:#f5f9ff}
|
||||
.webix_slider_box .webix_slider_handle{border:1px solid #a4bed4;-moz-box-shadow:inset 0 1px 1px 1px #fff;-webkit-box-shadow:inset 0 1px 1px 1px #fff;box-shadow:inset 0 1px 1px #fff;background:#fafcff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#d6e8ff),color-stop(100%,#fafcff));background-image:-webkit-linear-gradient(#d6e8ff,#fafcff);background-image:-moz-linear-gradient(#d6e8ff,#fafcff);background-image:-ms-linear-gradient(top,#d6e8ff,#fafcff);background-image:-o-linear-gradient(top,#d6e8ff,#fafcff);top:10px}
|
||||
.webix_slider_box .webix_slider_handle{border:1px solid #a4bed4;-moz-box-shadow:inset 0 1px 1px 1px #fff;-webkit-box-shadow:inset 0 1px 1px 1px #fff;box-shadow:inset 0 1px 1px #fff;background:#fafcff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#d6e8ff),color-stop(100%,#fafcff));background:-webkit-linear-gradient(#d6e8ff,#fafcff);background:-moz-linear-gradient(#d6e8ff,#fafcff);background:-ms-linear-gradient(top,#d6e8ff,#fafcff);background:-o-linear-gradient(top,#d6e8ff,#fafcff);top:10px}
|
||||
.webix_rangeslider .webix_slider_box .webix_slider_left{position:absolute}
|
||||
.webix_rangeslider .webix_slider_box .webix_slider_active{z-index:1}
|
||||
.webix_rangeslider .webix_slider_box .webix_slider_right{border-radius:5px}
|
||||
.webix_rangeslider .webix_slider_title_box{position:relative;float:left;width:1px}
|
||||
.webix_rangeslider .webix_slider_title.webix_slider_move{position:absolute}
|
||||
.webix_rangeslider.webix_slider_vertical .webix_slider_box .webix_slider_right{-webkit-border-top-left-radius:5px;-webkit-border-bottom-left-radius:5px;-webkit-border-top-right-radius:5px;-webkit-border-bottom-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-topright:5px;-moz-border-radius-bottomright:5px;border-top-left-radius:5px;border-bottom-left-radius:5px;border-top-right-radius:5px;border-bottom-right-radius:5px}
|
||||
.webix_rangeslider.webix_slider_vertical .webix_slider_title.webix_slider_move{display:block;position:relative}
|
||||
.webix_slider_alt .webix_slider_box .webix_slider_left,.webix_slider_alt .webix_slider_box .webix_slider_right{border:1px solid #e1e1e1}
|
||||
.webix_slider_alt .webix_slider_box .webix_slider_handle{width:11px;margin:0 2px;height:14px;border-radius:2px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTJCMjdFNENBRTg4MTFFMjk2NjJGMTJENjkyNDA2NTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTJCMjdFNERBRTg4MTFFMjk2NjJGMTJENjkyNDA2NTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5MkIyN0U0QUFFODgxMUUyOTY2MkYxMkQ2OTI0MDY1OSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5MkIyN0U0QkFFODgxMUUyOTY2MkYxMkQ2OTI0MDY1OSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Powz/icAAAAaSURBVHjaYmBgYDBjgAA4zcSABQysIECAAQBn+ACx2PqtbAAAAABJRU5ErkJggg==);background-repeat:no-repeat;background-position:3px center}
|
||||
.webix_slider_alt .webix_slider_box .webix_slider_left{background:#f0f6ff}
|
||||
.webix_slider_alt .webix_slider_box .webix_slider_right{background:#eee}
|
||||
.webix_slider_alt .webix_slider_box .webix_slider_handle{background-color:#f5f9ff;top:10px}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_left,.webix_slider_vertical .webix_slider_box .webix_slider_right{width:10px;float:none}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_left{-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:5px;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:5px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:5px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:5px;border-top-left-radius:0;border-bottom-left-radius:5px;border-top-right-radius:0;border-bottom-right-radius:5px}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_right{-webkit-border-top-left-radius:5px;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:5px;-webkit-border-bottom-right-radius:0;-moz-border-radius-topleft:5px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:5px;-moz-border-radius-bottomright:0;border-top-left-radius:5px;border-bottom-left-radius:0;border-top-right-radius:5px;border-bottom-right-radius:0}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_left{-webkit-border-radius:0 0 5px 5px;-moz-border-radius-topleft:0;-moz-border-radius-bottomleft:5px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:5px;border-radius:0 0 5px 5px}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_right{-webkit-border-radius:5px 5px 0 0;-moz-border-radius-topleft:5px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:5px;-moz-border-radius-bottomright:0;border-radius:5px 5px 0 0}
|
||||
.webix_slider_vertical .webix_slider_box .webix_slider_handle{left:7px}
|
||||
.webix_slider_vertical .webix_slider_title{padding-top:1px;text-align:left}
|
||||
.webix_slider_vertical.webix_slider_alt .webix_slider_handle{height:11px;width:14px;left:5px;background-position:4px center}
|
||||
.webix_slider_title{text-align:center}
|
||||
.webix_slider_title.webix_slider_move{position:relative;text-align:left;display:inline-block;width:auto;white-space:nowrap}
|
||||
.webix_el_box .webix_switch_box{margin-top:4px}
|
||||
.webix_switch_toggle{position:absolute;visibility:hidden}
|
||||
.webix_switch_box{display:block;position:relative;cursor:pointer;height:24px;width:60px;background-color:#f1f1f1;border:1px solid #a4bed4;border-radius:60px;box-sizing:border-box;transition:background-color .4s ease;color:#666;text-align:center;float:left}
|
||||
.webix_el_switch .webix_label_right{display:inline-block;padding-top:3px;margin-top:4px}
|
||||
.webix_switch_handle{height:22px;width:22px;border-radius:100%;box-shadow:0 1px 5px rgba(0,0,0,.3);border:1px solid #eee;position:absolute;top:0;background-color:#fff;transition:left .3s ease;cursor:pointer;box-sizing:border-box}
|
||||
.webix_switch_box:active .webix_switch_handle,.webix_switch_handle:focus{box-shadow:0 0 2px 2px rgba(0,0,0,.2)}
|
||||
.webix_switch_text{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;padding:1px 0 0 18px;display:inline-block;box-sizing:border-box;width:100%}
|
||||
.webix_switch_on .webix_switch_text{padding:1px 18px 0 0}
|
||||
.webix_switch_box.webix_switch_on{color:#fff}
|
||||
.webix_slider_title.webix_slider_move{position:relative;text-align:left;display:inline-block;width:auto}
|
||||
.webix_progress_bottom,.webix_progress_top{width:100%;position:absolute;top:0;left:0;height:6px;overflow:hidden;z-index:20}
|
||||
.webix_progress_bottom{bottom:0;top:auto;height:17px}
|
||||
.webix_progress_bottom .webix_progress_state,.webix_progress_top .webix_progress_state{width:0;height:6px;background:#ffdb8f;-moz-transition:width 3s;transition:width 3s}
|
||||
|
@ -578,7 +562,7 @@ label.webix_required:after,legend.webix_required:after{padding-left:4px;content:
|
|||
.webix_gage{height:100%;width:100%;transform:rotate(180deg)}
|
||||
.webix_gage_label{font-size:.9em;text-align:center;margin-top:10px}
|
||||
.webix_gage_placeholder{margin-top:-20px}
|
||||
.webix_gage_info{text-align:center;font-size:.7em;position:relative;margin:0 auto 10px auto}
|
||||
.webix_gage_info{text-align:center;font-size:.7em;position:relative;margin:0 auto 10px}
|
||||
.webix_gage_min_range{left:-74px}
|
||||
.webix_gage_max_range{right:-74px}
|
||||
.webix_gage_max_range,.webix_gage_min_range{display:inline-block;margin-top:20px;position:absolute;text-align:center;width:150px}
|
||||
|
@ -587,190 +571,22 @@ label.webix_required:after,legend.webix_required:after{padding-left:4px;content:
|
|||
.webix_gage_gradient_point_animated{transition:transform 1.3s linear}
|
||||
.webix_gage_animated{stroke:#0f0;animation:gage_dash 1.3s linear forwards;transition:stroke 1.3s linear,stroke-dasharray 1.3s linear}
|
||||
.webix_gage_animated_first_load{stroke:#0f0;animation:gage_dash 1.3s linear forwards;transition:stroke 1.3s linear}
|
||||
@keyframes gage_dash{to{stroke-dashoffset:0}
|
||||
}
|
||||
@keyframes gage_dash{to{stroke-dashoffset:0}}
|
||||
.webix_bullet_name{width:100}
|
||||
.webix_bullet_header{font-weight:700;font-size:15px}
|
||||
.webix_bullet_subheader{font-size:15px}
|
||||
.webix_bullet_scale{font-size:12px;font-weight:700}
|
||||
.webix_organogram canvas{position:absolute}
|
||||
.webix_organogram_item{position:absolute;z-index:1;text-align:center;border-radius:4px;background-color:#e3f2fd;border:1px solid #bbdefb;padding:7px 7px 10px 7px;box-sizing:border-box}
|
||||
.webix_organogram_item{position:absolute;z-index:1;text-align:center;border-radius:4px;background-color:#e3f2fd;border:1px solid #bbdefb;padding:7px 7px 10px;box-sizing:border-box}
|
||||
.webix_organogram_item.webix_selected{background-color:#ffdb8f;border-color:#ffdb8f}
|
||||
.webix_organogram_list{border-radius:4px;position:absolute;z-index:1;height:auto;border:1px solid #ddd;box-sizing:border-box}
|
||||
.webix_organogram_list .webix_organogram_list_item{border:none;text-align:left;position:static;padding:5px;border-radius:0;box-sizing:border-box}
|
||||
.webix_icon,.webix_icon_btn,.webix_input_icon{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}
|
||||
.webix_icon,.webix_input_icon{font-size:17px;display:inline-block;width:20px}
|
||||
.webix_input_icon{float:right;font-size:19px;color:#888}
|
||||
.webix_icon_button{background-color:transparent;border:none;padding:0;cursor:pointer;position:relative}
|
||||
.webix_icon_button .webix_icon{font-size:20px;height:23px;width:21px;display:inline-block;text-align:center;color:#606060}
|
||||
.webix_icon_btn{font-size:17px;display:inline-block;text-align:center;width:24px;color:#606060}
|
||||
.webix_el_iconBbutton .webix_icon_btn{text-align:center;width:100%;padding:5px 0}
|
||||
.webix_el_icon{cursor:pointer}
|
||||
.webix_badge{background-color:#ff8839;color:#fff;border-radius:50%;font-size:12px;height:22px;min-width:22px;box-sizing:border-box;padding:0 4px;text-align:center;line-height:21px;position:absolute;right:0;top:0}
|
||||
.webix_list_item .webix_badge{position:static;float:right;margin:4px -5px 0 10px}
|
||||
.webixtype_base .webix_badge{top:50%;margin-top:-11px;margin-right:8px}
|
||||
.webix_treemap{background-color:#f5f5f5}
|
||||
.webix_treemap .webix_scroll_cont{position:relative;height:100%;width:100%}
|
||||
.webix_treemap_item{position:absolute;color:#444;overflow:hidden;text-align:left;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:3px 5px;border-width:0 1px 1px 0;border-style:solid;border-color:rgba(0,0,0,.2);background:0 0;cursor:pointer}
|
||||
.webix_treemap_level_top{z-index:1;border-color:rgba(0,0,0,.4)}
|
||||
.webix_treemap_item_bottom{border-bottom-width:0}
|
||||
.webix_treemap_item_right{border-right-width:0}
|
||||
.webix_treemap_item:hover{box-shadow:inset 0 0 5px #666}
|
||||
.webix_treemap_item.webix_selected{border-color:#ffdb8f;box-shadow:inset 0 0 1px 2px #ffdb8f}
|
||||
.webix_treemap_header{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 10px;border-bottom:1px solid #a4bed4}
|
||||
.webix_treemap_header_item{cursor:pointer}
|
||||
.webix_treemap_header_item:last-child{cursor:default}
|
||||
.webix_treemap_reset{float:right;width:25px;text-align:center}
|
||||
.webix_treemap_reset:before{content:"\f00d";color:#1e2022;font-family:FontAwesome;font-size:16px;display:block;cursor:pointer}
|
||||
.webix_treemap_path_icon{width:20px;text-align:center}
|
||||
.webix_barcode{position:relative}
|
||||
.webix_barcode .webix_canvas_text{font-size:13px;padding:0 2px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.portlet_drag{position:absolute;z-index:1;top:5px;right:5px;width:18px;opacity:.5;cursor:pointer}
|
||||
.portlet_in_drag{opacity:.4}
|
||||
.portlet_marker,.portlet_markerbottom,.portlet_markerleft,.portlet_markerright,.portlet_markertop{opacity:.5;background:#9169BE;position:absolute;z-index:2;transition:top .5s,left .5s,width .5s,height .5s;top:0;left:0;width:100%;height:100%}
|
||||
.portlet_markertop{height:50%}
|
||||
.portlet_markerbottom{height:50%;top:50%}
|
||||
.portlet_markerleft{width:50%}
|
||||
.portlet_markerright{width:50%;left:50%}
|
||||
.panel_icon{position:absolute;z-index:100;top:5px;right:5px;line-height:normal;font-size:13px;width:18px;opacity:.5;cursor:pointer}
|
||||
.panel_target{position:absolute;background:rgba(120,120,120,.84);box-shadow:0 0 10px 5px #666;z-index:3}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_left{border-width:0 1px 0 0;box-shadow:2px 0 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_left.webix_animate{transition:left .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_right{left:auto;border-width:0 0 0 1px;box-shadow:-2px 0 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_right.webix_animate{transition:right .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_top{border-width:0 0 1px 0;box-shadow:0 2px 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_top .webix_win_body{position:relative}
|
||||
.webix_sidemenu_top .webix_win_body>.webix_view{position:absolute;top:auto;left:0;bottom:0}
|
||||
.webix_sidemenu_top.webix_animate,.webix_sidemenu_top.webix_animate .webix_win_body{transition:height .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_bottom{border-width:1px 0 0 0;top:auto;box-shadow:0 -2px 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_bottom.webix_animate,.webix_sidemenu_bottom.webix_animate .webix_win_body{transition:height .6s}
|
||||
.webix_sidebar{background:#ECEFF1}
|
||||
.webix_sidebar .webix_tree_item{color:#454545;height:35px;line-height:35px}
|
||||
.webix_sidebar .webix_scroll_cont>.webix_tree_leaves{padding:0}
|
||||
.webix_sidebar .webix_tree_leaves .webix_tree_leaves{margin-left:0}
|
||||
.webix_sidebar_expanded .webix_tree_item:hover,.webix_sidebar_selected{background-color:rgba(0,0,0,.02)}
|
||||
.webix_sidebar .webix_tree_item.webix_selected,.webix_sidebar .webix_tree_item.webix_selected span{background-color:#27ae60;padding-right:0}
|
||||
.webix_sidebar .webix_tree_branch_1 .webix_tree_item{padding-left:40px}
|
||||
.webix_sidebar .webix_tree_branch_1>.webix_tree_item{height:40px;line-height:40px;padding-left:0}
|
||||
.webix_sidebar .webix_tree_branch_1{border-bottom:1px solid #e5e5e5}
|
||||
.webix_sidebar .webix_tree_item span,.webix_sidebar .webix_tree_item.webix_selected span{margin:0;padding:0}
|
||||
.webix_sidebar_icon{width:40px;text-align:center}
|
||||
.webix_sidebar_dir_icon{float:right;line-height:inherit}
|
||||
.webix_sidebar_popup{border:none!important;box-shadow:2px 3px 3px #ddd}
|
||||
.webix_sidebar_popup,.webix_sidebar_popup .webix_list_item{border-radius:0}
|
||||
.webix_sidebar_popup_right{box-shadow:-1px 3px 3px #ddd}
|
||||
.webix_sidebar_popup_list.webix_sidebar_popup_left .webix_icon{float:right;line-height:inherit;width:7px}
|
||||
.webix_sidebar_popup_title{background:#ECEFF1}
|
||||
.webix_sidebar_popup_title.webix_selected{border-left-color:#27ae60;background:#27ae60}
|
||||
.webix_sidebar_popup_title .webix_template{line-height:40px;padding:0 10px;border:1px solid #E5E5E5;border-left:none}
|
||||
.webix_sidebar_selected.webix_sidebar_popup_title .webix_template{background:rgba(0,0,0,.03);border-left:none}
|
||||
.webix_sidebar_popup_list .webix_list_item{border-left:1px solid #E5E5E5;border-right:1px solid #E5E5E5}
|
||||
.webix_sidebar_popup_list .webix_list_item:first-child{border-top:1px solid #E5E5E5}
|
||||
.webix_sidebar_popup_list .webix_list_item:hover{background:#f6f9fb}
|
||||
.webix_sidebar_popup_list .webix_list_item.webix_selected:hover{background:#27ae60}
|
||||
.webix_menu .webix_list_item.webix_sidebar_selected{background:rgba(0,0,0,.02)}
|
||||
.webix_menu .webix_list_item.webix_sidebar_selected:hover{background:rgba(0,0,0,.02)!important}
|
||||
.webix_view.webix_pdf{background-color:#404040;overflow:auto;-webkit-overflow-scrolling:touch}
|
||||
.webix_pdf .canvas_wrapper{margin:0 auto;box-shadow:5px 5px 15px #1c1c1c;width:100%;height:100%}
|
||||
.webix_toolbar.pdf_bar{background-color:#474747}
|
||||
.webix_toolbar.pdf_bar .webix_icon_btn{font-size:15px}
|
||||
.webix_toolbar.pdf_bar .webix_img_btn:focus,.webix_toolbar.pdf_bar .webix_img_btn:hover{background-color:#404040}
|
||||
.webix_toolbar.pdf_bar .webix_template{background-color:#3498db;color:#fff;line-height:2em}
|
||||
.webix_toolbar.pdf_bar .webix_el_box input,.webix_toolbar.pdf_bar .webix_inp_static{background-color:#5c5c5c;color:#fff;border-color:#404040}
|
||||
.webix_toolbar.pdf_bar .webix_el_box input:focus,.webix_toolbar.pdf_bar .webix_inp_static:focus{border-color:#333}
|
||||
.webix_toolbar.pdf_bar .webix_el_box .webix_input_icon{color:#fff}
|
||||
.webix_view.webix_popup.pdf_opt_list{box-shadow:5px 5px 15px #1c1c1c;border:none}
|
||||
.pdf_opt_list .webix_list{background-color:#404040;color:#fff}
|
||||
.pdf_opt_list .webix_list .webix_list_item{border-color:#474747;line-height:1.5em}
|
||||
.pdf_opt_list .webix_list .webix_list_item.webix_selected,.pdf_opt_list .webix_list .webix_list_item:hover{color:#404040;background-color:#fff}
|
||||
.webix_dbllist .webix_list{background:#ededed}
|
||||
.webix_dbllist .webix_list_item{background:#fff;margin:3px 4px 0 4px;box-sizing:border-box}
|
||||
.webix_dbllist .webix_list_item.webix_selected{color:#FFF;background:#27ae60}
|
||||
.webix_dbllist button{width:45%;height:30px;margin-top:5px;background:#fff;border-radius:6px;border:1px solid #a4bed4;cursor:pointer;font-size:13px;font-family:Helvetica,Verdana}
|
||||
.webix_dbllist button:active{box-shadow:inset 1px 1px 0 silver}
|
||||
.webix_dbllist button .webix_icon{color:#888;font-size:26px}
|
||||
.webix_dbllist button:first-child{margin-top:32px;margin-right:5%}
|
||||
.webix_dbllist button:last-child{margin-left:5%}
|
||||
.webix_dbllist .bottom_label{font-size:10px;text-transform:uppercase;background:#ededed;padding-left:13px}
|
||||
.webix_invalid .webix_list{background:#f8e2e2}
|
||||
.webix_toolbar .webix_el_label,.webix_toolbar .webix_inp_label{color:#1e2022}
|
||||
.webix_ss_sort_asc{position:absolute;float:right;right:3px;top:8px;width:7px;height:13px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR4nGNgQAKGxib/GbABkIS7b8B/DAUwCRiGK0CXwFBAb1DfP/U/LszwHwi2X7qFgUEArBtdAVwCBmAKMCSQFSDzAWXXaOHsXeqkAAAAAElFTkSuQmCC)}
|
||||
.webix_ss_sort_desc{position:absolute;right:3px;top:8px;width:7px;height:13px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR42mNgQAL1/VP/M2ADIIntF2/9x1AAlrh0C47hCmA60DFYwX88gIFGwNDY5D8uDFbg7hvwHx2jmIBTAlkB0e4BAEjlaNtBWJPnAAAAAElFTkSuQmCC)}
|
||||
.webix_group_back .webix_arrow_icon{color:#1e2022}
|
||||
.webix_menu-x .webix_list_item:active,.webix_menu-x .webix_list_item:focus,.webix_menu-x .webix_list_item:hover{background-color:rgba(255,255,255,.4)!important}
|
||||
.webix_menu .webix_list_item:active,.webix_menu .webix_list_item:hover{background-color:rgba(0,0,0,.05)!important}
|
||||
.webix_list_item .webix_submenu_icon{width:0;height:0;border-width:4px;border-style:solid}
|
||||
.webix_menu-x .webix_list_item .webix_submenu_icon{border-color:#375975 transparent transparent transparent}
|
||||
.webix_menu .webix_list_item .webix_submenu_icon{border-color:transparent transparent transparent #375975}
|
||||
.webix_popup_title{color:#1e2022!important;background:#e3e3e3!important;font-size:15px!important;font-weight:700;border-bottom:1px solid #dedede!important;text-shadow:none!important}
|
||||
.webix_modal_box{background:#ebebeb!important;border:1px solid #a4bed4!important}
|
||||
.confirmButton{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.confirmButtonActive{background:#fff}
|
||||
.webix_item_tab{font-size:13px}
|
||||
.buttonStyle{font-size:13px;font-family:Helvetica,Verdana}
|
||||
.activeShadow{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}
|
||||
.webix_img_btn_abs:active+input,.webix_inp_counter_next:active,.webix_inp_counter_prev:active,.webixtype_base:active{background:#f5f5f5;box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-repeat:none}
|
||||
.webix_icon_button:active,.webix_img_btn:active,.webix_img_btn_top:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-color:rgba(0,0,0,.05)}
|
||||
.webix_pressed .webix_img_btn_abs+input,.webix_pressed .webixtype_base{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background:#f5f5f5!important}
|
||||
.webix_slider_vertical .webix_slider_box{margin-top:-8px}
|
||||
.webix_rangeslider .webix_slider_title_box{height:17px}
|
||||
.webix_switch_box.webix_switch_on{background-color:#a4bed4}
|
||||
.webix_switch_text{line-height:21px}
|
||||
.webix_accordionitem_label .webix_icon{font-size:19px;width:25px}
|
||||
.webix_accordionitem.vertical>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAARUlEQVR42o2PAQYAMAwD9+iEFvTpnZYZU7EQRa4kaxKAXD9y9yTZluCBALRJpATNrIG6rAdjjmBVeCuB6EyAYkNEiDE33yMJRSaycR8/AAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.vertical.collapsed>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAASElEQVR42n2PMQoAMAgD++gEdPLpFkshS9oDEcxlcA1V1euNcpI9k5m2MPfrqABCBS8KBptAR8QJZks0kGjgjMQn/oc/AKy4Acp9RSZl+HEYAAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAASUlEQVR42p2QMQoAQQgD79EZ0Mqn5xCu2cPdYgUbJ0rMMxXgLeiuKq8gsJAz8weQ0QiwJEfECnr4wdlEnwJ68+yyhReC+c85oRecj0Um+pmo9wAAAABJRU5ErkJggg==);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal:last-child>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAARElEQVR42qXPsQoAIAhF0T76PdDJT7cUmtQhcmk4N8QVQ9JXN2bmgWOgqp+BiCRG2AYAMoi3/LxYdyagAnhA6G93TrABZaJFJjrFY8IAAAAASUVORK5CYII=);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal.collapsed:last-child>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAASElEQVR42n2PMQoAMAgD++gEdPLpFkshS9oDEcxlcA1V1euNcpI9k5m2MPfrqABCBS8KBptAR8QJZks0kGjgjMQn/oc/AKy4Acp9RSZl+HEYAAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal.collapsed>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAARUlEQVR42o2PAQYAMAwD9+iEFvTpnZYZU7EQRa4kaxKAXD9y9yTZluCBALRJpATNrIG6rAdjjmBVeCuB6EyAYkNEiDE33yMJRSaycR8/AAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_progress_bottom,.webix_progress_top{background:#f7f7f7;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f2f2f2),color-stop(50%,#f7f7f7),color-stop(100%,#f2f2f2));background-image:-webkit-linear-gradient(top,#f2f2f2 0,#f7f7f7 50%,#f2f2f2 100%);background-image:-moz-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%);background-image:-ms-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%);background-image:-o-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%);background-position:0 1px;background-repeat:repeat-x}
|
||||
.webix_daterange .webix_range_timepicker .webix_cal_time{padding:5px 15px}
|
||||
.webix_daterange .webix_range_footer .webix_template{padding:10px 0}
|
||||
.webix_cal_range{background-color:#fff4dc}
|
||||
.webix_item_tab .webix_icon{width:30px;font-size:19px}
|
||||
.webix_tab_more_icon{border-bottom:1px solid #a4bed4}
|
||||
.webix_skin_mark{height:110px}
|
||||
.webix_sparklines{padding:1px 0;box-sizing:border-box}
|
||||
.webix_sparklines svg{box-sizing:border-box}
|
||||
.webix_sparklines_line{stroke:#3498db;stroke-width:1;fill:transparent;stroke-linecap:round}
|
||||
.webix_sparklines_item{fill:#3498db;stroke-width:1}
|
||||
.webix_sparklines_bar{fill:#6dbcf0}
|
||||
.webix_sparklines_bar_negative{fill:#d86c79}
|
||||
.webix_sparklines_area{fill:#e5eef4}
|
||||
.webix_sparklines_origin{stroke:#888;stroke-width:1}
|
||||
.webix_sparklines_event_area{fill:transparent}
|
||||
.webix_sparklines_area_chart .webix_sparklines_event_area:hover,.webix_sparklines_line_chart .webix_sparklines_event_area:hover,.webix_sparklines_splinearea_chart .webix_sparklines_event_area:hover{fill:rgba(220,220,220,.4);stroke:rgba(255,255,255,.6)}
|
||||
.webix_sparklines_bar_chart .webix_sparklines_event_area:hover,.webix_sparklines_pie_chart .webix_sparklines_event_area:hover{fill:rgba(255,255,255,.3)}
|
||||
.webix_ui_print{display:none}
|
||||
body.webix_print{margin-top:0}
|
||||
@media print{body.webix_print{overflow:visible!important;background-color:none!important}
|
||||
body.webix_print>*{display:none}
|
||||
body.webix_print *{visibility:hidden}
|
||||
.webix_ui_print{display:block!important;margin:0!important;visibility:visible!important}
|
||||
.webix_ui_print *{visibility:visible!important}
|
||||
.webix_print_noscroll{height:auto!important;width:auto!important}
|
||||
.webix_print_noscroll,.webix_print_noscroll .webix_scroll_cont{overflow:visible!important}
|
||||
.webix_print_pagebreak{page-break-after:always}
|
||||
.webix_print_footer,.webix_print_header{display:block!important;margin:20px 0;text-align:center;height:auto!important;visibility:visible!important}
|
||||
.webix_print_footer *,.webix_print_header *{visibility:visible!important}
|
||||
.webix_table_print{display:table;visibility:visible!important;table-layout:fixed;width:100%;border:1px solid #ebebeb;margin-bottom:20px;position:initial}
|
||||
.webix_table_print td{overflow:hidden}
|
||||
.webix_table_print tr{page-break-inside:avoid}
|
||||
.webix_table_print .webix_cell{display:table-cell!important;border-right:1px solid #ebebeb;border-bottom:1px solid #ebebeb;padding:0 10px;white-space:nowrap}
|
||||
.webix_table_print .webix_header_cell{display:table-cell;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:#e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff));background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-position:0 1px;background-repeat:repeat-x;border-right:1px solid #a4bed4;border-bottom:1px solid #a4bed4}
|
||||
.webix_table_print .webix_footer_cell{display:table-cell;background:#fafafa;border-right:1px solid #ebebeb;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb}
|
||||
.webix_table_print .webix_cell.webix_dtable_span{position:initial!important;white-space:normal}
|
||||
.webix_table_print .webix_rotate{transform-origin:center 40%!important;-webkit-transform-origin:center 40%!important}
|
||||
.webix_table_print.borderless,.webix_table_print.borderless .webix_cell{border:none}
|
||||
.webix_table_print.webix_view.webix_list-x{white-space:normal}
|
||||
.webix_table_print.webix_view.webix_list-x .webix_list_item{display:table-cell}
|
||||
}
|
||||
/*!
|
||||
* Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
*/
|
||||
@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.7.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont.woff2?v=4.7.0) format('woff2'),url(../fonts/fontawesome-webfont.woff?v=4.7.0) format('woff'),url(../fonts/fontawesome-webfont.ttf?v=4.7.0) format('truetype'),url(../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}
|
||||
.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}
|
||||
.fa,.webix_icon,.webix_icon_btn,.webix_input_icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}
|
||||
.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}
|
||||
.fa-2x{font-size:2em}
|
||||
.fa-3x{font-size:3em}
|
||||
|
@ -781,7 +597,7 @@ body.webix_print *{visibility:hidden}
|
|||
.fa-ul>li{position:relative}
|
||||
.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}
|
||||
.fa-li.fa-lg{left:-1.85714286em}
|
||||
.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}
|
||||
.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}
|
||||
.fa-pull-left{float:left}
|
||||
.fa-pull-right{float:right}
|
||||
.fa.fa-pull-left{margin-right:.3em}
|
||||
|
@ -793,11 +609,9 @@ body.webix_print *{visibility:hidden}
|
|||
.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}
|
||||
.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}
|
||||
@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}
|
||||
100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}
|
||||
}
|
||||
100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}
|
||||
@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}
|
||||
100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}
|
||||
}
|
||||
100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}
|
||||
.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}
|
||||
.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}
|
||||
.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}
|
||||
|
@ -1486,6 +1300,140 @@ body.webix_print *{visibility:hidden}
|
|||
.fa-meetup:before{content:"\f2e0"}
|
||||
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;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}
|
||||
.webix_icon,.webix_input_icon{font-size:17px;display:inline-block;width:20px}
|
||||
.webix_input_icon{float:right;font-size:19px;color:#888}
|
||||
.webix_icon_button{background-color:transparent;border:none;padding:0;cursor:pointer;position:relative}
|
||||
.webix_icon_button .webix_icon{font-size:20px;height:23px;width:21px;display:inline-block;text-align:center;color:#606060}
|
||||
.webix_icon_btn{font-size:17px;display:inline-block;text-align:center;width:24px;color:#606060}
|
||||
.webix_el_iconBbutton .webix_icon_btn{text-align:center;width:100%;padding:5px 0}
|
||||
.webix_el_icon{cursor:pointer}
|
||||
.webix_badge{background-color:#ff8839;color:#fff;border-radius:50%;font-size:12px;height:22px;min-width:22px;box-sizing:border-box;padding:0 4px;text-align:center;line-height:21px;position:absolute;right:0;top:0}
|
||||
.webix_list_item .webix_badge{position:static;float:right;margin:4px -5px 0 10px}
|
||||
.webixtype_base .webix_badge{top:50%;margin-top:-11px;margin-right:8px}
|
||||
.webix_treemap{background-color:#f5f5f5}
|
||||
.webix_treemap .webix_scroll_cont{position:relative;height:100%;width:100%}
|
||||
.webix_treemap_item{position:absolute;color:#444;overflow:hidden;text-align:left;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:3px 5px;border-width:0 1px 1px 0;border-style:solid;border-color:rgba(0,0,0,.2);background:0 0}
|
||||
.webix_treemap_level_top{z-index:1;border-color:rgba(0,0,0,.4)}
|
||||
.webix_treemap_item_bottom{border-bottom-width:0}
|
||||
.webix_treemap_item_right{border-right-width:0}
|
||||
.webix_treemap_item:hover{box-shadow:inset 0 0 5px #666}
|
||||
.webix_treemap_item.webix_selected{border-color:#ffdb8f;box-shadow:inset 0 0 1px 2px #ffdb8f}
|
||||
.webix_treemap_header{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 10px;border-bottom:1px solid #a4bed4}
|
||||
.webix_treemap_header_item{cursor:pointer}
|
||||
.webix_treemap_header_item:last-child{cursor:default}
|
||||
.webix_treemap_reset{float:right;width:25px;text-align:center}
|
||||
.webix_treemap_reset:before{content:"\f00d";color:#1e2022;font-family:FontAwesome;font-size:16px;display:block;cursor:pointer}
|
||||
.webix_treemap_path_icon{width:20px;text-align:center}
|
||||
.webix_barcode{position:relative}
|
||||
.webix_barcode .webix_canvas_text{font-size:13px;padding:0 2px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
.portlet_drag{position:absolute;z-index:1;top:5px;right:5px;width:18px;opacity:.5;cursor:pointer}
|
||||
.portlet_in_drag{opacity:.4}
|
||||
.portlet_marker,.portlet_markerbottom,.portlet_markerleft,.portlet_markerright,.portlet_markertop{opacity:.5;background:#9169BE;position:absolute;transition:top .5s,left .5s,width .5s,height .5s;top:0;left:0;width:100%;height:100%}
|
||||
.portlet_markertop{height:50%}
|
||||
.portlet_markerbottom{height:50%;top:50%}
|
||||
.portlet_markerleft{width:50%}
|
||||
.portlet_markerright{width:50%;left:50%}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_left{border-width:0 1px 0 0;box-shadow:2px 0 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_left.webix_animate{transition:left .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_right{left:auto;border-width:0 0 0 1px;box-shadow:-2px 0 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_right.webix_animate{transition:right .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_top{border-width:0 0 1px;box-shadow:0 2px 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_top .webix_win_body{position:relative}
|
||||
.webix_sidemenu_top .webix_win_body>.webix_view{position:absolute;top:auto;left:0;bottom:0}
|
||||
.webix_sidemenu_top.webix_animate,.webix_sidemenu_top.webix_animate .webix_win_body{transition:height .6s}
|
||||
.webix_popup.webix_sidemenu.webix_sidemenu_bottom{border-width:1px 0 0;top:auto;box-shadow:0 -2px 2px rgba(0,0,0,.05)}
|
||||
.webix_sidemenu_bottom.webix_animate,.webix_sidemenu_bottom.webix_animate .webix_win_body{transition:height .6s}
|
||||
.webix_view.webix_pdf{background-color:#404040;overflow:auto;-webkit-overflow-scrolling:touch}
|
||||
.webix_pdf .canvas_wrapper{margin:0 auto;box-shadow:5px 5px 15px #1c1c1c;width:100%;height:100%}
|
||||
.webix_toolbar.pdf_bar{background-color:#474747}
|
||||
.webix_toolbar.pdf_bar .webix_icon_btn{font-size:15px}
|
||||
.webix_toolbar.pdf_bar .webix_img_btn:focus,.webix_toolbar.pdf_bar .webix_img_btn:hover{background-color:#404040}
|
||||
.webix_toolbar.pdf_bar .webix_template{background-color:#3498db;color:#fff;line-height:2em}
|
||||
.webix_toolbar.pdf_bar .webix_el_box input,.webix_toolbar.pdf_bar .webix_inp_static{background-color:#5c5c5c;color:#fff;border-color:#404040}
|
||||
.webix_toolbar.pdf_bar .webix_el_box input:focus,.webix_toolbar.pdf_bar .webix_inp_static:focus{border-color:#333}
|
||||
.webix_toolbar.pdf_bar .webix_el_box .webix_input_icon{color:#fff}
|
||||
.webix_view.webix_popup.pdf_opt_list{box-shadow:5px 5px 15px #1c1c1c;border:none}
|
||||
.pdf_opt_list .webix_list{background-color:#404040;color:#fff}
|
||||
.pdf_opt_list .webix_list .webix_list_item{border-color:#474747;line-height:1.5em}
|
||||
.pdf_opt_list .webix_list .webix_list_item.webix_selected,.pdf_opt_list .webix_list .webix_list_item:hover{color:#404040;background-color:#fff}
|
||||
.webix_dbllist .webix_list{background:#ededed}
|
||||
.webix_dbllist .webix_list_item{background:#fff;margin:3px 4px 0;box-sizing:border-box}
|
||||
.webix_dbllist .webix_list_item.webix_selected{color:#FFF;background:#27ae60}
|
||||
.webix_dbllist button{width:45%;height:30px;margin-top:5px;background:#fff;border-radius:6px;border:1px solid #a4bed4;cursor:pointer;font-size:13px;font-family:Helvetica,Verdana}
|
||||
.webix_dbllist button:active{box-shadow:inset 1px 1px 0 silver}
|
||||
.webix_dbllist button .webix_icon{color:#888;font-size:26px}
|
||||
.webix_dbllist button:first-child{margin-top:32px;margin-right:5%}
|
||||
.webix_dbllist button:last-child{margin-left:5%}
|
||||
.webix_dbllist .bottom_label{font-size:10px;text-transform:uppercase;background:#ededed;padding-left:13px}
|
||||
.webix_invalid .webix_list{background:#f8e2e2}
|
||||
.webix_toolbar .webix_el_label,.webix_toolbar .webix_inp_label{color:#1e2022}
|
||||
.webix_ss_sort_asc{position:absolute;float:right;right:3px;top:8px;width:7px;height:13px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR4nGNgQAKGxib/GbABkIS7b8B/DAUwCRiGK0CXwFBAb1DfP/U/LszwHwi2X7qFgUEArBtdAVwCBmAKMCSQFSDzAWXXaOHsXeqkAAAAAElFTkSuQmCC)}
|
||||
.webix_ss_sort_desc{position:absolute;right:3px;top:8px;width:7px;height:13px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAANCAYAAABlyXS1AAAARUlEQVR42mNgQAL1/VP/M2ADIIntF2/9x1AAlrh0C47hCmA60DFYwX88gIFGwNDY5D8uDFbg7hvwHx2jmIBTAlkB0e4BAEjlaNtBWJPnAAAAAElFTkSuQmCC)}
|
||||
.webix_group_back .webix_arrow_icon{color:#1e2022}
|
||||
.webix_menu-x .webix_list_item:active,.webix_menu-x .webix_list_item:focus,.webix_menu-x .webix_list_item:hover{background-color:rgba(255,255,255,.4)!important}
|
||||
.webix_menu .webix_list_item:active,.webix_menu .webix_list_item:hover{background-color:rgba(0,0,0,.05)!important}
|
||||
.webix_list_item .webix_submenu_icon{width:0;height:0;border-width:4px;border-style:solid}
|
||||
.webix_menu-x .webix_list_item .webix_submenu_icon{border-color:#375975 transparent transparent}
|
||||
.webix_menu .webix_list_item .webix_submenu_icon{border-color:transparent transparent transparent #375975}
|
||||
.webix_popup_title{color:#1e2022!important;background:#e3e3e3!important;font-size:15px!important;font-weight:700;border-bottom:1px solid #dedede!important;text-shadow:none!important}
|
||||
.webix_modal_box{background:#ebebeb!important;border:1px solid #a4bed4!important}
|
||||
.confirmButton{color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%)}
|
||||
.confirmButtonActive{background:#fff}
|
||||
.webix_item_tab{font-size:13px}
|
||||
.buttonStyle{font-size:13px;font-family:Helvetica,Verdana}
|
||||
.activeShadow{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}
|
||||
.webix_img_btn_abs:active+input,.webix_inp_counter_next:active,.webix_inp_counter_prev:active,.webixtype_base:active{background:none #f5f5f5;box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}
|
||||
.webix_icon_button:active,.webix_img_btn:active,.webix_img_btn_top:active{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background-color:rgba(0,0,0,.05)}
|
||||
.webix_pressed .webix_img_btn_abs+input,.webix_pressed .webixtype_base{box-shadow:inset 0 3px 5px rgba(0,0,0,.125);background:#f5f5f5!important}
|
||||
.webix_slider_vertical .webix_slider_box{margin-top:-8px}
|
||||
.webix_accordionitem_label .webix_icon{font-size:19px;width:25px}
|
||||
.webix_accordionitem.vertical>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAARUlEQVR42o2PAQYAMAwD9+iEFvTpnZYZU7EQRa4kaxKAXD9y9yTZluCBALRJpATNrIG6rAdjjmBVeCuB6EyAYkNEiDE33yMJRSaycR8/AAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.vertical.collapsed>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAASElEQVR42n2PMQoAMAgD++gEdPLpFkshS9oDEcxlcA1V1euNcpI9k5m2MPfrqABCBS8KBptAR8QJZks0kGjgjMQn/oc/AKy4Acp9RSZl+HEYAAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAASUlEQVR42p2QMQoAQQgD79EZ0Mqn5xCu2cPdYgUbJ0rMMxXgLeiuKq8gsJAz8weQ0QiwJEfECnr4wdlEnwJ68+yyhReC+c85oRecj0Um+pmo9wAAAABJRU5ErkJggg==);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal:last-child>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAALCAYAAACzkJeoAAAARElEQVR42qXPsQoAIAhF0T76PdDJT7cUmtQhcmk4N8QVQ9JXN2bmgWOgqp+BiCRG2AYAMoi3/LxYdyagAnhA6G93TrABZaJFJjrFY8IAAAAASUVORK5CYII=);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal.collapsed:last-child>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAASElEQVR42n2PMQoAMAgD++gEdPLpFkshS9oDEcxlcA1V1euNcpI9k5m2MPfrqABCBS8KBptAR8QJZks0kGjgjMQn/oc/AKy4Acp9RSZl+HEYAAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_accordionitem.horizontal.collapsed>.webix_accordionitem_header .webix_accordionitem_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAARUlEQVR42o2PAQYAMAwD9+iEFvTpnZYZU7EQRa4kaxKAXD9y9yTZluCBALRJpATNrIG6rAdjjmBVeCuB6EyAYkNEiDE33yMJRSaycR8/AAAAAElFTkSuQmCC);background-repeat:no-repeat}
|
||||
.webix_progress_bottom,.webix_progress_top{background:0 1px repeat-x #f7f7f7;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f2f2f2),color-stop(50%,#f7f7f7),color-stop(100%,#f2f2f2)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#f2f2f2 0,#f7f7f7 50%,#f2f2f2 100%);background-image:-moz-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%);background-image:-ms-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%);background-image:-o-linear-gradient(top,#f2f2f2 0,#f7f7f7 60%,#f2f2f2 100%)}
|
||||
.webix_daterange .webix_range_timepicker .webix_cal_time{padding:5px 15px}
|
||||
.webix_daterange .webix_range_footer .webix_template{padding:10px 0}
|
||||
.webix_cal_range{background-color:#fff4dc}
|
||||
.webix_item_tab .webix_icon{width:30px;font-size:19px}
|
||||
.webix_tab_more_icon{border-bottom:1px solid #a4bed4}
|
||||
.webix_skin_mark{height:110px}
|
||||
.webix_sparklines{padding:1px 0;box-sizing:border-box}
|
||||
.webix_sparklines svg{box-sizing:border-box}
|
||||
.webix_sparklines_line{stroke:#3498db;stroke-width:1;fill:transparent;stroke-linecap:round}
|
||||
.webix_sparklines_item{fill:#3498db;stroke-width:1}
|
||||
.webix_sparklines_bar{fill:#6dbcf0}
|
||||
.webix_sparklines_bar_negative{fill:#d86c79}
|
||||
.webix_sparklines_area{fill:#e5eef4}
|
||||
.webix_sparklines_origin{stroke:#888;stroke-width:1}
|
||||
.webix_sparklines_event_area{fill:transparent}
|
||||
.webix_sparklines_area_chart .webix_sparklines_event_area:hover,.webix_sparklines_line_chart .webix_sparklines_event_area:hover,.webix_sparklines_splinearea_chart .webix_sparklines_event_area:hover{fill:rgba(220,220,220,.4);stroke:rgba(255,255,255,.6)}
|
||||
.webix_sparklines_bar_chart .webix_sparklines_event_area:hover,.webix_sparklines_pie_chart .webix_sparklines_event_area:hover{fill:rgba(255,255,255,.3)}
|
||||
.webix_ui_print{display:none}
|
||||
body.webix_print{margin-top:0}
|
||||
@media print{body.webix_print{overflow:visible!important;background-color:none!important}
|
||||
body.webix_print>*{display:none}
|
||||
body.webix_print *{visibility:hidden}
|
||||
.webix_ui_print{display:block!important;margin:0!important;visibility:visible!important}
|
||||
.webix_ui_print *{visibility:visible!important}
|
||||
.webix_print_noscroll{height:auto!important;width:auto!important}
|
||||
.webix_print_noscroll,.webix_print_noscroll .webix_scroll_cont{overflow:visible!important}
|
||||
.webix_print_pagebreak{page-break-after:always}
|
||||
.webix_print_footer,.webix_print_header{display:block!important;margin:20px 0;text-align:center;height:auto!important;visibility:visible!important}
|
||||
.webix_print_footer *,.webix_print_header *{visibility:visible!important}
|
||||
.webix_table_print{display:table;visibility:visible!important;table-layout:fixed;width:100%;border:1px solid #ebebeb;margin-bottom:20px;position:initial}
|
||||
.webix_table_print td{overflow:hidden}
|
||||
.webix_table_print tr{page-break-inside:avoid}
|
||||
.webix_table_print .webix_cell{display:table-cell!important;border-right:1px solid #ebebeb;border-bottom:1px solid #ebebeb;padding:0 10px;white-space:nowrap}
|
||||
.webix_table_print .webix_header_cell{display:table-cell;color:#1e2022!important;box-shadow:0 1px 1px #fff inset;background:0 1px repeat-x #e5f1ff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#eaf3ff),color-stop(50%,#e5f1ff),color-stop(100%,#d6e8ff)) 0 1px repeat-x;background-image:-webkit-linear-gradient(top,#eaf3ff 0,#e5f1ff 50%,#d6e8ff 100%);background-image:-moz-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-ms-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);background-image:-o-linear-gradient(top,#eaf3ff 0,#e5f1ff 60%,#d6e8ff 100%);border-right:1px solid #a4bed4;border-bottom:1px solid #a4bed4}
|
||||
.webix_table_print .webix_footer_cell{display:table-cell;background:#fafafa;border-right:1px solid #ebebeb;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb}
|
||||
.webix_table_print .webix_cell.webix_dtable_span{position:initial!important;white-space:normal}
|
||||
.webix_table_print .webix_rotate{transform-origin:center 40%!important;-webkit-transform-origin:center 40%!important}
|
||||
.webix_table_print.borderless,.webix_table_print.borderless .webix_cell{border:none}
|
||||
.webix_table_print.webix_view.webix_list-x{white-space:normal}
|
||||
.webix_table_print.webix_view.webix_list-x .webix_list_item{display:table-cell}}
|
||||
.webix_strong{font-weight:700;white-space:nowrap}
|
||||
.webix_light{color:#666d73}
|
||||
.webix_debug div{border:1px solid orange;background-color:#FF9;color:#000}
|
||||
|
|
|
@ -24,43 +24,12 @@
|
|||
font-size: 125%;
|
||||
color: DarkRed;
|
||||
}
|
||||
.right_footer2 {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 150%;
|
||||
color: DarkRed;
|
||||
}
|
||||
.right_footer3 {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
color: DarkBlue;
|
||||
}
|
||||
.footer3 {
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
color: DarkBlue;
|
||||
}
|
||||
|
||||
.lbl_partner {
|
||||
font-weight: bold;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
.link_default {
|
||||
font-weight: bold;
|
||||
color: #610B0B;
|
||||
text-decoration: none;
|
||||
}
|
||||
.link_default:hover {text-decoration:underline;}
|
||||
|
||||
.link_forum {
|
||||
font-weight: bold;
|
||||
color: #610B0B;
|
||||
text-decoration: none;
|
||||
}
|
||||
.link_forum:hover {text-decoration:underline;}
|
||||
|
||||
.delete {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
@ -68,10 +37,6 @@
|
|||
color: red;
|
||||
}
|
||||
|
||||
.cancel {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
.cmd_close_partner div button {
|
||||
background-color: red !important;
|
||||
|
@ -91,28 +56,6 @@
|
|||
|
||||
.webix_success div {
|
||||
background-color: #00a65a !important;
|
||||
font-weight: bold;
|
||||
font-size: 1.5vw;
|
||||
font-size: 1vw;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.webix_error div {
|
||||
background-color: #DF0101 !important;
|
||||
font-weight: bold;
|
||||
font-size: 1.5vw;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table_sg .webix_hcell{
|
||||
background: #A64C4C;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
.table_sg .webix_column{
|
||||
font-style: italic;
|
||||
background: #FFF8DC;
|
||||
}
|
||||
.table_sg .webix_column > div{
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
|
|
@ -1,519 +0,0 @@
|
|||
@page{
|
||||
size: Letter;
|
||||
margin: 0.5cm;
|
||||
background-color: white !important;
|
||||
}
|
||||
|
||||
|
||||
@media print {
|
||||
thead {display: table-header-group;}
|
||||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.emisor-cintilla{
|
||||
background-color: #975759;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fiscales-emisor{
|
||||
color: #7d1916;
|
||||
}
|
||||
|
||||
.fiscales-emisor .telefono, .fiscales-emisor .correo, .fiscales-emisor .web{
|
||||
color: #333;
|
||||
}
|
||||
|
||||
header .titulo-vertical{
|
||||
background-color: #dbc5c6;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.receptor .nombre{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.receptor .rfc{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.receptor .direccion{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.receptor .estado{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.cfdi .folio span{
|
||||
color: #ed483d;
|
||||
}
|
||||
|
||||
.cfdi .tipo span{
|
||||
color: #ed483d;
|
||||
}
|
||||
|
||||
.cfdi .folio-fiscal span{
|
||||
color: #ed483d;
|
||||
}
|
||||
|
||||
.conceptos th{
|
||||
background-color: #975759;
|
||||
}
|
||||
|
||||
.conceptos td.clave, .conceptos td.unidad, .conceptos td.valor-unitario{
|
||||
background-color: #dbc5c6;
|
||||
}
|
||||
|
||||
.conceptos td.descripcion, .conceptos td.cantidad, .conceptos td.importe{
|
||||
background-color: #f0e7e7;
|
||||
}
|
||||
|
||||
table.subtotal th{
|
||||
background-color: #dbc5c6;
|
||||
}
|
||||
|
||||
table.subtotal td{
|
||||
background-color: #f0e7e7;
|
||||
}
|
||||
|
||||
.sello .cadenas-sello .cadena div {
|
||||
background-color: #dbc5c6;
|
||||
color: #7d1916;
|
||||
}
|
||||
|
||||
.rfc-pac {
|
||||
background-color: #dbc5c6;
|
||||
color: #7d1916;
|
||||
}
|
||||
|
||||
.cancelada{
|
||||
color: #ed3833;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Avenir Next';
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.eot');
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.woff2') format('woff2'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.woff') format('woff'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.ttf') format('truetype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Regular.svg#AvenirNextLTPro-Regular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Avenir Next';
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.eot');
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.woff2') format('woff2'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.woff') format('woff'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.ttf') format('truetype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-Bold.svg#AvenirNextLTPro-Bold') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Avenir Next';
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-It.eot');
|
||||
src: url('/static/fonts/avenir_next/AvenirNextLTPro-It.eot?#iefix') format('embedded-opentype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-It.woff2') format('woff2'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-It.woff') format('woff'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-It.ttf') format('truetype'),
|
||||
url('/static/fonts/avenir_next/AvenirNextLTPro-It.svg#AvenirNextLTPro-It') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
/*
|
||||
font-family: 'Avenir Next';
|
||||
*/
|
||||
}
|
||||
|
||||
#plantilla {
|
||||
border: 1px solid #fff;
|
||||
border-color: rgb(204,204,204);
|
||||
background: #fff;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 19.5cm;
|
||||
height: 25.9cm;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cancelada{
|
||||
-ms-transform: rotate(320deg);
|
||||
-webkit-transform: rotate(320deg);
|
||||
transform: rotate(320deg);
|
||||
color: #ed3833;
|
||||
font-size: 100px;
|
||||
font-weight: bold;
|
||||
left: 18%;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 30%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.cancelada div{
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.emisor-cintilla{
|
||||
background-color: #975759;
|
||||
color: #fff;
|
||||
font-size: 7pt;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.datos-emisor .logo{
|
||||
margin-left: 20px;
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
.datos-emisor .fiscales-emisor{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.fiscales-emisor{
|
||||
color: #7d1916;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fiscales-emisor .nombre{
|
||||
font-size: 18px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.fiscales-emisor .rfc{
|
||||
font-size: 16px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.fiscales-emisor .regimen{
|
||||
font-size: 12px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.fiscales-emisor .telefono, .fiscales-emisor .correo, .fiscales-emisor .web{
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
line-height: 15px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.fiscales-emisor img{
|
||||
margin-left: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.clear{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
header .titulo-vertical{
|
||||
background-color: #dbc5c6;
|
||||
-ms-transform: rotate(270deg);
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
left: -31px;
|
||||
line-height: 35px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 35px;
|
||||
width: 105px;
|
||||
}
|
||||
|
||||
header .receptor{
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
height: 106px;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 45px;
|
||||
padding-top: 5px;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.receptor .nombre{
|
||||
color: #000;
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.receptor .rfc{
|
||||
color: #000;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.receptor .direccion,
|
||||
.receptor .estado{
|
||||
color: #000;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.receptor img{
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.receptor .correo,
|
||||
.receptor .telefono{
|
||||
float: right;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.receptor .uso-cfdi{
|
||||
color: #000;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
header .cfdi{
|
||||
box-sizing: border-box;
|
||||
float: right;
|
||||
font-size: 10px;
|
||||
height: 100px;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 45px;
|
||||
padding-top: 5px;
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.cfdi .folio, .cfdi .tipo{
|
||||
color: #000;
|
||||
float: left;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.cfdi .folio span, .cfdi .tipo span{
|
||||
color: #ed483d;
|
||||
}
|
||||
|
||||
.cfdi .folio span{
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.cfdi .tipo span{
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.cfdi .folio-fiscal{
|
||||
color: #000;
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cfdi .folio-fiscal span{
|
||||
color: #ed483d;
|
||||
}
|
||||
|
||||
.cfdi .fecha-emision, .cfdi .fecha-certificacion, .cfdi .lugar-expedicion{
|
||||
color: #333;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.conceptos{
|
||||
margin-bottom: 10px;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.conceptos th{
|
||||
background-color: #975759;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.conceptos .clave{
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.conceptos .descripcion{
|
||||
width: 45%;
|
||||
}
|
||||
.conceptos .descripcion div{
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.conceptos .unidad{
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
.conceptos .cantidad{
|
||||
width: 9%;
|
||||
}
|
||||
|
||||
.conceptos .valor-unitario{
|
||||
width: 13%;
|
||||
}
|
||||
|
||||
.conceptos .importe{
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
.conceptos td{
|
||||
background-color: #975759;
|
||||
color: #000;
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.conceptos td.clave, .conceptos td.unidad, .conceptos td.valor-unitario{
|
||||
background-color: #dbc5c6;
|
||||
}
|
||||
|
||||
.conceptos td.descripcion, .conceptos td.cantidad, .conceptos td.importe{
|
||||
background-color: #f0e7e7;
|
||||
}
|
||||
|
||||
.conceptos td.valor-unitario, .conceptos td.importe{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.total-letras{
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
margin: 5px 0;
|
||||
width: 63%;
|
||||
}
|
||||
|
||||
table.subtotal{
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
text-align: right;
|
||||
width: 37%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.subtotal th{
|
||||
background-color: #f0e7e7;
|
||||
width: 60%;
|
||||
padding: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
table.subtotal td{
|
||||
background-color: #dbc5c6;
|
||||
width: 40%;
|
||||
padding: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
.condiciones-pago{
|
||||
font-size: 11px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.notas{
|
||||
float: left;
|
||||
font-size: 11px;
|
||||
margin: 20px 0;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.formapago-metodopago, .moneda-tipocambio, .tiporelacion, .relacionados{
|
||||
float: left;
|
||||
font-size: 11px;
|
||||
line-height: 12px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.factura-info{
|
||||
float: left;
|
||||
font-size: 11px;
|
||||
line-height: 13px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.tipocomite, .tipoproceso, .idcontabilidad{
|
||||
float: right;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.sello{
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.sello .cbb{
|
||||
border: 1px solid #000;
|
||||
height: auto;
|
||||
margin-top: 10px;
|
||||
margin-right: 1px;
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.sello .cadenas-sello{
|
||||
color: #000;
|
||||
float: right;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
width: 79%;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.sello .cadenas-sello .cadena{
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.sello .cadenas-sello .cadena div{
|
||||
font-weight: normal;
|
||||
background-color: #dbc5c6;
|
||||
color: #7d1916;
|
||||
}
|
||||
|
||||
.cadena-original{
|
||||
color: #000;
|
||||
float: right;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
line-height: 15px;
|
||||
width: 99%;
|
||||
margin: 5px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.cadena-original div{
|
||||
font-weight: normal;
|
||||
background-color: #dbc5c6;
|
||||
color: #7d1916;
|
||||
}
|
||||
|
||||
.rfc-pac{
|
||||
background-color: #dbc5c6;
|
||||
color: #7d1916;
|
||||
font-size: 10px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
/* SideBar*/
|
||||
.webix_sidebar{
|
||||
background: #ECEFF1;
|
||||
}
|
||||
.webix_sidebar .webix_tree_item {
|
||||
color: #454545;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
.webix_sidebar .webix_scroll_cont > .webix_tree_leaves {
|
||||
padding: 0;
|
||||
}
|
||||
.webix_sidebar .webix_tree_leaves .webix_tree_leaves {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.webix_sidebar_selected,
|
||||
.webix_sidebar_expanded .webix_tree_item:hover{
|
||||
background-color: rgba(0,0,0,0.02);
|
||||
}
|
||||
.webix_sidebar .webix_tree_item.webix_selected,
|
||||
.webix_sidebar .webix_tree_item.webix_selected span{
|
||||
background-color: #27ae60;
|
||||
padding-right:0;
|
||||
}
|
||||
.webix_sidebar .webix_tree_branch_1 .webix_tree_item{
|
||||
padding-left:40px;
|
||||
}
|
||||
.webix_sidebar .webix_tree_branch_1>.webix_tree_item{
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left:0;
|
||||
}
|
||||
.webix_sidebar .webix_tree_branch_1{
|
||||
border-bottom:1px solid #e5e5e5;
|
||||
}
|
||||
.webix_sidebar .webix_tree_item.webix_selected span,
|
||||
.webix_sidebar .webix_tree_item span{
|
||||
margin:0;
|
||||
padding:0px;
|
||||
}
|
||||
.webix_sidebar_icon{
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.webix_sidebar_dir_icon{
|
||||
float: right;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/*SubMenu (Popup) */
|
||||
.webix_sidebar_popup{
|
||||
border:none !important;
|
||||
box-shadow: 2px 3px 3px #ddd;
|
||||
}
|
||||
.webix_sidebar_popup, .webix_sidebar_popup .webix_list_item{
|
||||
border-radius:0;
|
||||
}
|
||||
.webix_sidebar_popup_right{
|
||||
box-shadow: -1px 3px 3px #ddd;
|
||||
}
|
||||
/*SubMenu: title*/
|
||||
.webix_sidebar_popup_title{
|
||||
background: #ECEFF1;
|
||||
}
|
||||
.webix_sidebar_popup_title.webix_selected{
|
||||
border-left-color: #27ae60;
|
||||
background: #27ae60;
|
||||
}
|
||||
.webix_sidebar_popup_title .webix_template{
|
||||
line-height: 40px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #E5E5E5;
|
||||
border-left:none;
|
||||
}
|
||||
.webix_sidebar_selected.webix_sidebar_popup_title .webix_template{
|
||||
background: rgba(0,0,0,0.03);
|
||||
border-left: none;
|
||||
}
|
||||
.webix_sidebar_popup_list .webix_list_item{
|
||||
border-left: 1px solid #E5E5E5;
|
||||
border-right: 1px solid #E5E5E5;
|
||||
}
|
||||
/*SubMenu: list*/
|
||||
.webix_sidebar_popup_list .webix_list_item:first-child{
|
||||
border-top: 1px solid #E5E5E5;
|
||||
}
|
||||
.webix_sidebar_popup_list .webix_list_item:hover{
|
||||
background: #f6f9fb;
|
||||
}
|
||||
|
||||
.webix_sidebar_popup_list .webix_list_item.webix_selected:hover{
|
||||
background: #27ae60;
|
||||
}
|
Before Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 191 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,87 +1,57 @@
|
|||
var gi = null
|
||||
|
||||
|
||||
function configuracion_inicial(){
|
||||
webix.ajax().get('/values/admin', function(text, data){
|
||||
var values = data.json()
|
||||
show('cmd_ir_al_admin', values)
|
||||
})
|
||||
webix.ajax().sync().get('/values/main', function(text, data){
|
||||
var values = data.json()
|
||||
$$('lbl_title_main').setValue(values.empresa)
|
||||
var pos = 4
|
||||
if(values.escuela){
|
||||
var node = {
|
||||
id: 'app_school',
|
||||
icon: 'graduation-cap',
|
||||
value: 'Escuela'}
|
||||
$$('main_sidebar').add(node, pos)
|
||||
pos += 1
|
||||
}
|
||||
if(values.nomina){
|
||||
var node = {
|
||||
id: 'app_nomina',
|
||||
icon: 'users',
|
||||
value: 'Nómina'}
|
||||
$$('main_sidebar').add(node, pos)
|
||||
pos += 1
|
||||
}
|
||||
if(values.punto_de_venta){
|
||||
var node = {
|
||||
id: 'app_tickets',
|
||||
icon: 'money',
|
||||
value: 'Punto de venta'}
|
||||
$$('main_sidebar').add(node, pos)
|
||||
}
|
||||
|
||||
$$('cmd_update_timbres').define('badge', values.timbres)
|
||||
$$('cmd_update_timbres').refresh()
|
||||
add_config({'key': 'decimales_precios', 'value': values.decimales_precios})
|
||||
add_config({'key': 'used_cfdi_pays', 'value': values.pagos})
|
||||
add_config({'key': 'multi_currency', 'value': values.multi_currency})
|
||||
add_config({'key': 'pays_data_bank', 'value': values.pays_data_bank})
|
||||
add_config({'key': 'show_filter_by_day', 'value': values.show_filter_by_day})
|
||||
|
||||
})
|
||||
|
||||
get_way_payment()
|
||||
|
||||
}
|
||||
|
||||
|
||||
function cmd_ir_al_admin_click(){
|
||||
window.location = '/admin'
|
||||
}
|
||||
|
||||
|
||||
var controllers = {
|
||||
init: function(){
|
||||
//~ Main
|
||||
$$('menu_user').attachEvent('onMenuItemClick', menu_user_click);
|
||||
configuracion_inicial()
|
||||
|
||||
var tb_invoice = $$('tv_invoice').getTabbar()
|
||||
tb_invoice.attachEvent('onChange', tb_invoice_change)
|
||||
$$('prefilter_year').attachEvent('onChange', prefilter_year_change)
|
||||
$$('prefilter_month').attachEvent('onChange', prefilter_month_change)
|
||||
$$('cmd_delete_preinvoice').attachEvent('onItemClick', cmd_delete_preinvoice_click)
|
||||
$$('cmd_facturar_preinvoice').attachEvent('onItemClick', cmd_facturar_preinvoice_click)
|
||||
$$('cmd_update_timbres').attachEvent('onItemClick', cmd_update_timbres_click)
|
||||
$$('grid_preinvoices').attachEvent('onItemClick', grid_preinvoices_click)
|
||||
|
||||
partners_controllers.init()
|
||||
products_controllers.init()
|
||||
bancos_controllers.init()
|
||||
invoices_controllers.init()
|
||||
controllers_school.init()
|
||||
nomina_controllers.init()
|
||||
tickets_controllers.init()
|
||||
//~ Partner
|
||||
$$('cmd_new_partner').attachEvent('onItemClick', cmd_new_partner_click);
|
||||
$$('cmd_new_contact').attachEvent('onItemClick', cmd_new_contact_click);
|
||||
$$('cmd_edit_partner').attachEvent('onItemClick', cmd_edit_partner_click);
|
||||
$$('cmd_delete_partner').attachEvent('onItemClick', cmd_delete_partner_click);
|
||||
$$('cmd_save_partner').attachEvent('onItemClick', cmd_save_partner_click);
|
||||
$$('cmd_cancel_partner').attachEvent('onItemClick', cmd_cancel_partner_click);
|
||||
$$('cmd_cancel_contact').attachEvent('onItemClick', cmd_cancel_contact_click);
|
||||
$$('codigo_postal').attachEvent('onKeyPress', postal_code_key_press);
|
||||
$$('codigo_postal').attachEvent('onTimedKeyPress', postal_code_key_up);
|
||||
$$('colonia').attachEvent('onFocus', colonia_on_focus)
|
||||
$$("tipo_persona").attachEvent( "onChange", opt_tipo_change)
|
||||
$$("es_cliente").attachEvent( "onChange", is_client_change)
|
||||
$$("es_proveedor").attachEvent( "onChange", is_supplier_change)
|
||||
$$("rfc").attachEvent( "onBlur", rfc_lost_focus)
|
||||
$$('multi').attachEvent('onViewChange', multi_change)
|
||||
//~ Products
|
||||
$$("cmd_new_product").attachEvent("onItemClick", cmd_new_product_click)
|
||||
$$("cmd_edit_product").attachEvent("onItemClick", cmd_edit_product_click)
|
||||
$$("cmd_delete_product").attachEvent("onItemClick", cmd_delete_product_click)
|
||||
$$("cmd_save_product").attachEvent("onItemClick", cmd_save_product_click)
|
||||
$$("cmd_cancel_product").attachEvent("onItemClick", cmd_cancel_product_click)
|
||||
$$("chk_automatica").attachEvent("onChange", chk_automatica_change)
|
||||
$$("valor_unitario").attachEvent("onChange", valor_unitario_change)
|
||||
//~ Invoices
|
||||
$$('cmd_new_invoice').attachEvent("onItemClick", cmd_new_invoice_click)
|
||||
$$('cmd_refacturar').attachEvent("onItemClick", cmd_refacturar_click)
|
||||
$$('cmd_delete_invoice').attachEvent("onItemClick", cmd_delete_invoice_click)
|
||||
$$('cmd_timbrar').attachEvent('onItemClick', cmd_timbrar_click)
|
||||
$$('cmd_close_invoice').attachEvent('onItemClick', cmd_close_invoice_click)
|
||||
$$('search_client_id').attachEvent('onKeyPress', search_client_id_key_press)
|
||||
$$('grid_clients_found').attachEvent('onValueSuggest', grid_clients_found_click)
|
||||
$$('search_product_id').attachEvent('onKeyPress', search_product_id_key_press)
|
||||
$$('grid_products_found').attachEvent('onValueSuggest', grid_products_found_click)
|
||||
$$('grid_details').attachEvent('onItemClick', grid_details_click)
|
||||
$$('grid_details').attachEvent('onHeaderClick', grid_details_header_click)
|
||||
$$('grid_details').attachEvent('onBeforeEditStart', grid_details_before_edit_start)
|
||||
$$('grid_details').attachEvent('onBeforeEditStop', grid_details_before_edit_stop)
|
||||
$$('cmd_invoice_timbrar').attachEvent('onItemClick', cmd_invoice_timbrar_click)
|
||||
$$('cmd_invoice_cancelar').attachEvent('onItemClick', cmd_invoice_cancelar_click)
|
||||
$$('grid_invoices').attachEvent('onItemClick', grid_invoices_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_uso_cfdi_to_table(){
|
||||
webix.ajax().sync().get('/values/usocfdi', function(text, data){
|
||||
function get_uso_cfdi_to_table(args){
|
||||
webix.ajax().sync().get('/values/usocfdi', args, function(text, data){
|
||||
var values = data.json()
|
||||
table_usocfdi.clear()
|
||||
table_usocfdi.insert(values)
|
||||
|
@ -90,18 +60,52 @@ function get_uso_cfdi_to_table(){
|
|||
|
||||
|
||||
function get_partners(){
|
||||
webix.ajax().get('/partners', {}, {
|
||||
webix.ajax().get("/partners", {}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
webix.message({ type:"error", text: "Error al consultar"});
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
$$('grid_partners').clearAll();
|
||||
if (values.data){
|
||||
$$('grid_partners').parse(values.data, 'json');
|
||||
$$("grid_partners").clearAll();
|
||||
if (values.ok){
|
||||
$$("grid_partners").parse(values.rows, 'json');
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function get_products(){
|
||||
var grid = $$('grid_products')
|
||||
webix.ajax().get('/products', {}, {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type: 'error', text: 'Error al consultar'})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json');
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function get_invoices(){
|
||||
var grid = $$('grid_invoices')
|
||||
webix.ajax().get('/invoices', {}, {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type: 'error', text: 'Error al consultar'})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json');
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,41 +117,8 @@ function menu_user_click(id, e, node){
|
|||
}
|
||||
|
||||
|
||||
function current_dates(){
|
||||
var fy = $$('filter_year')
|
||||
var fm = $$('filter_month')
|
||||
var fd = $$('filter_day')
|
||||
var pfy = $$('prefilter_year')
|
||||
var pfm = $$('prefilter_month')
|
||||
var d = new Date()
|
||||
|
||||
fy.blockEvent()
|
||||
fm.blockEvent()
|
||||
fd.blockEvent()
|
||||
pfy.blockEvent()
|
||||
pfm.blockEvent()
|
||||
|
||||
fm.setValue(d.getMonth() + 1)
|
||||
fd.setValue(d.getDate())
|
||||
pfm.setValue(d.getMonth() + 1)
|
||||
webix.ajax().sync().get('/values/filteryears', function(text, data){
|
||||
var values = data.json()
|
||||
fy.getList().parse(values[0])
|
||||
pfy.getList().parse(values[1])
|
||||
fy.setValue(d.getFullYear())
|
||||
pfy.setValue(d.getFullYear())
|
||||
})
|
||||
|
||||
fy.unblockEvent()
|
||||
fm.unblockEvent()
|
||||
fd.unblockEvent()
|
||||
pfy.unblockEvent()
|
||||
pfm.unblockEvent()
|
||||
}
|
||||
|
||||
|
||||
function multi_change(prevID, nextID){
|
||||
|
||||
//~ webix.message(nextID)
|
||||
if(nextID == 'app_partners'){
|
||||
active = $$('multi_partners').getActiveId()
|
||||
if(active == 'partners_home'){
|
||||
|
@ -164,44 +135,10 @@ function multi_change(prevID, nextID){
|
|||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_bancos'){
|
||||
active = $$('multi_bancos').getActiveId()
|
||||
if(active == 'banco_home'){
|
||||
get_cuentas_banco()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_school'){
|
||||
active = $$('multi_school').getActiveId()
|
||||
if(active == 'school_home'){
|
||||
init_config_school()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_nomina'){
|
||||
active = $$('multi_nomina').getActiveId()
|
||||
if(active == 'nomina_home'){
|
||||
default_config_nomina()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_tickets'){
|
||||
active = $$('multi_tickets').getActiveId()
|
||||
if(active == 'tickets_home'){
|
||||
configuracion_inicial_ticket()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_invoices'){
|
||||
active = $$('multi_invoices').getActiveId()
|
||||
if(active == 'invoices_home'){
|
||||
current_dates()
|
||||
get_invoices()
|
||||
validar_timbrar()
|
||||
}
|
||||
gi = $$('grid_invoices')
|
||||
return
|
||||
|
@ -219,12 +156,3 @@ function get_taxes(){
|
|||
$$("grid_product_taxes").parse(values, 'json')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_update_timbres_click(){
|
||||
webix.ajax().get('/values/timbres', function(text, data){
|
||||
var value = data.json()
|
||||
$$('cmd_update_timbres').define('badge', value)
|
||||
$$('cmd_update_timbres').refresh()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,627 +0,0 @@
|
|||
var query = []
|
||||
var cfg_nomina = new Object()
|
||||
|
||||
|
||||
var nomina_controllers = {
|
||||
init: function(){
|
||||
$$('cmd_nomina_import').attachEvent('onItemClick', cmd_nomina_import_click)
|
||||
$$('cmd_empleados').attachEvent('onItemClick', cmd_empleados_click)
|
||||
$$('cmd_close_empleados').attachEvent('onItemClick', cmd_close_empleados_click)
|
||||
$$('cmd_delete_empleado').attachEvent('onItemClick', cmd_delete_empleado_click)
|
||||
$$('cmd_import_empleados').attachEvent('onItemClick', cmd_import_empleados_click)
|
||||
$$('cmd_nomina_without_stamp').attachEvent('onItemClick', cmd_nomina_without_stamp_click)
|
||||
$$('cmd_nomina_delete').attachEvent('onItemClick', cmd_nomina_delete_click)
|
||||
$$('cmd_nomina_timbrar').attachEvent('onItemClick', cmd_nomina_timbrar_click)
|
||||
$$('cmd_nomina_sat').attachEvent('onItemClick', cmd_nomina_sat_click)
|
||||
$$('cmd_nomina_log').attachEvent('onItemClick', cmd_nomina_log_click)
|
||||
$$('cmd_nomina_download').attachEvent('onItemClick', cmd_nomina_download_click)
|
||||
$$('cmd_nomina_cancel').attachEvent('onItemClick', cmd_nomina_cancel_click)
|
||||
$$('grid_nomina').attachEvent('onItemClick', grid_nomina_click)
|
||||
$$('filter_year_nomina').attachEvent('onChange', filter_year_nomina_change)
|
||||
$$('filter_month_nomina').attachEvent('onChange', filter_month_nomina_change)
|
||||
$$('filter_dates_nomina').attachEvent('onChange', filter_dates_nomina_change)
|
||||
$$('grid_nomina').attachEvent('onSelectChange', grid_nomina_on_select_change)
|
||||
webix.extend($$('grid_nomina'), webix.ProgressBar)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function default_config_nomina(){
|
||||
current_dates_nomina()
|
||||
get_nomina()
|
||||
}
|
||||
|
||||
|
||||
function current_dates_nomina(){
|
||||
var fy = $$('filter_year_nomina')
|
||||
var fm = $$('filter_month_nomina')
|
||||
var d = new Date()
|
||||
|
||||
fy.blockEvent()
|
||||
fm.blockEvent()
|
||||
|
||||
fm.setValue(d.getMonth() + 1)
|
||||
webix.ajax().sync().get('/values/filteryearsnomina', function(text, data){
|
||||
var values = data.json()
|
||||
fy.getList().parse(values)
|
||||
fy.setValue(d.getFullYear())
|
||||
})
|
||||
|
||||
fy.unblockEvent()
|
||||
fm.unblockEvent()
|
||||
}
|
||||
|
||||
|
||||
function get_nomina(filters){
|
||||
var grid = $$('grid_nomina')
|
||||
grid.showProgress({type: 'icon'})
|
||||
|
||||
|
||||
webix.ajax().get('/nomina', filters, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok){
|
||||
grid.clearAll();
|
||||
grid.parse(values.rows, 'json');
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_import_click(){
|
||||
win_import_nomina.init()
|
||||
$$('win_import_nomina').show()
|
||||
}
|
||||
|
||||
|
||||
function cmd_import_template_nomina_click(){
|
||||
var form = $$('form_upload_nomina')
|
||||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!$$('lst_upload_nomina').count()){
|
||||
$$('win_import_nomina').close()
|
||||
return
|
||||
}
|
||||
|
||||
if($$('lst_upload_nomina').count() > 1){
|
||||
msg = 'Selecciona solo un archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var template = $$('up_nomina').files.getItem($$('up_nomina').files.getFirstId())
|
||||
|
||||
if(template.type.toLowerCase() != 'ods'){
|
||||
msg = 'Archivo inválido.\n\nSe requiere un archivo ODS'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de importar este archivo?'
|
||||
webix.confirm({
|
||||
title: 'Importar Nómina',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
$$('up_nomina').send()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function up_nomina_upload_complete(response){
|
||||
if(response.status != 'server'){
|
||||
msg = 'Ocurrio un error al subir el archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
msg = 'Archivo subido correctamente.\n\nComenzando importación.'
|
||||
msg_ok(msg)
|
||||
$$('win_import_nomina').close()
|
||||
|
||||
webix.ajax().get('/nomina', {opt: 'import'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al importar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok){
|
||||
msg_ok(values.msg)
|
||||
get_nomina()
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_employees(){
|
||||
webix.ajax().get('/employees', {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok){
|
||||
$$('grid_employees').clearAll();
|
||||
$$('grid_employees').parse(values.rows, 'json');
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_empleados_click(){
|
||||
get_employees()
|
||||
$$('multi_nomina').setValue('nomina_empleados')
|
||||
}
|
||||
|
||||
|
||||
function cmd_close_empleados_click(){
|
||||
$$('multi_nomina').setValue('nomina_home')
|
||||
}
|
||||
|
||||
|
||||
function cmd_import_empleados_click(){
|
||||
win_import_employees.init()
|
||||
$$('win_import_employees').show()
|
||||
}
|
||||
|
||||
function cmd_import_employees_click(){
|
||||
var form = $$('form_upload_employees')
|
||||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!$$('lst_upload_employees').count()){
|
||||
$$('win_import_employees').close()
|
||||
return
|
||||
}
|
||||
|
||||
if($$('lst_upload_employees').count() > 1){
|
||||
msg = 'Selecciona solo un archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var template = $$('up_employees').files.getItem($$('up_employees').files.getFirstId())
|
||||
|
||||
if(template.type.toLowerCase() != 'ods'){
|
||||
msg = 'Archivo inválido.\n\nSe requiere un archivo ODS'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de importar este archivo?'
|
||||
webix.confirm({
|
||||
title: 'Importar Empleados',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
$$('up_employees').send()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function up_employees_upload_complete(response){
|
||||
if(response.status != 'server'){
|
||||
msg = 'Ocurrio un error al subir el archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
msg = 'Archivo subido correctamente.\n\nComenzando importación.'
|
||||
msg_ok(msg)
|
||||
$$('win_import_employees').close()
|
||||
|
||||
webix.ajax().get('/employees', {opt: 'import'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al importar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok){
|
||||
msg_ok(values.msg)
|
||||
get_employees()
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function delete_empleado(id){
|
||||
webix.ajax().del('/employees', {id: id}, function(text, xml, xhr){
|
||||
var msg = 'Empleado eliminado correctamente'
|
||||
if(xhr.status == 200){
|
||||
$$('grid_employees').remove(id);
|
||||
msg_ok(msg)
|
||||
}else{
|
||||
msg = 'El Empleado tiene recibos timbrados'
|
||||
msg_error(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_delete_empleado_click(){
|
||||
var row = $$('grid_employees').getSelectedItem()
|
||||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Empleado'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de eliminar al Empleado?<BR><BR>'
|
||||
msg += row['nombre_completo'] + ' (' + row['rfc'] + ')'
|
||||
msg += '<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER<BR><BR>'
|
||||
webix.confirm({
|
||||
title: 'Eliminar Empleado',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
delete_empleado(row['id'])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_without_stamp_click(){
|
||||
get_nomina()
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_delete_click(){
|
||||
var rows = $$('grid_nomina').getSelectedItem()
|
||||
|
||||
if (rows == undefined){
|
||||
msg = 'Selecciona al menos un registro'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
var ids = []
|
||||
if(Array.isArray(rows)){
|
||||
for(var i in rows){
|
||||
ids.push(rows[i].id)
|
||||
}
|
||||
}else{
|
||||
ids.push(rows.id)
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de eliminar los recibos seleccionado?<BR><BR>'
|
||||
msg += 'ESTA ACCIÓN NO SE PUEDE DESHACER<BR><BR>'
|
||||
msg += 'Solo se eliminan recibos no timbrados'
|
||||
webix.confirm({
|
||||
title: 'Eliminar Nomina',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
delete_nomina(ids)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function delete_nomina(ids){
|
||||
webix.ajax().del('/nomina', {id: ids}, function(text, xml, xhr){
|
||||
var msg = 'Registros eliminados correctamente'
|
||||
if (xhr.status == 200){
|
||||
get_nomina()
|
||||
msg_ok(msg)
|
||||
} else {
|
||||
msg = 'No se pudo eliminar.'
|
||||
msg_error(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_timbrar_click(){
|
||||
get_nomina()
|
||||
|
||||
msg = 'Se enviarán a timbrar todos los recibos sin timbrar<BR><BR>'
|
||||
msg += '¿Estás seguro de continuar?<BR><BR>'
|
||||
webix.confirm({
|
||||
title: 'Enviar a timbrar',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
timbrar_nomina()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function timbrar_nomina(){
|
||||
webix.ajax().get('/nomina', {opt: 'stamp'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al timbrar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if(values.ok){
|
||||
cmd_update_timbres_click()
|
||||
get_nomina()
|
||||
msg_ok(values.msg_ok)
|
||||
}
|
||||
if(values.error){
|
||||
webix.alert({
|
||||
title: 'Error al Timbrar',
|
||||
text: values.msg_error,
|
||||
type: 'alert-error'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function send_mail(row){
|
||||
if(!row.uuid){
|
||||
msg_error('La nómina no esta timbrada')
|
||||
return
|
||||
}
|
||||
var data = {'opt': 'send_mail', 'id': row.id}
|
||||
|
||||
msg = '¿Estás seguro de enviar por correo este Recibo de Nómina?'
|
||||
webix.confirm({
|
||||
title: 'Enviar Recibo de Nómina',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
webix.ajax().post('/nomina', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_nomina_click(id, e, node){
|
||||
var row = this.getItem(id)
|
||||
|
||||
if(id.column == 'xml'){
|
||||
location = '/doc/nomxml/' + row.id
|
||||
}else if(id.column == 'pdf'){
|
||||
window.open('/doc/nompdf/' + row.id, '_blank')
|
||||
}else if(id.column == 'email'){
|
||||
send_mail(row)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function filter_year_nomina_change(nv, ov){
|
||||
var fm = $$('filter_month_nomina')
|
||||
filters = {'opt': 'yearmonth', 'year': nv, 'month': fm.getValue()}
|
||||
get_nomina(filters)
|
||||
}
|
||||
|
||||
|
||||
function filter_month_nomina_change(nv, ov){
|
||||
var fy = $$('filter_year_nomina')
|
||||
filters = {'opt': 'yearmonth', 'year': fy.getValue(), 'month': nv}
|
||||
get_nomina(filters)
|
||||
}
|
||||
|
||||
|
||||
function filter_dates_nomina_change(range){
|
||||
if(range.start != null && range.end != null){
|
||||
filters = {'opt': 'dates', 'range': range}
|
||||
get_nomina(filters)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_cancel_click(){
|
||||
var row = $$('grid_nomina').getSelectedItem()
|
||||
|
||||
if(row == undefined){
|
||||
msg = 'Selecciona un registro'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(Array.isArray(row)){
|
||||
msg = 'Selecciona solo un registro'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(row['estatus'] != 'Timbrado'){
|
||||
msg = 'Solo se pueden cancelar recibos timbrados'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
win_invoice_cancel_nomina.init()
|
||||
$$('win_invoice_cancel_nomina').show()
|
||||
}
|
||||
|
||||
|
||||
function cmd_win_cancel_nomina_close_click(){
|
||||
$$('win_invoice_cancel_nomina').close()
|
||||
}
|
||||
|
||||
|
||||
function cmd_invoice_cancel_nomina_click(){
|
||||
var reason = $$('lst_reasons_cancel').getValue()
|
||||
var uuid = $$('txt_cancel_uuid').getValue()
|
||||
|
||||
if(!reason){
|
||||
msg = 'Selecciona un motivo para esta cancelación'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
if(reason=='01' & !uuid){
|
||||
msg = 'Debes de capturar el UUID que reemplaza a este CFDI'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
$$('win_invoice_cancel_nomina').close()
|
||||
send_cancel_nomina(reason, uuid)
|
||||
}
|
||||
|
||||
|
||||
function send_cancel_nomina(reason, uuid){
|
||||
var grid = $$('grid_nomina')
|
||||
var row = grid.getSelectedItem()
|
||||
var data = new Object()
|
||||
data['opt'] = 'cancel'
|
||||
data['id'] = row.id
|
||||
data['args'] = {reason: reason, uuid: uuid}
|
||||
|
||||
webix.ajax().sync().post('nomina', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
grid.updateItem(row.id, values.row)
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_log_click(){
|
||||
location = '/doc/nomlog/0'
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_download_click(){
|
||||
var grid = $$('grid_nomina')
|
||||
|
||||
if(!grid.count()){
|
||||
msg = 'Sin documentos a descargar'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var ids = []
|
||||
grid.eachRow(function(row){
|
||||
var r = grid.getItem(row)
|
||||
ids.push(r.id)
|
||||
})
|
||||
|
||||
var filters = {'by': 'download', 'ids': ids}
|
||||
|
||||
webix.ajax().response('blob').get('/nomina', filters, function(text, data){
|
||||
webix.html.download(data, 'nomina.zip');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function grid_nomina_on_select_change(){
|
||||
var g = $$('grid_nomina')
|
||||
var rows = g.getSelectedItem(true)
|
||||
var total = 0
|
||||
|
||||
for (i = 0; i < rows.length; i++) {
|
||||
if(typeof(rows[i].total) == 'string'){
|
||||
total += rows[i].total.to_float()
|
||||
}else{
|
||||
total += rows[i].total
|
||||
}
|
||||
}
|
||||
g.getColumnConfig('empleado').footer[0].text = webix.i18n.priceFormat(total)
|
||||
g.refreshColumns()
|
||||
}
|
||||
|
||||
|
||||
function cmd_nomina_sat_click(){
|
||||
var g = $$('grid_nomina')
|
||||
|
||||
if(g.count() == 0){
|
||||
return
|
||||
}
|
||||
|
||||
var row = g.getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un recibo de nómina')
|
||||
return
|
||||
}
|
||||
if (row instanceof Array){
|
||||
msg_error('Selecciona solo un recibo de nómina')
|
||||
return
|
||||
}
|
||||
|
||||
if(!row.uuid){
|
||||
msg_error('La factura no esta timbrada, solo es posible consultar \
|
||||
el estatus en el SAT de facturas timbradas')
|
||||
return
|
||||
}
|
||||
|
||||
var options = {opt: 'status_sat', id: row.id}
|
||||
webix.ajax().get('/nomina', options, function(text, data){
|
||||
var value = data.json()
|
||||
if(value == 'Vigente'){
|
||||
msg_ok(value)
|
||||
}else if(value == 'uncancel'){
|
||||
ask_invoice_uncancel(row.id)
|
||||
}else{
|
||||
msg_error(value)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,101 +1,16 @@
|
|||
//~ Empresa Libre
|
||||
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
//~
|
||||
//~ This program is free software: you can redistribute it and/or modify
|
||||
//~ it under the terms of the GNU General Public License as published by
|
||||
//~ the Free Software Foundation, either version 3 of the License, or
|
||||
//~ (at your option) any later version.
|
||||
//~
|
||||
//~ This program is distributed in the hope that it will be useful,
|
||||
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//~ GNU General Public License for more details.
|
||||
//~
|
||||
//~ You should have received a copy of the GNU General Public License
|
||||
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
var cfg_partners = new Object()
|
||||
|
||||
|
||||
var partners_controllers = {
|
||||
init: function(){
|
||||
$$('cmd_new_partner').attachEvent('onItemClick', cmd_new_partner_click);
|
||||
//~ $$('cmd_new_contact').attachEvent('onItemClick', cmd_new_contact_click);
|
||||
$$('cmd_edit_partner').attachEvent('onItemClick', cmd_edit_partner_click);
|
||||
$$('cmd_delete_partner').attachEvent('onItemClick', cmd_delete_partner_click);
|
||||
$$('cmd_save_partner').attachEvent('onItemClick', cmd_save_partner_click);
|
||||
$$('cmd_cancel_partner').attachEvent('onItemClick', cmd_cancel_partner_click);
|
||||
//~ $$('cmd_cancel_contact').attachEvent('onItemClick', cmd_cancel_contact_click);
|
||||
//~ $$('cmd_partner_zero').attachEvent('onItemClick', cmd_partner_zero_click);
|
||||
$$('codigo_postal').attachEvent('onKeyPress', postal_code_key_press);
|
||||
$$('codigo_postal').attachEvent('onTimedKeyPress', postal_code_key_up);
|
||||
$$('colonia').attachEvent('onFocus', colonia_on_focus)
|
||||
$$("tipo_persona").attachEvent( "onChange", opt_tipo_change)
|
||||
$$("es_cliente").attachEvent( "onChange", is_client_change)
|
||||
$$("es_proveedor").attachEvent( "onChange", is_supplier_change)
|
||||
$$("rfc").attachEvent( "onBlur", rfc_lost_focus)
|
||||
$$('multi').attachEvent('onViewChange', multi_change)
|
||||
$$('grid_partners').attachEvent('onItemDblClick', grid_partners_double_click)
|
||||
//~ $$('grid_partners').attachEvent('onSelectChange', grid_partners_on_select_change)
|
||||
|
||||
$$('partner_balance').attachEvent('onChange', partner_balance_on_change)
|
||||
$$('cmd_partner_add_account_bank').attachEvent('onItemClick', cmd_partner_add_account_bank_click)
|
||||
$$('grid_partner_account_bank').attachEvent('onItemClick', grid_partner_account_bank_click)
|
||||
default_config_partners()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function default_config_partners(){
|
||||
webix.ajax().get('/config', {'fields': 'partners'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
cfg_partners = values
|
||||
//~ show('cmd_partner_zero', cfg_partners['chk_config_change_balance_partner'])
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get_condicion_pago(){
|
||||
webix.ajax().get('/values/condicionespago', {
|
||||
error: function(text, data, xhr) {
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
$$('condicion_pago').define('suggest', values)
|
||||
$$('condicion_pago').refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_new_partner_click(id, e, node){
|
||||
$$('form_partner').clearValidation()
|
||||
$$('form_partner_account_bank').clearValidation()
|
||||
|
||||
$$('form_partner').setValues({
|
||||
id: 0, pais: 'México', tipo_persona: 1, es_activo: true,
|
||||
partner_balance: 0.00})
|
||||
id: 0, pais: 'México', tipo_persona: 1, es_activo: true})
|
||||
$$('forma_pago').getList().load('/values/formapago')
|
||||
get_condicion_pago()
|
||||
$$('grid_partners').clearSelection()
|
||||
$$('multi_partners').setValue('partners_new')
|
||||
$$('tab_partner').setValue('Datos Fiscales')
|
||||
|
||||
get_uso_cfdi_to_table()
|
||||
get_uso_cfdi_to_table({})
|
||||
query = table_usocfdi.chain().find({fisica: true}).data()
|
||||
$$('lst_uso_cfdi_socio').getList().parse(query)
|
||||
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
|
||||
get_partner_banks()
|
||||
get_partner_accounts_bank(0)
|
||||
get_sat_regimenes()
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,39 +20,30 @@ function cmd_new_contact_click(id, e, node){
|
|||
}
|
||||
|
||||
|
||||
function cmd_edit_partner_click(){
|
||||
function cmd_edit_partner_click(id, e, node){
|
||||
var msg = ''
|
||||
var row = $$('grid_partners').getSelectedItem()
|
||||
|
||||
$$('form_partner_account_bank').clearValidation()
|
||||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Socio de Negocio'
|
||||
msg_error(msg)
|
||||
webix.message({type:'error', text: msg})
|
||||
return
|
||||
}
|
||||
get_condicion_pago()
|
||||
|
||||
webix.ajax().get("/partners", {id: row['id']}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error()
|
||||
webix.message({type:"error", text: "Error al consultar"})
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
|
||||
$$('form_partner').clearValidation()
|
||||
$$('form_partner').setValues(values)
|
||||
$$('forma_pago').getList().load('/values/formapago')
|
||||
|
||||
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
|
||||
get_uso_cfdi_to_table()
|
||||
|
||||
get_uso_cfdi_to_table({})
|
||||
if(values.tipo_persona == 1){
|
||||
query = table_usocfdi.chain().find({fisica: true}).data()
|
||||
get_sat_regimenes()
|
||||
}else if(values.tipo_persona == 2){
|
||||
query = table_usocfdi.chain().find({moral: true}).data()
|
||||
get_sat_regimenes(true)
|
||||
}else{
|
||||
query = [{id: 'P01', value: 'Por definir'}]
|
||||
}
|
||||
|
@ -148,17 +54,12 @@ function cmd_edit_partner_click(){
|
|||
if(values.es_proveedor){
|
||||
$$('cuenta_proveedor').enable()
|
||||
}
|
||||
get_partner_accounts_bank(row['id'])
|
||||
pause(250)
|
||||
$$('lst_receptor_regimenes_fiscales').select(values.regimenes)
|
||||
}
|
||||
})
|
||||
|
||||
$$('multi_partners').setValue('partners_new')
|
||||
$$('tab_partner').setValue('Datos Fiscales')
|
||||
get_partner_banks()
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function cmd_delete_partner_click(id, e, node){
|
||||
|
@ -167,7 +68,7 @@ function cmd_delete_partner_click(id, e, node){
|
|||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Cliente o Proveedor'
|
||||
msg_error(msg)
|
||||
webix.message({type:'error', text: msg})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -196,10 +97,10 @@ function delete_partner(id){
|
|||
var msg = 'Socio eliminado correctamente'
|
||||
if (xhr.status == 200){
|
||||
$$('grid_partners').remove(id);
|
||||
msg_ok(msg)
|
||||
webix.message({type: 'success', text: msg})
|
||||
} else {
|
||||
msg = 'No se pudo eliminar. Asegurate de que no tenga documentos relacionados'
|
||||
msg_error(msg)
|
||||
webix.message({type: 'error', text: msg})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -210,27 +111,18 @@ function cmd_save_partner_click(id, e, node){
|
|||
var form = this.getFormView();
|
||||
|
||||
if (!form.validate()) {
|
||||
msg_error(msg)
|
||||
webix.message({type: 'error', text: msg})
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues();
|
||||
|
||||
if(!values.rfc){
|
||||
msg = 'Captura el RFC'
|
||||
if(values.codigo_postal && values.codigo_postal.length != 5){
|
||||
msg = 'Longitud inválida del C.P.'
|
||||
msg_error(msg)
|
||||
$$('tab_partner').setValue('Datos Fiscales')
|
||||
return
|
||||
}
|
||||
|
||||
if(values.tipo_persona != 4){
|
||||
if(values.codigo_postal && values.codigo_postal.length != 5){
|
||||
msg = 'Longitud inválida del C.P.'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!values.es_cliente && !values.es_proveedor){
|
||||
msg = 'Selecciona si es cliente, proveedor o ambos'
|
||||
msg_error(msg)
|
||||
|
@ -238,37 +130,17 @@ function cmd_save_partner_click(id, e, node){
|
|||
return
|
||||
}
|
||||
|
||||
if(values.tipo_persona == 4){
|
||||
if(values.pais && values.pais.length != 3){
|
||||
msg = 'Longitud de país inválida'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var ids_regimenes = $$('lst_receptor_regimenes_fiscales').getSelectedId()
|
||||
if(values.tipo_persona < 3){
|
||||
if(!ids_regimenes){
|
||||
msg = 'Selecciona al menos un Regimen Fiscal'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
values['accounts'] = $$('grid_partner_account_bank').data.getRange()
|
||||
values['regimenes'] = ids_regimenes
|
||||
|
||||
webix.ajax().post('/partners', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico';
|
||||
msg_error(msg)
|
||||
webix.message({type:'error', text:msg});
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
update_grid_partner(values)
|
||||
} else {
|
||||
msg_error(values.msg)
|
||||
webix.message({type:'error', text:values.msg});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -286,7 +158,7 @@ function update_grid_partner(values){
|
|||
$$("grid_partners").updateItem(values.row['id'], values.row)
|
||||
}
|
||||
$$('multi_partners').setValue('partners_home')
|
||||
msg_ok(msg)
|
||||
webix.message({type:'success', text: msg})
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,13 +178,13 @@ function postal_code_key_up(){
|
|||
if( value.length == 5 ){
|
||||
webix.ajax().get('/values/cp', {cp: value}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar el C.P.')
|
||||
webix.message({type:'error', text:'Error al consultar el C.P.'})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.estado == undefined){
|
||||
msg = 'No se encontró el C.P., asegurate de que sea correcto'
|
||||
msg_error(msg)
|
||||
webix.message({type:'error', text:msg})
|
||||
} else {
|
||||
$$('form_partner').setValues({
|
||||
estado: values.estado,
|
||||
|
@ -357,31 +229,20 @@ function opt_tipo_change(new_value, old_value){
|
|||
$$("nombre").define("value", "")
|
||||
$$("pais").define("readonly", true)
|
||||
$$("pais").define("value", PAIS)
|
||||
$$('id_fiscal').define('value', '')
|
||||
show('id_fiscal', new_value == 4)
|
||||
|
||||
$$('lst_receptor_regimenes_fiscales').clearAll()
|
||||
var regimen_616 = {id: 11, value: '[616] Sin obligaciones fiscales'}
|
||||
|
||||
if (new_value == 1 || new_value == 2){
|
||||
$$("rfc").define("value", "")
|
||||
$$("rfc").define("readonly", false)
|
||||
moral = false
|
||||
if(new_value == 2){
|
||||
moral = true
|
||||
}
|
||||
get_sat_regimenes(moral)
|
||||
$$("rfc").define("value", "");
|
||||
$$("rfc").define("readonly", false);
|
||||
} else if (new_value == 3) {
|
||||
$$("rfc").define("value", RFC_PUBLICO)
|
||||
$$("nombre").define("value", PUBLICO)
|
||||
$$("rfc").define("readonly", true)
|
||||
$$('lst_receptor_regimenes_fiscales').parse(regimen_616)
|
||||
$$("rfc").define("value", RFC_PUBLICO);
|
||||
$$("nombre").define("value", PUBLICO);
|
||||
$$("rfc").define("readonly", true);
|
||||
} else if (new_value == 4) {
|
||||
$$("rfc").define("value", RFC_EXTRANJERO)
|
||||
$$("rfc").define("readonly", true)
|
||||
$$("pais").define("readonly", false)
|
||||
$$("pais").define("value", "")
|
||||
$$('lst_receptor_regimenes_fiscales').parse(regimen_616)
|
||||
$$("rfc").define("value", RFC_EXTRANJERO);
|
||||
$$("rfc").define("readonly", true);
|
||||
$$("pais").define("readonly", false);
|
||||
$$("pais").define("value", "");
|
||||
}
|
||||
|
||||
$$("nombre").refresh();
|
||||
|
@ -399,12 +260,10 @@ function opt_tipo_change(new_value, old_value){
|
|||
}else if (new_value == 2){
|
||||
query = table_usocfdi.chain().find({moral: true}).data()
|
||||
}else{
|
||||
query = [{id: 'S01', value: '[S01] Sin efectos fiscales. '}]
|
||||
query = [{id: 'P01', value: 'Por definir'}]
|
||||
}
|
||||
$$('lst_uso_cfdi_socio').getList().parse(query)
|
||||
$$('lst_uso_cfdi_socio').refresh()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,9 +280,9 @@ function is_client_change(new_value, old_value){
|
|||
function is_supplier_change(new_value, old_value){
|
||||
var value = Boolean(new_value)
|
||||
if (value){
|
||||
$$("cuenta_proveedor").enable()
|
||||
$$("cuenta_proveedor").enable();
|
||||
} else {
|
||||
$$("cuenta_proveedor").disable()
|
||||
$$("cuenta_proveedor").disable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,204 +324,6 @@ function rfc_lost_focus(prev_view){
|
|||
|
||||
|
||||
function multi_partners_change(prevID, nextID){
|
||||
//~ webix.message(prevID)
|
||||
//~ webix.message(nextID)
|
||||
webix.message(prevID)
|
||||
webix.message(nextID)
|
||||
}
|
||||
|
||||
|
||||
function grid_partners_double_click(id, e, node){
|
||||
//~ if(id.column!='saldo_cliente'){
|
||||
cmd_edit_partner_click()
|
||||
//~ }
|
||||
}
|
||||
|
||||
|
||||
function partner_balance_on_change(new_value, old_value){
|
||||
if(!isFinite(new_value)){
|
||||
this.config.value = old_value
|
||||
this.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cmd_partner_add_account_bank_click(){
|
||||
var form = $$('form_partner_account_bank')
|
||||
|
||||
if (!form.validate()){
|
||||
msg = 'Valores inválidos'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues()
|
||||
var id_partner = $$('form_partner').getValues().id
|
||||
|
||||
var account = {
|
||||
id_partner: id_partner,
|
||||
delete: '-',
|
||||
banco: $$('lst_partner_bank').getText(),
|
||||
cuenta: values.partner_account.trim(),
|
||||
clabe: values.partner_clabe.trim(),
|
||||
}
|
||||
|
||||
if(!account.cuenta){
|
||||
msg = 'La cuenta es requerida'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(!account.cuenta.is_number()){
|
||||
msg = 'Solo digitos en la cuenta'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(account.cuenta.length < 10){
|
||||
msg = 'Longitud incorrecta de la cuenta'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(!account.clabe){
|
||||
msg = 'La CLABE es requerida'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(account.clabe.length != 18){
|
||||
msg = 'La CLABE debe ser de 18 digitos'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(!account.clabe.is_number()){
|
||||
msg = 'Solo digitos en la CLABE'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var grid = $$('grid_partner_account_bank')
|
||||
|
||||
if(id_partner){
|
||||
partner_new_account_bank(account, grid)
|
||||
}else{
|
||||
grid.add(account)
|
||||
}
|
||||
|
||||
form.setValues({})
|
||||
}
|
||||
|
||||
|
||||
function get_partner_banks(){
|
||||
webix.ajax().get('/satbancos', {opt: 'active'}, function(text, data){
|
||||
var values = data.json()
|
||||
$$('lst_partner_bank').getList().parse(values)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function partner_new_account_bank(account, grid){
|
||||
webix.ajax().post('/socioscb', {opt: 'new', values: account}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al guardar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
account['id'] = values.id
|
||||
grid.add(account)
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_partner_accounts_bank(id_partner){
|
||||
var grid = $$('grid_partner_account_bank')
|
||||
grid.clearAll()
|
||||
|
||||
if(id_partner){
|
||||
var data = {opt: 'by_partner', id_partner: id_partner}
|
||||
webix.ajax().get('/socioscb', data, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
grid.parse(values)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function grid_partner_account_bank_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
var id_partner = $$('form_partner').getValues().id
|
||||
var grid = $$('grid_partner_account_bank')
|
||||
|
||||
var msg = '¿Estás seguro de eliminar la cuenta de banco seleccionada?<BR><BR>'
|
||||
msg += 'ESTA ACCION NO SE PUEDE DESHACER'
|
||||
webix.confirm({
|
||||
title: 'Eliminar cuenta de banco',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
if(id_partner){
|
||||
partner_delete_account_bank(id.row)
|
||||
}else{
|
||||
grid.remove(id.row)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function partner_delete_account_bank(row){
|
||||
var grid = $$('grid_partner_account_bank')
|
||||
|
||||
webix.ajax().post('/socioscb', {opt: 'delete', values: {id: row}}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al eliminar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
grid.remove(row)
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_sat_regimenes(morales=false){
|
||||
var data = {opt: 'actives', morales: morales}
|
||||
webix.ajax().sync().get('/satregimenes', data, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
$$('lst_receptor_regimenes_fiscales').clearAll()
|
||||
$$('lst_receptor_regimenes_fiscales').parse(values)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,141 +1,33 @@
|
|||
var cfg_products = new Object()
|
||||
var gis_admin = false
|
||||
|
||||
|
||||
function products_default_config(){
|
||||
webix.ajax().get('/config', {'fields': 'main_products'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
cfg_products['inventario'] = values.chk_llevar_inventario
|
||||
cfg_products['predial'] = values.chk_config_cuenta_predial
|
||||
cfg_products['codigo_barras'] = values.chk_config_codigo_barras
|
||||
cfg_products['con_impuestos'] = values.chk_config_precio_con_impuestos
|
||||
cfg_products['default_unit'] = values.default_unidad
|
||||
cfg_products['default_tax'] = values.default_tax
|
||||
if(cfg_products['inventario']){
|
||||
$$('grid_products').showColumn('existencia')
|
||||
}
|
||||
//~ show('cant_by_packing', values.chk_use_packing)
|
||||
show('cmd_show_exists', values.chk_multi_stock)
|
||||
}
|
||||
})
|
||||
|
||||
webix.ajax().get('/users', {'opt': 'is_admin'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al consultar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
gis_admin = values.is_admin
|
||||
if(values.is_admin){
|
||||
$$('cmd_add_inventory').show()
|
||||
//~ $$('cmd_products_add').show()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
var products_controllers = {
|
||||
init: function(){
|
||||
$$('cmd_new_product').attachEvent('onItemClick', cmd_new_product_click)
|
||||
$$("cmd_edit_product").attachEvent("onItemClick", cmd_edit_product_click)
|
||||
$$("cmd_delete_product").attachEvent("onItemClick", cmd_delete_product_click)
|
||||
$$("cmd_save_product").attachEvent("onItemClick", cmd_save_product_click)
|
||||
$$("cmd_cancel_product").attachEvent("onItemClick", cmd_cancel_product_click)
|
||||
$$("cmd_import_products").attachEvent("onItemClick", cmd_import_products_click)
|
||||
$$("cmd_add_inventory").attachEvent("onItemClick", cmd_add_inventory_click)
|
||||
$$("cmd_products_add").attachEvent("onItemClick", cmd_products_add_click)
|
||||
$$('cmd_add_products_from_xml').attachEvent('onItemClick', cmd_add_products_from_xml_click)
|
||||
$$('cmd_show_exists').attachEvent('onItemClick', cmd_show_exists_click)
|
||||
$$('cmd_save_products_add').attachEvent('onItemClick', cmd_save_products_add_click)
|
||||
$$('cmd_close_products_add').attachEvent('onItemClick', cmd_close_products_add_click)
|
||||
$$("chk_automatica").attachEvent("onChange", chk_automatica_change)
|
||||
$$("valor_unitario").attachEvent("onChange", valor_unitario_change)
|
||||
$$('precio_con_impuestos').attachEvent('onChange', precio_con_impuestos_change)
|
||||
$$('precio_con_impuestos').attachEvent('onTimedKeyPress', precio_con_impuestos_key_up);
|
||||
$$("chk_inventario").attachEvent("onChange", chk_inventario_change)
|
||||
$$('grid_products').attachEvent('onItemDblClick', cmd_edit_product_click)
|
||||
products_default_config()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function configurar_producto(){
|
||||
show('cuenta_predial', cfg_products['predial'])
|
||||
show('codigo_barras', cfg_products['codigo_barras'])
|
||||
show('precio_con_impuestos', cfg_products['con_impuestos'])
|
||||
show('chk_inventario', cfg_products['inventario'])
|
||||
show('txt_existencia', cfg_products['inventario'])
|
||||
show('txt_minimo', cfg_products['inventario'])
|
||||
}
|
||||
|
||||
|
||||
function get_categorias(){
|
||||
webix.ajax().sync().get('/values/categorias', function(text, data){
|
||||
var values = data.json()
|
||||
$$('categoria').getList().parse(values, 'plainjs')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_products(){
|
||||
var grid = $$('grid_products')
|
||||
webix.ajax().get('/products', {}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json');
|
||||
grid.refresh()
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function cmd_new_product_click(id, e, node){
|
||||
get_taxes()
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
configurar_producto()
|
||||
$$('form_product').setValues({
|
||||
id: 0, es_activo_producto: true})
|
||||
id: 0, es_activo_producto: true})
|
||||
add_config({'key': 'id_product', 'value': ''})
|
||||
get_new_key()
|
||||
get_categorias()
|
||||
$$('unidad').setValue(cfg_products['default_unit'])
|
||||
$$('grid_product_taxes').select(cfg_products['default_tax'])
|
||||
get_taxes()
|
||||
$$('grid_products').clearSelection()
|
||||
$$('categoria').getList().load('/values/categorias')
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
$$("multi_products").setValue("product_new")
|
||||
}
|
||||
|
||||
|
||||
function cmd_edit_product_click(){
|
||||
get_taxes()
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
configurar_producto()
|
||||
|
||||
function cmd_edit_product_click(id, e, node){
|
||||
var grid = $$('grid_products')
|
||||
var row = grid.getSelectedItem()
|
||||
if(row == undefined){
|
||||
msg_error('Selecciona un Producto')
|
||||
webix.message({type: 'error', text: 'Selecciona un Producto'})
|
||||
return
|
||||
}
|
||||
|
||||
get_taxes()
|
||||
$$('categoria').getList().load('/values/categorias')
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
|
||||
webix.ajax().get('/products', {id: row['id']}, {
|
||||
webix.ajax().get('/products', {id:row['id']}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error(text)
|
||||
webix.message({type: 'error', text: 'Error al consultar'})
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
|
@ -156,10 +48,10 @@ function delete_product(id){
|
|||
var msg = 'Producto eliminado correctamente'
|
||||
if(xhr.status == 200){
|
||||
$$('grid_products').remove(id)
|
||||
msg_ok(msg)
|
||||
webix.message({type:'success', text:msg})
|
||||
}else{
|
||||
msg = 'No se pudo eliminar'
|
||||
msg_error(msg)
|
||||
webix.message({type:'error', text:msg})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -168,7 +60,7 @@ function delete_product(id){
|
|||
function cmd_delete_product_click(id, e, node){
|
||||
var row = $$('grid_products').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Producto')
|
||||
webix.message({type:'error', text: 'Selecciona un Producto'})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -216,9 +108,8 @@ function update_grid_products(values){
|
|||
msg = 'Producto actualizado correctamente'
|
||||
$$("grid_products").updateItem(values.row['id'], values.row)
|
||||
}
|
||||
$$('grid_products').refresh()
|
||||
$$('multi_products').setValue('products_home')
|
||||
msg_ok(msg)
|
||||
webix.message({type: 'success', text: msg})
|
||||
}
|
||||
|
||||
|
||||
|
@ -227,48 +118,35 @@ function cmd_save_product_click(id, e, node){
|
|||
var form = this.getFormView()
|
||||
|
||||
if(!form.validate()){
|
||||
msg_error('Valores inválidos')
|
||||
webix.message({type: 'error', text: 'Valores inválidos'})
|
||||
return
|
||||
}
|
||||
|
||||
var rows = $$('grid_product_taxes').getSelectedId(true, true)
|
||||
if (rows.length == 0){
|
||||
webix.message({type: 'error', text: 'Selecciona un impuesto'})
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues();
|
||||
|
||||
if(!validate_sat_key_product(values.clave_sat, false)){
|
||||
msg_error('La clave SAT no existe')
|
||||
return
|
||||
}
|
||||
|
||||
if(values.descripcion.length > 1000){
|
||||
msg_error('Descripción con ' + values.descripcion.length + 'caracteres, captura solo 1000 caracteres')
|
||||
return
|
||||
}
|
||||
|
||||
if(values['objeto_impuesto']=='01' && rows.length > 0){
|
||||
msg = 'Si Objeto de Impuestos = 01, no debes seleccionar ningún impuesto'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
if(values['objeto_impuesto']=='02' && rows.length == 0){
|
||||
msg = 'Si Objeto de Impuestos = 02, debes de seleccionar al menos un impuesto'
|
||||
msg_error(msg)
|
||||
if (!validate_sat_key_product(values.clave_sat, false)){
|
||||
webix.message({ type:'error', text:'La clave SAT no existe' })
|
||||
return
|
||||
}
|
||||
|
||||
values['taxes'] = JSON.stringify(rows)
|
||||
|
||||
webix.ajax().sync().post('products', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
webix.message({type: 'error', text: msg})
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
update_grid_products(values)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
webix.message({type:'error', text:values.msg})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -276,7 +154,9 @@ function cmd_save_product_click(id, e, node){
|
|||
|
||||
|
||||
function cmd_cancel_product_click(id, e, node){
|
||||
|
||||
$$("multi_products").setValue("products_home")
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -301,24 +181,10 @@ function chk_automatica_change(new_value, old_value){
|
|||
}
|
||||
|
||||
|
||||
function chk_inventario_change(new_value, old_value){
|
||||
var value = Boolean(new_value)
|
||||
if(value){
|
||||
$$('txt_existencia').enable()
|
||||
$$('txt_minimo').enable()
|
||||
}else{
|
||||
$$('txt_existencia').disable()
|
||||
$$('txt_minimo').disable()
|
||||
$$('txt_existencia').setValue(0)
|
||||
$$('txt_minimo').setValue(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_new_key(){
|
||||
webix.ajax().get('/values/newkey', {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error(text)
|
||||
webix.message({type:'error', text: text})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
|
@ -335,657 +201,3 @@ function valor_unitario_change(new_value, old_value){
|
|||
this.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function precio_con_impuestos_change(new_value, old_value){
|
||||
if(!isFinite(new_value)){
|
||||
this.config.value = old_value
|
||||
this.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function calcular_sin_impuestos(value, taxes){
|
||||
var vu = $$('valor_unitario')
|
||||
var precio = value
|
||||
|
||||
taxes.forEach(function(tax){
|
||||
var tasa = 1.00 + tax.tasa.to_float()
|
||||
if(tax.tipo == 'T' && tax.name == 'IVA'){
|
||||
precio = (value / tasa).round(DECIMALES)
|
||||
}
|
||||
})
|
||||
vu.setValue(precio)
|
||||
}
|
||||
|
||||
function precio_con_impuestos_key_up(){
|
||||
var value = this.getValue()
|
||||
|
||||
if(!value){
|
||||
return
|
||||
}
|
||||
|
||||
var taxes = $$('grid_product_taxes').getSelectedItem(true)
|
||||
if (taxes.length == 0){
|
||||
msg = 'Selecciona al menos un impuesto'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(!isFinite(value)){
|
||||
msg = 'Captura un valor válido'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
calcular_sin_impuestos(parseFloat(value), taxes)
|
||||
}
|
||||
|
||||
|
||||
function cmd_import_products_click(){
|
||||
win_import_products.init()
|
||||
$$('win_import_products').show()
|
||||
}
|
||||
|
||||
|
||||
function cmd_upload_products_click(){
|
||||
var form = $$('form_upload_products')
|
||||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!$$('lst_upload_products').count()){
|
||||
$$('win_import_products').close()
|
||||
return
|
||||
}
|
||||
|
||||
if($$('lst_upload_products').count() > 1){
|
||||
msg = 'Selecciona solo un archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var template = $$('up_products').files.getItem($$('up_products').files.getFirstId())
|
||||
|
||||
if(template.type.toLowerCase() != 'ods'){
|
||||
msg = 'Archivo inválido.\n\nSe requiere un archivo ODS'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de importar este archivo?'
|
||||
webix.confirm({
|
||||
title: 'Importar Productos',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
$$('up_products').send()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function up_products_upload_complete(response){
|
||||
if(response.status != 'server'){
|
||||
msg = 'Ocurrio un error al subir el archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
msg = 'Archivo subido correctamente.\n\nComenzando importación.'
|
||||
msg_ok(msg)
|
||||
$$('win_import_products').close()
|
||||
|
||||
webix.ajax().post('/products', {opt: 'import'}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg = 'Error al importar'
|
||||
msg_error(msg)
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok){
|
||||
get_products()
|
||||
webix.alert({
|
||||
title: 'Importación terminada',
|
||||
text: values.msg,
|
||||
})
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//~ Add inventory
|
||||
function cmd_add_inventory_click(id, e, node){
|
||||
var row = $$('grid_products').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Producto')
|
||||
return
|
||||
}
|
||||
|
||||
win_add_inventory.init()
|
||||
$$('txt_add_id').setValue(row.id)
|
||||
$$('txt_add_key').setValue(row.clave)
|
||||
$$('txt_add_unit').setValue(row.unidad)
|
||||
$$('txt_add_description').setValue(row.descripcion)
|
||||
$$('lst_warehouses').getList().load('/warehouse?opt=for_select')
|
||||
$$('win_add_inventory').show()
|
||||
}
|
||||
|
||||
|
||||
//~ Show details inventory
|
||||
function cmd_show_exists_click(id, e, node){
|
||||
var row = $$('grid_products').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Producto')
|
||||
return
|
||||
}
|
||||
win_show_exists.init()
|
||||
$$('txt_id_product').setValue(row.id)
|
||||
$$('grid_warehouse_exists').load('warehouseproduct?opt=by_product&id=' + row.id)
|
||||
|
||||
if(gis_admin){
|
||||
$$('lst_warehouse_target').getList().load('/warehouse?opt=for_select')
|
||||
}else{
|
||||
$$('lbl_title_move').hide()
|
||||
$$('txt_cant_to_move').hide()
|
||||
$$('lst_warehouse_target').hide()
|
||||
$$('cmd_warehouse_move').hide()
|
||||
}
|
||||
|
||||
$$('win_show_exists').show()
|
||||
}
|
||||
|
||||
|
||||
function cmd_warehouse_move_click(id, e, node){
|
||||
var id_product = $$('txt_id_product').getValue()
|
||||
var row = $$('grid_warehouse_exists').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Almacen origen')
|
||||
return
|
||||
}
|
||||
var warehouse_source = row.id
|
||||
var cant_to_move = $$('txt_cant_to_move').getValue()
|
||||
var warehouse_target = $$('lst_warehouse_target').getValue()
|
||||
|
||||
if(!cant_to_move){
|
||||
msg_error('La cantidad no puede ser cero')
|
||||
return
|
||||
}
|
||||
|
||||
if(cant_to_move > row.exists){
|
||||
msg_error('La cantidad a mover no puede ser mayor a la existencia')
|
||||
return
|
||||
}
|
||||
|
||||
if (warehouse_target == ''){
|
||||
msg_error('Selecciona un Almacen destino')
|
||||
return
|
||||
}
|
||||
|
||||
if (warehouse_source == warehouse_target){
|
||||
msg_error('Los almacenes origen y destino deben ser diferentes')
|
||||
return
|
||||
}
|
||||
|
||||
var values = {
|
||||
id_product: id_product,
|
||||
cant: cant_to_move,
|
||||
source: warehouse_source,
|
||||
target: warehouse_target
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de hacer este movimiento?'
|
||||
webix.confirm({
|
||||
title: 'Movimiento de Almacen',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
_warehouse_movement(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function _warehouse_movement(args){
|
||||
var values = {
|
||||
opt: 'warehouse_movement',
|
||||
values: args,
|
||||
}
|
||||
|
||||
webix.ajax().sync().post('inventoryentries', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
$$('txt_cant_to_move').setValue(0)
|
||||
$$('lst_warehouse_target').setValue('')
|
||||
$$('grid_warehouse_exists').load('warehouseproduct?opt=by_product&id=' + args.id_product)
|
||||
$$('grid_warehouse_exists').clearSelection()
|
||||
msg_ok('Movimiento realizado correctamente')
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_win_show_exists_close_click(id, e, node){
|
||||
$$('win_show_exists').close()
|
||||
}
|
||||
|
||||
|
||||
//~ Add products
|
||||
function cmd_products_add_click(id, e, node){
|
||||
$$("multi_products").setValue("product_add")
|
||||
cfg_products['partner_id'] = 0
|
||||
cfg_products['partner_rfc'] = ''
|
||||
}
|
||||
|
||||
//~ Close add products
|
||||
function cmd_close_products_add_click(id, e, node){
|
||||
var grid = $$('grid_partner_products')
|
||||
|
||||
$$('multi_invoices').setValue('products_home')
|
||||
$$('lbl_partner').setValue('')
|
||||
grid.clearAll()
|
||||
}
|
||||
|
||||
|
||||
function _add_entries_inventory(data){
|
||||
var grid = $$('grid_partner_products')
|
||||
var values = {
|
||||
opt: 'create',
|
||||
values: data,
|
||||
}
|
||||
|
||||
webix.ajax().sync().post('inventoryentries', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
get_products()
|
||||
$$('multi_invoices').setValue('products_home')
|
||||
$$('lbl_partner').setValue('')
|
||||
grid.clearAll()
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//~ Save add products
|
||||
function cmd_save_products_add_click(id, e, node){
|
||||
var grid = $$('grid_partner_products')
|
||||
var count = 0
|
||||
var products = []
|
||||
var validate_import = false
|
||||
var validate_cant = false
|
||||
|
||||
grid.eachRow(function(row){
|
||||
var r = grid.getItem(row)
|
||||
if(r.select){
|
||||
var p = {}
|
||||
count += 1
|
||||
p.id_product = r.id_product
|
||||
p.key = r.key
|
||||
p.key_sat = r.key_sat1
|
||||
p.description = r.description1
|
||||
p.unit = r.unit
|
||||
p.unit_value = r.unit_value1
|
||||
p.cant = r.cant1
|
||||
products.push(p)
|
||||
|
||||
if(p.unit_value < parseFloat(r.unit_value)){
|
||||
validate_import = true
|
||||
}
|
||||
if(p.cant > r.cant){
|
||||
validate_cant = true
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
if(!count){
|
||||
msg = 'Selecciona al menos un registro'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(validate_import){
|
||||
msg = 'El Valor Unitario no puede ser menor al Valor Unitario del proveedor'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(validate_cant){
|
||||
msg = 'La Cantidad no puede ser mayor a la Cantidad del proveedor'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var data = {
|
||||
partner: cfg_products['partner'],
|
||||
products: products,
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de ingresar estos productos? <br/><br/>\
|
||||
Esta acción no se puede deshacer.'
|
||||
webix.confirm({
|
||||
title: 'Agregar entrada',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
_add_entries_inventory(data)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//~ Import from xml
|
||||
function cmd_add_products_from_xml_click(){
|
||||
win_add_products_from_xml.init()
|
||||
$$('win_add_products_from_xml').show()
|
||||
}
|
||||
|
||||
//~ Upload XML
|
||||
function cmd_upload_products_from_xml_click(){
|
||||
var form = $$('form_upload_products_from_xml')
|
||||
var values = form.getValues()
|
||||
var list = $$('lst_up_products_from_xml')
|
||||
var upload = $$('up_products_from_xml')
|
||||
|
||||
if(!list.count()){
|
||||
$$('win_add_products_from_xml').close()
|
||||
return
|
||||
}
|
||||
|
||||
if(list.count() > 1){
|
||||
msg = 'Selecciona solo un archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var template = upload.files.getItem(upload.files.getFirstId())
|
||||
|
||||
if(template.type.toLowerCase() != 'xml'){
|
||||
msg = 'Archivo inválido.\n\nSe requiere un archivo XML'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de importar este archivo? <br/><br/>\
|
||||
Si hay datos previos seran reemplazados.'
|
||||
webix.confirm({
|
||||
title: 'Importar Productos',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
upload.send()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function up_products_from_xml_upload_complete(response){
|
||||
if(response.status != 'server'){
|
||||
msg = 'Ocurrio un error al subir el archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
$$('win_add_products_from_xml').close()
|
||||
|
||||
if(response.error){
|
||||
msg_error(response.error)
|
||||
return
|
||||
}
|
||||
|
||||
var grid = $$('grid_partner_products')
|
||||
var data = response.data
|
||||
cfg_products['partner'] = data.emisor
|
||||
//~ cfg_products['xml'] = data.xml
|
||||
|
||||
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
||||
html += data.emisor.nombre + ' (' + data.emisor.rfc + ')</span>'
|
||||
$$('lbl_partner').setValue(html)
|
||||
|
||||
grid.clearAll()
|
||||
grid.parse(data.conceptos, 'json')
|
||||
grid.refresh()
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get_partner_product(grid, row){
|
||||
grid.refresh(row.id)
|
||||
|
||||
var partner_id = cfg_products['partner'].id
|
||||
var filters = {
|
||||
opt: 'product',
|
||||
partner: cfg_products['partner'],
|
||||
product_key: row.key,
|
||||
}
|
||||
|
||||
if(!partner_id){
|
||||
msg = 'El Proveedor no esta dado de alta'
|
||||
msg_ok(msg)
|
||||
return
|
||||
}
|
||||
|
||||
webix.ajax().get('/partnerproducts', filters, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Ocurrio un error, consulta a soporte técnico.')
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
row['id_product'] = values.row.id_product
|
||||
row['key_sat1'] = values.row.key_sat1
|
||||
row['description1'] = values.row.description1
|
||||
row['unit_value1'] = values.row.unit_value1
|
||||
grid.refresh(row.id)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function grid_partner_products_select(row_id, state){
|
||||
var grid = $$('grid_partner_products')
|
||||
var row = grid.getItem(row_id)
|
||||
|
||||
if(state){
|
||||
row['key_sat1'] = row.key_sat
|
||||
row['description1'] = row.description
|
||||
row['cant1'] = row.cant
|
||||
row['unit_value1'] = 0.0
|
||||
get_partner_product(grid, row)
|
||||
}else{
|
||||
row['key_sat1'] = ''
|
||||
row['description1'] = ''
|
||||
row['cant1'] = ''
|
||||
grid.refresh(row_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cmd_add_inventory_cancel_click(id, e, node){
|
||||
$$('win_add_inventory').close()
|
||||
}
|
||||
|
||||
|
||||
function cmd_add_inventory_save_click(id, e, node){
|
||||
var product_id = $$('txt_add_id').getValue()
|
||||
//~ var product_key = $$('txt_add_key').getValue()
|
||||
var new_cant = $$('txt_new_cant').getValue()
|
||||
var warehouse = $$('lst_warehouses').getValue()
|
||||
|
||||
if(new_cant<=0) {
|
||||
msg = 'La cantidad no puede ser cero'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if($$('lst_warehouses').isVisible()){
|
||||
if(!warehouse){
|
||||
msg = 'Selecciona un almacen'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
msg = '¿Estas seguro de guardar esta entrada? <br/><br/>\
|
||||
Esta acción no se puede deshacer'
|
||||
|
||||
webix.confirm({
|
||||
title: 'Agregar entrada',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
add_product_stock(product_id, new_cant, warehouse)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function add_product_stock(product_id, new_cant, warehouse){
|
||||
var data = {
|
||||
product_id: product_id,
|
||||
cant: new_cant,
|
||||
warehouse: warehouse,
|
||||
}
|
||||
_add_entries_inventory_manual(product_id, data)
|
||||
$$('win_add_inventory').close()
|
||||
}
|
||||
|
||||
|
||||
function _add_entries_inventory_manual(row_id, data){
|
||||
var grid = $$('grid_products')
|
||||
var values = {
|
||||
opt: 'create_manual',
|
||||
values: data,
|
||||
}
|
||||
|
||||
webix.ajax().sync().post('inventoryentries', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
grid.updateItem(row_id, values.row)
|
||||
grid.refresh()
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_adjust_stock_click(id, e, node){
|
||||
var id_product = $$('txt_id_product').getValue()
|
||||
var row = $$('grid_warehouse_exists').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Almacen origen')
|
||||
return
|
||||
}
|
||||
var warehouse_source = row.id
|
||||
var cant_to_adjust = $$('txt_cant_to_adjust').getValue()
|
||||
|
||||
if(cant_to_adjust == 0){
|
||||
msg_error('La cantidad a ajustar no puede ser cero')
|
||||
return
|
||||
}
|
||||
|
||||
if(cant_to_adjust > row.exists){
|
||||
msg_error('La cantidad a ajustar no puede ser mayor a la existencia')
|
||||
return
|
||||
}
|
||||
|
||||
var values = {
|
||||
id_product: id_product,
|
||||
cant: cant_to_adjust,
|
||||
storage: warehouse_source,
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de hacer este ajuste?'
|
||||
webix.confirm({
|
||||
title: 'Ajuste de Almacen',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
_adjust_stock(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function _adjust_stock(args){
|
||||
var grid = $$('grid_products')
|
||||
var row = grid.getSelectedItem()
|
||||
|
||||
var values = {
|
||||
opt: 'adjust_stock',
|
||||
values: args,
|
||||
}
|
||||
|
||||
webix.ajax().sync().post('warehouseproduct', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
$$('txt_cant_to_adjust').setValue(0)
|
||||
$$('grid_warehouse_exists').load('warehouseproduct?opt=by_product&id=' + args.id_product)
|
||||
$$('grid_warehouse_exists').clearSelection()
|
||||
|
||||
grid.updateItem(row['id'], values.row)
|
||||
grid.refresh()
|
||||
|
||||
msg_ok('Ajuste realizado correctamente')
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
|
||||
|
||||
var controllers_school = {
|
||||
init: function(){
|
||||
$$('cmd_new_student').attachEvent('onItemClick', cmd_new_student_click)
|
||||
$$('cmd_edit_student').attachEvent('onItemClick', cmd_edit_student_click)
|
||||
$$('cmd_delete_student').attachEvent('onItemClick', cmd_delete_student_click)
|
||||
$$('cmd_save_student').attachEvent('onItemClick', cmd_save_student_click)
|
||||
$$('cmd_cancel_student').attachEvent('onItemClick', cmd_cancel_student_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_school_groups(){
|
||||
webix.ajax().get('/values/schoolgroups', {
|
||||
error: function(text, data, xhr) {
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
$$('student_grupo').define('suggest', values)
|
||||
$$('student_grupo').refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function init_config_school(){
|
||||
get_students()
|
||||
get_school_groups()
|
||||
}
|
||||
|
||||
|
||||
function cmd_new_student_click(){
|
||||
$$('form_student').setValues({})
|
||||
$$('grid_students').clearSelection()
|
||||
$$('multi_school').setValue('new_student')
|
||||
}
|
||||
|
||||
|
||||
function cmd_edit_student_click(){
|
||||
var row = $$('grid_students').getSelectedItem()
|
||||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Alumno'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
webix.ajax().get('/students', {id: row['id']}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error()
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
$$('form_student').setValues(values)
|
||||
}
|
||||
})
|
||||
|
||||
$$('multi_school').setValue('new_student')
|
||||
}
|
||||
|
||||
|
||||
function delete_student(id){
|
||||
webix.ajax().del('/students', {id: id}, function(text, xml, xhr){
|
||||
msg = 'Alumno eliminado correctamente'
|
||||
if (xhr.status == 200){
|
||||
$$('grid_students').remove(id);
|
||||
msg_ok(msg)
|
||||
} else {
|
||||
msg = 'No se pudo eliminar.'
|
||||
msg_error(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_delete_student_click(){
|
||||
var row = $$('grid_students').getSelectedItem()
|
||||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Alumno'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de eliminar al Alumno?<BR><BR>'
|
||||
msg += row['nombre'] + ' ' + row['paterno'] + ' (' + row['rfc'] + ')'
|
||||
msg += '<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER<BR><BR>'
|
||||
webix.confirm({
|
||||
title:'Eliminar Alumno',
|
||||
ok:'Si',
|
||||
cancel:'No',
|
||||
type:'confirm-error',
|
||||
text:msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
delete_student(row['id'])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_cancel_student_click(){
|
||||
$$('multi_school').setValue('school_home')
|
||||
}
|
||||
|
||||
|
||||
function cmd_save_student_click(){
|
||||
msg = ''
|
||||
var form = this.getFormView();
|
||||
|
||||
if (!form.validate()) {
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues();
|
||||
opt = 'add'
|
||||
if(values.id){
|
||||
opt = 'edit'
|
||||
}
|
||||
|
||||
webix.ajax().post('/students', {opt: opt, values: values}, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico';
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
form.setValues({})
|
||||
$$('multi_school').setValue('school_home')
|
||||
get_students()
|
||||
} else {
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get_students(){
|
||||
webix.ajax().get('/students', {}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json()
|
||||
$$('grid_students').clearAll()
|
||||
$$('grid_students').parse(values)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,903 +0,0 @@
|
|||
var query = []
|
||||
var msg = ''
|
||||
var cfg_ticket = new Object()
|
||||
var last_forma_pago = ''
|
||||
|
||||
|
||||
var tickets_controllers = {
|
||||
init: function(){
|
||||
$$('cmd_nuevo_ticket').attachEvent('onItemClick', cmd_nuevo_ticket_click)
|
||||
$$('cmd_ticket_from_ticket').attachEvent('onItemClick', cmd_ticket_from_ticket_click)
|
||||
$$('cmd_ticket_to_invoice').attachEvent('onItemClick', cmd_ticket_to_invoice_click)
|
||||
$$('cmd_ticket_report_pdf').attachEvent('onItemClick', cmd_ticket_report_pdf_click)
|
||||
$$('cmd_ticket_report_xls').attachEvent('onItemClick', cmd_ticket_report_xls_click)
|
||||
$$('cmd_generar_ticket').attachEvent('onItemClick', cmd_generar_ticket_click)
|
||||
$$('cmd_cerrar_ticket').attachEvent('onItemClick', cmd_cerrar_ticket_click)
|
||||
$$('cmd_new_invoice_from_ticket').attachEvent('onItemClick', cmd_new_invoice_from_ticket_click)
|
||||
$$('cmd_close_ticket_invoice').attachEvent('onItemClick', cmd_cerrar_ticket_click)
|
||||
$$('cmd_cancelar_ticket').attachEvent('onItemClick', cmd_cancelar_ticket_click)
|
||||
$$('cmd_move_tickets_right').attachEvent('onItemClick', cmd_move_tickets_right_click)
|
||||
$$('cmd_move_tickets_left').attachEvent('onItemClick', cmd_move_tickets_left_click)
|
||||
$$('cmd_ticket_notes').attachEvent('onItemClick', cmd_ticket_notes_click)
|
||||
$$('tsearch_product_key').attachEvent('onKeyPress', tsearch_product_key_press)
|
||||
$$('grid_tickets').attachEvent('onItemClick', grid_tickets_click)
|
||||
$$('grid_tdetails').attachEvent('onItemClick', grid_ticket_details_click)
|
||||
$$('grid_tdetails').attachEvent('onBeforeEditStop', grid_tickets_details_before_edit_stop)
|
||||
$$('gt_productos_found').attachEvent('onValueSuggest', gt_productos_found_click)
|
||||
$$('cmd_ticket_filter_today').attachEvent('onItemClick', cmd_ticket_filter_today_click)
|
||||
$$('filter_year_ticket').attachEvent('onChange', filter_year_ticket_change)
|
||||
$$('filter_month_ticket').attachEvent('onChange', filter_month_ticket_change)
|
||||
$$('filter_dates_ticket').attachEvent('onChange', filter_dates_ticket_change)
|
||||
$$('chk_is_invoice_day').attachEvent('onChange', chk_is_invoice_day_change)
|
||||
$$('grid_tickets_active').attachEvent('onItemDblClick', grid_tickets_active_double_click)
|
||||
$$('grid_tickets_invoice').attachEvent('onItemDblClick', grid_tickets_invoice_double_click)
|
||||
$$('tsearch_client_key').attachEvent('onKeyPress', tsearch_client_key_press)
|
||||
$$('grid_ticket_clients_found').attachEvent('onValueSuggest', grid_ticket_clients_found_click)
|
||||
$$('grid_tdetails').attachEvent('onAfterRender', grid_tdetails_render)
|
||||
|
||||
webix.extend($$('grid_tickets'), webix.ProgressBar)
|
||||
webix.extend($$('grid_tickets_active'), webix.ProgressBar)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function current_dates_tickets(){
|
||||
var fy = $$('filter_year_ticket')
|
||||
var fm = $$('filter_month_ticket')
|
||||
var d = new Date()
|
||||
|
||||
fy.blockEvent()
|
||||
fm.blockEvent()
|
||||
|
||||
fm.setValue(d.getMonth() + 1)
|
||||
webix.ajax().sync().get('/values/filteryearsticket', function(text, data){
|
||||
var values = data.json()
|
||||
fy.getList().parse(values)
|
||||
fy.setValue(d.getFullYear())
|
||||
})
|
||||
|
||||
fy.unblockEvent()
|
||||
fm.unblockEvent()
|
||||
}
|
||||
|
||||
|
||||
function get_tickets(filters){
|
||||
if(filters == undefined){
|
||||
filters = {'opt': 'today'}
|
||||
}
|
||||
|
||||
var grid = $$('grid_tickets')
|
||||
grid.showProgress({type: 'icon'})
|
||||
|
||||
webix.ajax().get('/tickets', filters, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_filter_today_click(){
|
||||
get_tickets()
|
||||
}
|
||||
|
||||
|
||||
function filter_year_ticket_change(nv, ov){
|
||||
var fm = $$('filter_month_ticket')
|
||||
filters = {'opt': 'yearmonth', 'year': nv, 'month': fm.getValue()}
|
||||
get_tickets(filters)
|
||||
}
|
||||
|
||||
|
||||
function filter_month_ticket_change(nv, ov){
|
||||
var fy = $$('filter_year_ticket')
|
||||
filters = {'opt': 'yearmonth', 'year': fy.getValue(), 'month': nv}
|
||||
get_tickets(filters)
|
||||
}
|
||||
|
||||
|
||||
function filter_dates_ticket_change(range){
|
||||
if(range.start != null && range.end != null){
|
||||
filters = {'opt': 'dates', 'range': range}
|
||||
get_tickets(filters)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function configuracion_inicial_ticket(){
|
||||
current_dates_tickets()
|
||||
get_tickets()
|
||||
|
||||
webix.ajax().sync().get('/values/configticket', function(text, data){
|
||||
var values = data.json()
|
||||
//~ showvar(values)
|
||||
cfg_ticket['open_pdf'] = values.open_pdf
|
||||
cfg_ticket['direct_print'] = values.direct_print
|
||||
cfg_ticket['edit_cant'] = values.edit_cant
|
||||
cfg_ticket['total_up'] = values.total_up
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_active_tickets(grid){
|
||||
filters = {'opt': 'active'}
|
||||
grid.showProgress({type: 'icon'})
|
||||
|
||||
webix.ajax().get('/tickets', filters, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function configuracion_inicial_ticket_to_invoice(){
|
||||
var grid = $$('grid_tickets_active')
|
||||
var gridt = $$('grid_tickets_invoice')
|
||||
var form = $$('form_ticket_invoice')
|
||||
var chk = $$('chk_is_invoice_day')
|
||||
|
||||
chk.setValue(false)
|
||||
get_active_tickets(grid)
|
||||
form.setValues({id_partner: 0, lbl_tclient: 'Ninguno'})
|
||||
gridt.attachEvent('onAfterAdd', function(id, index){
|
||||
gridt.adjustColumn('index')
|
||||
gridt.adjustColumn('folio', 'all')
|
||||
gridt.adjustColumn('fecha', 'all')
|
||||
});
|
||||
gridt.clearAll()
|
||||
}
|
||||
|
||||
|
||||
function configuracion_inicial_nuevo_ticket(){
|
||||
var grid = $$('grid_tdetails')
|
||||
|
||||
webix.ajax().sync().get('/values/taxes', function(text, data){
|
||||
var values = data.json()
|
||||
table_taxes.clear()
|
||||
table_taxes.insert(values)
|
||||
})
|
||||
get_forma_pago('lst_ticket_forma_pago')
|
||||
grid.clearAll()
|
||||
table_pt.clear()
|
||||
table_totals.clear()
|
||||
show('grid_ticket_total_up', cfg_ticket['total_up'])
|
||||
$$('form_new_ticket').setValues({notas: '', forma_pago: last_forma_pago})
|
||||
}
|
||||
|
||||
|
||||
function cmd_nuevo_ticket_click(){
|
||||
configuracion_inicial_nuevo_ticket()
|
||||
$$('multi_tickets').setValue('tickets_new')
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_from_ticket_click(){
|
||||
var grid = $$('grid_tickets')
|
||||
|
||||
if(grid.count() == 0){
|
||||
return
|
||||
}
|
||||
|
||||
var row = grid.getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un ticket')
|
||||
return
|
||||
}
|
||||
|
||||
configuracion_inicial_nuevo_ticket()
|
||||
$$('multi_tickets').setValue('tickets_new')
|
||||
$$('grid_tdetails').load('ticketsdetails?opt=by_ticket_id&id=' + row.id)
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_to_invoice_click(){
|
||||
configuracion_inicial_ticket_to_invoice()
|
||||
$$('multi_tickets').setValue('tickets_invoice')
|
||||
}
|
||||
|
||||
|
||||
function validar_ticket(){
|
||||
var grid = $$('grid_tdetails')
|
||||
|
||||
if(!grid.count()){
|
||||
webix.UIManager.setFocus('tsearch_product_key')
|
||||
msg = 'Agrega al menos un producto'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
|
||||
var values = $$('form_new_ticket').getValues()
|
||||
if(!values.forma_pago){
|
||||
msg = 'La forma de pago es requerida'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
function get_ticket_pdf(id){
|
||||
window.open('/doc/tpdf/' + id, '_blank')
|
||||
}
|
||||
|
||||
|
||||
function guardar_ticket(values){
|
||||
var gd = $$('grid_tdetails')
|
||||
var grid = $$('grid_tickets')
|
||||
|
||||
var rows = gd.data.getRange()
|
||||
for (i = 0; i < rows.length; i++) {
|
||||
delete rows[i]['id']
|
||||
delete rows[i]['delete']
|
||||
delete rows[i]['clave']
|
||||
delete rows[i]['clave_sat']
|
||||
delete rows[i]['unidad']
|
||||
delete rows[i]['importe']
|
||||
rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario'])
|
||||
rows[i]['descuento'] = parseFloat(rows[i]['descuento'])
|
||||
}
|
||||
|
||||
last_forma_pago = values.forma_pago
|
||||
var data = new Object()
|
||||
data['opt'] = 'add'
|
||||
data['productos'] = rows
|
||||
data['forma_pago'] = values.forma_pago
|
||||
data['notas'] = values.notas
|
||||
|
||||
webix.ajax().sync().post('tickets', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
msg_ok('Ticket generado correctamente')
|
||||
$$('form_new_ticket').setValues({})
|
||||
gd.clearAll()
|
||||
grid.add(values.row)
|
||||
$$('multi_tickets').setValue('tickets_home')
|
||||
if(cfg_ticket.open_pdf){
|
||||
get_ticket_pdf(values.row.id)
|
||||
}
|
||||
if(cfg_ticket.direct_print){
|
||||
print_ticket(values.row.id)
|
||||
}
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function cmd_generar_ticket_click(){
|
||||
var form = $$('form_new_ticket')
|
||||
|
||||
if(!form.validate()) {
|
||||
msg_error('Valores inválidos')
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues()
|
||||
if(!validar_ticket()){
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Todos los datos son correctos?<BR><BR>'
|
||||
msg += '¿Estás seguro de generar este Ticket?'
|
||||
|
||||
webix.confirm({
|
||||
title: 'Generar Ticket',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
guardar_ticket(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_cerrar_ticket_click(){
|
||||
$$('multi_tickets').setValue('tickets_home')
|
||||
}
|
||||
|
||||
|
||||
function calcular_precio_con_impuestos(precio, taxes){
|
||||
var precio_final = precio
|
||||
|
||||
for(var tax of taxes){
|
||||
impuesto = table_taxes.findOne({'id': tax.tax})
|
||||
if(impuesto.tipo == 'E'){
|
||||
continue
|
||||
}
|
||||
var base = precio
|
||||
if(impuesto.tipo == 'R'){
|
||||
base = (precio * -1).round(DECIMALES)
|
||||
}
|
||||
precio_final += (impuesto.tasa * base).round(DECIMALES)
|
||||
}
|
||||
|
||||
return precio_final
|
||||
}
|
||||
|
||||
|
||||
function edit_cant(id){
|
||||
if(!cfg_ticket['edit_cant']){
|
||||
return
|
||||
}
|
||||
$$('grid_tdetails').edit({row: id, column: 'cantidad'})
|
||||
}
|
||||
|
||||
|
||||
function agregar_producto(values){
|
||||
var taxes = values.taxes
|
||||
var producto = values.row
|
||||
var form = $$('form_new_ticket')
|
||||
var grid = $$('grid_tdetails')
|
||||
var row = grid.getItem(producto.id)
|
||||
var precio_final = 0.0
|
||||
|
||||
if(row == undefined){
|
||||
producto['cantidad'] = 1
|
||||
producto['valor_unitario'] = calcular_precio_con_impuestos(
|
||||
parseFloat(producto['valor_unitario']), taxes)
|
||||
producto['importe'] = producto['valor_unitario']
|
||||
//~ var id = grid.add(producto, 0)
|
||||
//~ edit_cant(id)
|
||||
}else{
|
||||
producto['cantidad'] = parseFloat(row.cantidad) + 1
|
||||
producto['descuento'] = parseFloat(row.descuento)
|
||||
producto['valor_unitario'] = parseFloat(row.valor_unitario)
|
||||
precio_final = producto['valor_unitario'] - producto['descuento']
|
||||
producto['importe'] = (precio_final * producto['cantidad']).round(DECIMALES)
|
||||
//~ grid.updateItem(row.id, producto)
|
||||
}
|
||||
form.setValues({tsearch_product_key: '', tsearch_product_name: ''}, true)
|
||||
|
||||
//~ Validate stock
|
||||
if(producto.inventario){
|
||||
if(producto.cantidad > producto.existencia){
|
||||
msg_error('No hay suficiente existencia de este producto')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if(row == undefined){
|
||||
var id = grid.add(producto, 0)
|
||||
edit_cant(id)
|
||||
}else{
|
||||
grid.updateItem(row.id, producto)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function buscar_producto_key(key){
|
||||
|
||||
var filters = {
|
||||
opt: 'by_key',
|
||||
key: key,
|
||||
}
|
||||
|
||||
webix.ajax().get('/products', filters, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
if (values.ok){
|
||||
agregar_producto(values)
|
||||
} else {
|
||||
msg = 'No se encontró la clave<BR><BR>' + key
|
||||
msg_error(msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
//~ webix.ajax().get('/values/productokey', {'key': key}, {
|
||||
//~ error: function(text, data, xhr) {
|
||||
//~ msg_error('Error al consultar')
|
||||
//~ },
|
||||
//~ success: function(text, data, xhr){
|
||||
//~ var values = data.json()
|
||||
//~ if (values.ok){
|
||||
//~ agregar_producto(values)
|
||||
//~ } else {
|
||||
//~ msg = 'No se encontró la clave<BR><BR>' + key
|
||||
//~ msg_error(msg)
|
||||
//~ }
|
||||
//~ }
|
||||
//~ })
|
||||
|
||||
}
|
||||
|
||||
|
||||
function tsearch_product_key_press(code, e){
|
||||
var value = this.getValue()
|
||||
if(code == 13 && value.trim().length > 0){
|
||||
buscar_producto_key(value.trim())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function grid_ticket_details_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
var grid = $$('grid_tdetails')
|
||||
grid.remove(id.row)
|
||||
}
|
||||
|
||||
|
||||
function grid_tickets_details_before_edit_stop(state, editor){
|
||||
var grid = $$('grid_tdetails')
|
||||
pause(500)
|
||||
var row = grid.getItem(editor.row)
|
||||
|
||||
if(editor.column == 'cantidad'){
|
||||
var cantidad = parseFloat(state.value)
|
||||
if(isNaN(cantidad)){
|
||||
msg = 'La cantidad debe ser un número'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}else if(cantidad <= 0){
|
||||
msg = 'La cantidad no puede cero o menor'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}
|
||||
|
||||
//~ Validate stock
|
||||
if(row['inventario']){
|
||||
if(cantidad > row['existencia']){
|
||||
msg = 'No hay suficiente existencia de este producto'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var valor_unitario = parseFloat(row['valor_unitario'])
|
||||
var descuento = parseFloat(row['descuento'])
|
||||
}
|
||||
|
||||
if(editor.column == 'valor_unitario'){
|
||||
var valor_unitario = parseFloat(state.value)
|
||||
if(isNaN(valor_unitario)){
|
||||
msg = 'El valor unitario debe ser un número'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}else if(valor_unitario <= 0){
|
||||
msg = 'El valor unitario no puede cero o menor'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}
|
||||
var cantidad = parseFloat(row['cantidad'])
|
||||
var descuento = parseFloat(row['descuento'])
|
||||
}
|
||||
|
||||
if(editor.column == 'descuento'){
|
||||
var descuento = parseFloat(state.value)
|
||||
if(isNaN(descuento)){
|
||||
msg = 'El descuento debe ser un número'
|
||||
msg_error(msg)
|
||||
grid.blockEvent()
|
||||
state.value = state.old
|
||||
grid.editCancel()
|
||||
grid.unblockEvent()
|
||||
return true
|
||||
}
|
||||
var cantidad = parseFloat(row['cantidad'])
|
||||
var valor_unitario = parseFloat(row['valor_unitario'])
|
||||
}
|
||||
|
||||
var precio_final = valor_unitario - descuento
|
||||
row['importe'] = (cantidad * precio_final).round(DECIMALES)
|
||||
|
||||
grid.refresh()
|
||||
if(cfg_ticket['edit_cant']){
|
||||
focus('tsearch_product_name')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function gt_productos_found_click(obj){
|
||||
buscar_producto_key(obj.clave)
|
||||
}
|
||||
|
||||
|
||||
function cancel_ticket(id){
|
||||
var grid = $$('grid_tickets')
|
||||
var data = new Object()
|
||||
data['opt'] = 'cancel'
|
||||
data['id'] = id
|
||||
|
||||
webix.ajax().sync().post('tickets', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
grid.updateItem(id, values.row)
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_cancelar_ticket_click(){
|
||||
var grid = $$('grid_tickets')
|
||||
|
||||
if(grid.count() == 0){
|
||||
return
|
||||
}
|
||||
|
||||
var row = grid.getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un ticket')
|
||||
return
|
||||
}
|
||||
|
||||
if(row['estatus']=='Cancelado'){
|
||||
msg_error('El ticket ya esta cancelado')
|
||||
return
|
||||
}
|
||||
|
||||
if(row['estatus']=='Facturado'){
|
||||
msg_error('El ticket esta facturado')
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de cancelar el siguiente Ticket?<BR><BR>'
|
||||
msg += 'Folio: ' + row['folio']
|
||||
msg += '<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER'
|
||||
webix.confirm({
|
||||
title:'Cancelar Ticket',
|
||||
ok:'Si',
|
||||
cancel:'No',
|
||||
type:'confirm-error',
|
||||
text:msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
cancel_ticket(row['id'])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function chk_is_invoice_day_change(new_value, old_value){
|
||||
var value = Boolean(new_value)
|
||||
|
||||
show('fs_ticket_search_client', !value)
|
||||
enable('lst_global_periodicidad_2', value)
|
||||
enable('lst_global_months_2', value)
|
||||
|
||||
var current_date = new Date()
|
||||
var current_month = (current_date.getMonth() + 1).toString().padStart(2, '0')
|
||||
$$('lst_global_months_2').setValue(current_month)
|
||||
}
|
||||
|
||||
|
||||
function send_timbrar_invoice(id){
|
||||
webix.ajax().post('invoices', {opt: 'timbrar', id: id, update: false}, function(text, data){
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
webix.alert({
|
||||
title: 'Error al Timbrar',
|
||||
text: values.msg,
|
||||
type: 'alert-error'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function save_ticket_to_invoice(data){
|
||||
webix.ajax().sync().post('tickets', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
send_timbrar_invoice(values.id)
|
||||
$$('chk_is_invoice_day').setValue(false)
|
||||
$$('multi_tickets').setValue('tickets_home')
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_new_invoice_from_ticket_click(){
|
||||
var form = this.getFormView();
|
||||
var chk = $$('chk_is_invoice_day')
|
||||
var grid = $$('grid_tickets_invoice')
|
||||
var values = form.getValues()
|
||||
var tickets = []
|
||||
|
||||
if(!chk.getValue()){
|
||||
if(values.id_partner == 0){
|
||||
webix.UIManager.setFocus('tsearch_client_name')
|
||||
msg = 'Selecciona un cliente'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if(!grid.count()){
|
||||
msg = 'Agrega al menos un ticket a facturar'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
|
||||
grid.eachRow(function(row){
|
||||
tickets.push(row)
|
||||
})
|
||||
|
||||
var data = new Object()
|
||||
data['opt'] = 'invoice'
|
||||
|
||||
data['client'] = values.id_partner
|
||||
data['tickets'] = tickets
|
||||
data['is_invoice_day'] = chk.getValue()
|
||||
|
||||
var periodicidad = ''
|
||||
if(data['is_invoice_day']){
|
||||
periodicidad = $$('lst_global_periodicidad_2').getValue() + '|'
|
||||
periodicidad += $$('lst_global_months_2').getValue() + '|'
|
||||
periodicidad += new Date().getFullYear()
|
||||
}
|
||||
data['periodicidad'] = periodicidad
|
||||
|
||||
msg = 'Todos los datos son correctos.<BR><BR>'
|
||||
if(data['is_invoice_day']){
|
||||
msg += 'Es Factura Global.<BR><BR>'
|
||||
}
|
||||
msg += '¿Estás seguro de generar esta factura?'
|
||||
|
||||
webix.confirm({
|
||||
title: 'Generar Factura',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
save_ticket_to_invoice(data)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_tickets_active_double_click(id, e, node){
|
||||
this.move(id.row, -1, $$('grid_tickets_invoice'))
|
||||
}
|
||||
|
||||
|
||||
function grid_tickets_invoice_double_click(id, e, node){
|
||||
this.move(id.row, -1, $$('grid_tickets_active'))
|
||||
}
|
||||
|
||||
|
||||
function cmd_move_tickets_right_click(){
|
||||
var source = $$('grid_tickets_active')
|
||||
var target = $$('grid_tickets_invoice')
|
||||
_move_tickets(source, target)
|
||||
}
|
||||
|
||||
|
||||
function cmd_move_tickets_left_click(){
|
||||
var target = $$('grid_tickets_active')
|
||||
var source = $$('grid_tickets_invoice')
|
||||
_move_tickets(source, target)
|
||||
}
|
||||
|
||||
|
||||
function _move_tickets(source, target){
|
||||
var rows = source.getSelectedItem()
|
||||
|
||||
if(rows == undefined){
|
||||
source.eachRow(
|
||||
function(row){
|
||||
this.copy(row, -1, target)
|
||||
}
|
||||
)
|
||||
source.clearAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ticket_set_client(row){
|
||||
var form = $$('form_ticket_invoice')
|
||||
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
||||
form.setValues({
|
||||
id_partner: row.id,
|
||||
tsearch_client_key: '',
|
||||
tsearch_client_name: ''}, true)
|
||||
html += row.nombre + ' (' + row.rfc + ')</span>'
|
||||
$$('lbl_tclient').setValue(html)
|
||||
}
|
||||
|
||||
|
||||
function ticket_search_client_by_id(id){
|
||||
webix.ajax().get('/values/client', {'id': id}, {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
if (values.ok){
|
||||
ticket_set_client(values.row)
|
||||
}else{
|
||||
msg = 'No se encontró un cliente con la clave: ' + id
|
||||
msg_error(msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function tsearch_client_key_press(code, e){
|
||||
var value = this.getValue()
|
||||
if(code == 13 && value.length > 0){
|
||||
var id = parseInt(value, 10)
|
||||
if (isNaN(id)){
|
||||
msg_error('Captura una clave válida')
|
||||
}else{
|
||||
ticket_search_client_by_id(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function grid_ticket_clients_found_click(obj){
|
||||
ticket_set_client(obj)
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_notes_click(){
|
||||
win_ticket_notes.init()
|
||||
var values = $$('form_new_ticket').getValues()
|
||||
$$('ticket_notes').setValue(values.notas)
|
||||
$$('win_ticket_notes').show()
|
||||
to_end('ticket_notes')
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_save_note_click(){
|
||||
var value = $$('ticket_notes').getValue()
|
||||
$$('form_new_ticket').setValues({notas: value}, true)
|
||||
$$('win_ticket_notes').close()
|
||||
|
||||
}
|
||||
|
||||
|
||||
function print_ticket(id){
|
||||
var data = new Object()
|
||||
data['opt'] = 'print'
|
||||
data['id'] = id
|
||||
|
||||
webix.ajax().post('tickets', data, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
values = data.json();
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_tickets_click(id, e, node){
|
||||
if(id.column == 'pdf'){
|
||||
//~ window.open('/doc/tpdf/' + id, '_blank')
|
||||
get_ticket_pdf(id.row)
|
||||
return
|
||||
}
|
||||
|
||||
if(id.column == 'print'){
|
||||
print_ticket(id.row)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_report_pdf_click(){
|
||||
webix.toPDF($$('grid_tickets'), {
|
||||
ignore: {'pdf': true, 'print': true},
|
||||
filename: 'Reporte_Tickets',
|
||||
width: 612,
|
||||
height: 792,
|
||||
columns:{
|
||||
index: true,
|
||||
serie: {width: 50},
|
||||
folio: {width: 50},
|
||||
fecha: {width: 125},
|
||||
estatus: true,
|
||||
total: {css: 'right'},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_ticket_report_xls_click(){
|
||||
webix.toExcel($$('grid_tickets'), {
|
||||
filename: 'Reporte_Tickets',
|
||||
name: 'Tickets',
|
||||
ignore: {'pdf': true, 'print': true},
|
||||
rawValues: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_tdetails_render(data){
|
||||
var total = 0.0
|
||||
this.eachRow(function(id){
|
||||
var item = this.getItem(id)
|
||||
total += item.importe
|
||||
})
|
||||
var id = $$('grid_ticket_total_up').getFirstId()
|
||||
$$('grid_ticket_total_up').updateItem(id, {total: total})
|
||||
}
|
|
@ -1,30 +1,8 @@
|
|||
//~ Empresa Libre
|
||||
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
//~
|
||||
//~ This program is free software: you can redistribute it and/or modify
|
||||
//~ it under the terms of the GNU General Public License as published by
|
||||
//~ the Free Software Foundation, either version 3 of the License, or
|
||||
//~ (at your option) any later version.
|
||||
//~
|
||||
//~ This program is distributed in the hope that it will be useful,
|
||||
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//~ GNU General Public License for more details.
|
||||
//~
|
||||
//~ You should have received a copy of the GNU General Public License
|
||||
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
var PUBLICO = "PUBLICO EN GENERAL";
|
||||
var PUBLICO = "Público en general";
|
||||
var RFC_PUBLICO = "XAXX010101000";
|
||||
var RFC_EXTRANJERO = "XEXX010101000";
|
||||
var PAIS = "México";
|
||||
var DECIMALES = 2;
|
||||
//~ var DECIMALES_PU = 4;
|
||||
var DECIMALES_TAX = 4;
|
||||
var CLAVE_ANTICIPOS = '84111506';
|
||||
var CURRENCY_MN = 'MXN';
|
||||
var KEY_SAT_01 = '01010101';
|
||||
|
||||
|
||||
var db = new loki('data.db');
|
||||
|
@ -34,149 +12,20 @@ var table_pt = db.addCollection('productstaxes')
|
|||
var table_totals = db.addCollection('totals', {unique: ['tax']})
|
||||
var table_series = db.addCollection('series')
|
||||
var table_usocfdi = db.addCollection('usocfdi')
|
||||
var table_relaciones = db.addCollection('relaciones')
|
||||
var table_waypayment = db.addCollection('waypayment')
|
||||
|
||||
var msg = ''
|
||||
|
||||
var months = [
|
||||
{id: -1, value: 'Todos'},
|
||||
{id: 1, value: 'Enero'},
|
||||
{id: 2, value: 'Febrero'},
|
||||
{id: 3, value: 'Marzo'},
|
||||
{id: 4, value: 'Abril'},
|
||||
{id: 5, value: 'Mayo'},
|
||||
{id: 6, value: 'Junio'},
|
||||
{id: 7, value: 'Julio'},
|
||||
{id: 8, value: 'Agosto'},
|
||||
{id: 9, value: 'Septiembre'},
|
||||
{id: 10, value: 'Octubre'},
|
||||
{id: 11, value: 'Noviembre'},
|
||||
{id: 12, value: 'Diciembre'},
|
||||
]
|
||||
|
||||
var days = [
|
||||
{id: -1, value: '00'},
|
||||
{id: 1, value: '01'},
|
||||
{id: 2, value: '02'},
|
||||
{id: 3, value: '03'},
|
||||
{id: 4, value: '04'},
|
||||
{id: 5, value: '05'},
|
||||
{id: 6, value: '06'},
|
||||
{id: 7, value: '07'},
|
||||
{id: 8, value: '08'},
|
||||
{id: 9, value: '09'},
|
||||
{id: 10, value: '10'},
|
||||
{id: 11, value: '11'},
|
||||
{id: 12, value: '12'},
|
||||
{id: 13, value: '13'},
|
||||
{id: 14, value: '14'},
|
||||
{id: 15, value: '15'},
|
||||
{id: 16, value: '16'},
|
||||
{id: 17, value: '17'},
|
||||
{id: 18, value: '18'},
|
||||
{id: 19, value: '19'},
|
||||
{id: 20, value: '20'},
|
||||
{id: 21, value: '21'},
|
||||
{id: 22, value: '22'},
|
||||
{id: 23, value: '23'},
|
||||
{id: 24, value: '24'},
|
||||
{id: 25, value: '25'},
|
||||
{id: 26, value: '26'},
|
||||
{id: 27, value: '27'},
|
||||
{id: 28, value: '28'},
|
||||
{id: 29, value: '29'},
|
||||
{id: 30, value: '30'},
|
||||
{id: 31, value: '31'},
|
||||
]
|
||||
|
||||
|
||||
|
||||
function get_icon(tipo){
|
||||
icons = {
|
||||
xml: 'fa-file-code-o',
|
||||
pdf: 'fa-file-pdf-o',
|
||||
html: 'fa-html5',
|
||||
zip: 'fa-file-zip-o',
|
||||
email: 'fa-envelope-o',
|
||||
print: 'fa-print',
|
||||
table: 'fa-table',
|
||||
}
|
||||
return "<span class='webix_icon " + icons[tipo] + "'></span>"
|
||||
}
|
||||
|
||||
|
||||
function focus(name){
|
||||
webix.UIManager.setFocus(name)
|
||||
}
|
||||
|
||||
|
||||
function select_all(name){
|
||||
focus(name)
|
||||
$$(name).getInputNode().select()
|
||||
}
|
||||
|
||||
|
||||
function to_end(name){
|
||||
focus(name)
|
||||
var txt = $$(name)
|
||||
var pos = txt.getValue().length
|
||||
var height = txt.getInputNode().scrollHeight
|
||||
|
||||
webix.html.setSelectionRange(txt.getInputNode(), pos)
|
||||
txt.getInputNode().scrollTop = height
|
||||
}
|
||||
|
||||
|
||||
function showvar(values){
|
||||
function show(values){
|
||||
webix.message(JSON.stringify(values, null, 2))
|
||||
}
|
||||
|
||||
|
||||
function showtype(values){
|
||||
webix.message(typeof(values))
|
||||
}
|
||||
|
||||
|
||||
function show(nombre, value){
|
||||
if(value == '0'){
|
||||
value = false
|
||||
}
|
||||
if(value){
|
||||
$$(nombre).show()
|
||||
}else{
|
||||
$$(nombre).hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function show_column(table, column){
|
||||
$$(table).showColumn(column)
|
||||
}
|
||||
|
||||
|
||||
function enable(nombre, value){
|
||||
if(value == '0'){
|
||||
value = false
|
||||
}
|
||||
if(value){
|
||||
$$(nombre).enable()
|
||||
}else{
|
||||
$$(nombre).disable()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function msg_error(msg){
|
||||
if(!msg){
|
||||
msg = 'Error al consultar'
|
||||
}
|
||||
webix.message({type: 'error', text: msg})
|
||||
}
|
||||
|
||||
|
||||
function msg_ok(msg){
|
||||
webix.message({type: 'success', text: msg})
|
||||
function msg_sucess(msg){
|
||||
webix.message({type: 'sucess', text: msg})
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,78 +34,12 @@ Number.prototype.round = function(decimals){
|
|||
}
|
||||
|
||||
|
||||
String.prototype.is_number = function(){
|
||||
return /^\d+$/.test(this)
|
||||
}
|
||||
String.prototype.to_float = function(){
|
||||
return get_float(this)
|
||||
}
|
||||
String.prototype.to_float4 = function(){
|
||||
return get_float4(this)
|
||||
}
|
||||
|
||||
|
||||
function get_float(value){
|
||||
var f = parseFloat(value.replace('$', '').replace(/,/g, '').trim()).round(DECIMALES)
|
||||
if(!f){
|
||||
f = 0.00
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
|
||||
function get_float4(value){
|
||||
var f = parseFloat(value.replace('$', '').replace(/,/g, '').trim()).round(DECIMALES_TAX)
|
||||
if(!f){
|
||||
f = 0.00
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
|
||||
var format_decimal_2 = webix.Number.numToStr({
|
||||
groupSize: 3,
|
||||
decimalSize: 2,
|
||||
groupDelimiter: ",",
|
||||
decimalDelimiter: "."
|
||||
})
|
||||
|
||||
var format_decimal_4 = webix.Number.numToStr({
|
||||
groupSize: 3,
|
||||
decimalSize: 4,
|
||||
groupDelimiter: ",",
|
||||
decimalDelimiter: "."
|
||||
})
|
||||
|
||||
|
||||
function format_currency(value){
|
||||
var fv = ''
|
||||
if(get_config('decimales_precios') == 4){
|
||||
fv = '$ ' + format_decimal_4(value)
|
||||
}else{
|
||||
fv = '$ ' + format_decimal_2(value)
|
||||
}
|
||||
return fv
|
||||
}
|
||||
|
||||
|
||||
function format_currency2(value){
|
||||
return '$ ' + format_decimal_2(value)
|
||||
}
|
||||
|
||||
|
||||
function format_currency4(value){
|
||||
return '$ ' + format_decimal_4(value)
|
||||
}
|
||||
|
||||
|
||||
webix.protoUI({
|
||||
$cssName: "text",
|
||||
name: "currency",
|
||||
$init:function(){
|
||||
this.attachEvent("onItemClick", function(){
|
||||
this.$setValue(this.config.raw, true)
|
||||
this.getInputNode().select()
|
||||
})
|
||||
this.attachEvent("onBlur", function(){
|
||||
this.$setValue(this.config.value)
|
||||
|
@ -268,138 +51,24 @@ webix.protoUI({
|
|||
$setValue:function(value, raw){
|
||||
this.config.raw = value
|
||||
if(!raw){
|
||||
value = format_currency(value)
|
||||
value = webix.i18n.priceFormat(value)
|
||||
}
|
||||
this.getInputNode().value = value
|
||||
}
|
||||
}, webix.ui.text)
|
||||
|
||||
|
||||
webix.protoUI({
|
||||
$cssName: "text",
|
||||
name: "currency4",
|
||||
$init:function(){
|
||||
this.attachEvent("onItemClick", function(){
|
||||
this.$setValue(this.config.raw, true)
|
||||
this.getInputNode().select()
|
||||
})
|
||||
this.attachEvent("onBlur", function(){
|
||||
this.$setValue(this.config.value)
|
||||
})
|
||||
},
|
||||
$render:function(){
|
||||
this.$setValue(this.config.value)
|
||||
},
|
||||
$setValue:function(value, raw){
|
||||
this.config.raw = value
|
||||
if(!raw){
|
||||
value = format_currency4(value)
|
||||
}
|
||||
this.getInputNode().value = value
|
||||
webix.ui.datafilter.rowCount = webix.extend({
|
||||
refresh:function(master, node, value){
|
||||
node.firstChild.innerHTML = master.count();
|
||||
}
|
||||
}, webix.ui.text)
|
||||
|
||||
|
||||
webix.protoUI({
|
||||
$cssName: "text",
|
||||
name: "currency2",
|
||||
$init:function(){
|
||||
this.attachEvent("onItemClick", function(){
|
||||
this.$setValue(this.config.raw, true)
|
||||
this.getInputNode().select()
|
||||
})
|
||||
this.attachEvent("onBlur", function(){
|
||||
this.$setValue(this.config.value)
|
||||
})
|
||||
},
|
||||
$render:function(){
|
||||
this.$setValue(this.config.value)
|
||||
},
|
||||
$setValue:function(value, raw){
|
||||
this.config.raw = value
|
||||
if(!raw){
|
||||
value = format_currency2(value)
|
||||
}
|
||||
this.getInputNode().value = value
|
||||
}
|
||||
}, webix.ui.text)
|
||||
|
||||
|
||||
webix.ui.datafilter.countRows = webix.extend({
|
||||
refresh:function(master, node, value){
|
||||
node.firstChild.innerHTML = master.count();
|
||||
}
|
||||
}, webix.ui.datafilter.summColumn);
|
||||
|
||||
|
||||
webix.ui.datafilter.summActive = webix.extend({
|
||||
refresh:function(master, node, value){
|
||||
node.firstChild.innerHTML = this.summGenerate(master);
|
||||
},
|
||||
summGenerate:function(master){
|
||||
var sum = 0
|
||||
master.eachRow(function(id){
|
||||
var row = master.getItem(id)
|
||||
if(row.estatus == 'Generado'){
|
||||
var importe = row.total
|
||||
if(typeof importe === 'string'){
|
||||
importe = row.total.to_float()
|
||||
}
|
||||
sum += importe
|
||||
}
|
||||
})
|
||||
return webix.i18n.priceFormat(sum)
|
||||
}
|
||||
}, webix.ui.datafilter.summColumn);
|
||||
|
||||
|
||||
webix.ui.datafilter.summTimbrada = webix.extend({
|
||||
refresh:function(master, node, value){
|
||||
node.firstChild.innerHTML = this.summGenerate(master);
|
||||
},
|
||||
summGenerate:function(master){
|
||||
var sum = 0
|
||||
master.eachRow(function(id){
|
||||
var row = master.getItem(id)
|
||||
if(row.estatus == 'Timbrada'){
|
||||
var importe = row.total_mn
|
||||
if(typeof importe === 'string'){
|
||||
importe = row.total_mn.to_float()
|
||||
}
|
||||
sum += importe
|
||||
}
|
||||
})
|
||||
return webix.i18n.priceFormat(sum)
|
||||
}
|
||||
}, webix.ui.datafilter.summColumn);
|
||||
|
||||
|
||||
webix.ui.datafilter.summTimbradaN = webix.extend({
|
||||
refresh:function(master, node, value){
|
||||
node.firstChild.innerHTML = this.summGenerate(master);
|
||||
},
|
||||
summGenerate:function(master){
|
||||
var sum = 0
|
||||
master.eachRow(function(id){
|
||||
var row = master.getItem(id)
|
||||
if(row.estatus == 'Timbrado'){
|
||||
var importe = row.total
|
||||
if(typeof importe === 'string'){
|
||||
importe = row.total.to_float()
|
||||
}
|
||||
sum += importe
|
||||
}
|
||||
})
|
||||
return webix.i18n.priceFormat(sum)
|
||||
}
|
||||
}, webix.ui.datafilter.summColumn);
|
||||
|
||||
}, webix.ui.datafilter.summColumn)
|
||||
|
||||
|
||||
function validate_rfc(value){
|
||||
rfc = value.trim().toUpperCase();
|
||||
if ( rfc == ""){
|
||||
msg_error('El RFC no puede estar vacío')
|
||||
webix.message({ type:"error", text:"El RFC no puede estar vacío" });
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -411,93 +80,41 @@ function validate_rfc(value){
|
|||
start = 2
|
||||
}
|
||||
if (rfc.length != length){
|
||||
msg_error('Longitud incorrecta del RFC')
|
||||
webix.message({ type:"error", text:"Longitud incorrecta del RFC" });
|
||||
return false
|
||||
}
|
||||
if (tipo_persona < 3 && (rfc == RFC_PUBLICO || rfc == RFC_EXTRANJERO)){
|
||||
msg_error('RFC incorrecto')
|
||||
webix.message({ type:"error", text:"RFC incorrecto" });
|
||||
return false
|
||||
}
|
||||
|
||||
var part = rfc.slice(0, start);
|
||||
var re = new RegExp('[a-z&Ñ]{' + start + '}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('El RFC tiene caractéres inválidos al inicio')
|
||||
webix.message({ type:"error", text: "El RFC tiene caractéres inválidos al inicio" });
|
||||
return false
|
||||
}
|
||||
part = rfc.slice(-3);
|
||||
re = new RegExp('[a-z0-9]{3}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('El RFC tiene caractéres inválidos al final')
|
||||
webix.message({ type:"error", text: "El RFC tiene caractéres inválidos al final" });
|
||||
return false
|
||||
}
|
||||
|
||||
part = rfc.slice(-9, -3);
|
||||
re = new RegExp('[0-9]{6}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('Fecha inválida')
|
||||
webix.message({ type:"error", text: "Fecha inválida" });
|
||||
return false
|
||||
}
|
||||
var month = parseInt(part.slice(-4, -2))
|
||||
if (month == 0 || month > 12 ){
|
||||
msg_error('Fecha inválida')
|
||||
webix.message({ type:"error", text: "Fecha inválida" });
|
||||
return false
|
||||
}
|
||||
var day = parseInt(part.slice(-2))
|
||||
if (day == 0 || day > 31 ){
|
||||
msg_error('Fecha inválida')
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
function validar_rfc(value){
|
||||
rfc = value.trim().toUpperCase();
|
||||
if (rfc == ""){
|
||||
msg_error('El RFC no puede estar vacío')
|
||||
return false
|
||||
}
|
||||
|
||||
if (rfc.length < 12 || rfc.length > 13){
|
||||
msg_error('Longitud incorrecta del RFC')
|
||||
return false
|
||||
}
|
||||
|
||||
var length = rfc.length
|
||||
var start = 4
|
||||
if(length==12){
|
||||
start = 2
|
||||
}
|
||||
|
||||
var part = rfc.slice(0, start);
|
||||
var re = new RegExp('[a-z&Ñ]{' + start + '}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('El RFC tiene caractéres inválidos al inicio')
|
||||
return false
|
||||
}
|
||||
part = rfc.slice(-3);
|
||||
re = new RegExp('[a-z0-9]{3}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('El RFC tiene caractéres inválidos al final')
|
||||
return false
|
||||
}
|
||||
|
||||
part = rfc.slice(-9, -3);
|
||||
re = new RegExp('[0-9]{6}', 'i');
|
||||
if (!part.match(re)){
|
||||
msg_error('Fecha inválida')
|
||||
return false
|
||||
}
|
||||
var month = parseInt(part.slice(-4, -2))
|
||||
if (month == 0 || month > 12 ){
|
||||
msg_error('Fecha inválida')
|
||||
return false
|
||||
}
|
||||
var day = parseInt(part.slice(-2))
|
||||
if (day == 0 || day > 31 ){
|
||||
msg_error('Fecha inválida')
|
||||
webix.message({ type:"error", text: "Fecha inválida" });
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -530,167 +147,3 @@ function get_config(value){
|
|||
return key.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
webix.DataDriver.plainjs = webix.extend({
|
||||
arr2hash:function(data){
|
||||
var hash = {};
|
||||
for (var i=0; i<data.length; i++){
|
||||
var pid = data[i].parent_id;
|
||||
if (!hash[pid]) hash[pid]=[];
|
||||
hash[pid].push(data[i]);
|
||||
}
|
||||
return hash;
|
||||
},
|
||||
hash2tree:function(hash, level){
|
||||
var top = hash[level];
|
||||
for (var i=0; i<top.length; i++){
|
||||
var branch = top[i].id;
|
||||
if (hash[branch])
|
||||
top[i].data = this.hash2tree(hash, branch);
|
||||
}
|
||||
return top;
|
||||
},
|
||||
getRecords:function(data, id){
|
||||
var hash = this.arr2hash(data);
|
||||
return this.hash2tree(hash, 0);
|
||||
}
|
||||
}, webix.DataDriver.json)
|
||||
|
||||
|
||||
function get_forma_pago(control){
|
||||
webix.ajax().get('/values/formapago', {key: true}, function(text, data){
|
||||
var values = data.json()
|
||||
$$(control).getList().parse(values)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_way_payment(){
|
||||
webix.ajax().get('/satformapago', {opt: 'active_by_id'}, function(text, data){
|
||||
var values = data.json()
|
||||
table_waypayment.clear()
|
||||
table_waypayment.insert(values)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function set_way_payment(control, filter99=false, current_way_payment=''){
|
||||
if(filter99){
|
||||
var values = table_waypayment.chain().find({'value': { '$ne' : 'Por definir' }}).data()
|
||||
}else{
|
||||
var values = table_waypayment.chain().data()
|
||||
}
|
||||
$$(control).getList().parse(values)
|
||||
if(current_way_payment){
|
||||
$$(control).setValue(current_way_payment)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function validate_regexp(value, pattern){
|
||||
re = new RegExp(pattern, 'i');
|
||||
if(value.match(re)){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function validate_pedimento(value){
|
||||
var pattern = '[0-9]{2} [0-9]{2} [0-9]{4} [0-9]{7}'
|
||||
return validate_regexp(value, pattern)
|
||||
}
|
||||
|
||||
|
||||
function validate_curp(value){
|
||||
var pattern = '[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][A-Z]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,A-Z][0-9]'
|
||||
return validate_regexp(value, pattern)
|
||||
}
|
||||
|
||||
|
||||
//config may as well include only text, color and date hash
|
||||
webix.editors.$popup = {
|
||||
text:{
|
||||
view: 'popup', width:500, height:200,
|
||||
body: {view: 'textarea'}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function pause(milliseconds) {
|
||||
var dt = new Date();
|
||||
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
|
||||
}
|
||||
|
||||
|
||||
|
||||
//~ Revisado
|
||||
|
||||
function lst_clear(lst){
|
||||
lst.setValue('')
|
||||
lst.define('options', [])
|
||||
lst.refresh()
|
||||
}
|
||||
|
||||
|
||||
function lst_parse(lst, values){
|
||||
lst.getList().parse(values)
|
||||
}
|
||||
|
||||
|
||||
function lst_parse2(lst_name, values){
|
||||
obj = $$(lst_name)
|
||||
obj.getList().parse(values)
|
||||
}
|
||||
|
||||
|
||||
function set_value(control, value){
|
||||
obj = $$(control)
|
||||
obj.blockEvent()
|
||||
obj.setValue(value)
|
||||
obj.unblockEvent()
|
||||
}
|
||||
|
||||
|
||||
function grid_parse(grid_name, values){
|
||||
obj = $$(grid_name)
|
||||
obj.clearAll()
|
||||
obj.parse(values)
|
||||
}
|
||||
|
||||
|
||||
function activate_tab(parent, name){
|
||||
$$(parent).getTabbar().setValue(name)
|
||||
}
|
||||
|
||||
|
||||
var opt_global_periodicidad = [
|
||||
{id: '01', value: '[01] Diario'},
|
||||
{id: '02', value: '[02] Semanal'},
|
||||
{id: '03', value: '[03] Quincenal'},
|
||||
{id: '04', value: '[04] Mensual'},
|
||||
{id: '05', value: '[05] Bimestral'},
|
||||
]
|
||||
|
||||
var opt_global_months = [
|
||||
{id: '01', value: '[01] Enero'},
|
||||
{id: '02', value: '[02] Febrero'},
|
||||
{id: '03', value: '[03] Marzo'},
|
||||
{id: '04', value: '[04] Abril'},
|
||||
{id: '05', value: '[05] Mayo'},
|
||||
{id: '06', value: '[06] Junio'},
|
||||
{id: '07', value: '[07] Julio'},
|
||||
{id: '08', value: '[08] Agosto'},
|
||||
{id: '09', value: '[09] Septiembre'},
|
||||
{id: '10', value: '[10] Octubre'},
|
||||
{id: '11', value: '[11] Noviembre'},
|
||||
{id: '12', value: '[12] Diciembre'},
|
||||
{id: '13', value: '[13] Enero-Febrero'},
|
||||
{id: '14', value: '[14] Marzo-Abril'},
|
||||
{id: '15', value: '[15] Mayo-Junio'},
|
||||
{id: '16', value: '[16] Julio-Agosto'},
|
||||
{id: '17', value: '[17] Septiembre-Octubre'},
|
||||
{id: '18', value: '[18] Noviembre-Diciembre'},
|
||||
]
|
||||
|
|
|
@ -29,6 +29,10 @@ webix.i18n.locales["es-ES"] = {
|
|||
today: "Hoy"
|
||||
},
|
||||
|
||||
controls:{
|
||||
select:"Seleccione",
|
||||
invalidMessage: "Valor de entrada no válido"
|
||||
},
|
||||
dataExport:{
|
||||
page:"Página",
|
||||
of:"de"
|
||||
|
@ -77,12 +81,7 @@ webix.i18n.locales["es-ES"] = {
|
|||
italic: "Itálico"
|
||||
},
|
||||
combo:{
|
||||
select:"Seleccionar",
|
||||
selectAll:"Seleccionar todo",
|
||||
unselectAll:"Deselecciona todo"
|
||||
},
|
||||
message:{
|
||||
ok:"OK",
|
||||
cancel:"Cancelar"
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
webix.protoUI({
|
||||
name: "sidebar",
|
||||
defaults:{
|
||||
titleHeight: 40,
|
||||
type: "sideBar",
|
||||
activeTitle: true,
|
||||
select: true,
|
||||
scroll: false,
|
||||
collapsed: false,
|
||||
collapsedWidth: 41,
|
||||
position: "left",
|
||||
width: 250,
|
||||
mouseEventDelay: 10
|
||||
},
|
||||
$init: function(config){
|
||||
this.$ready.push(this._initSidebar);
|
||||
this.$ready.push(this._initContextMenu);
|
||||
},
|
||||
|
||||
on_context:{},
|
||||
on_mouse_move:{},
|
||||
_initSidebar: function(){
|
||||
this._fullWidth = this.config.width;
|
||||
this.attachEvent("onBeforeOpen", function(id){
|
||||
if(!this.config.multipleOpen)
|
||||
this.closeAll();
|
||||
return !this.config.collapsed;
|
||||
});
|
||||
this.attachEvent("onItemClick", function(id, ev, node){
|
||||
if(this.getPopup() && !this.getPopup().config.hidden)
|
||||
ev.showpopup = true;
|
||||
if(webix.env.touch)
|
||||
this._showPopup(id, node);
|
||||
});
|
||||
this.attachEvent("onBeforeSelect", function(id){
|
||||
if(!this.getItem(id).$count){
|
||||
var selected = this.getSelectedId();
|
||||
if(selected && id!= selected){
|
||||
var parentId = this.getParentId(selected);
|
||||
|
||||
this.removeCss(parentId, "webix_sidebar_selected");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
this.attachEvent("onAfterSelect", function(id){
|
||||
var parentId = this.getParentId(id);
|
||||
this.addCss(parentId, "webix_sidebar_selected");
|
||||
var title = this.getPopupTitle();
|
||||
|
||||
title.callEvent("onMasterSelect",[id]);
|
||||
});
|
||||
this.attachEvent("onMouseMove", function(id, ev, node){
|
||||
this._showPopup(id, node);
|
||||
});
|
||||
|
||||
if(this.config.collapsed)
|
||||
this.collapse();
|
||||
},
|
||||
_showPopup: function(id, node){
|
||||
if(this.config.collapsed){
|
||||
var popup = this.getPopup();
|
||||
|
||||
if(popup){
|
||||
var title = this.getPopupTitle();
|
||||
if(title){
|
||||
this._updateTitle(id);
|
||||
}
|
||||
var list = this.getPopupList();
|
||||
if(list){
|
||||
this._updateList(id);
|
||||
}
|
||||
var x = (this.config.position == "left"?this.config.collapsedWidth:-popup.config.width);
|
||||
popup.show(node, {x: x , y:-1});
|
||||
}
|
||||
}
|
||||
},
|
||||
_updateTitle: function(id){
|
||||
var title = this.getPopupTitle();
|
||||
title.masterId = id;
|
||||
title.parse(this.getItem(id));
|
||||
var selectedId = this.getSelectedId();
|
||||
if(selectedId && this.getParentId(selectedId) == id){
|
||||
webix.html.addCss(title.$view, "webix_sidebar_selected", true);
|
||||
}
|
||||
else{
|
||||
webix.html.removeCss(title.$view, "webix_sidebar_selected");
|
||||
}
|
||||
|
||||
if(selectedId == id){
|
||||
webix.html.addCss(title.$view, "webix_selected", true);
|
||||
}
|
||||
else{
|
||||
webix.html.removeCss(title.$view, "webix_selected");
|
||||
}
|
||||
},
|
||||
_updateList: function(id){
|
||||
var list = this.getPopupList();
|
||||
list.masterId = id;
|
||||
var selectedId = this.getSelectedId();
|
||||
var data = [].concat(webix.copy(this.data.getBranch(id)));
|
||||
list.unselect();
|
||||
if(data.length){
|
||||
list.show();
|
||||
list.data.importData(data);
|
||||
if(list.exists(selectedId))
|
||||
list.select(selectedId);
|
||||
}
|
||||
else
|
||||
list.hide();
|
||||
|
||||
},
|
||||
_initContextMenu: function(){
|
||||
var config = this.config,
|
||||
popup;
|
||||
|
||||
if(config.popup){
|
||||
popup = webix.$$(config.popup);
|
||||
}
|
||||
if(!popup){
|
||||
var dirClassName = (config.position=="left"?"webix_sidebar_popup_left":"webix_sidebar_popup_right");
|
||||
var popupConfig = {
|
||||
view:"popup",
|
||||
css: "webix_sidebar_popup "+dirClassName,
|
||||
autofit: false,
|
||||
width: this._fullWidth - this.config.collapsedWidth,
|
||||
borderless: true,
|
||||
padding:0,
|
||||
body:{
|
||||
rows:[
|
||||
{
|
||||
view: "template", borderless: true, css: "webix_sidebar_popup_title",
|
||||
template: "#value#", height: this.config.titleHeight+2,
|
||||
on:{
|
||||
onMasterSelect: function(id){
|
||||
var master = this.getTopParentView().master;
|
||||
if( master && master.getParentId(id) == this.masterId){
|
||||
webix.html.addCss(this.$view, "webix_sidebar_selected", true);
|
||||
}
|
||||
if(master.config.collapsed && master.getItem(id).$level ==1){
|
||||
webix.html.addCss(this.$view, "webix_selected", true);
|
||||
}
|
||||
}
|
||||
},
|
||||
onClick:{
|
||||
webix_template: function(){
|
||||
var id = this.masterId;
|
||||
var master = this.getTopParentView().master;
|
||||
if(!master.getItem(id).$count)
|
||||
master.select(id);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ view: "list", select: true, borderless: true, css: "webix_sidebar_popup_list", autoheight: true,
|
||||
on:{
|
||||
onAfterSelect: function(id){
|
||||
this.getTopParentView().master.select(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
webix.extend(popupConfig, config.popup||{}, true);
|
||||
popup = webix.ui(popupConfig);
|
||||
popup.master = this;
|
||||
}
|
||||
popup.attachEvent("onBeforeShow",function(){
|
||||
return config.collapsed;
|
||||
});
|
||||
var master = this;
|
||||
var h = webix.event(document.body,"mousemove", function(e){
|
||||
var trg = e.target || e.srcElement;
|
||||
if(!popup.config.hidden && !popup.$view.contains(trg) && !master.$view.firstChild.contains(trg)){
|
||||
popup.hide();
|
||||
}
|
||||
});
|
||||
this.attachEvent("onDestruct", function(){
|
||||
if(webix.removeEvent)
|
||||
webix.removeEvent(h);
|
||||
if(popup)
|
||||
popup.destructor();
|
||||
});
|
||||
config.popupId = popup.config.id;
|
||||
},
|
||||
getPopup: function(){
|
||||
return webix.$$(this.config.popupId);
|
||||
},
|
||||
getPopupTitle: function(){
|
||||
var popup = this.getPopup();
|
||||
return popup.getBody().getChildViews()[0];
|
||||
},
|
||||
getPopupList: function(){
|
||||
var popup = this.getPopup();
|
||||
return popup.getBody().getChildViews()[1];
|
||||
},
|
||||
position_setter:function(value){
|
||||
var newPos = value;
|
||||
var oldPos = value=="left"?"right":"left";
|
||||
|
||||
webix.html.removeCss(this.$view, "webix_sidebar_"+oldPos);
|
||||
webix.html.addCss(this.$view, "webix_sidebar_"+newPos, true);
|
||||
|
||||
var popup = this.getPopup();
|
||||
if(popup){
|
||||
var popupEl = popup.$view;
|
||||
webix.html.removeCss(popupEl, "webix_sidebar_popup_"+oldPos);
|
||||
webix.html.addCss(popupEl, "webix_sidebar_popup_"+newPos, true);
|
||||
}
|
||||
return value;
|
||||
},
|
||||
collapse: function(){
|
||||
this.define("collapsed", true);
|
||||
},
|
||||
expand: function(){
|
||||
this.define("collapsed", false);
|
||||
},
|
||||
toggle: function(){
|
||||
var collapsed = !this.config.collapsed;
|
||||
this.define("collapsed", collapsed);
|
||||
},
|
||||
collapsed_setter: function(value){
|
||||
var width;
|
||||
|
||||
if(!value){
|
||||
width = this._fullWidth;
|
||||
}
|
||||
else{
|
||||
width = this.config.collapsedWidth;
|
||||
this.closeAll();
|
||||
}
|
||||
|
||||
if(!value){
|
||||
this.type.collapsed = false;
|
||||
webix.html.addCss(this.$view, "webix_sidebar_expanded", true);
|
||||
}
|
||||
else{
|
||||
this.type.collapsed = true;
|
||||
webix.html.removeCss(this.$view, "webix_sidebar_expanded");
|
||||
}
|
||||
|
||||
this.define("width",width);
|
||||
this.resize();
|
||||
|
||||
return value;
|
||||
}
|
||||
}, webix.ui.tree);
|
||||
|
||||
webix.type(webix.ui.tree, {
|
||||
name:"sideBar",
|
||||
height: "auto",
|
||||
css: "webix_sidebar",
|
||||
template: function(obj, common){
|
||||
if(common.collapsed)
|
||||
return common.icon(obj, common);
|
||||
return common.arrow(obj, common)+common.icon(obj, common) +"<span>"+obj.value+"</span>";
|
||||
},
|
||||
arrow: function(obj, common){
|
||||
var html = "";
|
||||
var open = "";
|
||||
for (var i=1; i<=obj.$level; i++){
|
||||
if (i==obj.$level && obj.$count){
|
||||
var className = "webix_sidebar_dir_icon webix_icon fa-angle-"+(obj.open?"down":"left");
|
||||
html+="<span class='"+className+"'></span>";
|
||||
}
|
||||
}
|
||||
return html;
|
||||
},
|
||||
icon:function(obj, common){
|
||||
if(obj.icon)
|
||||
return "<span class='webix_icon webix_sidebar_icon fa-"+obj.icon+"'></span>";
|
||||
return "";
|
||||
}
|
||||
});
|
|
@ -1,688 +0,0 @@
|
|||
//~ Empresa Libre
|
||||
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
//~
|
||||
//~ This program is free software: you can redistribute it and/or modify
|
||||
//~ it under the terms of the GNU General Public License as published by
|
||||
//~ the Free Software Foundation, either version 3 of the License, or
|
||||
//~ (at your option) any later version.
|
||||
//~
|
||||
//~ This program is distributed in the hope that it will be useful,
|
||||
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//~ GNU General Public License for more details.
|
||||
//~
|
||||
//~ You should have received a copy of the GNU General Public License
|
||||
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
var toolbar_banco = [
|
||||
{view: 'richselect', id: 'lst_cuentas_banco', label: 'Cuenta',
|
||||
labelWidth: 100, options: []},
|
||||
{view: 'text', id: 'txt_cuenta_moneda', label: 'Moneda', readonly: true},
|
||||
{view: 'currency2', id: 'txt_cuenta_saldo', label: 'Saldo', readonly: true,
|
||||
inputAlign: 'right', value: 0}
|
||||
]
|
||||
|
||||
|
||||
var toolbar_filtro_cuenta = [
|
||||
{view: 'richselect', id: 'filter_cuenta_year', label: 'Año',
|
||||
labelAlign: 'right', labelWidth: 50, width: 150, options: []},
|
||||
{view: 'richselect', id: 'filter_cuenta_month', label: 'Mes',
|
||||
labelAlign: 'right', labelWidth: 50, width: 200, options: months},
|
||||
{view: 'daterangepicker', id: 'filter_cuenta_dates', label: 'Fechas',
|
||||
labelAlign: 'right', width: 300},
|
||||
{},
|
||||
]
|
||||
|
||||
|
||||
var toolbar_movimientos_banco = [
|
||||
{view: 'button', id: 'cmd_agregar_retiro', label: 'Retiro',
|
||||
type: 'iconButton', autowidth: true, icon: 'minus'},
|
||||
{view: 'button', id: 'cmd_agregar_deposito', label: 'Depósito',
|
||||
type: 'iconButton', autowidth: true, icon: 'plus'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_complemento_pago', label: 'Generar Factura de Pago',
|
||||
type: 'iconButton', autowidth: true, icon: 'file-code-o'},
|
||||
{view: 'button', id: 'cmd_show_invoice_pay', label: 'Ver Facturas de Pago',
|
||||
type: 'iconButton', autowidth: true, icon: 'table'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_cancelar_movimiento', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cuentabanco_cols = [
|
||||
{id: 'id', header:'ID', hidden: true},
|
||||
{id: 'fecha', header: 'Fecha', width: 150},
|
||||
{id: 'numero_operacion', header: 'Referencia'},
|
||||
{id: 'way_payment', header: 'Forma de Pago', hidden: true},
|
||||
{id: 'descripcion', header: ['Descripción', {content: 'textFilter'}],
|
||||
fillspace:true},
|
||||
{id: 'retiro', header: ['Retiro', {content: 'numberFilter'}],
|
||||
width: 125, format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'deposito', header: ['Depósito', {content: 'numberFilter'}],
|
||||
width: 125, format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'saldo', header: ['Saldo'],
|
||||
width: 125, format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'invoice', header: ['FP'], width: 40, css: 'center', hidden: true},
|
||||
]
|
||||
|
||||
|
||||
var grid_cuentabanco = {
|
||||
view: 'datatable',
|
||||
id: 'grid_cuentabanco',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_cuentabanco_cols,
|
||||
}
|
||||
|
||||
|
||||
var grid_cfdi_por_pagar_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'serie', header: 'Serie', adjust: 'data'},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'data', css: 'right'},
|
||||
{id: 'uuid', header: 'UUID', width: 250, hidden: true},
|
||||
{id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'},
|
||||
{id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'},
|
||||
{id: 'estatus', header: 'Estatus', adjust: 'header'},
|
||||
{id: 'cliente', header: ['Razón Social', {content: 'selectFilter'}],
|
||||
fillspace:true, sort: 'string'},
|
||||
{id: 'total', header: ['Total'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right', hidden: true},
|
||||
{id: 'currency', header: ['Moneda', {content: 'selectFilter'}],
|
||||
adjust: 'data', sort: 'string', hidden: true},
|
||||
{id: 'total_mn', header: ['Total M.N'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'saldo', header: ['Saldo'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cfdi_este_deposito_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'serie', header: 'Serie', adjust: 'data'},
|
||||
{id: 'folio', header: 'Folio', adjust: 'data', css: 'right'},
|
||||
{id: 'uuid', header: 'UUID', width: 250, hidden: true},
|
||||
{id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'},
|
||||
{id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'},
|
||||
{id: 'estatus', header: 'Estatus', adjust: 'header'},
|
||||
{id: 'cliente', header: ['Razón Social'], fillspace: true},
|
||||
{id: 'total', header: ['Total'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right', hidden: true},
|
||||
{id: 'currency', header: ['Moneda', {content: 'selectFilter'}],
|
||||
adjust: 'data', sort: 'string', hidden: true},
|
||||
{id: 'total_mn', header: ['Total M.N'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'saldo', header: ['Saldo'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'this_pay', header: ['Este pago'], width: 125, sort: 'int', hidden: true,
|
||||
format: webix.i18n.priceFormat, css: 'right', editor: 'text'},
|
||||
{id: 'importe', header: ['Este pago'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right', editor: 'text'},
|
||||
{id: 'type_change', header: ['T.C.'], width: 75, hidden: true,
|
||||
format: format_currency4, css: 'right'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cfdi_pay_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: 'serie', header: ["Serie"], adjust: "data", sort: 'string'},
|
||||
{id: 'folio', header: ['Folio'], adjust: 'data',
|
||||
sort: 'int', css: 'right', footer: {text: 'Facturas', colspan: 3}},
|
||||
{id: "uuid", header: ["UUID"], adjust: "data",
|
||||
sort:"string", hidden:true},
|
||||
{id: "fecha", header: ["Fecha y Hora"],
|
||||
adjust: "data", sort: "string"},
|
||||
{id: "tipo_comprobante", header: ["Tipo"],
|
||||
adjust: 'header', sort: 'string'},
|
||||
{id: "estatus", header: ["Estatus"],
|
||||
adjust: "data", sort:"string"},
|
||||
{id: 'cliente', header: ['Razón Social'], fillspace: true},
|
||||
{id: 'xml', header: 'XML', adjust: 'data', template: get_icon('xml')},
|
||||
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
|
||||
{id: 'email', header: '@', adjust: 'data', template: get_icon('email')}
|
||||
]
|
||||
|
||||
|
||||
var grid_pay_related_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'serie', header: 'Serie', adjust: 'data'},
|
||||
{id: 'folio', header: 'Folio', adjust: 'data', css: 'right'},
|
||||
{id: 'uuid', header: 'UUID', width: 250, hidden: true},
|
||||
{id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'},
|
||||
{id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'},
|
||||
{id: 'estatus', header: 'Estatus', adjust: 'header'},
|
||||
{id: 'cliente', header: ['Razón Social'], fillspace: true},
|
||||
{id: 'total', header: ['Total'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'saldo', header: ['Saldo'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right', css: 'right',
|
||||
footer: 'Importe Depósito'},
|
||||
{id: 'importe', header: ['Este pago'], width: 125, sort: 'int',
|
||||
format: webix.i18n.priceFormat, css: 'right',
|
||||
footer: {content: 'summColumn', css: 'right'}},
|
||||
]
|
||||
|
||||
|
||||
var grid_cfdi_por_pagar = {
|
||||
view: 'datatable',
|
||||
id: 'grid_cfdi_por_pagar',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
autoConfig: false,
|
||||
adjust: true,
|
||||
height: 250,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
drag: true,
|
||||
columns: grid_cfdi_por_pagar_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var grid_cfdi_este_deposito = {
|
||||
view: 'datatable',
|
||||
id: 'grid_cfdi_este_deposito',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
autoConfig: false,
|
||||
adjust: true,
|
||||
height: 200,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
drag: true,
|
||||
editable: true,
|
||||
columns: grid_cfdi_este_deposito_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var grid_cfdi_pay = {
|
||||
view: 'datatable',
|
||||
id: 'grid_cfdi_pay',
|
||||
select: 'row',
|
||||
autoConfig: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_cfdi_pay_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var grid_pay_related = {
|
||||
view: 'datatable',
|
||||
id: 'grid_pay_related',
|
||||
select: 'row',
|
||||
autoConfig: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
footer: true,
|
||||
columns: grid_pay_related_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var grid_bank_invoice_pay_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: 'serie', header: ["Serie"], adjust: "data", sort: 'string',
|
||||
template: '{common.subrow()} #serie#'},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
|
||||
sort: 'int', css: 'right', footer: {text: 'Facturas', colspan: 3}},
|
||||
{id: "uuid", header: ["UUID", {content: "textFilter"}], adjust: "data",
|
||||
sort:"string", hidden:true},
|
||||
{id: "fecha", header: ["Fecha y Hora"], width: 135,
|
||||
sort: "string"},
|
||||
{id: "tipo_comprobante", header: ["Tipo"], adjust: 'data',
|
||||
sort: 'string'},
|
||||
{id: "estatus", header: ["Estatus", {content: "selectFilter"}],
|
||||
adjust: "header", sort:"string"},
|
||||
{id: 'movimiento', header: ['Movimiento', {content: "selectFilter"}],
|
||||
adjust: 'data', sort: 'string'},
|
||||
{id: 'total', header: ['Total', {content: 'numberFilter'}],
|
||||
width: 125, sort: 'int', format: webix.i18n.priceFormat, css: 'right',
|
||||
hidden: true},
|
||||
{id: 'currency', header: ['Moneda', {content: 'selectFilter'}],
|
||||
adjust: 'data', sort: 'string', hidden: true},
|
||||
{id: 'total_mn', header: ['Total M.N.', {content: 'numberFilter'}],
|
||||
width: 150, sort: 'int', format: webix.i18n.priceFormat, css: 'right',
|
||||
footer: {content: 'summTimbrada', css: 'right'}},
|
||||
{id: 'cliente', header: ['Razón Social', {content: 'selectFilter'}],
|
||||
fillspace: true, sort: 'string'},
|
||||
{id: 'xml', header: 'XML', adjust: 'data', template: get_icon('xml')},
|
||||
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
|
||||
//~ {id: 'ods', header: 'ODS', adjust: 'data', template: get_icon('table')},
|
||||
//~ {id: 'zip', header: 'ZIP', adjust: 'data', template: get_icon('zip')},
|
||||
{id: 'email', header: '@', adjust: 'data', template: get_icon('email')}
|
||||
]
|
||||
|
||||
|
||||
var grid_bank_invoice_pay = {
|
||||
view: 'datatable',
|
||||
id: 'grid_bank_invoice_pay',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_bank_invoice_pay_cols,
|
||||
scheme:{
|
||||
$change:function(item){
|
||||
if (item.estatus == 'Cancelada'){
|
||||
item.$css = 'cancel'
|
||||
}
|
||||
}
|
||||
},
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var toolbar_banco_retiro = [
|
||||
{view: 'label', label: 'Agregar retiro de banco', id: 'title_bank_retiro'},
|
||||
{view: 'button', id: 'cmd_guardar_retiro', label: 'Guardar Retiro',
|
||||
type: 'iconButton', autowidth: true, icon: 'minus'},
|
||||
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||
icon: 'times-circle'}
|
||||
]
|
||||
|
||||
|
||||
var toolbar_banco_deposito = [
|
||||
{view: 'label', label: 'Agregar depósito de banco', id: 'title_bank_deposit'},
|
||||
{view: 'button', id: 'cmd_guardar_deposito', label: 'Guardar Depósito',
|
||||
type: 'iconButton', autowidth: true, icon: 'plus'},
|
||||
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||
icon: 'times-circle'}
|
||||
]
|
||||
|
||||
|
||||
var toolbar_bank_pay = [
|
||||
{view: 'label', label: 'Factura de pago'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_pay_stamp', label: 'Timbrar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ticket'},
|
||||
{view: 'button', id: 'cmd_pay_cancel', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'minus'},
|
||||
{view: 'button', id: 'cmd_pay_delete', label: 'Eliminar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
{view: 'checkbox', id: 'chk_pay_close_when_stamp',
|
||||
label: 'Cerrar al timbrar', tooltip: 'Cerrar al timbrar'},
|
||||
{},
|
||||
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||
icon: 'times-circle'}
|
||||
]
|
||||
|
||||
|
||||
var toolbar_bank_invoice_pay = [
|
||||
{view: 'label', label: 'Administración de Facturas de Pago'},
|
||||
{},
|
||||
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||
icon: 'times-circle'}
|
||||
]
|
||||
|
||||
|
||||
var toolbar_bank_invoice_pay_filter = [
|
||||
{view: 'richselect', id: 'filter_invoice_pay_year', label: 'Año',
|
||||
labelAlign: 'right', labelWidth: 50, width: 150, options: []},
|
||||
{view: 'richselect', id: 'filter_invoice_pay_month', label: 'Mes',
|
||||
labelAlign: 'right', labelWidth: 50, width: 175, options: months},
|
||||
{view: 'daterangepicker', id: 'filter_invoice_pay_dates', label: 'Fechas',
|
||||
labelAlign: 'right', width: 275},
|
||||
{view: 'button', id: 'cmd_invoice_pay_sat', label: 'SAT',
|
||||
type: 'iconButton', autowidth: true, icon: 'check-circle'},
|
||||
{view: 'button', id: 'cmd_invoice_pay_cancel', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
{},
|
||||
]
|
||||
|
||||
|
||||
var controls_banco_retiro = [
|
||||
{view: 'toolbar', elements: toolbar_banco_retiro},
|
||||
{cols: [
|
||||
{view: 'datepicker', id: 'date_retiro', name: 'retiro_fecha',
|
||||
label: 'Fecha', format: '%d-%M-%Y', labelAlign: 'right',
|
||||
required: true, invalidMessage: 'Selecciona una fecha',
|
||||
labelWidth: 125},
|
||||
{view: 'search', id: 'time_retiro', name: 'retiro_hora',
|
||||
label: 'Hora', icon: 'clock-o', labelAlign: 'right',
|
||||
pattern:{mask: '##:##:##', allow:/[0-9]/g}, required: true,
|
||||
invalidMessage: 'Captura una hora'},
|
||||
{view: 'text', id: 'retiro_referencia', name: 'retiro_referencia',
|
||||
label: 'Referencia', labelAlign: 'right'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'lst_retiro_forma_pago',
|
||||
name: 'retiro_forma_pago', label: 'Forma de Pago', required: true,
|
||||
options: [], labelWidth: 125, labelAlign: 'right'},
|
||||
{view: 'currency2', type: 'text', id: 'txt_retiro_importe',
|
||||
name: 'retiro_importe', label: 'Importe', labelAlign: 'right',
|
||||
required: true, invalidMessage: 'Captura un valor númerico',
|
||||
inputAlign: 'right', value: ''}
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'text', id: 'retiro_descripcion', name: 'retiro_descripcion',
|
||||
label: 'Descripción', labelAlign: 'right', required: true,
|
||||
labelWidth: 125},
|
||||
]},
|
||||
]
|
||||
|
||||
|
||||
var controls_banco_deposito = [
|
||||
{view: 'toolbar', elements: toolbar_banco_deposito},
|
||||
{cols: [
|
||||
{view: 'datepicker', id: 'date_deposito', name: 'deposito_fecha',
|
||||
label: 'Fecha', format: '%d-%M-%Y', labelAlign: 'right',
|
||||
required: true, invalidMessage: 'Selecciona una fecha',
|
||||
labelWidth: 125},
|
||||
{view: 'search', id: 'time_deposito', name: 'deposito_hora',
|
||||
label: 'Hora', icon: 'clock-o', labelAlign: 'right',
|
||||
pattern:{mask: '##:##:##', allow:/[0-9]/g}, required: true,
|
||||
invalidMessage: 'Captura una hora'},
|
||||
{view: 'text', id: 'deposito_referencia', name: 'deposito_referencia',
|
||||
label: 'Referencia', labelAlign: 'right'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'lst_deposito_forma_pago',
|
||||
name: 'deposito_forma_pago', label: 'Forma de Pago', required: true,
|
||||
options: [], labelWidth: 125, labelAlign: 'right'},
|
||||
{view: 'currency2', type: 'text', id: 'txt_deposito_importe',
|
||||
name: 'deposito_importe', label: 'Importe', labelAlign: 'right',
|
||||
required: true, invalidMessage: 'Captura un valor númerico',
|
||||
inputAlign: 'right', value: ''},
|
||||
{view: 'currency4', type: 'text', id: 'deposit_type_change',
|
||||
name: 'deposit_type_change', label: 'T.C.', labelAlign: 'right',
|
||||
required: false, invalidMessage: 'Captura un valor númerico',
|
||||
inputAlign: 'right', value: '1.0000', width: 175, hidden: true}
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'textarea', id: 'deposito_descripcion', label: 'Descripción',
|
||||
name: 'deposito_descripcion', labelAlign: 'right', required: true,
|
||||
labelWidth: 125, height: 70},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'label', label: '<b>Facturas por pagar: </b>'},
|
||||
{view: 'richselect', id: 'lst_partner_account_bank', hidden: true,
|
||||
name: 'partner_account_bank', label: 'Cuenta Origen', required: false,
|
||||
options: [], labelWidth: 125, labelAlign: 'right'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_invoice_payed', label: 'Solo marcar pagada',
|
||||
type: 'iconButton', autowidth: true, icon: 'check-circle',
|
||||
tooltip: 'No afecta a saldos'},
|
||||
]},
|
||||
grid_cfdi_por_pagar,
|
||||
{view: 'label', label: '<b>Facturas a pagar en este depósito: </b>'},
|
||||
grid_cfdi_este_deposito,
|
||||
]
|
||||
|
||||
|
||||
var controls_bank_pay = [
|
||||
{view: 'toolbar', elements: toolbar_bank_pay},
|
||||
{view: 'label', label: '<b>Este depósito: </b>'},
|
||||
{cols: [
|
||||
{view: 'datepicker', id: 'pay_date', name: 'pay_date',
|
||||
label: 'Fecha', format: '%d-%M-%Y', labelAlign: 'right',
|
||||
required: true, invalidMessage: 'Selecciona una fecha',
|
||||
labelWidth: 125, readonly: true},
|
||||
{view: 'search', id: 'pay_time', name: 'pay_time', label: 'Hora',
|
||||
icon: 'clock-o', labelAlign: 'right', required: true,
|
||||
readonly: true,
|
||||
invalidMessage: 'Captura una hora'},
|
||||
{view: 'text', id: 'pay_reference', name: 'pay_reference',
|
||||
label: 'Referencia', labelAlign: 'right', readonly: true},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'pay_way_payment', readonly: true,
|
||||
name: 'pay_way_payment', label: 'Forma de Pago', required: true,
|
||||
options: [], labelWidth: 125, labelAlign: 'right'},
|
||||
{view: 'currency', type: 'text', id: 'pay_import', name: 'pay_import',
|
||||
label: 'Importe', labelAlign: 'right', required: true, readonly: true,
|
||||
invalidMessage: 'Captura un valor númerico', inputAlign: 'right'}
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'textarea', id: 'pay_description', label: 'Descripción',
|
||||
name: 'pay_description', labelAlign: 'right', required: true,
|
||||
labelWidth: 125, height: 70, readonly: true},
|
||||
]},
|
||||
{view: 'label', label: '<b>Facturas de pago de este depósito: </b>'},
|
||||
grid_cfdi_pay,
|
||||
{view: 'label', label: '<b>Facturas relacionadas en este pago: </b>'},
|
||||
grid_pay_related
|
||||
]
|
||||
|
||||
|
||||
var controls_bank_invoice_pay = [
|
||||
{view: 'toolbar', elements: toolbar_bank_invoice_pay},
|
||||
{view: 'toolbar', elements: toolbar_bank_invoice_pay_filter},
|
||||
grid_bank_invoice_pay
|
||||
]
|
||||
|
||||
|
||||
var form_banco_retiro = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_banco_retiro',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_banco_retiro,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var form_banco_deposito = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_banco_deposito',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_banco_deposito,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var form_bank_pay = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_bank_pay',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_bank_pay,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var form_bank_invoice_pay = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_bank_invoice_pay',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_bank_invoice_pay,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var multi_bancos = {
|
||||
id: 'multi_bancos',
|
||||
animate: true,
|
||||
cells:[
|
||||
{id: 'banco_home', rows:[
|
||||
{view: 'toolbar', elements: toolbar_banco},
|
||||
{view: 'toolbar', elements: toolbar_filtro_cuenta},
|
||||
{view: 'toolbar', elements: toolbar_movimientos_banco},
|
||||
grid_cuentabanco,
|
||||
]},
|
||||
{id: 'banco_retiro', rows: [form_banco_retiro]},
|
||||
{id: 'banco_deposito', rows: [form_banco_deposito]},
|
||||
{id: 'bank_pay', rows: [form_bank_pay]},
|
||||
{id: 'bank_invoice_pay', rows: [form_bank_invoice_pay]}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var title_partners = 'Administración de Bancos'
|
||||
var app_bancos = {
|
||||
id: 'app_bancos',
|
||||
rows:[
|
||||
{view: 'template', id: 'th_bancos', type: 'header',
|
||||
template: title_partners},
|
||||
multi_bancos
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
var win_body_mov_description = {rows: [
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
{view: 'textarea', id: 'mov_description', name: 'mov_description',
|
||||
height: 300},
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_save_mov_description', autowidth: true,
|
||||
label: 'Guardar', type: 'iconButton', icon: 'save', hotkey: 'Ctrl+enter'},
|
||||
{maxWidth: 50},
|
||||
{view: 'button', id: 'cmd_close_mov_description', autowidth: true,
|
||||
label: 'Cerrar', type: 'iconButton', icon: 'times-circle', hotkey: 'esc'},
|
||||
{}]},
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
],}
|
||||
|
||||
|
||||
var win_mov_description = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_mov_description',
|
||||
height: 400,
|
||||
width: 600,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Descripción del movimiento',
|
||||
body: win_body_mov_description,
|
||||
})
|
||||
$$('cmd_save_mov_description').attachEvent('onItemClick', cmd_save_mov_description_click)
|
||||
$$('cmd_close_mov_description').attachEvent('onItemClick', cmd_close_mov_description_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var opt_reasons_cancel_pay = [
|
||||
{id: '', value: ''},
|
||||
{id: '01', value: '[01] Comprobante emitido con errores con relación'},
|
||||
{id: '02', value: '[02] Comprobante emitido con errores sin relación'},
|
||||
{id: '03', value: '[03] No se llevó acabo la operación'},
|
||||
{id: '04', value: '[04] Operación nominativa relacionada en una factura global'},
|
||||
]
|
||||
|
||||
|
||||
var body_invoice_cancel_pay = {rows: [{minHeight: 15},
|
||||
{view: 'richselect', id: 'lst_reasons_cancel', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400},
|
||||
{view: 'text', id: 'txt_cancel_uuid', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
|
||||
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
|
||||
{view: 'label', label: '¿Estás seguro de continuar?', autowidth: true, align: 'center'},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_invoice_cancel_pay', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
|
||||
{maxWidth: 25},
|
||||
{view: 'button', id: 'cmd_win_cancel_pay_close', width: 100, label: 'Cerrar'},
|
||||
{}
|
||||
]},
|
||||
{minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_invoice_cancel_pay = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_invoice_cancel_pay',
|
||||
modal: true,
|
||||
width: 400,
|
||||
position: 'center',
|
||||
head: 'Cancelar CFDI',
|
||||
body: body_invoice_cancel_pay,
|
||||
})
|
||||
$$('cmd_invoice_cancel_pay').attachEvent('onItemClick', cmd_invoice_cancel_pay_click)
|
||||
$$('cmd_win_cancel_pay_close').attachEvent('onItemClick', cmd_win_cancel_pay_close_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_invoice_cancel_pay2 = {rows: [{minHeight: 15},
|
||||
{view: 'richselect', id: 'lst_reasons_cancel2', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400},
|
||||
{view: 'text', id: 'txt_cancel_uuid2', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
|
||||
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
|
||||
{view: 'label', label: '¿Estás seguro de continuar?', autowidth: true, align: 'center'},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_invoice_cancel_pay2', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
|
||||
{maxWidth: 25},
|
||||
{view: 'button', id: 'cmd_win_cancel_pay_close2', width: 100, label: 'Cerrar'},
|
||||
{}
|
||||
]},
|
||||
{minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_invoice_cancel_pay2 = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_invoice_cancel_pay2',
|
||||
modal: true,
|
||||
width: 400,
|
||||
position: 'center',
|
||||
head: 'Cancelar CFDI de Pago',
|
||||
body: body_invoice_cancel_pay2,
|
||||
})
|
||||
$$('cmd_invoice_cancel_pay2').attachEvent('onItemClick', cmd_invoice_cancel_pay2_click)
|
||||
$$('cmd_win_cancel_pay_close2').attachEvent('onItemClick', cmd_win_cancel_pay_close2_click)
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
|
||||
var msg_rfc = 'El RFC es requerido'
|
||||
|
||||
var form_controls_empresa = [
|
||||
{view: 'text', label: 'RFC', id: 'txt_alta_rfc', name: 'alta_rfc',
|
||||
labelPosition: 'top', required: true, invalidMessage: msg_rfc},
|
||||
{margin: 10, cols:[{}, {view: 'button', value: 'Agregar RFC',
|
||||
click: 'validate_nuevo_rfc', hotkey: 'enter'}, {}]}
|
||||
]
|
||||
|
||||
|
||||
var msg_header = '<font color="#610B0B">Bienvenido a Empresa Libre</font>'
|
||||
var header = [
|
||||
{view: 'label', label: '<b><font color="#610B0B">Alta de Emisor</font></b>'},
|
||||
{},
|
||||
{view: 'button', type: 'icon', width: 40, css: 'app_button',
|
||||
icon: 'home', click: 'window.location = "/"'},
|
||||
]
|
||||
var footer = [
|
||||
{},
|
||||
{view: 'button', value: 'Respaldar BD', click: 'cmd_respaldar_bd'},
|
||||
{},
|
||||
]
|
||||
|
||||
|
||||
var grid_empresas_cols = [
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: 'rfc', header: 'RFC Emisor', fillspace: true,
|
||||
footer: {content: 'countRows', css: 'right'}},
|
||||
]
|
||||
|
||||
|
||||
var grid_empresas = {
|
||||
view: 'datatable',
|
||||
id: 'grid_empresas',
|
||||
select: 'row',
|
||||
url: '/values/empresas',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
footer: true,
|
||||
columns: grid_empresas_cols,
|
||||
}
|
||||
|
||||
|
||||
var ui_empresas = {
|
||||
rows: [
|
||||
{maxHeight: 50},
|
||||
{view: 'template', template: msg_header, maxHeight: 50, css: 'login_header'},
|
||||
{maxHeight: 50},
|
||||
{cols: [{}, {type: 'space', padding: 5,
|
||||
rows: [
|
||||
{view: 'toolbar', elements: header},
|
||||
{
|
||||
container: 'form_empresas',
|
||||
view: 'form',
|
||||
id: 'form_empresas',
|
||||
width: 400,
|
||||
elements: form_controls_empresa,
|
||||
rules:{
|
||||
alta_rfc:function(value){ return value.trim() != '';},
|
||||
}
|
||||
},
|
||||
grid_empresas,
|
||||
{view: 'toolbar', elements: footer},
|
||||
]}, {}, ]
|
||||
},
|
||||
]
|
||||
}
|
|
@ -16,16 +16,16 @@ var form_controls = [
|
|||
]
|
||||
|
||||
|
||||
var msg_header = 'Bienvenido a Empresa Libre'
|
||||
|
||||
var ui_login = {
|
||||
rows: [
|
||||
{maxHeight: 50},
|
||||
{view: 'template', id: 'title_login', template: '', maxHeight: 50,
|
||||
css: 'login_header'},
|
||||
{view: 'template', template: msg_header, maxHeight: 50, css: 'login_header'},
|
||||
{maxHeight: 50},
|
||||
{cols: [{}, {type: 'space', padding: 5,
|
||||
rows: [
|
||||
{view: 'template', type: 'header',
|
||||
template: '<font color="#610B0B">Acceso al sistema</font>'},
|
||||
{view: 'template', template: 'Acceso al sistema', type: 'header'},
|
||||
{
|
||||
container: 'form_login',
|
||||
view: 'form',
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
|
||||
|
||||
var menu_data = [
|
||||
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
|
||||
{id: 'app_partners', icon: 'address-book-o', value: 'Clientes y Proveedores'},
|
||||
{id: 'app_partners', icon: 'users', value: 'Clientes y Proveedores'},
|
||||
{id: 'app_products', icon: 'server', value: 'Productos y Servicios'},
|
||||
{id: 'app_bancos', icon: 'university', value: 'Bancos'},
|
||||
{id: 'app_invoices', icon: 'file-code-o', value: 'Facturas'},
|
||||
]
|
||||
{id: 'app_invoices', icon: 'cart-plus', value: 'Facturas'},
|
||||
];
|
||||
|
||||
|
||||
var sidebar = {
|
||||
view: 'sidebar',
|
||||
id: 'main_sidebar',
|
||||
data: menu_data,
|
||||
ready: function(){
|
||||
this.select('app_home');
|
||||
|
@ -21,8 +18,8 @@ var sidebar = {
|
|||
onAfterSelect: function(id){
|
||||
$$('multi').setValue(id)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var multi_main = {
|
||||
|
@ -36,13 +33,9 @@ var multi_main = {
|
|||
},
|
||||
app_partners,
|
||||
app_products,
|
||||
app_bancos,
|
||||
app_school,
|
||||
app_nomina,
|
||||
app_tickets,
|
||||
app_invoices,
|
||||
],
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var menu_user = {
|
||||
|
@ -56,33 +49,20 @@ var menu_user = {
|
|||
type: {
|
||||
subsign: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var link_blog = "<a class='link_default' target='_blank' href='https://empresalibre.net/blog'>Blog</a>";
|
||||
var link_forum = "<a class='link_default' target='_blank' href='https://git.cuates.net/elmau/empresa-libre/issues'>Foro</a>";
|
||||
var link_doc = "<a class='link_default' target='_blank' href='https://empresalibre.net/docs'>Doc</a>";
|
||||
|
||||
};
|
||||
|
||||
var ui_main = {
|
||||
rows: [
|
||||
{view: 'toolbar', padding: 3, elements: [
|
||||
{view: 'button', type: 'icon', icon: 'bars',
|
||||
width: 37, align: 'left', css: 'app_button', click: function(){
|
||||
$$('main_sidebar').toggle()
|
||||
$$('$sidebar1').toggle()
|
||||
}
|
||||
},
|
||||
{view: 'label', id: 'lbl_title_main', label: '<b>Empresa Libre</b>'},
|
||||
{view: 'label', label: 'Empresa Libre'},
|
||||
{},
|
||||
{view: 'label', id: 'lbl_blog', label: link_blog, align: 'right', width: 30},
|
||||
{view: 'label', id: 'lbl_forum', label: link_forum, align: 'right', width: 30},
|
||||
{view: 'label', id: 'lbl_doc', label: link_doc, align: 'right', width: 25},
|
||||
menu_user,
|
||||
{view: 'button', id: 'cmd_update_timbres', type: 'icon', width: 45,
|
||||
css: 'app_button', icon: 'bell-o', badge: 0},
|
||||
{view: 'button', type: 'icon', width: 30, css: 'app_button',
|
||||
icon: 'cogs', id: 'cmd_ir_al_admin', hidden: true,
|
||||
click: 'cmd_ir_al_admin_click'}
|
||||
{view: 'button', type: 'icon', width: 45, css: 'app_button', icon: 'bell-o', badge: 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,288 +0,0 @@
|
|||
|
||||
var toolbar_nomina = [
|
||||
{view: 'button', id: 'cmd_empleados', label: 'Empleados', type: 'iconButton',
|
||||
autowidth: true, icon: 'users'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_nomina_report', label: 'Reporte', type: 'iconButton',
|
||||
autowidth: true, icon: 'table'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_nomina_delete', label: 'Eliminar',
|
||||
type: 'iconButton', autowidth: true, icon: 'minus'},
|
||||
]
|
||||
|
||||
|
||||
var toolbar_nomina_util = [
|
||||
{view: 'button', id: 'cmd_nomina_import', label: 'Importar',
|
||||
type: 'iconButton', autowidth: true, icon: 'upload'},
|
||||
{view: 'button', id: 'cmd_nomina_timbrar', label: 'Timbrar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ticket'},
|
||||
{view: 'button', id: 'cmd_nomina_sat', label: 'SAT',
|
||||
type: 'iconButton', autowidth: true, icon: 'check-circle'},
|
||||
{view: 'button', id: 'cmd_nomina_log', label: 'Log',
|
||||
type: 'iconButton', autowidth: true, icon: 'download'},
|
||||
{view: 'button', id: 'cmd_nomina_download', label: 'Descargar',
|
||||
type: 'iconButton', autowidth: true, icon: 'download'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_nomina_cancel', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
]
|
||||
|
||||
|
||||
var toolbar_nomina_filter = [
|
||||
{view: 'richselect', id: 'filter_year_nomina', label: 'Año',
|
||||
labelAlign: 'right', labelWidth: 50, width: 150, options: []},
|
||||
{view: 'richselect', id: 'filter_month_nomina', label: 'Mes',
|
||||
labelAlign: 'right', labelWidth: 50, width: 200, options: months},
|
||||
{view: 'daterangepicker', id: 'filter_dates_nomina', label: 'Fechas',
|
||||
labelAlign: 'right', width: 300},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_nomina_without_stamp', label: 'Sin Timbrar',
|
||||
type: 'iconButton', autowidth: true, icon: 'filter'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_nomina = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "serie", header: ["Serie"], adjust: "header"},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
|
||||
sort: 'int', css: 'right', footer: {text: 'Recibos', colspan: 3}},
|
||||
{id: "uuid", header: ["UUID", {content: "textFilter"}], adjust: "data",
|
||||
sort:"string", hidden:true},
|
||||
{id: "fecha", header: ["Fecha y Hora"], adjust: "data", sort: "string"},
|
||||
{id: "estatus", header: ["Estatus", {content: "selectFilter"}],
|
||||
adjust: "data", sort:"string"},
|
||||
{id: 'fecha_pago', header: ['Fecha de Pago', {content: 'selectFilter'}],
|
||||
adjust: 'data', sort: 'string'},
|
||||
{id: 'total', header: ['Total', {content: 'numberFilter'}], width: 150,
|
||||
sort: 'int', format: webix.i18n.priceFormat, css: 'right',
|
||||
footer: {content: 'summTimbradaN', css: 'right'}},
|
||||
{id: "empleado", header: ["Empleado", {content: "selectFilter"}],
|
||||
fillspace:true, sort:"string", footer: {text: '$ 0.00'}},
|
||||
{id: 'xml', header: 'XML', adjust: 'data', template: get_icon('xml')},
|
||||
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
|
||||
{id: 'email', header: '@', adjust: 'data', template: get_icon('email')}
|
||||
]
|
||||
|
||||
|
||||
var grid_nomina = {
|
||||
view: 'datatable',
|
||||
id: 'grid_nomina',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
scrollY: true,
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_cols_nomina,
|
||||
scheme:{
|
||||
$change:function(item){
|
||||
if (item.estatus == 'Cancelado'){
|
||||
item.$css = 'cancel'
|
||||
}
|
||||
}
|
||||
},
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var rows_nomina_home = [
|
||||
{view: 'toolbar', elements: toolbar_nomina},
|
||||
{view: 'toolbar', elements: toolbar_nomina_util},
|
||||
{view: 'toolbar', elements: toolbar_nomina_filter},
|
||||
grid_nomina,
|
||||
]
|
||||
|
||||
|
||||
var toolbar_nomina_empleados = [
|
||||
{view: 'button', id: 'cmd_new_empleado', label: 'Nuevo', type: 'iconButton',
|
||||
autowidth: true, icon: 'user-plus'},
|
||||
{view: 'button', id: 'cmd_edit_empleado', label: 'Editar', type: 'iconButton',
|
||||
autowidth: true, icon: 'user'},
|
||||
{view: 'button', id: 'cmd_delete_empleado', label: 'Eliminar', type: 'iconButton',
|
||||
autowidth: true, icon: 'user-times'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_import_empleados', label: 'Importar',
|
||||
type: 'iconButton', autowidth: true, icon: 'upload'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_close_empleados', label: 'Cerrar', type: 'iconButton',
|
||||
autowidth: true, icon: 'times-circle-o'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_empleados = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "num_empleado", header: ["No Empleado"], adjust: "data"},
|
||||
{id: "rfc", header: ["RFC", {content: 'textFilter'}], adjust: "data", sort: "string"},
|
||||
{id: "curp", header: ["CURP"], adjust: "data", hidden:true, sort: "string"},
|
||||
{id: "nombre_completo", header: ["Empleado", {content: 'textFilter'}],
|
||||
adjust: "data", fillspace: true, sort: "string"},
|
||||
{id: 'imss', header: ['IMSS'], adjust: 'data'},
|
||||
{id: 'salario_base', header: ['Salario Base'], adjust: 'header',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: 'salario_diario', header: ['Salario Diario'], adjust: 'header',
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: "fecha_ingreso", header: ["Fecha de Ingreso"], adjust: "header",
|
||||
sort: "string"},
|
||||
]
|
||||
|
||||
|
||||
var grid_empleados = {
|
||||
view: 'datatable',
|
||||
id: 'grid_employees',
|
||||
select: 'row',
|
||||
scrollY: true,
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_cols_empleados,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var rows_nomina_empleados = [
|
||||
{view: 'toolbar', elements: toolbar_nomina_empleados},
|
||||
grid_empleados,
|
||||
]
|
||||
|
||||
|
||||
var multi_nomina = {
|
||||
id: 'multi_nomina',
|
||||
view: 'multiview',
|
||||
animate: true,
|
||||
cells:[
|
||||
{id: 'nomina_home', rows: rows_nomina_home},
|
||||
{id: 'nomina_empleados', rows: rows_nomina_empleados},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var app_nomina = {
|
||||
id: 'app_nomina',
|
||||
rows:[
|
||||
{view: 'template', type: 'header', template: 'Timbrado de Nómina'},
|
||||
multi_nomina
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var body_import_employees = {rows: [
|
||||
{view: 'form', id: 'form_upload_employees', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'up_employees', autosend: false,
|
||||
link: 'lst_upload_employees', value: 'Seleccionar Plantilla',
|
||||
upload: '/files/employees'}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_upload_employees', name: 'lst_employees',
|
||||
type: 'uploader', autoheight: true, borderless: true}]},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_import_employees',
|
||||
label: 'Importar Empleados'}, {}]},
|
||||
]},
|
||||
],}
|
||||
|
||||
|
||||
var win_import_employees = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_import_employees',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Importar Empleados',
|
||||
body: body_import_employees,
|
||||
})
|
||||
$$('cmd_import_employees').attachEvent('onItemClick', cmd_import_employees_click)
|
||||
$$('up_employees').attachEvent('onUploadComplete', up_employees_upload_complete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_import_nomina = {rows: [
|
||||
{view: 'form', id: 'form_upload_nomina', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'up_nomina', autosend: false,
|
||||
link: 'lst_upload_nomina', value: 'Seleccionar Plantilla',
|
||||
upload: '/files/nomina'}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_upload_nomina', name: 'lst_nomina',
|
||||
type: 'uploader', autoheight: true, borderless: true}]},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_import_template_nomina',
|
||||
label: 'Importar Nómina'}, {}]},
|
||||
]},
|
||||
],}
|
||||
|
||||
|
||||
var win_import_nomina = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_import_nomina',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Importar Nómina',
|
||||
body: body_import_nomina,
|
||||
})
|
||||
$$('cmd_import_template_nomina').attachEvent('onItemClick', cmd_import_template_nomina_click)
|
||||
$$('up_nomina').attachEvent('onUploadComplete', up_nomina_upload_complete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var opt_reasons_cancel_nomina = [
|
||||
{id: '', value: ''},
|
||||
{id: '01', value: '[01] Comprobante emitido con errores con relación'},
|
||||
{id: '02', value: '[02] Comprobante emitido con errores sin relación'},
|
||||
{id: '03', value: '[03] No se llevó acabo la operación'},
|
||||
{id: '04', value: '[04] Operación nominativa relacionada en una factura global'},
|
||||
]
|
||||
|
||||
|
||||
var body_invoice_cancel_nomina = {rows: [{minHeight: 15},
|
||||
{view: 'richselect', id: 'lst_reasons_cancel', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400},
|
||||
{view: 'text', id: 'txt_cancel_uuid', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
|
||||
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
|
||||
{view: 'label', label: '¿Estás segura de continuar?', autowidth: true, align: 'center'},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_invoice_cancel_nomina', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
|
||||
{maxWidth: 25},
|
||||
{view: 'button', id: 'cmd_win_cancel_nomina_close', width: 100, label: 'Cerrar'},
|
||||
{}
|
||||
]},
|
||||
{minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_invoice_cancel_nomina = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_invoice_cancel_nomina',
|
||||
modal: true,
|
||||
width: 400,
|
||||
position: 'center',
|
||||
head: 'Cancelar CFDI',
|
||||
body: body_invoice_cancel_nomina,
|
||||
})
|
||||
$$('cmd_invoice_cancel_nomina').attachEvent('onItemClick', cmd_invoice_cancel_nomina_click)
|
||||
$$('cmd_win_cancel_nomina_close').attachEvent('onItemClick', cmd_win_cancel_nomina_close_click)
|
||||
}
|
||||
}
|
|
@ -1,18 +1,3 @@
|
|||
//~ Empresa Libre
|
||||
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||
//~
|
||||
//~ This program is free software: you can redistribute it and/or modify
|
||||
//~ it under the terms of the GNU General Public License as published by
|
||||
//~ the Free Software Foundation, either version 3 of the License, or
|
||||
//~ (at your option) any later version.
|
||||
//~
|
||||
//~ This program is distributed in the hope that it will be useful,
|
||||
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//~ GNU General Public License for more details.
|
||||
//~
|
||||
//~ You should have received a copy of the GNU General Public License
|
||||
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
var toolbar_partners = [
|
||||
|
@ -22,22 +7,17 @@ var toolbar_partners = [
|
|||
autowidth: true, icon: 'user'},
|
||||
{view: 'button', id: 'cmd_delete_partner', label: 'Eliminar', type: 'iconButton',
|
||||
autowidth: true, icon: 'user-times'},
|
||||
{},
|
||||
//~ {view: 'button', id: 'cmd_partner_zero', label: 'Saldo 0', type: 'iconButton',
|
||||
//~ autowidth: true, icon: 'power-off', disabled: true},
|
||||
]
|
||||
|
||||
|
||||
var grid_partners_cols = [
|
||||
{id: 'index', header:'#', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 2, css: 'right'}},
|
||||
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
|
||||
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
|
||||
{id: 'index', header:'#', adjust:'data', css: 'right',
|
||||
footer: {content: 'rowCount', colspan: 2, css: 'right'}},
|
||||
{id: 'id', header: 'Clave', adjust:'data', sort: 'int', css: 'right'},
|
||||
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust:'data',
|
||||
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
|
||||
{id: 'nombre', header: ['Razón Social', {content: 'textFilter'}],
|
||||
fillspace:true, sort: 'string'},
|
||||
{id: 'saldo_cliente', header: ['Saldo Cliente', {content: 'numberFilter'}],
|
||||
width: 150, sort: 'int', format: webix.i18n.priceFormat, css: 'right'},
|
||||
]
|
||||
|
||||
|
||||
|
@ -50,15 +30,6 @@ var grid_partners = {
|
|||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_partners_cols,
|
||||
pager: 'pager_clientes',
|
||||
//~ datafetch: 100,
|
||||
//~ loadahead: 100,
|
||||
//~ url: '/partners',
|
||||
ready:function(){
|
||||
this.adjustColumn('index');
|
||||
this.adjustColumn('id');
|
||||
this.adjustColumn('rfc');
|
||||
},
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
|
@ -84,10 +55,7 @@ var controls_fiscales = [
|
|||
invalidMessage: 'El Tipo de Persona es requerido'},
|
||||
{template: 'Dirección Fiscal', type: 'section'},
|
||||
{cols: [{view: 'text', id: 'rfc', name: 'rfc', label: 'RFC: ', width: 300,
|
||||
required: true, invalidMessage: 'RFC inválido', attributes: {maxlength: 13}},
|
||||
{view: 'text', id: 'id_fiscal', name: 'id_fiscal', label: 'ID Fiscal: ',
|
||||
width: 400, required: false, attributes: {maxlength: 40}, hidden: true},
|
||||
{}]},
|
||||
required: true, invalidMessage: 'RFC inválido', attributes: {maxlength: 13}},{}]},
|
||||
{view: 'text', id: 'nombre', name: 'nombre', label: 'Razón Social: ', required: true,
|
||||
invalidMessage: 'La Razón Social es requerida'},
|
||||
{view: 'text', id: 'calle', name: 'calle', label: 'Calle: '},
|
||||
|
@ -96,19 +64,19 @@ var controls_fiscales = [
|
|||
{cols: [{view: 'text', id: 'no_interior', name: 'no_interior', width: 300,
|
||||
label: 'No Interior: '},{}]},
|
||||
{cols: [{view: 'search', id: 'codigo_postal', name: 'codigo_postal',
|
||||
width: 300, label: 'C.P.: ', attributes: {maxlength: 5}, required: true},{}]},
|
||||
width: 300, label: 'C.P.: ', attributes: {maxlength: 5}},{}]},
|
||||
{view: 'text', id: 'colonia', name: 'colonia', label: 'Colonia: '},
|
||||
{view: 'text', id: 'municipio', name: 'municipio', label: 'Municipio: '},
|
||||
{view: 'text', id: 'estado', name: 'estado', label: 'Estado: '},
|
||||
{view: 'text', id: 'pais', name: 'pais', label: 'País: ', value: 'México',
|
||||
readonly: true, placeholder: 'Usa solo tres letras de acuerdo al catalogo del SAT'},
|
||||
{view: 'text', id: 'pais', name: 'pais', label: 'País: ',
|
||||
value: 'México', readonly: true},
|
||||
{template: 'Condiciones Comerciales', type: 'section'},
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'forma_pago', name: 'forma_pago',
|
||||
label: 'Forma de Pago: ', required: true, options: [],
|
||||
invalidMessage: 'La Forma de pago es requerida'},
|
||||
{view: 'text', id: 'condicion_pago', name: 'condicion_pago',
|
||||
label: 'Condiciones de Pago: ', suggest: []},
|
||||
label: 'Condiciones de Pago: '},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'counter', id: 'dias_pago', name: 'dias_pago',
|
||||
|
@ -122,41 +90,25 @@ var controls_fiscales = [
|
|||
{view: 'richselect', id: 'lst_uso_cfdi_socio', name: 'uso_cfdi_socio',
|
||||
label: 'Uso del CFDI', options: []},
|
||||
{},
|
||||
]},
|
||||
{template: 'Regimenes Fiscales', type: 'section'},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_receptor_regimenes_fiscales', data: [],
|
||||
select: 'multiselect', width: 600, height: 125, required: true},
|
||||
{},
|
||||
]}
|
||||
]
|
||||
|
||||
|
||||
var controls_others = [
|
||||
{view: 'checkbox', id: 'es_activo', name: 'es_activo', label: 'Activo: ',
|
||||
value: true, bottomLabel: ' Se recomienda solo desactivar y no eliminar'},
|
||||
value: true, bottomLabel: ' Se recomienda solo desactivar y no eliminar'},
|
||||
{view: 'text', id: 'commercial_name', name: 'nombre_comercial',
|
||||
label: 'Nombre Comercial: '},
|
||||
{view: 'text', id: 'telefonos', name: 'telefonos', label: 'Teléfonos: '},
|
||||
{view: 'text', id: 'web', name: 'web', label: 'Página Web: '},
|
||||
{cols: [
|
||||
{view: 'text', id: 'correo_facturas', name: 'correo_facturas',
|
||||
label: 'Correos para Facturas: ', tooltip: 'Separados por comas',
|
||||
bottomLabel: 'Uno o más correos electrónicos separados por comas'},
|
||||
{view: 'text', id: 'partner_email_fp', name: 'partner_email_fp',
|
||||
label: 'Para Facturas de pago: ', tooltip: 'Separados por comas',
|
||||
bottomLabel: 'Uno o más correos electrónicos separados por comas'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'checkbox', id: 'es_cliente', name: 'es_cliente',
|
||||
label: 'Es Cliente: ', value: true, width: 180},
|
||||
{view: 'text', id: 'cuenta_cliente', name: 'cuenta_cliente',
|
||||
label: 'Cuenta Cliente: ', disabled: true},
|
||||
{view: "currency", type: "text", id: 'partner_balance', width: 300,
|
||||
name: 'partner_balance', label: 'Saldo', labelWidth: 100,
|
||||
labelAlign: "right", required: true, inputAlign: "right",
|
||||
invalidMessage: "Captura un valor númerico", readonly: true},
|
||||
]
|
||||
label: 'Cuenta Cliente: ', disabled: true}, {}]
|
||||
},
|
||||
{cols: [
|
||||
{view: 'checkbox', id: 'es_proveedor', name: 'es_proveedor',
|
||||
|
@ -165,56 +117,12 @@ var controls_others = [
|
|||
label: 'Cuenta Proveedor: ', disabled: true}, {}]
|
||||
},
|
||||
{view: 'checkbox', name: 'es_ong', label: 'Es ONG: ', value: false},
|
||||
{view: 'text', name: 'tags', label: 'Etiquetas', disabled: true,
|
||||
{view: 'text', name: 'tags', label: 'Etiquetas',
|
||||
tooltip: 'Utiles para filtrados rápidos. Separa por comas.'},
|
||||
{view: 'textarea' , height: 200, name: 'notas', label: 'Notas'},
|
||||
]
|
||||
|
||||
|
||||
var grid_partner_account_bank_cols = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: 'banco', header: 'Banco', fillspace: 1},
|
||||
{id: 'cuenta', header: 'Cuenta', fillspace: 1},
|
||||
{id: 'clabe', header: 'CLABE', fillspace: 1},
|
||||
//~ {id: 'moneda', header: 'Moneda', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_partner_account_bank = {
|
||||
view: 'datatable',
|
||||
id: 'grid_partner_account_bank',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
columns: grid_partner_account_bank_cols,
|
||||
}
|
||||
|
||||
|
||||
var controls_partner_bank = [
|
||||
{template: 'Agregar cuenta de banco', type: 'section'},
|
||||
{view: 'form', id: 'form_partner_account_bank', rows: [
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'lst_partner_bank', name: 'partner_bank',
|
||||
label: 'Banco: ', required: true, options: []},
|
||||
{view: 'text', id: 'partner_account', name: 'partner_account',
|
||||
label: 'Cuenta: ', required: true},
|
||||
{view: 'text', id: 'partner_clabe', name: 'partner_clabe',
|
||||
label: 'CLABE: ', required: true},
|
||||
]},
|
||||
{minHeight: 10},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_partner_add_account_bank', maxWidth: 200,
|
||||
label: 'Agregar cuenta'},
|
||||
{}]},
|
||||
],
|
||||
},
|
||||
{minHeight: 20, maxHeight: 20},
|
||||
{template: 'Cuentas de banco existentes', type: 'section'},
|
||||
grid_partner_account_bank,
|
||||
{minHeight: 50},
|
||||
]
|
||||
|
||||
|
||||
var toolbar_contacts = [
|
||||
{view: 'button', id: 'cmd_new_contact', label: 'Nuevo', type: 'iconButton',
|
||||
|
@ -224,7 +132,7 @@ var toolbar_contacts = [
|
|||
|
||||
var grid_contacts_cols = [
|
||||
{id: 'index', header: '#', adjust:'data', css:'right',
|
||||
footer: {content: 'countRows'}},
|
||||
footer: {content: 'rowCount'}},
|
||||
{id: 'id', header: '', hidden: true},
|
||||
{id: 'title', header: 'Título', adjust:'data', sort: 'string',
|
||||
footer: 'Contactos'},
|
||||
|
@ -352,12 +260,11 @@ var controls_partner = [
|
|||
{
|
||||
view: 'tabview',
|
||||
id: 'tab_partner',
|
||||
tabbar: {ptions: ['Datos Fiscales', 'Otros Datos', 'Cuentas de Banco']},
|
||||
animate: true,
|
||||
tabbar: {options: ['Datos Fiscales', 'Otros Datos', 'Contactos']}, animate: true,
|
||||
cells: [
|
||||
{id: 'Datos Fiscales', rows: controls_fiscales},
|
||||
{id: 'Otros Datos', rows: controls_others},
|
||||
{id: 'Cuentas de Banco', rows: controls_partner_bank}
|
||||
{id: 'Contactos', rows: [multi_contacts]},
|
||||
]
|
||||
},
|
||||
{rows: [
|
||||
|
@ -377,12 +284,12 @@ var form_partner = {
|
|||
view: 'form',
|
||||
id: 'form_partner',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_partner,
|
||||
elementsConfig: {
|
||||
labelWidth: 150,
|
||||
labelAlign: 'right'
|
||||
},
|
||||
autoheight: true,
|
||||
rules: {
|
||||
nombre: function(value){ return value.trim() != '';},
|
||||
rfc: validate_rfc,
|
||||
|
@ -391,15 +298,6 @@ var form_partner = {
|
|||
}
|
||||
|
||||
|
||||
var pager_clientes = {
|
||||
view: "pager",
|
||||
id: "pager_clientes",
|
||||
template: "{common.prev()} {common.pages()} {common.next()}",
|
||||
size: 100,
|
||||
group: 10,
|
||||
}
|
||||
|
||||
|
||||
var multi_partners = {
|
||||
id: 'multi_partners',
|
||||
animate: true,
|
||||
|
@ -407,9 +305,8 @@ var multi_partners = {
|
|||
{id: 'partners_home', rows:[
|
||||
{view: 'toolbar', elements: toolbar_partners},
|
||||
grid_partners,
|
||||
pager_clientes,
|
||||
]},
|
||||
{id: 'partners_new', rows:[form_partner]}
|
||||
{id: 'partners_new', rows:[form_partner, {}]}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -7,60 +7,38 @@ var toolbar_products = [
|
|||
autowidth: true, icon: "pencil"},
|
||||
{view: "button", id: "cmd_delete_product", label: "Eliminar",
|
||||
type: "iconButton", autowidth: true, icon: "minus"},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_import_products', label: 'Importar',
|
||||
type: 'iconButton', autowidth: true, icon: 'upload'},
|
||||
{view: "button", id: "cmd_add_inventory", label: "Altas", hidden: true,
|
||||
type: "iconButton", autowidth: true, icon: "plus"},
|
||||
{view: "button", id: "cmd_products_add", label: "Altas CFDI", hidden: true,
|
||||
type: "iconButton", autowidth: true, icon: "plus"},
|
||||
{view: 'button', id: 'cmd_show_exists', label: 'Existencias', hidden: true,
|
||||
type: 'iconButton', autowidth: true, icon: 'table'},
|
||||
]
|
||||
|
||||
|
||||
var grid_products_cols = [
|
||||
{ id: "id", header: "ID", width: 75, hidden: true},
|
||||
{ id: 'es_activo', header: 'Activo', hidden: true},
|
||||
{ id: "clave_sat", header: ["Clave SAT"], width: 100,},
|
||||
{ id: "id", header: "ID", width: 75},
|
||||
{ id: "clave", header: ["Clave", {content: "textFilter"}], width: 100,
|
||||
sort: 'string', footer: {content: 'countRows', css: 'right'}},
|
||||
sort:"string" },
|
||||
{ id: "descripcion", header: ["Descripción", {content: "textFilter"}],
|
||||
fillspace:true, sort: 'string', footer: 'Productos y Servicios'},
|
||||
fillspace:true, sort:"string" },
|
||||
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
|
||||
sort:"string" },
|
||||
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}],
|
||||
width: 150, sort: 'int', format: format_currency, css: "right" },
|
||||
{ id: 'existencia', header: ['Existencia', {content: 'numberFilter'}],
|
||||
width: 100, sort: 'int', format: webix.i18n.numberFormat,
|
||||
hidden: true, css: 'right' },
|
||||
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}], width: 150,
|
||||
sort:"int", format: webix.i18n.priceFormat, css: "right" },
|
||||
]
|
||||
|
||||
|
||||
var grid_products = {
|
||||
view: 'datatable',
|
||||
id: 'grid_products',
|
||||
select: 'row',
|
||||
view: "datatable",
|
||||
id: "grid_products",
|
||||
select: "row",
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_products_cols,
|
||||
scheme:{
|
||||
$change:function(item){
|
||||
if(!item.es_activo){
|
||||
item.$css = 'cancel'
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var suggest_categories = {
|
||||
view: 'datasuggest',
|
||||
type: 'tree',
|
||||
view: "datasuggest",
|
||||
type: "tree",
|
||||
width: 400,
|
||||
body: {data: []},
|
||||
body: { data: [] },
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,55 +63,19 @@ var grid_product_taxes = {
|
|||
}
|
||||
|
||||
|
||||
var suggest_sat_producto = {
|
||||
view: 'gridsuggest',
|
||||
id: 'grid_producto_found',
|
||||
name: 'grid_producto_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
scroll: true,
|
||||
autoheight: false,
|
||||
header: true,
|
||||
yCount: 10,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'key', adjust: 'data', header: 'Clave SAT'},
|
||||
{id: 'name', header: 'Producto', width: 750},
|
||||
],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 3){
|
||||
this.load('/values/satproductos?key=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var opt_tax_object = [
|
||||
{id: '01', value: '[01] No objeto de impuesto.'},
|
||||
{id: '02', value: '[02] Sí objeto de impuesto.'},
|
||||
{id: '03', value: '[03] Sí objeto del impuesto y no obligado al desglose.'},
|
||||
{id: '04', value: '[04] Sí objeto del impuesto y no causa impuesto.'},
|
||||
{id: '05', value: '[05] Sí objeto del impuesto, IVA crédito PODEBI.'},
|
||||
]
|
||||
|
||||
|
||||
var controls_generals = [
|
||||
{view: 'checkbox', id: 'es_activo_producto', name: 'es_activo_producto',
|
||||
label: 'Activo: ', value: true,
|
||||
bottomLabel: 'Se recomienda solo desactivar y no eliminar'},
|
||||
{cols: [
|
||||
{view: 'combo', id: 'categoria', name: 'categoria', label: 'Categoría',
|
||||
labelPosition: 'top', suggest: suggest_categories},
|
||||
labelPosition: 'top', options: suggest_categories},
|
||||
{view: 'text', id: 'clave', name: 'clave', label: 'Clave',
|
||||
labelPosition: 'top', readonly: true, required: true},
|
||||
{view: 'checkbox', id: 'chk_automatica', label: 'Automática',
|
||||
labelPosition: 'top', value: true, maxWidth: 80},
|
||||
{view: 'search', id: 'clave_sat', name: 'clave_sat', label: 'Clave SAT',
|
||||
labelPosition: 'top', required: true, suggest: suggest_sat_producto,
|
||||
placeholder: 'Al menos 4 caracteres...'},
|
||||
labelPosition: 'top', required: true, placeholder: 'Buscar clave...'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'text', id: 'codigo_barras', name: 'codigo_barras',
|
||||
|
@ -143,37 +85,28 @@ var controls_generals = [
|
|||
{id: 'txt_col1'}]},
|
||||
{view: "textarea", id: "descripcion", name: "descripcion", height: 200,
|
||||
label: "Descripción", required: true, labelPosition: "top",
|
||||
invalidMessage: "La Descripción es requerida",
|
||||
placeholder: 'El SAT solo permite 1000 caracteres en este campo'},
|
||||
invalidMessage: "La Descripción es requerida" },
|
||||
{minHeight: 5},
|
||||
{cols: [
|
||||
{view: "richselect", id: "unidad", name: "unidad", label: "Unidad",
|
||||
width: 300, labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "La Unidad es requerida", options: []},
|
||||
{view: 'richselect', id: 'objeto_impuesto', name: 'objeto_impuesto', label: 'Objeto de Impuestos',
|
||||
width: 500, labelWidth: 150, labelAlign: "right", required: true,
|
||||
invalidMessage: 'Este campo es requerido', options: opt_tax_object},
|
||||
{},
|
||||
{view: 'text', id: 'tags_producto', name: 'tags_producto',
|
||||
labelAlign: 'right', label: 'Etiquetas',
|
||||
placeholder: 'Separadas por comas'}
|
||||
]},
|
||||
{cols: [{view: "currency", type: "text", id: "valor_unitario",
|
||||
name: "valor_unitario", label: "Valor Unitario", width: 300,
|
||||
labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "Captura un valor númerico", inputAlign: "right" },{}]},
|
||||
{cols: [
|
||||
{view: "currency", type: "text", id: "valor_unitario",
|
||||
name: "valor_unitario", label: "Valor Unitario", width: 300,
|
||||
labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "Captura un valor númerico", inputAlign: "right"},
|
||||
{view: 'currency', type: 'text', id: 'precio_con_impuestos',
|
||||
name: 'precio_con_impuestos', label: 'Con Impuestos', width: 300,
|
||||
labelWidth: 115, labelAlign: 'right', required: false,
|
||||
invalidMessage: 'Captura un valor númerico', inputAlign: 'right'},
|
||||
{},]},
|
||||
{cols: [
|
||||
{view: 'checkbox', id: 'chk_inventario', name: 'inventario', hidden: true,
|
||||
{view: 'checkbox', id: 'inventario', name: 'inventario', hidden: true,
|
||||
label: 'Inventario', labelAlign: 'right', labelWidth: 130},
|
||||
{view: 'counter', id: 'txt_existencia', name: 'existencia',
|
||||
hidden: true, label: 'Existencia', step: 5, value: 0, min: 0,
|
||||
disabled: true, readonly: true},
|
||||
{view: 'counter', id: 'txt_minimo', name: 'minimo', hidden: true,
|
||||
{view: 'counter', id: 'existencia', name: 'existencia', hidden: true,
|
||||
label: 'Existencia', step: 5, value: 0, min: 0, disabled: true},
|
||||
{view: 'counter', id: 'minimo', name: 'minimo', hidden: true,
|
||||
label: 'Mínimo', step: 5, value: 0, min: 0, disabled: true},
|
||||
{},]},
|
||||
{id: 'txt_col2'}]},
|
||||
{cols:[{view:'label', label:'Impuestos', width: 300, align:'center'}, {}]},
|
||||
{cols:[grid_product_taxes, {}]}
|
||||
]
|
||||
|
@ -188,8 +121,8 @@ var controls_products = [
|
|||
],
|
||||
},
|
||||
{rows: [
|
||||
{template: "", type: "section"},
|
||||
{margin: 10, cols: [{},
|
||||
{ template:"", type: "section" },
|
||||
{ margin: 10, cols: [{},
|
||||
{view: "button", id: "cmd_save_product", label: "Guardar" , type: "form", autowidth: true, align:"center"},
|
||||
{view: "button", id: "cmd_cancel_product", label: "Cancelar" , type: "danger", autowidth: true, align:"center"},
|
||||
{}]
|
||||
|
@ -203,7 +136,7 @@ var form_product = {
|
|||
cols: [{
|
||||
view: "form",
|
||||
id: "form_product",
|
||||
scroll: true,
|
||||
//~ width: 600,
|
||||
complexData: true,
|
||||
elements: controls_products,
|
||||
rules: {
|
||||
|
@ -214,129 +147,6 @@ var form_product = {
|
|||
}
|
||||
|
||||
|
||||
var toolbar_products_add = {view: 'toolbar', elements: [{},
|
||||
{view: 'button', id: 'cmd_add_products_from_xml', label: 'Desde XML',
|
||||
type: 'iconButton', autowidth: true, icon: 'upload'},
|
||||
{}]}
|
||||
|
||||
|
||||
var rows_pro_add_partner = [
|
||||
{view: 'fieldset', label: 'Buscar Proveedor', body: {rows: [
|
||||
{cols: [
|
||||
{view: 'search', id: 'search_partner_id', label: 'por Clave',
|
||||
labelPosition: 'top', maxWidth: 200, placeholder: 'Captura la clave'},
|
||||
{view: 'search', id: 'search_partner_name', label: 'por Nombre o RFC',
|
||||
labelPosition: 'top', placeholder: 'Captura al menos tres letras'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'label', id: 'lbl_partner_title', label: 'Seleccionado: ', autowidth: true},
|
||||
{view: 'label', id: 'lbl_partner', label: 'Ninguno'},
|
||||
]}
|
||||
]}},
|
||||
]
|
||||
|
||||
|
||||
var grid_partner_products_cols = [
|
||||
{id: 'select', header: '', template:'{common.checkbox()}', width:35},
|
||||
{id: 'key', header: {text: 'Clave', css: 'center'}, width: 100,
|
||||
adjust: 'data'},
|
||||
{id: 'key_sat', header:{text: 'Clave SAT', css: 'center'}, width: 100,
|
||||
adjust: 'data'},
|
||||
{id: 'description', header:{text: 'Descripción', css: 'center'},
|
||||
fillspace: true},
|
||||
{id: "pedimento", header: 'Pedimento', editor: 'text', hidden: true},
|
||||
{id: 'unit', header:{text: 'Unidad', css: 'center'}, width: 100,
|
||||
adjust: 'data'},
|
||||
{id: 'unit_value', header:{text: 'Valor Unitario', css: 'center'},
|
||||
width: 100, format: format_currency, css: 'right'},
|
||||
{id: 'cant', header: {text: 'Cantidad', css: 'center'}, width: 50,
|
||||
format: webix.i18n.numberFormat, css: 'right'},
|
||||
{id: 'separate', header: '', width: 25},
|
||||
{id: 'id_product', header: '', hidden: true},
|
||||
{id: 'key1', header:{text: 'Clave', css: 'center'}, width: 100,
|
||||
adjust: true, editor: 'text', hidden: true},
|
||||
{id: 'key_sat1', header:{text: 'Clave SAT', css: 'center'}, width: 100,
|
||||
adjust: true, editor: 'text'},
|
||||
{id: 'description1', header:{text: 'Descripción', css: 'center'},
|
||||
fillspace: true, editor: 'popup'},
|
||||
{id: 'unit_value1', header:{text: 'Valor Unitario', css: 'center'},
|
||||
width: 100, format: format_currency, css: 'right', editor: 'text'},
|
||||
{id: 'cant1', header: {text: 'Cantidad', css: 'center'}, width: 50,
|
||||
format: webix.i18n.numberFormat, css: 'right', editor: 'text'},
|
||||
]
|
||||
|
||||
|
||||
var grid_partner_products = {
|
||||
view: 'datatable',
|
||||
id: 'grid_partner_products',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
editable: true,
|
||||
columns: grid_partner_products_cols,
|
||||
data: [],
|
||||
fixedRowHeight: false,
|
||||
on:{
|
||||
onCheck:function(rowId, colId, state){
|
||||
grid_partner_products_select(rowId, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var controls_products_add = [
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
toolbar_products_add,
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
{cols: [
|
||||
{rows: rows_pro_add_partner},
|
||||
{maxWidth: 10},
|
||||
{},
|
||||
]},
|
||||
{view: 'label', label: 'Detalle', height: 30, align: 'left'},
|
||||
{cols: [
|
||||
grid_partner_products,
|
||||
//~ grid_products_add,
|
||||
]},
|
||||
{rows: [
|
||||
{template:"", type: "section" },
|
||||
{margin: 10, cols: [{},
|
||||
{view: 'button', id: 'cmd_save_products_add', label: 'Guardar',
|
||||
autowidth: true, align: 'center'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_close_products_add', label: 'Cancelar',
|
||||
type: 'danger', autowidth: true, align: 'center'}
|
||||
]
|
||||
},
|
||||
]}
|
||||
]
|
||||
|
||||
|
||||
var controls_form_products_add = [
|
||||
{
|
||||
view: 'tabview',
|
||||
id: 'tv_invoice',
|
||||
animate: true,
|
||||
cells: [
|
||||
{id: 'Altas a inventario', rows: controls_products_add},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
var form_products_add = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_products_add',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_form_products_add,
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
var multi_products = {
|
||||
id: "multi_products",
|
||||
animate: true,
|
||||
|
@ -345,197 +155,17 @@ var multi_products = {
|
|||
{view:"toolbar", elements: toolbar_products},
|
||||
grid_products,
|
||||
]},
|
||||
{id: "product_new", rows:[form_product]},
|
||||
{id: "product_add", rows:[form_products_add]}
|
||||
{id: "product_new", rows:[form_product, {}]}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var app_products = {
|
||||
id: 'app_products',
|
||||
id: "app_products",
|
||||
rows:[
|
||||
{view: 'template', id: 'th_products', type: 'header',
|
||||
template: 'Administración de Productos y Servicios'},
|
||||
{view: "template", id: "th_products", type: "header", template:"Administración de Productos" },
|
||||
multi_products
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var body_import_products = {rows: [
|
||||
{view: 'form', id: 'form_upload_products', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'up_products', autosend: false,
|
||||
link: 'lst_upload_products', value: 'Seleccionar Archivo',
|
||||
upload: '/files/products'}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_upload_products', name: 'lst_upload_products',
|
||||
type: 'uploader', autoheight: true, borderless: true}]},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_upload_products',
|
||||
label: 'Importar Productos'}, {}]},
|
||||
]},
|
||||
]}
|
||||
|
||||
|
||||
var win_import_products = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_import_products',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Importar Productos',
|
||||
body: body_import_products,
|
||||
})
|
||||
$$('cmd_upload_products').attachEvent('onItemClick', cmd_upload_products_click)
|
||||
$$('up_products').attachEvent('onUploadComplete', up_products_upload_complete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_add_products_from_xml = {rows: [
|
||||
{view: 'form', id: 'form_upload_products_from_xml', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'up_products_from_xml', autosend: false,
|
||||
link: 'lst_up_products_from_xml', value: 'Seleccionar Archivo',
|
||||
upload: '/files/productsadd'}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_up_products_from_xml', type: 'uploader',
|
||||
autoheight: true, borderless: true}]},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_upload_products_from_xml',
|
||||
label: 'Cargar Productos'}, {}]},
|
||||
]},
|
||||
]}
|
||||
|
||||
|
||||
var win_add_products_from_xml = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_add_products_from_xml',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Agregar Productos desde XML',
|
||||
body: body_add_products_from_xml,
|
||||
})
|
||||
$$('cmd_upload_products_from_xml').attachEvent('onItemClick', cmd_upload_products_from_xml_click)
|
||||
$$('up_products_from_xml').attachEvent('onUploadComplete', up_products_from_xml_upload_complete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_add_inventory = {rows: [{minHeight: 10},
|
||||
{view: 'text', id: 'txt_add_id', readonly: true, hidden: true},
|
||||
{cols: [
|
||||
{view: 'text', id: 'txt_add_key', label: 'Clave',
|
||||
labelPosition: 'top', readonly: true},
|
||||
{view: 'text', id: 'txt_add_unit', label: 'Unidad',
|
||||
labelPosition: 'top', readonly: true},
|
||||
]},
|
||||
{view: 'textarea', id: 'txt_add_description', height: 100,
|
||||
label: 'Descripción', readonly: true, labelPosition: 'top'},
|
||||
{minHeight: 10},
|
||||
{cols: [
|
||||
{view: 'counter', id: 'txt_new_cant', label: 'Cantidad a agregar',
|
||||
labelWidth: 'auto', step: 1, value: 0, min: 0.01},
|
||||
{view: 'richselect', id: 'lst_warehouses', label: 'Almacen: ',
|
||||
labelPosition: 'left', required: false, options: [], hidden: false},
|
||||
]},
|
||||
{minHeight: 20},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_add_inventory_save', label: 'Guardar'}, {},
|
||||
{view: 'button', id: 'cmd_add_inventory_cancel', label: 'Cancelar', type: 'danger'}, {}
|
||||
]},
|
||||
{minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_add_inventory = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_add_inventory',
|
||||
width: 600,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Agregar entrada manualmente',
|
||||
body: body_add_inventory,
|
||||
})
|
||||
$$('cmd_add_inventory_save').attachEvent('onItemClick', cmd_add_inventory_save_click)
|
||||
$$('cmd_add_inventory_cancel').attachEvent('onItemClick', cmd_add_inventory_cancel_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var grid_warehouse_exists_cols = [
|
||||
{ id: 'id', header: 'ID', width: 75, hidden: true},
|
||||
{ id: 'warehouse', header: ['Almacen'], fillspace:true,
|
||||
footer: {text: 'Total', css: 'right'}},
|
||||
{ id: 'exists', header: ['Existencia'], width: 100, sort: 'int',
|
||||
format: webix.i18n.numberFormat, css: 'right',
|
||||
footer: {content: 'summColumn', css: 'right'} },
|
||||
]
|
||||
|
||||
|
||||
var grid_warehouse_exists = {
|
||||
view: 'datatable',
|
||||
id: 'grid_warehouse_exists',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
select: 'row',
|
||||
footer: true,
|
||||
columns: grid_warehouse_exists_cols,
|
||||
}
|
||||
|
||||
|
||||
var body_win_show_exists = {rows: [{maxHeight: 10, minHeight: 10},
|
||||
{minWidth: 500},
|
||||
{cols: [
|
||||
{maxWidth: 10},
|
||||
{view: 'text', id: 'txt_id_product', readonly: true, hidden: true},
|
||||
grid_warehouse_exists,
|
||||
{maxWidth: 10}
|
||||
]},
|
||||
{maxHeight: 10},
|
||||
{cols: [{maxWidth: 10},
|
||||
{view: 'label', id: 'lbl_title_move', label: 'Primero, selecciona el almacen origen en la tabla superior.'},
|
||||
]},
|
||||
{cols: [{maxWidth: 10},
|
||||
{view: 'counter', id: 'txt_cant_to_move', label: 'Cantidad a mover:',
|
||||
labelPosition: 'top', step: 1, value: 0, min: 0.01},
|
||||
{view: 'richselect', id: 'lst_warehouse_target', label: 'Almacen destino: ',
|
||||
labelPosition: 'top', required: false, options: []}, {maxWidth: 10},
|
||||
{view: 'button', id: 'cmd_warehouse_move', label: 'Mover', maxWidth: 100},
|
||||
{maxWidth: 10}]},
|
||||
{minHeight: 25, maxHeight: 25},
|
||||
{template: 'Ajuste de almacen', type: 'section'},
|
||||
{cols: [{maxWidth: 10},
|
||||
{view: 'counter', id: 'txt_cant_to_adjust', label: 'Cantidad a ajustar:',
|
||||
labelPosition: 'top', step: 1, value: 0, min: -1000000},
|
||||
{view: 'button', id: 'cmd_adjust_stock', label: 'Ajustar', maxWidth: 100},
|
||||
{maxWidth: 10}]},
|
||||
{maxHeight: 20, minHeight: 20},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_win_show_exists_close', label: 'Cerrar', type: 'danger'},
|
||||
{}]},
|
||||
{maxHeight: 20, minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_show_exists = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_show_exists',
|
||||
width: 500,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Existencia por Almacen',
|
||||
body: body_win_show_exists,
|
||||
})
|
||||
$$('cmd_win_show_exists_close').attachEvent('onItemClick', cmd_win_show_exists_close_click)
|
||||
$$('cmd_warehouse_move').attachEvent('onItemClick', cmd_warehouse_move_click)
|
||||
$$('cmd_adjust_stock').attachEvent('onItemClick', cmd_adjust_stock_click)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
|
||||
|
||||
var toolbar_students = [
|
||||
{view: 'button', id: 'cmd_new_student', label: 'Nuevo', type: 'iconButton',
|
||||
autowidth: true, icon: 'user-plus'},
|
||||
{view: 'button', id: 'cmd_edit_student', label: 'Editar', type: 'iconButton',
|
||||
autowidth: true, icon: 'user'},
|
||||
{view: 'button', id: 'cmd_delete_student', label: 'Eliminar', type: 'iconButton',
|
||||
autowidth: true, icon: 'user-times'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_students = [
|
||||
{id: 'index', header:'#', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 2, css: 'right'}},
|
||||
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
|
||||
{id: 'nombre', header: ['Nombre', {content: 'textFilter'}],
|
||||
sort: 'string'},
|
||||
{id: 'paterno', header: ['A. Paterno', {content: 'textFilter'}],
|
||||
sort: 'string'},
|
||||
{id: 'materno', header: ['A. Materno', {content: 'textFilter'}],
|
||||
sort: 'string'},
|
||||
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
|
||||
sort: 'string'},
|
||||
{id: 'curp', header: ['CURP'], sort: 'string', adjust: 'data'},
|
||||
]
|
||||
|
||||
|
||||
var grid_students = {
|
||||
view: 'datatable',
|
||||
id: 'grid_students',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_cols_students,
|
||||
ready:function(){
|
||||
this.adjustColumn('index');
|
||||
this.adjustColumn('id');
|
||||
this.adjustColumn('nombre');
|
||||
this.adjustColumn('rfc');
|
||||
this.adjustColumn('curp');
|
||||
},
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i+1;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var rows_school_home = [
|
||||
{view: 'toolbar', elements: toolbar_students},
|
||||
grid_students,
|
||||
]
|
||||
|
||||
|
||||
var student_controls_generales = [
|
||||
{view: 'text', id: 'student_name', name: 'nombre', label: 'Nombre: ',
|
||||
required: true, invalidMessage: 'El nombre es requerido'},
|
||||
{view: 'text', id: 'student_paterno', name: 'paterno', label: 'Apellido Paterno: ',
|
||||
required: true, invalidMessage: 'El apellido paterno es requerido'},
|
||||
{view: 'text', id: 'student_materno', name: 'materno',
|
||||
label: 'Apellido Materno: '},
|
||||
{cols: [
|
||||
{view: 'text', id: 'student_rfc', name: 'rfc', label: 'RFC: ',
|
||||
invalidMessage: 'RFC inválido', adjust: 'data',
|
||||
attributes: {maxlength: 13}},
|
||||
{view: 'text', id: 'student_curp', name: 'curp', label: 'CURP: ',
|
||||
required: true, invalidMessage: 'CURP inválido', adjust: 'data',
|
||||
attributes: {maxlength: 20}},
|
||||
{}]},
|
||||
{cols: [
|
||||
{view: 'richselect', id: 'student_grupo', name: 'grupo',
|
||||
label: 'Nivel Educativo: ', required: true, options: [],
|
||||
invalidMessage: 'El Nivel Educativo es requerido'},
|
||||
{},
|
||||
]},
|
||||
]
|
||||
|
||||
|
||||
var form_controls_student = [
|
||||
{
|
||||
view: 'tabview',
|
||||
id: 'tab_student',
|
||||
tabbar: {options: ['Datos Generales']}, animate: true,
|
||||
cells: [
|
||||
{id: 'Datos Generales', rows: student_controls_generales},
|
||||
]
|
||||
},
|
||||
{rows: [
|
||||
{ template:"", type: "section" },
|
||||
{ margin: 10, cols: [{},
|
||||
{view: "button", id: "cmd_save_student", label: "Guardar" ,
|
||||
type: "form", autowidth: true, align: "center"},
|
||||
{view: "button", id: "cmd_cancel_student", label: "Cancelar" ,
|
||||
type: "danger", autowidth: true, align: "center"},
|
||||
{}]
|
||||
},
|
||||
]}
|
||||
]
|
||||
|
||||
|
||||
var form_student = {
|
||||
type: 'space',
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_student',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: form_controls_student,
|
||||
elementsConfig: {
|
||||
labelWidth: 150,
|
||||
labelAlign: 'right'
|
||||
},
|
||||
rules: {
|
||||
nombre: function(value){ return value.trim() != '';},
|
||||
curp: validate_curp,
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
var multi_school = {
|
||||
id: 'multi_school',
|
||||
view: 'multiview',
|
||||
animate: true,
|
||||
cells:[
|
||||
{id: 'school_home', rows: rows_school_home},
|
||||
{id: 'school_groups', rows: []},
|
||||
{id: 'new_student', rows: [form_student]},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var app_school = {
|
||||
id: 'app_school',
|
||||
rows:[
|
||||
{view: 'template', id: 'th_school', type: 'header',
|
||||
template: 'Administración de Escuela'},
|
||||
multi_school
|
||||
],
|
||||
}
|
|
@ -1,492 +0,0 @@
|
|||
|
||||
|
||||
var toolbar_tickets = [
|
||||
{view: 'button', id: 'cmd_nuevo_ticket', label: 'Nuevo', type: 'iconButton',
|
||||
autowidth: true, icon: 'plus'},
|
||||
{view: 'button', id: 'cmd_ticket_from_ticket', label: 'Regenerar',
|
||||
type: 'iconButton', autowidth: true, icon: 'pencil'},
|
||||
{view: 'button', id: 'cmd_ticket_to_invoice', label: 'Facturar',
|
||||
type: 'iconButton', autowidth: true, icon: 'file-code-o'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_ticket_report_pdf', label: 'Reporte',
|
||||
type: 'iconButton', autowidth: true, icon: 'file-pdf-o'},
|
||||
{view: 'button', id: 'cmd_ticket_report_xls', label: 'Reporte',
|
||||
type: 'iconButton', autowidth: true, icon: 'table'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_cancelar_ticket', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
]
|
||||
|
||||
|
||||
var toolbar_tickets_filter = [
|
||||
{view: 'button', id: 'cmd_ticket_filter_today', label: 'Hoy', type: 'iconButton',
|
||||
autowidth: true, icon: 'filter'},
|
||||
{view: 'richselect', id: 'filter_year_ticket', label: 'Año',
|
||||
labelAlign: 'right', labelWidth: 50, width: 150, options: []},
|
||||
{view: 'richselect', id: 'filter_month_ticket', label: 'Mes',
|
||||
labelAlign: 'right', labelWidth: 50, width: 200, options: months},
|
||||
{view: 'daterangepicker', id: 'filter_dates_ticket', label: 'Fechas',
|
||||
labelAlign: 'right', width: 300},
|
||||
]
|
||||
|
||||
|
||||
var grid_tickets_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "header",
|
||||
sort: "string"},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
|
||||
sort: 'int', css: 'right', footer: {text: 'Tickets', colspan: 3}},
|
||||
{id: "fecha", header: ["Fecha y Hora"],
|
||||
adjust: "data", sort: "date"},
|
||||
{id: "estatus", header: ["Estatus", {content: "selectFilter"}],
|
||||
adjust: "data", sort:"string"},
|
||||
{id: 'total', header: ['Total', {content: 'numberFilter'}], width: 150,
|
||||
sort: 'int', format: webix.i18n.priceFormat, css: 'right',
|
||||
footer: {content: 'summActive', css: 'right'}},
|
||||
{id: "cliente", header: ["Razón Social", {content: "selectFilter"}],
|
||||
fillspace:true, sort:"string", hidden: true},
|
||||
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
|
||||
{id: 'print', header: '', adjust: 'data', template: get_icon('print')},
|
||||
]
|
||||
|
||||
|
||||
var grid_tickets = {
|
||||
view: 'datatable',
|
||||
id: 'grid_tickets',
|
||||
select: 'row',
|
||||
scrollY: true,
|
||||
adjust: true,
|
||||
footer: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_tickets_cols,
|
||||
scheme:{
|
||||
$change:function(item){
|
||||
if (item.estatus == 'Cancelado'){
|
||||
item.$css = 'cancel'
|
||||
}
|
||||
}
|
||||
},
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var rows_tickets_home = [
|
||||
{view: 'toolbar', elements: toolbar_tickets},
|
||||
{view: 'toolbar', elements: toolbar_tickets_filter},
|
||||
grid_tickets,
|
||||
]
|
||||
|
||||
|
||||
var ticket_suggest_products = {
|
||||
view: 'gridsuggest',
|
||||
id: 'gt_productos_found',
|
||||
name: 'gt_productos_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
header: true,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'clave', header: 'Clave', adjust: 'data'},
|
||||
{id: 'descripcion', header: 'Descripción', width: 500},
|
||||
{id: 'unidad', header: 'Unidad', adjust: 'data'},
|
||||
{id: 'valor_unitario', header: 'Valor Unitario', adjust: 'data',
|
||||
format: webix.i18n.priceFormat}
|
||||
],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 2){
|
||||
this.load('/values/product?name=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var tbody_buscar_producto = {rows: [
|
||||
{cols: [
|
||||
{view: 'search', id: 'tsearch_product_key', name: 'tsearch_product_key',
|
||||
label: 'por Clave', labelPosition:'top', maxWidth: 250,
|
||||
placeholder: 'Presiona ENTER para buscar'},
|
||||
{view: 'search', id: 'tsearch_product_name', name: 'tsearch_product_name',
|
||||
label: 'por Descripción', labelPosition:'top',
|
||||
suggest: ticket_suggest_products, placeholder: 'Captura al menos tres letras'},
|
||||
]},
|
||||
]}
|
||||
|
||||
|
||||
var grid_tdetails_cols = [
|
||||
{id: "id_product", header:"ID", hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: "clave", header:{text: 'Clave', css: 'center'}, width: 100,
|
||||
footer: {text: 'Artículos', css: 'right_footer3'}},
|
||||
{id: "clave_sat", hidden: true},
|
||||
{id: "descripcion", header:{text: 'Descripción', css: 'center'},
|
||||
fillspace: true, footer: {content: 'countRows', css: 'footer3'}},
|
||||
{id: "unidad", header:{text: 'Unidad', css: 'center'}, width: 100,
|
||||
editor: 'select', options: 'values/unidades'},
|
||||
{id: 'cantidad', header: {text: 'Cantidad', css: 'center'}, width: 100,
|
||||
format: webix.i18n.numberFormat, css: 'right', editor: 'text',
|
||||
footer: {content: 'summColumn', css: 'right_footer3'}},
|
||||
{id: "valor_unitario", header:{text: 'Valor Unitario', css: 'center'},
|
||||
width: 100, format: webix.i18n.priceFormat, css: 'right', editor: 'text',
|
||||
footer: {text: 'Total ', css: 'right_footer2'}},
|
||||
{id: 'descuento', header: {text: 'Descuento', css: 'center'}, hidden: true,
|
||||
width: 80, format: webix.i18n.priceFormat, css: 'right', editor: 'text'},
|
||||
{id: 'precio_final', hidden: true, header: 'precio_final', width: 80,
|
||||
format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: "importe", header:{text: 'Importe', css: 'center'}, width: 150,
|
||||
format: webix.i18n.priceFormat, css: 'right',
|
||||
footer: {content: 'summColumn', css: 'right_footer2'}},
|
||||
{id: "inventario", hidden: true},
|
||||
{id: "existencia", hidden: true},
|
||||
]
|
||||
|
||||
|
||||
var grid_tdetails = {
|
||||
view: 'datatable',
|
||||
id: 'grid_tdetails',
|
||||
select: 'row',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
editable: true,
|
||||
footer: true,
|
||||
columns: grid_tdetails_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.delete = '-'
|
||||
})
|
||||
}
|
||||
},
|
||||
data: [],
|
||||
}
|
||||
|
||||
|
||||
var body_ticket_informacion = {rows: [
|
||||
{view: 'richselect', id: 'lst_ticket_forma_pago', name: 'forma_pago',
|
||||
label: 'Forma de Pago', labelPosition: 'top', required: true,
|
||||
options: []},
|
||||
],}
|
||||
|
||||
|
||||
var toolbar_new_ticket = {
|
||||
view: 'toolbar', elements: [
|
||||
{view: 'button', id: 'cmd_generar_ticket', label: 'Generar',
|
||||
icon: 'ticket', type: 'iconButton', autowidth: true,
|
||||
align: 'center', hotkey: 'Ctrl+g'}, {},
|
||||
{view: 'button', id: 'cmd_ticket_notes', label: 'Notas',
|
||||
autowidth: true, type: 'iconButton', icon: 'commenting-o'}, {},
|
||||
{view: 'button', id: 'cmd_cerrar_ticket', label: 'Cerrar',
|
||||
type: 'danger', autowidth: true, align: 'center'}
|
||||
]}
|
||||
|
||||
|
||||
var grid_ticket_total_up = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ticket_total_up',
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
width: 250,
|
||||
header: false,
|
||||
footer: true,
|
||||
hidden: true,
|
||||
rowHeight: 0,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'title', width: 100,
|
||||
footer: {text: 'Total ', css: 'right_footer2'}},
|
||||
{id: 'total', fillspace: true, format: webix.i18n.priceFormat,
|
||||
footer: {content: 'summColumn', css: 'right_footer2'}},
|
||||
],
|
||||
data: [{id:0, title: '', total: 0.00}]
|
||||
}
|
||||
|
||||
|
||||
var cells_new_ticket = [
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
toolbar_new_ticket,
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
{cols: [{rows: [
|
||||
{view: 'fieldset', label: 'Buscar Producto', body: tbody_buscar_producto},
|
||||
]},
|
||||
{maxWidth: 10},
|
||||
{maxWidth: 300, rows: [
|
||||
{view: 'fieldset', label: 'Información', body: body_ticket_informacion},
|
||||
]},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'label', label: 'Detalle', height: 30, align: 'left'},
|
||||
{},
|
||||
grid_ticket_total_up,
|
||||
]},
|
||||
grid_tdetails,
|
||||
]
|
||||
|
||||
|
||||
var toolbar_ticket_invoice = {view: 'toolbar', elements: [{},
|
||||
{view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150,
|
||||
labelRight: 'Es Factura Global'},
|
||||
{view: 'richselect', id: 'lst_global_periodicidad_2', labelWidth: 90, width: 225,
|
||||
label: 'Periodicidad:', options: opt_global_periodicidad, value: '01', disabled: true},
|
||||
{view: 'richselect', id: 'lst_global_months_2', labelWidth: 50, width: 250,
|
||||
label: 'Mes:', options: opt_global_months, value: '01', disabled: true},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar',
|
||||
type: 'danger', autowidth: true, align: 'center'}
|
||||
]}
|
||||
|
||||
|
||||
var ticket_suggest_partners = {
|
||||
view: 'gridsuggest',
|
||||
id: 'grid_ticket_clients_found',
|
||||
name: 'grid_ticket_clients_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
header: false,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'nombre', adjust: 'data'},
|
||||
{id: 'rfc', adjust: 'data'},
|
||||
{id: 'forma_pago', hidden: true},
|
||||
{id: 'uso_cfdi', hidden: true},
|
||||
],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 2){
|
||||
this.load('/values/client?name=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ticket_search_client = {cols: [{rows: [
|
||||
{view: 'fieldset', id: 'fs_ticket_search_client', label: 'Buscar Cliente', body: {rows: [
|
||||
{cols: [
|
||||
{view: 'search', id: 'tsearch_client_key', name: 'tsearch_client_key',
|
||||
label: 'por Clave', labelPosition: 'top', maxWidth: 250,
|
||||
placeholder:'Presiona ENTER para buscar'},
|
||||
{view: 'search', id: 'tsearch_client_name',
|
||||
name: 'tsearch_client_name', label: 'por Nombre o RFC',
|
||||
labelPosition: 'top', suggest: ticket_suggest_partners,
|
||||
placeholder: 'Captura al menos tres letras'},
|
||||
]},
|
||||
{cols: [
|
||||
{view: 'label', id: 'lbl_tclient_title', autowidth:true,
|
||||
name: "lbl_tclient_title", label: 'Seleccionado: ' },
|
||||
{view: 'label', id: 'lbl_tclient', name: 'lbl_tclient',
|
||||
label: 'Ninguno'},
|
||||
]}
|
||||
]}},
|
||||
]},]}
|
||||
|
||||
|
||||
var grid_tickets_active_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
|
||||
sort: "string"},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
|
||||
sort: 'int', css: 'right', footer: {content: 'countRows', css: 'right'}},
|
||||
{id: "fecha", header: ["Fecha y Hora"], adjust: "data", sort: "string",
|
||||
footer: 'Tickets'},
|
||||
{id: 'total', header: 'Total', width: 150,sort: 'int', css: 'right',
|
||||
format: webix.i18n.priceFormat, footer: {content: 'summColumn',
|
||||
css: 'right'}},
|
||||
]
|
||||
|
||||
|
||||
var grid_tickets_active = {
|
||||
view: 'datatable',
|
||||
id: 'grid_tickets_active',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
adjust: true,
|
||||
footer: true,
|
||||
drag: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_tickets_active_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var grid_tickets_invoice_cols = [
|
||||
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
|
||||
sort: "string"},
|
||||
{id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
|
||||
sort: 'int', css: 'right', footer: {content: 'countRows', css: 'right'}},
|
||||
{id: "fecha", header: ["Fecha y Hora"], adjust: "data", sort: "string",
|
||||
footer: 'Tickets'},
|
||||
{id: 'total', header: 'Total', width: 150,sort: 'int', css: 'right',
|
||||
format: webix.i18n.priceFormat, footer: {content: 'summColumn',
|
||||
css: 'right'}},
|
||||
]
|
||||
|
||||
|
||||
var grid_tickets_invoice = {
|
||||
view: 'datatable',
|
||||
id: 'grid_tickets_invoice',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
adjust: true,
|
||||
footer: true,
|
||||
drag: true,
|
||||
resizeColumn: true,
|
||||
headermenu: true,
|
||||
columns: grid_tickets_invoice_cols,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.index = i + 1
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var controls_ticket_to_invoice = [
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
toolbar_ticket_invoice,
|
||||
{minHeight: 10, maxHeight: 10},
|
||||
ticket_search_client,
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
{cols:[
|
||||
{rows: [{view: 'label', label: 'Tickets sin facturar', height: 30,
|
||||
align: 'left'},
|
||||
grid_tickets_active]},
|
||||
{rows:[{},
|
||||
{view: 'button', id: 'cmd_move_tickets_right', label: '->', autowidth: true},
|
||||
{view: 'button', id: 'cmd_move_tickets_left', label: '<-', autowidth: true},
|
||||
{}]},
|
||||
{rows: [{view: 'label', label: 'Tickets a facturar', height: 30,
|
||||
align: 'left'},
|
||||
grid_tickets_invoice]},
|
||||
]},
|
||||
{minHeight: 20, maxHeight: 20},
|
||||
{margin: 20, cols: [{},
|
||||
{view: 'button', id: 'cmd_new_invoice_from_ticket', label: 'Facturar',
|
||||
icon: 'ticket', type: 'iconButton', autowidth: true, align: 'center'},
|
||||
{}]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
var controls_new_ticket = [
|
||||
{
|
||||
view: 'tabview',
|
||||
id: 'tv_new_ticket',
|
||||
animate: true,
|
||||
cells: [
|
||||
{id: 'Generar', rows: cells_new_ticket},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
var controls_ticket_invoice = [
|
||||
{
|
||||
view: 'tabview',
|
||||
id: 'tv_ticket_invoice',
|
||||
animate: true,
|
||||
cells: [
|
||||
{id: 'Facturar Tickets', rows: controls_ticket_to_invoice},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
var form_new_ticket = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_new_ticket',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_new_ticket,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var form_ticket_invoice = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_ticket_invoice',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_ticket_invoice,
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
var multi_tickets = {
|
||||
id: 'multi_tickets',
|
||||
view: 'multiview',
|
||||
animate: true,
|
||||
cells:[
|
||||
{id: 'tickets_home', rows: rows_tickets_home},
|
||||
{id: 'tickets_new', rows:[form_new_ticket]},
|
||||
{id: 'tickets_invoice', rows:[form_ticket_invoice]}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var app_tickets = {
|
||||
id: 'app_tickets',
|
||||
rows:[
|
||||
{view: 'template', id: 'th_ticckets', type: 'header',
|
||||
template: 'Punto de venta - Tickets'},
|
||||
multi_tickets
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
var body_ticket_notes = {rows: [
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
{view: 'textarea', id: 'ticket_notes', name: 'ticket_notes', height: 300,
|
||||
placeholder: 'Captura las notas'},
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_ticket_save_note', autowidth: true,
|
||||
label: 'Guardar y Cerrar', type: 'iconButton', hotkey: 'Ctrl+enter'},
|
||||
{}]},
|
||||
{minHeight: 5, maxHeight: 5},
|
||||
]}
|
||||
|
||||
|
||||
var win_ticket_notes = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_ticket_notes',
|
||||
height: 400,
|
||||
width: 500,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Notas',
|
||||
body: body_ticket_notes,
|
||||
})
|
||||
$$('cmd_ticket_save_note').attachEvent('onItemClick', cmd_ticket_save_note_click)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
<%inherit file="base.html"/>
|
||||
|
||||
<%block name="media">
|
||||
<link rel="stylesheet" href="/static/css/sidebar_air.css" type="text/css">
|
||||
<link rel="stylesheet" href="/static/css/app.css" type="text/css">
|
||||
<script src="/static/js/sidebar.js" type="text/javascript" ></script>
|
||||
|
||||
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/admin.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/admin.js" type="text/javascript" ></script>
|
||||
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
<meta charset="utf-8" />
|
||||
<link rel="shortcut icon" href="/static/img/favicon.png">
|
||||
<link rel="stylesheet" href="/static/css/air.css" type="text/css">
|
||||
<link rel="stylesheet" href="/static/css/sidebar_air.css" type="text/css">
|
||||
<link rel="stylesheet" href="/static/css/app.css" type="text/css">
|
||||
<script src="/static/js/webix.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/webix_debug.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/es-MX.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/lokijs.min.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
|
||||
|
||||
<%block name="media"/>
|
||||
|
||||
</head>
|
||||
|
@ -20,7 +17,7 @@
|
|||
<body>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
webix.debug = false;
|
||||
webix.debug = true;
|
||||
webix.i18n.setLocale("es-MX");
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Cancelacion RfcEmisor="{rfc}" Fecha="{fecha}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://cancelacfd.sat.gob.mx">
|
||||
<Folios>
|
||||
<UUID>{uuid}</UUID>
|
||||
</Folios>
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
|
||||
<Reference URI="">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
|
||||
<DigestValue />
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue />
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509SubjectName />
|
||||
<X509IssuerSerial />
|
||||
<X509Certificate />
|
||||
</X509Data>
|
||||
<KeyValue />
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</Cancelacion>
|
|
@ -1,142 +0,0 @@
|
|||
<%inherit file="base.html"/>
|
||||
|
||||
<%block name="media">
|
||||
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/empresas.js" type="text/javascript" ></script>
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
|
||||
<div id="form_empresas"></div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
|
||||
function agregar_empresa(values){
|
||||
webix.ajax().post("/empresas", values, function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
$$('form_empresas').clear()
|
||||
$$('grid_empresas').add(values.row)
|
||||
$$('grid_empresas').refresh()
|
||||
msg_ok(values.msg)
|
||||
} else {
|
||||
msg_error(values.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function validate_nuevo_rfc(){
|
||||
var msg = ''
|
||||
var form = this.getFormView();
|
||||
|
||||
if (!form.validate()) {
|
||||
msg = 'Valores inválidos'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!validar_rfc(values['alta_rfc'])){
|
||||
return
|
||||
}
|
||||
|
||||
values['opt'] = 1
|
||||
|
||||
msg = '¿Estás seguro de agregar este nuevo emisor?'
|
||||
webix.confirm({
|
||||
title: 'Agregar Emisor',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
msg = 'Agregando empresa, espera la confirmación...'
|
||||
msg_ok(msg)
|
||||
agregar_empresa(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function borrar_empresa(id){
|
||||
var row = $$('grid_empresas').getItem(id)
|
||||
webix.ajax().del('/empresas', {rfc: row.rfc}, function(text, xml, xhr){
|
||||
msg = 'Emisor eliminado correctamente'
|
||||
if(xhr.status == 200){
|
||||
$$('grid_empresas').remove(id)
|
||||
msg_ok(msg)
|
||||
}else{
|
||||
msg = 'No se pudo eliminar'
|
||||
msg_error(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_empresas_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de borrar el RFC seleccionado?<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER'
|
||||
webix.confirm({
|
||||
title: 'Borrar Emisor',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
borrar_empresa(id.row)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function respaldar_bd(){
|
||||
webix.ajax().post("/empresas", {'opt': 2}, function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
msg_ok(values.msg)
|
||||
} else {
|
||||
msg_error(values.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_respaldar_bd(){
|
||||
msg = '¿Estás seguro de respaldar las Bases de Datos?'
|
||||
webix.confirm({
|
||||
title: 'Respaldar BD',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
msg = 'Respaldando Bases de datos...'
|
||||
msg_ok(msg)
|
||||
respaldar_bd()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
webix.ready(function(){
|
||||
webix.ui(ui_empresas)
|
||||
$$('grid_empresas').attachEvent('onItemClick', grid_empresas_click)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</%block>
|
|
@ -36,11 +36,6 @@ function validate_login(){
|
|||
|
||||
webix.ready(function(){
|
||||
webix.ui(ui_login);
|
||||
webix.ajax().get("/values/titlelogin", function(text, data, xhr){
|
||||
var value = data.json();
|
||||
$$("title_login").setHTML(value);
|
||||
})
|
||||
$$("txt_rfc").focus();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
<%inherit file="base.html"/>
|
||||
|
||||
<%block name="media">
|
||||
<link rel="stylesheet" href="/static/css/sidebar_air.css" type="text/css">
|
||||
<script src="/static/js/sidebar.js" type="text/javascript" ></script>
|
||||
|
||||
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/partners.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/products.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/bancos.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/school.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/nomina.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/tickets.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/invoices.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/ui/main.js" type="text/javascript" ></script>
|
||||
|
||||
<script src="/static/js/controller/partners.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/products.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/bancos.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/school.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/nomina.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/tickets.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/invoices.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/controller/main.js" type="text/javascript" ></script>
|
||||
|
||||
|
|