forked from elmau/empresa-libre
Merge branch 'develop'
Error #287 Mejora - Facturas de pago con datos bancarios
This commit is contained in:
commit
2090aa743d
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,9 +1,17 @@
|
|||
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 la rama principal.
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
|
||||
|
||||
|
||||
v 1.19.1 [03-oct-2018]
|
||||
|
|
|
@ -19,6 +19,20 @@ a usar, esto se hace en ***Catalogos SAT***, pestaña ***Bancos***. Por default
|
|||
veras primero los bancos ya seleccionados. Marca la casilla de verificación de
|
||||
cada banco que deses tener disponible al agregar las cuentas bancarias. Usa la
|
||||
barra de desplazamiento de la tabla o la rueda de tu ratón para ver más bancos.
|
||||
Cada banco que selecciones, también estará disponible en la sección ***Clientes
|
||||
y Proveedores***.
|
||||
|
||||
<BR>
|
||||
<div class="alert-box notice"><span>TIP: </span>
|
||||
Si vas a agregar los datos bancarios en las ***Facturas de pago***, es
|
||||
necesario capturar el RFC de cada banco seleccionado.
|
||||
</div>
|
||||
|
||||
<BR>
|
||||
Para editar el RFC, solo da clic en la celda correspondiente y captura
|
||||
correctamente el RFC del banco, para guardar presionas ***Enter***. El sistema
|
||||
solo válida que sea un RFC válido, por lo que **asegurate de que sea el RFC
|
||||
correcto para cada banco**.
|
||||
|
||||
![Seleccionar bancos](img/02/admin_002.png)
|
||||
|
||||
|
|
|
@ -175,8 +175,11 @@ elimina un movimiento, no importa si es retiro o depósito, el saldo de la cuent
|
|||
se actualiza a partir de la fecha del movimiento eliminado y hasta el más
|
||||
reciente.
|
||||
|
||||
* Si es un depósito y tiene facturas relacionadas, las mismas estarán de nuevo marcadas como **Por pagar** y disponibles para relacionarse con otro depósito.
|
||||
* **No podrás eliminar** un depósito si este ya tiene generada una Factura de Pago. **Siempre, asegurate de que todo este correcto antes de generar una Factura de Pago**.
|
||||
* Si es un depósito y tiene facturas relacionadas, las mismas estarán de nuevo
|
||||
marcadas como **Por pagar** y disponibles para relacionarse con otro depósito.
|
||||
* Puedes eliminar un depósito aún si este tiene generada una Factura de Pago. La
|
||||
misma quedará ***huerfana***, pero disponible desde el listado de Facturas de
|
||||
Pago elaboradas.
|
||||
|
||||
![Cancelar movimiento](img/03/bancos_017.png)
|
||||
|
||||
|
@ -185,8 +188,8 @@ reciente.
|
|||
### Generar Factura de Pago
|
||||
|
||||
Para usar esta herramienta, debe estar activado el uso del [complemento de pago][2]
|
||||
dentro de administración. Si no ves en ***Bancos*** el botón de comando ***Factura
|
||||
de Pago***, solicita a un administrador que lo active.
|
||||
dentro de administración. Si no ves en ***Bancos*** el botón de comando ***Generar
|
||||
Factura de Pago***, solicita a un administrador que lo active.
|
||||
|
||||
![Factura de pago](img/03/bancos_018.png)
|
||||
|
||||
|
@ -198,8 +201,9 @@ de Pago***, solicita a un administrador que lo active.
|
|||
|
||||
<BR>
|
||||
|
||||
* Solo puedes generar ***Facturas de pago*** de movimientos de depósito que tengan facturas relacionadas.
|
||||
* Selecciona el depósito correcto y presiona el botón de comando ***Factura de Pago***.
|
||||
* Solo puedes generar ***Facturas de pago*** de movimientos de depósito que tengan
|
||||
facturas relacionadas.
|
||||
* Selecciona el depósito correcto y presiona el botón de comando ***Generar Factura de Pago***.
|
||||
|
||||
En la siguiente pantalla, **verifica una vez más que todos los datos con correctos**.
|
||||
En este momento puedes cerrar e incluso cancelar el movimiento para hacer cualquier
|
||||
|
@ -221,7 +225,7 @@ de Pago***.
|
|||
|
||||
![Factura de pago](img/03/bancos_021.png)
|
||||
|
||||
Con un clic en el icono ***PDF***, puedes generarl el PDF respectivo de esta
|
||||
Con un clic en el icono ***PDF***, puedes generar el PDF respectivo de esta
|
||||
***Factura de Pago***. Como con las plantillas de las facturas, puedes
|
||||
personalizar completamente esta plantilla.
|
||||
|
||||
|
@ -243,9 +247,14 @@ documento.
|
|||
Los siguientes pasos **son importantes y en este orden**, los campos que debes de modificar en la
|
||||
tabla ***Facturas a pagar en este depósito*** son:
|
||||
|
||||
* **Este pago**: Si el valor pagado es el total de la factura, no lo modifiques, si es parcial, captura el valor pagado **en la moneda del documento**, en este ejemplo, en UDS. Este valor se usa para el estado de cuenta de la factura.
|
||||
* **Este Pago MXM**: Captura el valor pagado en moneda nacional de este documento. En este ejemplo, sería el valor **real** del depósito. Este valor se usará para la ***Factura de pago***, para el estado de cuenta y para el saldo del cliente.
|
||||
* **T.C.**: Al capturar correctamente los dos valores anteriores, el sistema te calculará el tipo de cambio (***T.C***) usado, si no es correcto, puedes editarlo libremente. Este valor se usa para la ***Factura de pago***.
|
||||
* **Este pago**: Si el valor pagado es el total de la factura, no lo modifiques,
|
||||
si es parcial, captura el valor pagado **en la moneda del documento**, en este
|
||||
ejemplo, en UDS. Este valor se usa para el estado de cuenta de la factura.
|
||||
* **Este Pago MXM**: Captura el valor pagado en moneda nacional de este documento.
|
||||
En este ejemplo, sería el valor **real** del depósito. Este valor se usará para
|
||||
la ***Factura de pago***, para el estado de cuenta y para el saldo del cliente.
|
||||
* **T.C.**: Al capturar correctamente los dos valores anteriores, el sistema te
|
||||
calculará el tipo de cambio (***T.C***) usado. Este valor se usa para la ***Factura de pago***.
|
||||
|
||||
Ahora, nuestros datos deben verse así:
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 55 KiB |
|
@ -13,11 +13,12 @@ existe una relación humana.</B>
|
|||
diseñado para la legislación mexicana. **Empresa Libre** es totalmente
|
||||
[software libre][1].
|
||||
|
||||
### Índice
|
||||
### Contenido
|
||||
|
||||
1. [Instalación y configuración](instalacion.md)
|
||||
1. [Administración del sistema](administracion.md)
|
||||
1. [Guía de usuario](guiadeusuario.md)
|
||||
1. [Bancos](bancos.md)
|
||||
1. [Preguntas más frecuentes](preguntas.md)
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,12 @@ la brevedad.
|
|||
|
||||
![Versión del sistema](img/01/install_001.png)
|
||||
|
||||
<BR>
|
||||
<div class="alert-box notice"><span>TIP: </span>
|
||||
Para todas las instrucciones siguientes, se asume que son para nuestra
|
||||
maquina virtual (MV), las rutas pueden cambiar si has personalizado tu
|
||||
propia MV o estas ejecutando Empresa Libre en un servidor propio.
|
||||
</div>
|
||||
|
||||
<BR>
|
||||
Ya dentro del sistema, el proceso para actualizar es:
|
||||
|
|
|
@ -6,11 +6,18 @@ siempre actualizado.** Solo se da soporte sobre la ultima versión de **Empresa
|
|||
Libre**.
|
||||
|
||||
|
||||
### 1.21.0 [12-oct-2018]
|
||||
- Error [#287](https://gitlab.com/mauriciobaeza/empresa-libre/issues/287)
|
||||
- Mejora: Complemento de pago con datos de cuentas
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
|
||||
|
||||
|
||||
### 1.20.0 [08-oct-2018]
|
||||
- Error [#295](https://gitlab.com/mauriciobaeza/empresa-libre/issues/295)
|
||||
- Mejora - Cuentas de banco para clientes
|
||||
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
|
||||
|
||||
|
||||
### 1.19.1 [03-oct-2018]
|
||||
|
|
|
@ -40,7 +40,7 @@ Finkok, el mejor PAC de México, puedes [timbrar gratuitamente en su página][2]
|
|||
No, no se incluye ningún tipo de soporte técnico. Dado que **Empresa Libre** es
|
||||
[software libre][1] y se ofrece sin **ningún costo para todos**, el soporte técnico
|
||||
es parte de los ingresos indispensables para poder seguir desarrollando y
|
||||
manteniendo el sistema. Esto incluye cualquier tontería que se le ocurra al SAT.
|
||||
manteniendo el sistema. Esto incluye cualquier estulticia que se le ocurra al SAT.
|
||||
Por eso, por favor, **no pidas soporte técnico gratis**.
|
||||
|
||||
|
||||
|
@ -73,8 +73,18 @@ acceso al sistema de pruebas son:
|
|||
* **Usuario**: admin
|
||||
* **Contraseña**: salgueiro3.3
|
||||
|
||||
Toma en cuenta que este sitio esta en constante actualización, los datos generados
|
||||
se limpian de forma regular.
|
||||
Toma en cuenta que este sitio esta en constante actualización y desarrollo, los
|
||||
datos generados se limpian de forma regular.
|
||||
|
||||
|
||||
<BR>
|
||||
### ¿Dondé descargar los archivos necesarios?
|
||||
|
||||
Todos los archivos necesarios para probar localmente **Empresa Libre** en tu
|
||||
equipo, los puedes descargar desde nuestra carpeta compartida, donde también
|
||||
puedes descargar todas las plantillas necesarias para el sistema
|
||||
|
||||
[Carpeta pública de Empresa Libre][7]
|
||||
|
||||
|
||||
<BR>
|
||||
|
@ -92,3 +102,4 @@ tu pantalla, en la mayoría de los navegadores con la combinación de teclas
|
|||
[4]: https://gitlab.com/mauriciobaeza/empresa-libre/issues
|
||||
[5]:
|
||||
[6]: https://universolibre.org/hacemos/
|
||||
[7]: https://doc.elmau.net/d/dbb11c9186684457beb6/
|
||||
|
|
|
@ -552,12 +552,28 @@ class AppSATBancos(object):
|
|||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_satbancos(values)
|
||||
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.satbancos(values)
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ from controllers.main import (AppEmpresas,
|
|||
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
||||
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
||||
AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina,
|
||||
AppInvoicePay, AppCfdiPay, AppSATBancos, AppSociosCuentasBanco
|
||||
AppInvoicePay, AppCfdiPay, AppSATBancos, AppSociosCuentasBanco,
|
||||
AppSATFormaPago
|
||||
)
|
||||
|
||||
|
||||
|
@ -59,6 +60,7 @@ 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))
|
||||
|
||||
|
||||
|
|
|
@ -436,9 +436,12 @@ class StorageEngine(object):
|
|||
def get_cfdipay(self, values):
|
||||
return main.CfdiPagos.get_values(values)
|
||||
|
||||
def get_satbancos(self, 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)
|
||||
|
||||
|
@ -448,8 +451,11 @@ class StorageEngine(object):
|
|||
def bankmovement(self, values):
|
||||
return main.MovimientosBanco.post(values)
|
||||
|
||||
def satbancos(self, 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)
|
||||
|
|
|
@ -45,6 +45,7 @@ FORMAT6 = '{0:.6f}'
|
|||
FORMAT_TAX = FORMAT4
|
||||
FORMAT_PRECIO = FORMAT4
|
||||
RFC_PUBLICO = 'XAXX010101000'
|
||||
RFC_EXTRANJERO = 'XEXX010101000'
|
||||
|
||||
|
||||
database_proxy = Proxy()
|
||||
|
@ -241,7 +242,8 @@ def config_main():
|
|||
'nomina': nomina,
|
||||
'timbres': 0,
|
||||
'decimales_precios': DECIMALES,
|
||||
'pagos': Configuracion.get_bool('chk_config_pagos')
|
||||
'pagos': Configuracion.get_bool('chk_config_pagos'),
|
||||
'pays_data_bank': Configuracion.get_bool('chk_cfg_pays_data_bank')
|
||||
}
|
||||
dp = Configuracion.get_bool('chk_config_decimales_precios')
|
||||
if dp:
|
||||
|
@ -320,6 +322,28 @@ class Configuracion(BaseModel):
|
|||
values = {r.clave: util.get_bool(r.valor) for r in data}
|
||||
return values
|
||||
|
||||
def _get_complements(self):
|
||||
fields = (
|
||||
'chk_config_ine',
|
||||
'chk_config_edu',
|
||||
'chk_config_pagos',
|
||||
'chk_cfg_pays_data_bank',
|
||||
)
|
||||
data = (Configuracion
|
||||
.select()
|
||||
.where(Configuracion.clave.in_(fields))
|
||||
)
|
||||
values = {r.clave: util.get_bool(r.valor) for r in data}
|
||||
|
||||
fields = (
|
||||
'txt_config_cfdipay_serie',
|
||||
'txt_config_cfdipay_folio',
|
||||
)
|
||||
for f in fields:
|
||||
values[f] = Configuracion.get_(f)
|
||||
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
def get_(cls, keys):
|
||||
if isinstance(keys, str):
|
||||
|
@ -331,7 +355,7 @@ class Configuracion(BaseModel):
|
|||
return data[0].valor
|
||||
return ''
|
||||
|
||||
options = ('partners',)
|
||||
options = ('partners', 'complements')
|
||||
opt = keys['fields']
|
||||
if opt in options:
|
||||
return getattr(cls, '_get_{}'.format(opt))(cls)
|
||||
|
@ -388,9 +412,6 @@ class Configuracion(BaseModel):
|
|||
'chk_config_codigo_barras',
|
||||
'chk_config_precio_con_impuestos',
|
||||
'chk_llevar_inventario',
|
||||
'chk_config_ine',
|
||||
'chk_config_edu',
|
||||
'chk_config_pagos',
|
||||
'chk_usar_punto_de_venta',
|
||||
'chk_ticket_pdf_show',
|
||||
'chk_ticket_direct_print',
|
||||
|
@ -1244,6 +1265,31 @@ class SATFormaPago(BaseModel):
|
|||
def __str__(self):
|
||||
return 'Forma de pago: ({}) {}'.format(self.key, self.name)
|
||||
|
||||
@classmethod
|
||||
def get_values(cls, values):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, '_get_{}'.format(opt))(cls, values)
|
||||
|
||||
def _get_active_by_id(self, values):
|
||||
rows = (SATFormaPago
|
||||
.select(
|
||||
SATFormaPago.id,
|
||||
SATFormaPago.name.alias('value'))
|
||||
.where(SATFormaPago.activo==True)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
def _get_active_by_key(self, values):
|
||||
rows = (SATFormaPago
|
||||
.select(
|
||||
SATFormaPago.key.alias('id'),
|
||||
SATFormaPago.name.alias('value'))
|
||||
.where(SATFormaPago.activo==True)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
@classmethod
|
||||
def get_(self):
|
||||
rows = SATFormaPago.select().dicts()
|
||||
|
@ -1878,218 +1924,6 @@ class CuentasBanco(BaseModel):
|
|||
return data
|
||||
|
||||
|
||||
class MovimientosBanco(BaseModel):
|
||||
cuenta = ForeignKeyField(CuentasBanco)
|
||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||
descripcion = TextField(default='')
|
||||
forma_pago = ForeignKeyField(SATFormaPago)
|
||||
retiro = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
deposito = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
saldo = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
cancelado = BooleanField(default=False)
|
||||
conciliado = BooleanField(default=False)
|
||||
moneda = TextField(default='MXN') # Complemento de pagos
|
||||
tipo_cambio = DecimalField(default=1.0, max_digits=15, decimal_places=6,
|
||||
auto_round=True)
|
||||
numero_operacion = TextField(default='')
|
||||
origen_rfc = TextField(default='')
|
||||
origen_nombre = TextField(default='')
|
||||
origen_cuenta = TextField(default='')
|
||||
destino_rfc = TextField(default='')
|
||||
destino_cuenta = TextField(default='')
|
||||
tipo_cadena_pago = TextField(default='')
|
||||
certificado_pago = TextField(default='')
|
||||
cadena_pago = TextField(default='')
|
||||
sello_pago = TextField(default='')
|
||||
|
||||
class Meta:
|
||||
order_by = ('fecha', 'id')
|
||||
|
||||
def _ultimo_saldo(self, cuenta, fecha):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.fecha<=fecha) &
|
||||
(MovimientosBanco.cancelado==False))[-1]
|
||||
)
|
||||
return round(float(query.saldo), DECIMALES)
|
||||
|
||||
def _movimiento_anterior(self, cuenta, fecha):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.fecha<fecha) &
|
||||
(MovimientosBanco.cancelado==False))[-1]
|
||||
)
|
||||
return query
|
||||
|
||||
def _actualizar_saldos(self, row):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==row.cuenta) &
|
||||
(MovimientosBanco.fecha>row.fecha) &
|
||||
(MovimientosBanco.cancelado==False))
|
||||
)
|
||||
|
||||
saldo = round(Decimal(row.saldo), DECIMALES)
|
||||
for mov in query:
|
||||
mov.saldo = saldo + mov.deposito - mov.retiro
|
||||
mov.save()
|
||||
saldo = mov.saldo
|
||||
CuentasBanco.actualizar_saldo(row.cuenta, saldo)
|
||||
return saldo
|
||||
|
||||
@classmethod
|
||||
def post(cls, values):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, '_{}'.format(opt))(cls, values)
|
||||
|
||||
def _add(self, values):
|
||||
ids = values.pop('ids', '')
|
||||
|
||||
if ids and not Facturas.validate_count_partners(util.loads(ids)):
|
||||
msg = 'Facturas relacionadas a diferentes clientes'
|
||||
data = {'ok': False, 'msg': msg}
|
||||
return data
|
||||
|
||||
actualizar = False
|
||||
if 'saldo' in values:
|
||||
saldo = values['saldo']
|
||||
else:
|
||||
actualizar = True
|
||||
hora = values.pop('hora')
|
||||
account = CuentasBanco.get(CuentasBanco.id==int(values['cuenta']))
|
||||
values['fecha'] = '{}T{}'.format(values['fecha'][:10], hora)
|
||||
values['cuenta'] = account
|
||||
values['moneda'] = account.moneda.key
|
||||
values['retiro'] = util.get_float(values['retiro'])
|
||||
values['deposito'] = util.get_float(values['deposito'])
|
||||
values['tipo_cambio'] = util.get_float(
|
||||
values.get('tipo_cambio', 1.00), True)
|
||||
values['forma_pago'] = int(values['forma_pago'])
|
||||
|
||||
ultimo_saldo = self._ultimo_saldo(
|
||||
self, values['cuenta'], values['fecha'])
|
||||
values['saldo'] = \
|
||||
ultimo_saldo - values['retiro'] + values['deposito']
|
||||
|
||||
with database_proxy.transaction():
|
||||
try:
|
||||
obj = MovimientosBanco.create(**values)
|
||||
except IntegrityError:
|
||||
msg = 'Este movimiento ya existe'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if actualizar:
|
||||
saldo = self._actualizar_saldos(self, obj)
|
||||
if ids:
|
||||
FacturasPagos.add(obj, util.loads(ids))
|
||||
|
||||
return {'ok': True, 'saldo': saldo}
|
||||
|
||||
def _cancel(self, values):
|
||||
id = int(values['id'])
|
||||
try:
|
||||
obj = MovimientosBanco.get(MovimientosBanco.id==id)
|
||||
except MovimientosBanco.DoesNotExist:
|
||||
msg = 'No se encontró el movimiento'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if obj.cancelado:
|
||||
msg = 'El movimiento ya esta cancelado'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if obj.conciliado:
|
||||
msg = 'El movimiento esta conciliado, no se puede cancelar'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
# ~ filters = (CfdiPagos.movimiento==obj)
|
||||
# ~ cp = CfdiPagos.select().where(filters).count()
|
||||
# ~ if cp > 0:
|
||||
# ~ msg = 'El movimiento tiene Factura de Pago, no se puede cancelar'
|
||||
# ~ return {'ok': False, 'msg': msg}
|
||||
|
||||
with database_proxy.transaction():
|
||||
obj.cancelado = True
|
||||
obj.save()
|
||||
FacturasPagos.cancelar(obj)
|
||||
|
||||
obj = self._movimiento_anterior(self, obj.cuenta, obj.fecha)
|
||||
self._actualizar_saldos(self, obj)
|
||||
|
||||
balance = CuentasBanco.get_saldo(obj.cuenta.id)
|
||||
|
||||
msg = 'Movimiento cancelado correctamente'
|
||||
return {'ok': True, 'msg': msg, 'balance': balance}
|
||||
|
||||
@classmethod
|
||||
def con(cls, id):
|
||||
cant = (MovimientosBanco
|
||||
.select(MovimientosBanco.id)
|
||||
.where(MovimientosBanco.cuenta==id)
|
||||
.count()
|
||||
)
|
||||
if cant > 2:
|
||||
return {'ok': True}
|
||||
|
||||
return {'ok': False}
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_(cls, values):
|
||||
cuenta = int(values['cuenta'])
|
||||
if 'fechas' in values:
|
||||
rango = util.loads(values['fechas'])
|
||||
fd = (MovimientosBanco.fecha.between(
|
||||
util.get_date(rango['start']),
|
||||
util.get_date(rango['end'], True)))
|
||||
filtros = (fd &
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.cancelado==False)
|
||||
)
|
||||
else:
|
||||
year = int(values['year'])
|
||||
mes = int(values['mes'])
|
||||
if year == -1:
|
||||
fy = (MovimientosBanco.fecha.year > 0)
|
||||
else:
|
||||
fy = (MovimientosBanco.fecha.year == year)
|
||||
if mes == -1:
|
||||
fm = (MovimientosBanco.fecha.month > 0)
|
||||
else:
|
||||
fm = (MovimientosBanco.fecha.month == mes)
|
||||
filtros = (fy & fm &
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.cancelado==False)
|
||||
)
|
||||
|
||||
rows = tuple(MovimientosBanco.select(
|
||||
MovimientosBanco.id,
|
||||
MovimientosBanco.fecha,
|
||||
MovimientosBanco.numero_operacion,
|
||||
SATFormaPago.name.alias('way_payment'),
|
||||
MovimientosBanco.descripcion,
|
||||
MovimientosBanco.retiro,
|
||||
MovimientosBanco.deposito,
|
||||
MovimientosBanco.saldo,
|
||||
fn.COUNT(CfdiPagos.id).alias('invoice')
|
||||
)
|
||||
.join(SATFormaPago).switch(MovimientosBanco)
|
||||
.join(CfdiPagos, JOIN.LEFT_OUTER).switch(MovimientosBanco)
|
||||
.where(filtros)
|
||||
.group_by(MovimientosBanco.id, SATFormaPago.name)
|
||||
.dicts()
|
||||
)
|
||||
|
||||
return {'ok': True, 'rows': rows}
|
||||
|
||||
|
||||
class SATUsoCfdi(BaseModel):
|
||||
key = TextField(index=True, unique=True)
|
||||
name = TextField(default='', index=True)
|
||||
|
@ -2655,6 +2489,7 @@ class Socios(BaseModel):
|
|||
|
||||
@classmethod
|
||||
def add(cls, values):
|
||||
accounts = util.loads(values.pop('accounts', '[]'))
|
||||
fields = cls._clean(cls, values)
|
||||
try:
|
||||
obj = Socios.create(**fields)
|
||||
|
@ -2665,6 +2500,19 @@ class Socios(BaseModel):
|
|||
|
||||
#~ ToDo Agregar tags
|
||||
|
||||
for account in accounts:
|
||||
try:
|
||||
bank = SATBancos.get_by_name(account['banco'])
|
||||
fields = {
|
||||
'socio': obj,
|
||||
'banco': bank,
|
||||
'cuenta': account['cuenta'],
|
||||
'clabe': account['clabe'],
|
||||
}
|
||||
o = SociosCuentasBanco.create(**fields)
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
row = {
|
||||
'id': obj.id,
|
||||
'rfc': obj.rfc,
|
||||
|
@ -2704,15 +2552,11 @@ class Socios(BaseModel):
|
|||
if count:
|
||||
return False
|
||||
|
||||
q = SociosCuentasBanco.delete().where(SociosCuentasBanco.socio==id)
|
||||
q.execute()
|
||||
q = Socios.delete().where(Socios.id==id)
|
||||
return bool(q.execute())
|
||||
|
||||
# ~ def _reset_saldo(self, id):
|
||||
# ~ obj = Socios.get(Socios.id==id)
|
||||
# ~ obj.saldo_cliente = 0.0
|
||||
# ~ obj.save()
|
||||
# ~ return {'ok': True}
|
||||
|
||||
@classmethod
|
||||
def opt(cls, args):
|
||||
opt = args.get('opt', '')
|
||||
|
@ -2724,6 +2568,7 @@ class Socios(BaseModel):
|
|||
|
||||
class SociosCuentasBanco(BaseModel):
|
||||
socio = ForeignKeyField(Socios)
|
||||
activa = BooleanField(default=True)
|
||||
banco = ForeignKeyField(SATBancos)
|
||||
cuenta = TextField(default='')
|
||||
clabe = TextField(default='')
|
||||
|
@ -2738,10 +2583,15 @@ class SociosCuentasBanco(BaseModel):
|
|||
def __str__(self):
|
||||
return '{} ({})'.format(self.banco.name, self.cuenta[-4:])
|
||||
|
||||
@classmethod
|
||||
def get_values(cls, values):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, '_get_{}'.format(opt))(cls, values)
|
||||
def _get_by_name(self, values):
|
||||
name = values['name']
|
||||
query = (SociosCuentasBanco
|
||||
.select()
|
||||
.where(SociosCuentasBanco.activa==True, Socios.nombre==name)
|
||||
.join(Socios).switch(SociosCuentasBanco)
|
||||
)
|
||||
rows = tuple([{'id': q.id, 'value': str(q)} for q in query])
|
||||
return {'ok': True, 'values': rows}
|
||||
|
||||
def _get_by_partner(self, values):
|
||||
id = int(values['id_partner'])
|
||||
|
@ -2756,6 +2606,11 @@ class SociosCuentasBanco(BaseModel):
|
|||
.dicts())
|
||||
return tuple(rows)
|
||||
|
||||
@classmethod
|
||||
def get_values(cls, values):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, '_get_{}'.format(opt))(cls, values)
|
||||
|
||||
@classmethod
|
||||
def post(cls, values):
|
||||
opt = values.pop('opt')
|
||||
|
@ -2789,6 +2644,13 @@ class SociosCuentasBanco(BaseModel):
|
|||
msg = 'Cuenta borrada correctamente'
|
||||
return {'ok': result, 'msg': msg}
|
||||
|
||||
@classmethod
|
||||
def validate_partner_account(cls, id, invoices):
|
||||
id_invoice = int(tuple(invoices.keys())[0])
|
||||
account = SociosCuentasBanco.get(SociosCuentasBanco.id==id)
|
||||
invoice = Facturas.get(Facturas.id==id_invoice)
|
||||
return account.socio == invoice.cliente
|
||||
|
||||
|
||||
class Contactos(BaseModel):
|
||||
socio = ForeignKeyField(Socios)
|
||||
|
@ -2843,6 +2705,226 @@ class ContactoCorreos(BaseModel):
|
|||
)
|
||||
|
||||
|
||||
class MovimientosBanco(BaseModel):
|
||||
cuenta = ForeignKeyField(CuentasBanco)
|
||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||
descripcion = TextField(default='')
|
||||
forma_pago = ForeignKeyField(SATFormaPago)
|
||||
retiro = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
deposito = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
saldo = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||
auto_round=True)
|
||||
cancelado = BooleanField(default=False)
|
||||
conciliado = BooleanField(default=False)
|
||||
moneda = TextField(default='MXN') # Complemento de pagos
|
||||
tipo_cambio = DecimalField(default=1.0, max_digits=15, decimal_places=6,
|
||||
auto_round=True)
|
||||
numero_operacion = TextField(default='')
|
||||
cuenta_socio = ForeignKeyField(SociosCuentasBanco, null=True)
|
||||
tipo_cadena_pago = TextField(default='')
|
||||
certificado_pago = TextField(default='')
|
||||
cadena_pago = TextField(default='')
|
||||
sello_pago = TextField(default='')
|
||||
|
||||
class Meta:
|
||||
order_by = ('fecha', 'id')
|
||||
|
||||
def _ultimo_saldo(self, cuenta, fecha):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.fecha<=fecha) &
|
||||
(MovimientosBanco.cancelado==False))[-1]
|
||||
)
|
||||
return round(float(query.saldo), DECIMALES)
|
||||
|
||||
def _movimiento_anterior(self, cuenta, fecha):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.fecha<fecha) &
|
||||
(MovimientosBanco.cancelado==False))[-1]
|
||||
)
|
||||
return query
|
||||
|
||||
def _actualizar_saldos(self, row):
|
||||
query = (MovimientosBanco
|
||||
.select()
|
||||
.where(
|
||||
(MovimientosBanco.cuenta==row.cuenta) &
|
||||
(MovimientosBanco.fecha>row.fecha) &
|
||||
(MovimientosBanco.cancelado==False))
|
||||
)
|
||||
|
||||
saldo = round(Decimal(row.saldo), DECIMALES)
|
||||
for mov in query:
|
||||
mov.saldo = saldo + mov.deposito - mov.retiro
|
||||
mov.save()
|
||||
saldo = mov.saldo
|
||||
CuentasBanco.actualizar_saldo(row.cuenta, saldo)
|
||||
return saldo
|
||||
|
||||
@classmethod
|
||||
def post(cls, values):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, '_{}'.format(opt))(cls, values)
|
||||
|
||||
def _add(self, values):
|
||||
ids = values.pop('ids', '')
|
||||
|
||||
cuenta_socio = values.get('cuenta_socio', None)
|
||||
if not ids:
|
||||
cuenta_socio = None
|
||||
|
||||
if ids and cuenta_socio and \
|
||||
not SociosCuentasBanco.validate_partner_account(cuenta_socio, util.loads(ids)):
|
||||
msg = 'La cuenta seleccionada no corresponde al cliente'
|
||||
data = {'ok': False, 'msg': msg}
|
||||
return data
|
||||
|
||||
if ids and not Facturas.validate_count_partners(util.loads(ids)):
|
||||
msg = 'Facturas relacionadas a diferentes clientes'
|
||||
data = {'ok': False, 'msg': msg}
|
||||
return data
|
||||
|
||||
actualizar = False
|
||||
if 'saldo' in values:
|
||||
saldo = values['saldo']
|
||||
else:
|
||||
actualizar = True
|
||||
hora = values.pop('hora')
|
||||
account = CuentasBanco.get(CuentasBanco.id==int(values['cuenta']))
|
||||
values['fecha'] = '{}T{}'.format(values['fecha'][:10], hora)
|
||||
values['cuenta'] = account
|
||||
values['cuenta_socio'] = cuenta_socio
|
||||
values['moneda'] = account.moneda.key
|
||||
values['retiro'] = util.get_float(values['retiro'])
|
||||
values['deposito'] = util.get_float(values['deposito'])
|
||||
values['tipo_cambio'] = util.get_float(
|
||||
values.get('tipo_cambio', 1.00), True)
|
||||
values['forma_pago'] = int(values['forma_pago'])
|
||||
|
||||
ultimo_saldo = self._ultimo_saldo(
|
||||
self, values['cuenta'], values['fecha'])
|
||||
|
||||
values['saldo'] = \
|
||||
ultimo_saldo - values['retiro'] + values['deposito']
|
||||
|
||||
with database_proxy.transaction():
|
||||
try:
|
||||
obj = MovimientosBanco.create(**values)
|
||||
except IntegrityError:
|
||||
msg = 'Error al agregar el movimiento'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if actualizar:
|
||||
saldo = self._actualizar_saldos(self, obj)
|
||||
if ids:
|
||||
FacturasPagos.add(obj, util.loads(ids))
|
||||
|
||||
return {'ok': True, 'saldo': saldo}
|
||||
|
||||
def _cancel(self, values):
|
||||
id = int(values['id'])
|
||||
try:
|
||||
obj = MovimientosBanco.get(MovimientosBanco.id==id)
|
||||
except MovimientosBanco.DoesNotExist:
|
||||
msg = 'No se encontró el movimiento'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if obj.cancelado:
|
||||
msg = 'El movimiento ya esta cancelado'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
if obj.conciliado:
|
||||
msg = 'El movimiento esta conciliado, no se puede cancelar'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
# ~ filters = (CfdiPagos.movimiento==obj)
|
||||
# ~ cp = CfdiPagos.select().where(filters).count()
|
||||
# ~ if cp > 0:
|
||||
# ~ msg = 'El movimiento tiene Factura de Pago, no se puede cancelar'
|
||||
# ~ return {'ok': False, 'msg': msg}
|
||||
|
||||
with database_proxy.transaction():
|
||||
obj.cancelado = True
|
||||
obj.save()
|
||||
FacturasPagos.cancelar(obj)
|
||||
|
||||
obj = self._movimiento_anterior(self, obj.cuenta, obj.fecha)
|
||||
self._actualizar_saldos(self, obj)
|
||||
|
||||
balance = CuentasBanco.get_saldo(obj.cuenta.id)
|
||||
|
||||
msg = 'Movimiento cancelado correctamente'
|
||||
return {'ok': True, 'msg': msg, 'balance': balance}
|
||||
|
||||
@classmethod
|
||||
def con(cls, id):
|
||||
cant = (MovimientosBanco
|
||||
.select(MovimientosBanco.id)
|
||||
.where(MovimientosBanco.cuenta==id)
|
||||
.count()
|
||||
)
|
||||
if cant > 2:
|
||||
return {'ok': True}
|
||||
|
||||
return {'ok': False}
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_(cls, values):
|
||||
cuenta = int(values['cuenta'])
|
||||
if 'fechas' in values:
|
||||
rango = util.loads(values['fechas'])
|
||||
fd = (MovimientosBanco.fecha.between(
|
||||
util.get_date(rango['start']),
|
||||
util.get_date(rango['end'], True)))
|
||||
filtros = (fd &
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.cancelado==False)
|
||||
)
|
||||
else:
|
||||
year = int(values['year'])
|
||||
mes = int(values['mes'])
|
||||
if year == -1:
|
||||
fy = (MovimientosBanco.fecha.year > 0)
|
||||
else:
|
||||
fy = (MovimientosBanco.fecha.year == year)
|
||||
if mes == -1:
|
||||
fm = (MovimientosBanco.fecha.month > 0)
|
||||
else:
|
||||
fm = (MovimientosBanco.fecha.month == mes)
|
||||
filtros = (fy & fm &
|
||||
(MovimientosBanco.cuenta==cuenta) &
|
||||
(MovimientosBanco.cancelado==False)
|
||||
)
|
||||
|
||||
rows = tuple(MovimientosBanco.select(
|
||||
MovimientosBanco.id,
|
||||
MovimientosBanco.fecha,
|
||||
MovimientosBanco.numero_operacion,
|
||||
SATFormaPago.name.alias('way_payment'),
|
||||
MovimientosBanco.descripcion,
|
||||
MovimientosBanco.retiro,
|
||||
MovimientosBanco.deposito,
|
||||
MovimientosBanco.saldo,
|
||||
fn.COUNT(CfdiPagos.id).alias('invoice')
|
||||
)
|
||||
.join(SATFormaPago).switch(MovimientosBanco)
|
||||
.join(CfdiPagos, JOIN.LEFT_OUTER).switch(MovimientosBanco)
|
||||
.where(filtros)
|
||||
.group_by(MovimientosBanco.id, SATFormaPago.name)
|
||||
.dicts()
|
||||
)
|
||||
|
||||
return {'ok': True, 'rows': rows}
|
||||
|
||||
|
||||
class Alumnos(BaseModel):
|
||||
rfc = TextField(null=True)
|
||||
curp = TextField(index=True, unique=True)
|
||||
|
@ -3424,13 +3506,6 @@ class Facturas(BaseModel):
|
|||
@classmethod
|
||||
def validate_count_partners(cls, ids):
|
||||
filters = (Facturas.id.in_(tuple(ids.keys())))
|
||||
# ~ partners = (Facturas.select(fn.COUNT(Facturas.cliente))
|
||||
# ~ .where(filters)
|
||||
# ~ .group_by(Facturas.cliente)
|
||||
# ~ .order_by(Facturas.cliente).tuples())
|
||||
# ~ if len(partners) > 1:
|
||||
# ~ return False
|
||||
# ~ return True
|
||||
partners = (Facturas.select(fn.COUNT(Socios.rfc))
|
||||
.where(filters)
|
||||
.join(Socios).switch(Facturas)
|
||||
|
@ -5763,6 +5838,7 @@ class CfdiPagos(BaseModel):
|
|||
def _generate_xml(self, invoice, auth):
|
||||
emisor = Emisor.select()[0]
|
||||
cert = Certificado.get_cert()
|
||||
used_data_bank = Configuracion.get_bool('chk_cfg_pays_data_bank')
|
||||
|
||||
cfdi = {}
|
||||
related = {}
|
||||
|
@ -5812,7 +5888,6 @@ class CfdiPagos(BaseModel):
|
|||
impuestos = {}
|
||||
|
||||
mov = invoice.movimiento
|
||||
# ~ currency = mov.cuenta.moneda.key
|
||||
currency = mov.moneda
|
||||
related_docs = self._get_related_xml(self, invoice.movimiento, currency)
|
||||
pagos = {
|
||||
|
@ -5822,6 +5897,20 @@ class CfdiPagos(BaseModel):
|
|||
'Monto': FORMAT.format(mov.deposito),
|
||||
'relacionados': related_docs,
|
||||
}
|
||||
if mov.numero_operacion:
|
||||
pagos['NumOperacion'] = mov.numero_operacion
|
||||
|
||||
if used_data_bank and mov.cuenta_socio:
|
||||
if mov.cuenta_socio.banco.rfc:
|
||||
pagos['RfcEmisorCtaOrd'] = mov.cuenta_socio.banco.rfc
|
||||
if mov.cuenta_socio.banco.rfc == RFC_EXTRANJERO:
|
||||
pagos['NomBancoOrdExt'] = mov.cuenta_socio.banco.name
|
||||
pagos['CtaOrdenante'] = mov.cuenta_socio.cuenta
|
||||
if mov.cuenta.banco.rfc:
|
||||
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
|
||||
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
|
||||
|
||||
|
||||
if currency != CURRENCY_MN:
|
||||
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
|
||||
|
||||
|
@ -8382,6 +8471,23 @@ def _migrate_tables(rfc=''):
|
|||
fecha_cancelacion = DateTimeField(null=True)
|
||||
migrations.append(migrator.add_column('cfdipagos', 'fecha_cancelacion', fecha_cancelacion))
|
||||
|
||||
table = 'movimientosbanco'
|
||||
columns = [c.name for c in database_proxy.get_columns(table)]
|
||||
if not 'cuenta_socio_id' in columns:
|
||||
cuenta_socio = ForeignKeyField(SociosCuentasBanco, null=True, to_field=SociosCuentasBanco.id)
|
||||
migrations.append(migrator.add_column(table, 'cuenta_socio_id', cuenta_socio))
|
||||
migrations.append(migrator.drop_column(table, 'origen_rfc'))
|
||||
migrations.append(migrator.drop_column(table, 'origen_nombre'))
|
||||
migrations.append(migrator.drop_column(table, 'origen_cuenta'))
|
||||
migrations.append(migrator.drop_column(table, 'destino_rfc'))
|
||||
migrations.append(migrator.drop_column(table, 'destino_cuenta'))
|
||||
|
||||
table = 'socioscuentasbanco'
|
||||
columns = [c.name for c in database_proxy.get_columns(table)]
|
||||
if not 'activa' in columns:
|
||||
activa = BooleanField(default=True)
|
||||
migrations.append(migrator.add_column(table, 'activa', activa))
|
||||
|
||||
if migrations:
|
||||
with database_proxy.atomic() as txn:
|
||||
migrate(*migrations)
|
||||
|
|
|
@ -47,7 +47,7 @@ except ImportError:
|
|||
|
||||
|
||||
DEBUG = DEBUG
|
||||
VERSION = '1.20.0'
|
||||
VERSION = '1.21.0'
|
||||
EMAIL_SUPPORT = ('soporte@empresalibre.net',)
|
||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ var controllers = {
|
|||
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_edu').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_pagos').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_cfg_pays_data_bank').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_cuenta_predial').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_codigo_barras').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_precio_con_impuestos').attachEvent('onItemClick', chk_config_item_click)
|
||||
|
@ -1133,6 +1134,7 @@ function tab_options_change(nv, ov){
|
|||
var cv = {
|
||||
tab_admin_templates: 'templates',
|
||||
tab_admin_partners: 'partners',
|
||||
tab_admin_complements: 'complements',
|
||||
tab_admin_otros: 'configotros',
|
||||
}
|
||||
get_config_values(cv[nv])
|
||||
|
|
|
@ -37,8 +37,12 @@ function init_config_bank(){
|
|||
g3.showColumn('total')
|
||||
g3.showColumn('currency')
|
||||
}
|
||||
show('cmd_complemento_pago', get_config('used_cfdi_pays'))
|
||||
show('cmd_show_invoice_pay', get_config('used_cfdi_pays'))
|
||||
var used_cfdi_pays = get_config('used_cfdi_pays')
|
||||
show('cmd_complemento_pago', used_cfdi_pays)
|
||||
show('cmd_show_invoice_pay', used_cfdi_pays)
|
||||
if(used_cfdi_pays){
|
||||
show_column('grid_cuentabanco', 'invoice')
|
||||
}
|
||||
set_year_month()
|
||||
}
|
||||
|
||||
|
@ -69,6 +73,7 @@ var bancos_controllers = {
|
|||
$$('cmd_pay_delete').attachEvent('onItemClick', cmd_pay_delete_click)
|
||||
$$('grid_cfdi_pay').attachEvent('onItemClick', grid_cfdi_pay_click)
|
||||
$$('grid_cfdi_por_pagar').attachEvent('onItemDblClick', grid_cfdi_por_pagar_double_click)
|
||||
$$('grid_cfdi_por_pagar').attachEvent('onAfterFilter', grid_cfdi_por_pagar_on_after_filter)
|
||||
$$('grid_cfdi_este_deposito').attachEvent('onItemDblClick', grid_cfdi_este_deposito_double_click)
|
||||
$$('cmd_show_invoice_pay').attachEvent('onItemClick', cmd_show_invoice_pay_click)
|
||||
$$('filter_invoice_pay_year').attachEvent('onChange', filter_invoice_pay_change)
|
||||
|
@ -206,18 +211,18 @@ function lst_cuentas_banco_change(nv, ov){
|
|||
}
|
||||
|
||||
|
||||
function get_bancos_forma_pago(retiro){
|
||||
var values = table_waypayment.chain().find({'id': { '$ne' : '99' }}).data()
|
||||
if(retiro){
|
||||
lst = $$('lst_retiro_forma_pago')
|
||||
}else{
|
||||
lst = $$('lst_deposito_forma_pago')
|
||||
}
|
||||
lst.getList().parse(values)
|
||||
if(current_way_payment){
|
||||
lst.setValue(current_way_payment)
|
||||
}
|
||||
}
|
||||
//~ function get_bancos_forma_pago(retiro){
|
||||
//~ var values = table_waypayment.chain().find({'id': { '$ne' : '99' }}).data()
|
||||
//~ if(retiro){
|
||||
//~ lst = $$('lst_retiro_forma_pago')
|
||||
//~ }else{
|
||||
//~ lst = $$('lst_deposito_forma_pago')
|
||||
//~ }
|
||||
//~ lst.getList().parse(values)
|
||||
//~ if(current_way_payment){
|
||||
//~ lst.setValue(current_way_payment)
|
||||
//~ }
|
||||
//~ }
|
||||
|
||||
|
||||
function get_facturas_por_pagar(){
|
||||
|
@ -246,7 +251,7 @@ function get_facturas_por_pagar(){
|
|||
|
||||
|
||||
function cmd_agregar_retiro_click(){
|
||||
get_bancos_forma_pago(true)
|
||||
set_way_payment('lst_retiro_forma_pago', true, current_way_payment)
|
||||
var title = 'Agregar retiro de banco a la cuenta ' + $$('lst_cuentas_banco').getText() + ' en ' + $$('txt_cuenta_moneda').getValue()
|
||||
$$('title_bank_retiro').setValue(title)
|
||||
$$('multi_bancos').setValue('banco_retiro')
|
||||
|
@ -255,13 +260,17 @@ function cmd_agregar_retiro_click(){
|
|||
|
||||
function cmd_agregar_deposito_click(){
|
||||
msg_importe = ''
|
||||
get_bancos_forma_pago(false)
|
||||
|
||||
get_facturas_por_pagar()
|
||||
set_way_payment('lst_deposito_forma_pago', true, current_way_payment)
|
||||
|
||||
var g = $$('grid_cfdi_este_deposito')
|
||||
g.config.columns[g.getColumnIndex('importe')].header = 'Este Pago ' + current_currency
|
||||
g.refreshColumns()
|
||||
|
||||
show('deposit_type_change', current_currency!=CURRENCY_MN)
|
||||
var pays = get_config('used_cfdi_pays') && get_config('pays_data_bank')
|
||||
show('lst_partner_account_bank', pays)
|
||||
|
||||
var title = 'Agregar depósito de banco a la cuenta ' + $$('lst_cuentas_banco').getText() + ' en ' + $$('txt_cuenta_moneda').getValue()
|
||||
$$('title_bank_deposit').setValue(title)
|
||||
|
@ -666,6 +675,7 @@ function guardar_deposito(values){
|
|||
data['tipo_cambio'] = values.deposit_type_change.to_float4()
|
||||
data['retiro'] = 0.0
|
||||
data['descripcion'] = values.deposito_descripcion
|
||||
data['cuenta_socio'] = values.partner_account_bank
|
||||
|
||||
current_way_payment = data['forma_pago']
|
||||
|
||||
|
@ -716,41 +726,40 @@ function cmd_guardar_deposito_click(){
|
|||
return
|
||||
}
|
||||
|
||||
msg = 'Todos los datos son correctos.<br><br>'
|
||||
|
||||
if(!grid.count()){
|
||||
msg = 'Todos los datos son correctos<br>br>'
|
||||
msg = 'El depósito no tiene facturas relacionadas<br><br>¿Estás '
|
||||
msg += ' seguro de guardar el depósito sin facturas relacionadas?'
|
||||
webix.confirm({
|
||||
title: 'Guardar depósito',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
guardar_deposito(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
msg += 'El depósito no tiene facturas relacionadas<br>¿Estás '
|
||||
msg += ' seguro de guardar el depósito sin facturas relacionadas?<br><br>'
|
||||
}else{
|
||||
if(!msg_importe){
|
||||
msg_importe = 'Se van a relacionar ' + grid.count() + ' facturas.'
|
||||
}
|
||||
msg = 'Todos los datos son correctos.<br><br>' + msg_importe + '<br><br>'
|
||||
msg += '¿Deseas agregar este depósito?'
|
||||
webix.confirm({
|
||||
title: 'Guardar depósito',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
guardar_deposito(values)
|
||||
}
|
||||
if(grid.count()==1){
|
||||
msg += 'Se va a relacionar 1 factura.<br><br>'
|
||||
}else{
|
||||
msg += 'Se van a relacionar ' + grid.count() + ' facturas.<br><br>'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if(get_config('pays_data_bank') && grid.count() && !values.partner_account_bank){
|
||||
msg += 'NO seleccionaste cuenta origen.<br><br>'
|
||||
}
|
||||
|
||||
msg += '¿Deseas agregar este depósito?'
|
||||
|
||||
webix.confirm({
|
||||
title: 'Guardar depósito',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
guardar_deposito(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1259,3 +1268,28 @@ function get_invoices_pay(rango){
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_cfdi_por_pagar_on_after_filter(){
|
||||
var partner = $$('grid_cfdi_por_pagar').getFilter('cliente').value
|
||||
var lst = $$('lst_partner_account_bank')
|
||||
|
||||
lst_clear(lst)
|
||||
if(partner){
|
||||
var args = {opt: 'by_name', name: partner}
|
||||
webix.ajax().get('/socioscb', args, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var result = data.json()
|
||||
if (result.ok){
|
||||
lst_parse(lst, result.values)
|
||||
}else{
|
||||
msg_error(result.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ function configuracion_inicial(){
|
|||
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})
|
||||
|
||||
})
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ function get_condicion_pago(){
|
|||
|
||||
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})
|
||||
|
@ -106,6 +108,8 @@ function cmd_edit_partner_click(){
|
|||
var msg = ''
|
||||
var row = $$('grid_partners').getSelectedItem()
|
||||
|
||||
$$('form_partner_account_bank').clearValidation()
|
||||
|
||||
if (row == undefined){
|
||||
msg = 'Selecciona un Socio de Negocio'
|
||||
msg_error(msg)
|
||||
|
@ -235,6 +239,8 @@ function cmd_save_partner_click(id, e, node){
|
|||
}
|
||||
}
|
||||
|
||||
values['accounts'] = $$('grid_partner_account_bank').data.getRange()
|
||||
|
||||
webix.ajax().post('/partners', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico';
|
||||
|
@ -482,7 +488,7 @@ function cmd_partner_add_account_bank_click(){
|
|||
return
|
||||
}
|
||||
|
||||
if(account.cuenta.length < 9){
|
||||
if(account.cuenta.length < 10){
|
||||
msg = 'Longitud incorrecta de la cuenta'
|
||||
msg_error(msg)
|
||||
return
|
||||
|
@ -570,6 +576,8 @@ 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'
|
||||
|
@ -581,7 +589,11 @@ function grid_partner_account_bank_click(id, e, node){
|
|||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
partner_delete_account_bank(id.row)
|
||||
if(id_partner){
|
||||
partner_delete_account_bank(id.row)
|
||||
}else{
|
||||
grid.remove(id.row)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -112,6 +112,11 @@ function show(nombre, value){
|
|||
}
|
||||
|
||||
|
||||
function show_column(table, column){
|
||||
$$(table).showColumn(column)
|
||||
}
|
||||
|
||||
|
||||
function enable(nombre, value){
|
||||
if(value == '0'){
|
||||
value = false
|
||||
|
@ -502,7 +507,7 @@ function get_forma_pago(control){
|
|||
|
||||
|
||||
function get_way_payment(){
|
||||
webix.ajax().get('/values/formapago', {key: true}, function(text, data){
|
||||
webix.ajax().get('/satformapago', {opt: 'active_by_id'}, function(text, data){
|
||||
var values = data.json()
|
||||
table_waypayment.clear()
|
||||
table_waypayment.insert(values)
|
||||
|
@ -510,9 +515,16 @@ function get_way_payment(){
|
|||
}
|
||||
|
||||
|
||||
function set_way_payment(control){
|
||||
var values = table_waypayment.chain().data()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -553,5 +565,16 @@ function pause(milliseconds) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//~ Revisado
|
||||
|
||||
function lst_clear(lst){
|
||||
lst.setValue('')
|
||||
lst.define('options', [])
|
||||
lst.refresh()
|
||||
}
|
||||
|
||||
|
||||
function lst_parse(lst, values){
|
||||
lst.getList().parse(values)
|
||||
}
|
||||
|
|
|
@ -667,22 +667,6 @@ var options_admin_otros = [
|
|||
labelRight: 'Mostrar inventario'},
|
||||
]},
|
||||
{maxHeight: 20},
|
||||
{template: 'Complementos', type: 'section'},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento INE'},
|
||||
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento EDU'},
|
||||
{}]},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
|
||||
labelRight: 'Usar complemento de pagos'},
|
||||
{view: 'text', id: 'txt_config_cfdipay_serie', name: 'txt_config_cfdipay_serie',
|
||||
label: 'Serie', labelWidth: 50, labelAlign: 'right'},
|
||||
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
|
||||
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
||||
{}]},
|
||||
{maxHeight: 20},
|
||||
{template: 'Punto de venta', type: 'section'},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_usar_punto_de_venta', labelWidth: 0,
|
||||
|
@ -723,6 +707,29 @@ var options_admin_partners = [
|
|||
]
|
||||
|
||||
|
||||
var options_admin_complements = [
|
||||
{maxHeight: 20},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento INE'},
|
||||
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento EDU'},
|
||||
{}]},
|
||||
{maxHeight: 20},
|
||||
{template: 'Complemento de Pagos', type: 'section'},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
|
||||
labelRight: 'Usar complemento de pagos'},
|
||||
{view: 'checkbox', id: 'chk_cfg_pays_data_bank', labelWidth: 0,
|
||||
labelRight: 'Usar datos bancarios'},
|
||||
{view: 'text', id: 'txt_config_cfdipay_serie', name: 'txt_config_cfdipay_serie',
|
||||
label: 'Serie', labelWidth: 50, labelAlign: 'right'},
|
||||
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
|
||||
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
||||
{maxWidth: 15}]},
|
||||
]
|
||||
|
||||
|
||||
var tab_options = {
|
||||
view: 'tabview',
|
||||
id: 'tab_options',
|
||||
|
@ -732,6 +739,8 @@ var tab_options = {
|
|||
rows: options_templates}},
|
||||
{header: 'Clientes y Proveedores', body: {id: 'tab_admin_partners',
|
||||
view: 'scrollview', body: {rows: options_admin_partners}}},
|
||||
{header: 'Complementos', body: {id: 'tab_admin_complements',
|
||||
view: 'scrollview', body: {rows: options_admin_complements}}},
|
||||
{header: 'Otros', body: {id: 'tab_admin_otros', view: 'scrollview',
|
||||
body: {rows: options_admin_otros}}},
|
||||
],
|
||||
|
|
|
@ -64,7 +64,7 @@ var grid_cuentabanco_cols = [
|
|||
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'},
|
||||
{id: 'invoice', header: ['FP'], width: 40, css: 'center', hidden: true},
|
||||
]
|
||||
|
||||
|
||||
|
@ -438,6 +438,10 @@ var controls_banco_deposito = [
|
|||
]},
|
||||
{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'},
|
||||
|
|
Loading…
Reference in New Issue