commit
28146ed47a
|
@ -269,6 +269,22 @@ class AppPreInvoices(object):
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
|
||||||
|
|
||||||
|
class AppTickets(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.get_tickets(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
def on_post(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.tickets(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
class AppEmisor(object):
|
class AppEmisor(object):
|
||||||
|
|
||||||
def __init__(self, db):
|
def __init__(self, db):
|
||||||
|
|
|
@ -235,6 +235,10 @@ def now():
|
||||||
return datetime.datetime.now().replace(microsecond=0)
|
return datetime.datetime.now().replace(microsecond=0)
|
||||||
|
|
||||||
|
|
||||||
|
def today():
|
||||||
|
return datetime.date.today()
|
||||||
|
|
||||||
|
|
||||||
def get_token():
|
def get_token():
|
||||||
return _get_hash(uuid.uuid4().hex)
|
return _get_hash(uuid.uuid4().hex)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ from controllers.main import (AppEmpresas,
|
||||||
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
||||||
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
||||||
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
||||||
AppMovimientosBanco
|
AppMovimientosBanco, AppTickets
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,11 +46,12 @@ api.add_route('/partners', AppPartners(db))
|
||||||
api.add_route('/products', AppProducts(db))
|
api.add_route('/products', AppProducts(db))
|
||||||
api.add_route('/invoices', AppInvoices(db))
|
api.add_route('/invoices', AppInvoices(db))
|
||||||
api.add_route('/preinvoices', AppPreInvoices(db))
|
api.add_route('/preinvoices', AppPreInvoices(db))
|
||||||
|
api.add_route('/tickets', AppTickets(db))
|
||||||
api.add_route('/cuentasbanco', AppCuentasBanco(db))
|
api.add_route('/cuentasbanco', AppCuentasBanco(db))
|
||||||
api.add_route('/movbanco', AppMovimientosBanco(db))
|
api.add_route('/movbanco', AppMovimientosBanco(db))
|
||||||
|
|
||||||
|
|
||||||
# ~ Activa si usas waitress
|
# ~ Activa si usas waitress y NO estas usando servidor web
|
||||||
# ~ api.add_sink(static, '/static')
|
# ~ api.add_sink(static, '/static')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ class StorageEngine(object):
|
||||||
years2 = main.PreFacturas.filter_years()
|
years2 = main.PreFacturas.filter_years()
|
||||||
return [years1, years2]
|
return [years1, years2]
|
||||||
|
|
||||||
|
def _get_filteryearsticket(self, values):
|
||||||
|
return main.Tickets.filter_years()
|
||||||
|
|
||||||
def _get_cuentayears(self, values):
|
def _get_cuentayears(self, values):
|
||||||
return main.CuentasBanco.get_years()
|
return main.CuentasBanco.get_years()
|
||||||
|
|
||||||
|
@ -221,6 +224,9 @@ class StorageEngine(object):
|
||||||
def _get_product(self, values):
|
def _get_product(self, values):
|
||||||
return main.Productos.get_by(values)
|
return main.Productos.get_by(values)
|
||||||
|
|
||||||
|
def _get_productokey(self, values):
|
||||||
|
return main.Productos.get_by_key(values)
|
||||||
|
|
||||||
def get_partners(self, values):
|
def get_partners(self, values):
|
||||||
return main.Socios.get_(values)
|
return main.Socios.get_(values)
|
||||||
|
|
||||||
|
@ -251,6 +257,18 @@ class StorageEngine(object):
|
||||||
#~ return main.PreFacturas.actualizar(values, id)
|
#~ return main.PreFacturas.actualizar(values, id)
|
||||||
return main.PreFacturas.add(values)
|
return main.PreFacturas.add(values)
|
||||||
|
|
||||||
|
def tickets(self, values):
|
||||||
|
opt = values.pop('opt')
|
||||||
|
if opt == 'add':
|
||||||
|
return main.Tickets.add(values)
|
||||||
|
if opt == 'cancel':
|
||||||
|
return main.Tickets.cancel(values)
|
||||||
|
if opt == 'invoice':
|
||||||
|
return main.Tickets.invoice(values)
|
||||||
|
|
||||||
|
def get_tickets(self, values):
|
||||||
|
return main.Tickets.get_by(values)
|
||||||
|
|
||||||
def get_invoices(self, values):
|
def get_invoices(self, values):
|
||||||
return main.Facturas.get_(values)
|
return main.Facturas.get_(values)
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,11 @@ def config_main():
|
||||||
except IndexError:
|
except IndexError:
|
||||||
obj = None
|
obj = None
|
||||||
|
|
||||||
|
punto_de_venta = util.get_bool(Configuracion.get_('chk_usar_punto_de_venta'))
|
||||||
data = {
|
data = {
|
||||||
'empresa': 'Empresa Libre',
|
'empresa': 'Empresa Libre',
|
||||||
|
'punto_de_venta': punto_de_venta
|
||||||
|
|
||||||
}
|
}
|
||||||
if not obj is None:
|
if not obj is None:
|
||||||
titulo = 'Empresa Libre - <b><font color="#610B0B">{}</font></b>'
|
titulo = 'Empresa Libre - <b><font color="#610B0B">{}</font></b>'
|
||||||
|
@ -126,10 +129,15 @@ def config_timbrar():
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return {'cfdi_donativo': False}
|
return {'cfdi_donativo': False}
|
||||||
|
|
||||||
|
mp = not util.get_bool(Configuracion.get_('chk_config_ocultar_metodo_pago'))
|
||||||
|
cp = not util.get_bool(
|
||||||
|
Configuracion.get_('chk_config_ocultar_condiciones_pago'))
|
||||||
conf = {
|
conf = {
|
||||||
'cfdi_anticipo': Configuracion.get_('chk_config_anticipo'),
|
|
||||||
'cfdi_donativo': obj.es_ong,
|
'cfdi_donativo': obj.es_ong,
|
||||||
|
'cfdi_anticipo': Configuracion.get_('chk_config_anticipo'),
|
||||||
'cfdi_ine': Configuracion.get_('chk_config_ine'),
|
'cfdi_ine': Configuracion.get_('chk_config_ine'),
|
||||||
|
'cfdi_metodo_pago': mp,
|
||||||
|
'cfdi_condicion_pago': cp,
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
|
@ -153,6 +161,21 @@ class Configuracion(BaseModel):
|
||||||
return data[0].valor
|
return data[0].valor
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
if keys['fields'] == 'productos':
|
||||||
|
fields = (
|
||||||
|
'chk_config_cuenta_predial',
|
||||||
|
'chk_config_codigo_barras',
|
||||||
|
'chk_config_precio_con_impuestos',
|
||||||
|
)
|
||||||
|
data = (Configuracion
|
||||||
|
.select()
|
||||||
|
.where(Configuracion.clave.in_(fields))
|
||||||
|
)
|
||||||
|
values = {r.clave: r.valor for r in data}
|
||||||
|
values['default_tax'] = SATImpuestos.select()[0].id
|
||||||
|
values['default_unidad'] = SATUnidades.get_default()
|
||||||
|
return values
|
||||||
|
|
||||||
if keys['fields'] == 'correo':
|
if keys['fields'] == 'correo':
|
||||||
fields = ('correo_servidor', 'correo_puerto', 'correo_ssl',
|
fields = ('correo_servidor', 'correo_puerto', 'correo_ssl',
|
||||||
'correo_usuario', 'correo_contra', 'correo_copia',
|
'correo_usuario', 'correo_contra', 'correo_copia',
|
||||||
|
@ -180,17 +203,25 @@ class Configuracion(BaseModel):
|
||||||
)
|
)
|
||||||
elif keys['fields'] == 'configotros':
|
elif keys['fields'] == 'configotros':
|
||||||
fields = (
|
fields = (
|
||||||
|
'chk_config_ocultar_metodo_pago',
|
||||||
|
'chk_config_ocultar_condiciones_pago',
|
||||||
'chk_config_anticipo',
|
'chk_config_anticipo',
|
||||||
'chk_config_cuenta_predial',
|
'chk_config_cuenta_predial',
|
||||||
|
'chk_config_codigo_barras',
|
||||||
|
'chk_config_precio_con_impuestos',
|
||||||
'chk_config_ine',
|
'chk_config_ine',
|
||||||
|
'chk_usar_punto_de_venta',
|
||||||
)
|
)
|
||||||
data = (Configuracion
|
data = (Configuracion
|
||||||
.select()
|
.select()
|
||||||
.where(Configuracion.clave.in_(fields))
|
.where(Configuracion.clave.in_(fields))
|
||||||
)
|
)
|
||||||
elif keys['fields'] == 'productos':
|
elif keys['fields'] == 'timbrar':
|
||||||
fields = (
|
fields = (
|
||||||
'chk_config_cuenta_predial',
|
'chk_config_ocultar_metodo_pago',
|
||||||
|
'chk_config_ocultar_condiciones_pago',
|
||||||
|
'chk_config_anticipo',
|
||||||
|
'chk_config_ine',
|
||||||
)
|
)
|
||||||
data = (Configuracion
|
data = (Configuracion
|
||||||
.select()
|
.select()
|
||||||
|
@ -844,6 +875,13 @@ class SATUnidades(BaseModel):
|
||||||
|
|
||||||
return {'ok': result}
|
return {'ok': result}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_default(cls):
|
||||||
|
obj = SATUnidades.select()[0]
|
||||||
|
if obj.default:
|
||||||
|
return obj.id
|
||||||
|
return 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_activos(cls):
|
def get_activos(cls):
|
||||||
rows = (SATUnidades
|
rows = (SATUnidades
|
||||||
|
@ -1752,7 +1790,7 @@ class Socios(BaseModel):
|
||||||
fields = cls._clean(cls, values)
|
fields = cls._clean(cls, values)
|
||||||
try:
|
try:
|
||||||
obj = Socios.create(**fields)
|
obj = Socios.create(**fields)
|
||||||
except IntegrityError:
|
except IntegrityError as e:
|
||||||
msg = 'Ya existe el RFC y Razón Social'
|
msg = 'Ya existe el RFC y Razón Social'
|
||||||
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
|
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
|
||||||
return data
|
return data
|
||||||
|
@ -1973,6 +2011,34 @@ class Productos(BaseModel):
|
||||||
value += 1
|
value += 1
|
||||||
return {'value': value}
|
return {'value': value}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_key(cls, values):
|
||||||
|
clave = values.get('key', '')
|
||||||
|
row = (Productos
|
||||||
|
.select(
|
||||||
|
Productos.id,
|
||||||
|
Productos.clave,
|
||||||
|
Productos.clave_sat,
|
||||||
|
Productos.descripcion,
|
||||||
|
SATUnidades.name.alias('unidad'),
|
||||||
|
Productos.valor_unitario,
|
||||||
|
Productos.descuento)
|
||||||
|
.join(SATUnidades).switch(Productos)
|
||||||
|
.where((Productos.clave==clave) | (Productos.codigo_barras==clave))
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
if len(row):
|
||||||
|
id = row[0]['id']
|
||||||
|
model_pt = Productos.impuestos.get_through_model()
|
||||||
|
taxes = tuple(model_pt
|
||||||
|
.select(
|
||||||
|
model_pt.productos_id.alias('product'),
|
||||||
|
model_pt.satimpuestos_id.alias('tax'))
|
||||||
|
.where(model_pt.productos_id==id).dicts())
|
||||||
|
return {'ok': True, 'row': row[0], 'taxes': taxes}
|
||||||
|
|
||||||
|
return {'ok': False}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by(cls, values):
|
def get_by(cls, values):
|
||||||
clave = values.get('id', '')
|
clave = values.get('id', '')
|
||||||
|
@ -2723,17 +2789,9 @@ class Facturas(BaseModel):
|
||||||
totals_tax[tax.id] = tax
|
totals_tax[tax.id] = tax
|
||||||
|
|
||||||
for tax in totals_tax.values():
|
for tax in totals_tax.values():
|
||||||
# ~ if tax.tipo == 'E' or tax.tipo == 'R':
|
|
||||||
if tax.tipo == 'E':
|
if tax.tipo == 'E':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ~ import_tax = round(float(tax.tasa) * tax.importe, DECIMALES)
|
|
||||||
# ~ if tax.key == '000':
|
|
||||||
# ~ locales_traslados += import_tax
|
|
||||||
# ~ else:
|
|
||||||
# ~ total_trasladados = (total_trasladados or 0) + import_tax
|
|
||||||
# ~ if tax.name == 'IVA':
|
|
||||||
# ~ total_iva += import_tax
|
|
||||||
|
|
||||||
invoice_tax = {
|
invoice_tax = {
|
||||||
'factura': invoice.id,
|
'factura': invoice.id,
|
||||||
|
@ -2743,26 +2801,6 @@ class Facturas(BaseModel):
|
||||||
}
|
}
|
||||||
FacturasImpuestos.create(**invoice_tax)
|
FacturasImpuestos.create(**invoice_tax)
|
||||||
|
|
||||||
# ~ for tax in totals_tax.values():
|
|
||||||
# ~ if tax.tipo == 'E' or tax.tipo == 'T':
|
|
||||||
# ~ continue
|
|
||||||
# ~ if tax.tasa == round(Decimal(2/3), 6):
|
|
||||||
# ~ import_tax = round(float(tax.tasa) * total_iva, DECIMALES)
|
|
||||||
# ~ else:
|
|
||||||
# ~ import_tax = round(float(tax.tasa) * tax.importe, DECIMALES)
|
|
||||||
# ~ if tax.key == '000':
|
|
||||||
# ~ locales_retenciones += import_tax
|
|
||||||
# ~ else:
|
|
||||||
# ~ total_retenciones = (total_retenciones or 0) + import_tax
|
|
||||||
|
|
||||||
# ~ invoice_tax = {
|
|
||||||
# ~ 'factura': invoice.id,
|
|
||||||
# ~ 'impuesto': tax.id,
|
|
||||||
# ~ 'base': tax.base,
|
|
||||||
# ~ 'importe': tax.suma_impuestos,
|
|
||||||
# ~ }
|
|
||||||
# ~ FacturasImpuestos.create(**invoice_tax)
|
|
||||||
|
|
||||||
total = subtotal - descuento_cfdi + \
|
total = subtotal - descuento_cfdi + \
|
||||||
(total_trasladados or 0) - (total_retenciones or 0) \
|
(total_trasladados or 0) - (total_retenciones or 0) \
|
||||||
+ locales_traslados - locales_retenciones
|
+ locales_traslados - locales_retenciones
|
||||||
|
@ -3834,6 +3872,339 @@ class Tickets(BaseModel):
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('fecha',)
|
order_by = ('fecha',)
|
||||||
|
|
||||||
|
def _get_folio(self, serie):
|
||||||
|
inicio = (Tickets
|
||||||
|
.select(fn.Max(Tickets.folio).alias('mf'))
|
||||||
|
.where(Tickets.serie==serie)
|
||||||
|
.order_by(SQL('mf'))
|
||||||
|
.scalar())
|
||||||
|
|
||||||
|
if inicio is None:
|
||||||
|
inicio = 1
|
||||||
|
else:
|
||||||
|
inicio += 1
|
||||||
|
|
||||||
|
return inicio
|
||||||
|
|
||||||
|
def _calcular_totales(self, ticket, productos):
|
||||||
|
subtotal = 0
|
||||||
|
descuento_cfdi = 0
|
||||||
|
totals_tax = {}
|
||||||
|
total_trasladados = None
|
||||||
|
|
||||||
|
for producto in productos:
|
||||||
|
id_producto = producto.pop('id')
|
||||||
|
p = Productos.get(Productos.id==id_producto)
|
||||||
|
producto['descripcion'] = p.descripcion
|
||||||
|
producto['ticket'] = ticket.id
|
||||||
|
producto['producto'] = id_producto
|
||||||
|
|
||||||
|
cantidad = float(producto['cantidad'])
|
||||||
|
valor_unitario = float(p.valor_unitario)
|
||||||
|
descuento = float(producto['descuento'])
|
||||||
|
precio_final = valor_unitario - descuento
|
||||||
|
importe = round(cantidad * precio_final, DECIMALES)
|
||||||
|
|
||||||
|
producto['cantidad'] = cantidad
|
||||||
|
producto['valor_unitario'] = valor_unitario
|
||||||
|
producto['descuento'] = descuento
|
||||||
|
producto['precio_final'] = precio_final
|
||||||
|
producto['importe'] = importe
|
||||||
|
|
||||||
|
descuento_cfdi += descuento
|
||||||
|
subtotal += importe
|
||||||
|
|
||||||
|
TicketsDetalle.create(**producto)
|
||||||
|
|
||||||
|
base = producto['importe']
|
||||||
|
for tax in p.impuestos:
|
||||||
|
impuesto_producto = round(float(tax.tasa) * base, DECIMALES)
|
||||||
|
if tax.tipo == 'T' and tax.key != '000':
|
||||||
|
total_trasladados = (total_trasladados or 0) + impuesto_producto
|
||||||
|
|
||||||
|
if tax.id in totals_tax:
|
||||||
|
totals_tax[tax.id].base += base
|
||||||
|
totals_tax[tax.id].importe += impuesto_producto
|
||||||
|
else:
|
||||||
|
tax.base = base
|
||||||
|
tax.importe = impuesto_producto
|
||||||
|
totals_tax[tax.id] = tax
|
||||||
|
|
||||||
|
|
||||||
|
for tax in totals_tax.values():
|
||||||
|
if tax.tipo == 'E':
|
||||||
|
continue
|
||||||
|
|
||||||
|
ticket_tax = {
|
||||||
|
'ticket': ticket.id,
|
||||||
|
'impuesto': tax.id,
|
||||||
|
'base': tax.base,
|
||||||
|
'importe': tax.importe,
|
||||||
|
}
|
||||||
|
TicketsImpuestos.create(**ticket_tax)
|
||||||
|
|
||||||
|
total = subtotal + (total_trasladados or 0)
|
||||||
|
data = {
|
||||||
|
'subtotal': subtotal + descuento,
|
||||||
|
'descuento': descuento_cfdi,
|
||||||
|
'total': total,
|
||||||
|
'total_trasladados': total_trasladados,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, values):
|
||||||
|
productos = util.loads(values.pop('productos'))
|
||||||
|
|
||||||
|
values['serie'] = 'T'
|
||||||
|
values['folio'] = cls._get_folio(cls, values['serie'])
|
||||||
|
|
||||||
|
with database_proxy.atomic() as txn:
|
||||||
|
obj = Tickets.create(**values)
|
||||||
|
totals = cls._calcular_totales(cls, obj, productos)
|
||||||
|
obj.subtotal = totals['subtotal']
|
||||||
|
obj.descuento = totals['descuento']
|
||||||
|
obj.total_trasladados = totals['total_trasladados']
|
||||||
|
obj.total = totals['total']
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
row = {
|
||||||
|
'id': obj.id,
|
||||||
|
'folio': obj.folio,
|
||||||
|
'fecha': obj.fecha,
|
||||||
|
'estatus': obj.estatus,
|
||||||
|
'total': obj.total,
|
||||||
|
}
|
||||||
|
data = {'ok': True, 'row': row}
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _get_folio_invoice(self, serie):
|
||||||
|
inicio = (Facturas
|
||||||
|
.select(fn.Max(Facturas.folio).alias('mf'))
|
||||||
|
.where(Facturas.serie==serie)
|
||||||
|
.order_by(SQL('mf'))
|
||||||
|
.scalar())
|
||||||
|
|
||||||
|
if inicio is None:
|
||||||
|
inicio = 1
|
||||||
|
else:
|
||||||
|
inicio += 1
|
||||||
|
|
||||||
|
return inicio
|
||||||
|
|
||||||
|
def _cancel_tickets(self, invoice, tickets):
|
||||||
|
query = (Tickets
|
||||||
|
.update(estatus='Facturado', cancelado=True, factura=invoice)
|
||||||
|
.where(Tickets.id.in_(tickets))
|
||||||
|
)
|
||||||
|
result = query.execute()
|
||||||
|
print (result)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _calculate_totals_invoice(self, invoice, tickets):
|
||||||
|
subtotal = 0
|
||||||
|
descuento_cfdi = 0
|
||||||
|
totals_tax = {}
|
||||||
|
total_trasladados = None
|
||||||
|
total_retenciones = None
|
||||||
|
|
||||||
|
details = TicketsDetalle.select().where(TicketsDetalle.ticket.in_(tickets))
|
||||||
|
|
||||||
|
for detail in details:
|
||||||
|
product = {}
|
||||||
|
p = detail.producto
|
||||||
|
product['unidad'] = p.unidad.key
|
||||||
|
product['clave'] = p.clave
|
||||||
|
product['clave_sat'] = p.clave_sat
|
||||||
|
|
||||||
|
product['factura'] = invoice.id
|
||||||
|
product['producto'] = p.id
|
||||||
|
product['descripcion'] = detail.descripcion
|
||||||
|
|
||||||
|
cantidad = float(detail.cantidad)
|
||||||
|
valor_unitario = float(detail.valor_unitario)
|
||||||
|
descuento = float(detail.descuento)
|
||||||
|
precio_final = valor_unitario - descuento
|
||||||
|
importe = round(cantidad * precio_final, DECIMALES)
|
||||||
|
|
||||||
|
product['cantidad'] = cantidad
|
||||||
|
product['valor_unitario'] = valor_unitario
|
||||||
|
product['descuento'] = round(descuento * cantidad, DECIMALES)
|
||||||
|
product['precio_final'] = precio_final
|
||||||
|
product['importe'] = round(cantidad * valor_unitario, DECIMALES)
|
||||||
|
|
||||||
|
descuento_cfdi += product['descuento']
|
||||||
|
subtotal += product['importe']
|
||||||
|
|
||||||
|
FacturasDetalle.create(**product)
|
||||||
|
|
||||||
|
base = product['importe'] - product['descuento']
|
||||||
|
for tax in p.impuestos:
|
||||||
|
impuesto_producto = round(float(tax.tasa) * base, DECIMALES)
|
||||||
|
if tax.tipo == 'T' and tax.key != '000':
|
||||||
|
total_trasladados = (total_trasladados or 0) + impuesto_producto
|
||||||
|
elif tax.tipo == 'R' and tax.key != '000':
|
||||||
|
total_retenciones = (total_retenciones or 0) + impuesto_producto
|
||||||
|
elif tax.tipo == 'T' and tax.key == '000':
|
||||||
|
locales_traslados += impuesto_producto
|
||||||
|
elif tax.tipo == 'R' and tax.key == '000':
|
||||||
|
locales_retenciones += impuesto_producto
|
||||||
|
|
||||||
|
if tax.id in totals_tax:
|
||||||
|
totals_tax[tax.id].base += base
|
||||||
|
totals_tax[tax.id].suma_impuestos += impuesto_producto
|
||||||
|
else:
|
||||||
|
tax.base = base
|
||||||
|
tax.suma_impuestos = impuesto_producto
|
||||||
|
totals_tax[tax.id] = tax
|
||||||
|
|
||||||
|
for tax in totals_tax.values():
|
||||||
|
if tax.tipo == 'E':
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
invoice_tax = {
|
||||||
|
'factura': invoice.id,
|
||||||
|
'impuesto': tax.id,
|
||||||
|
'base': tax.base,
|
||||||
|
'importe': tax.suma_impuestos,
|
||||||
|
}
|
||||||
|
FacturasImpuestos.create(**invoice_tax)
|
||||||
|
|
||||||
|
total = subtotal - descuento_cfdi + \
|
||||||
|
(total_trasladados or 0) - (total_retenciones or 0)
|
||||||
|
total_mn = round(total * invoice.tipo_cambio, DECIMALES)
|
||||||
|
data = {
|
||||||
|
'subtotal': subtotal,
|
||||||
|
'descuento': descuento_cfdi,
|
||||||
|
'total': total,
|
||||||
|
'total_mn': total_mn,
|
||||||
|
'total_trasladados': total_trasladados,
|
||||||
|
'total_retenciones': total_retenciones,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def invoice(cls, values):
|
||||||
|
is_invoice_day = util.get_bool(values['is_invoice_day'])
|
||||||
|
id_client = int(values['client'])
|
||||||
|
tickets = util.loads(values['tickets'])
|
||||||
|
|
||||||
|
if is_invoice_day:
|
||||||
|
filters = (
|
||||||
|
Socios.rfc == 'XAXX010101000' and
|
||||||
|
Socios.slug == 'publico_en_general')
|
||||||
|
try:
|
||||||
|
client = Socios.get(filters)
|
||||||
|
except Socios.DoesNotExist:
|
||||||
|
msg = 'No existe el cliente Público en General. Agregalo primero.'
|
||||||
|
data = {'ok': False, 'msg': msg}
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
client = Socios.get(Socios.id==id_client)
|
||||||
|
|
||||||
|
emisor = Emisor.select()[0]
|
||||||
|
data = {}
|
||||||
|
data['cliente'] = client
|
||||||
|
data['serie'] = 'T'
|
||||||
|
data['folio'] = cls._get_folio_invoice(cls, data['serie'])
|
||||||
|
data['forma_pago'] = client.forma_pago.key
|
||||||
|
data['tipo_cambio'] = 1.00
|
||||||
|
data['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
|
if client.uso_cfdi is None:
|
||||||
|
data['uso_cfdi'] = 'P01'
|
||||||
|
else:
|
||||||
|
data['uso_cfdi'] = client.uso_cfdi.key
|
||||||
|
data['regimen_fiscal'] = emisor.regimenes[0].key
|
||||||
|
|
||||||
|
with database_proxy.atomic() as txn:
|
||||||
|
obj = Facturas.create(**data)
|
||||||
|
totals = cls._calculate_totals_invoice(cls, obj, tickets)
|
||||||
|
obj.subtotal = totals['subtotal']
|
||||||
|
obj.descuento = totals['descuento']
|
||||||
|
obj.total_trasladados = totals['total_trasladados']
|
||||||
|
obj.total_retenciones = totals['total_retenciones']
|
||||||
|
obj.total = totals['total']
|
||||||
|
obj.saldo = totals['total']
|
||||||
|
obj.total_mn = totals['total_mn']
|
||||||
|
obj.save()
|
||||||
|
cls._cancel_tickets(cls, obj, tickets)
|
||||||
|
|
||||||
|
msg = 'Factura generada correctamente.<BR><BR>Enviando a timbrar'
|
||||||
|
data = {'ok': True, 'msg': msg, 'id': obj.id}
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def cancel(cls, values):
|
||||||
|
id = int(values['id'])
|
||||||
|
msg = 'Ticket cancelado correctamente'
|
||||||
|
u = {'cancelado': True, 'estatus': 'Cancelado'}
|
||||||
|
obj = Tickets.update(**u).where(Tickets.id==id)
|
||||||
|
result = bool(obj.execute())
|
||||||
|
row = {'estatus': 'Cancelado'}
|
||||||
|
return {'ok': result, 'row': row, 'msg': msg}
|
||||||
|
|
||||||
|
def _get_filters(self, values):
|
||||||
|
opt = values.get('opt', '')
|
||||||
|
if not opt:
|
||||||
|
return
|
||||||
|
|
||||||
|
if opt == 'active':
|
||||||
|
filters = (Tickets.cancelado==False)
|
||||||
|
return filters
|
||||||
|
|
||||||
|
if opt == 'today':
|
||||||
|
t = util.today()
|
||||||
|
filters = (
|
||||||
|
(Tickets.fecha.day == t.day) &
|
||||||
|
(Tickets.fecha.month == t.month) &
|
||||||
|
(Tickets.fecha.year == t.year)
|
||||||
|
)
|
||||||
|
return filters
|
||||||
|
|
||||||
|
if opt == 'yearmonth':
|
||||||
|
if values['year'] == '-1':
|
||||||
|
fy = (Tickets.fecha.year > 0)
|
||||||
|
else:
|
||||||
|
fy = (Tickets.fecha.year == int(values['year']))
|
||||||
|
if values['month'] == '-1':
|
||||||
|
fm = (Tickets.fecha.month > 0)
|
||||||
|
else:
|
||||||
|
fm = (Tickets.fecha.month == int(values['month']))
|
||||||
|
filters = (fy & fm)
|
||||||
|
return filters
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by(cls, values):
|
||||||
|
filters = cls._get_filters(cls, values)
|
||||||
|
|
||||||
|
rows = tuple(Tickets
|
||||||
|
.select(
|
||||||
|
Tickets.id,
|
||||||
|
Tickets.serie,
|
||||||
|
Tickets.folio,
|
||||||
|
Tickets.fecha,
|
||||||
|
Tickets.estatus,
|
||||||
|
Tickets.total)
|
||||||
|
.where(filters)
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
return {'ok': True, 'rows': rows}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def filter_years(cls):
|
||||||
|
data = [{'id': -1, 'value': 'Todos'}]
|
||||||
|
rows = (Tickets
|
||||||
|
.select(Tickets.fecha.year.alias('year'))
|
||||||
|
.group_by(Tickets.fecha.year)
|
||||||
|
.order_by(Tickets.fecha.year)
|
||||||
|
)
|
||||||
|
if not rows is None:
|
||||||
|
data += [{'id': int(r.year), 'value': int(r.year)} for r in rows]
|
||||||
|
return tuple(data)
|
||||||
|
|
||||||
|
|
||||||
class TicketsDetalle(BaseModel):
|
class TicketsDetalle(BaseModel):
|
||||||
ticket = ForeignKeyField(Tickets)
|
ticket = ForeignKeyField(Tickets)
|
||||||
|
|
|
@ -24,6 +24,23 @@
|
||||||
font-size: 125%;
|
font-size: 125%;
|
||||||
color: DarkRed;
|
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 {
|
.lbl_partner {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -37,6 +54,10 @@
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.cmd_close_partner div button {
|
.cmd_close_partner div button {
|
||||||
background-color: red !important;
|
background-color: red !important;
|
||||||
|
|
|
@ -50,9 +50,14 @@ var controllers = {
|
||||||
$$('txt_plantilla_factura_33').attachEvent('onItemClick', txt_plantilla_factura_33_click)
|
$$('txt_plantilla_factura_33').attachEvent('onItemClick', txt_plantilla_factura_33_click)
|
||||||
$$('txt_plantilla_factura_33j').attachEvent('onItemClick', txt_plantilla_factura_33j_click)
|
$$('txt_plantilla_factura_33j').attachEvent('onItemClick', txt_plantilla_factura_33j_click)
|
||||||
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
|
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
|
||||||
|
$$('chk_config_ocultar_metodo_pago').attachEvent('onItemClick', chk_config_item_click)
|
||||||
|
$$('chk_config_ocultar_condiciones_pago').attachEvent('onItemClick', chk_config_item_click)
|
||||||
$$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click)
|
$$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click)
|
||||||
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
|
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
|
||||||
$$('chk_config_cuenta_predial').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)
|
||||||
|
$$('chk_usar_punto_de_venta').attachEvent('onItemClick', chk_config_item_click)
|
||||||
|
|
||||||
$$('cmd_subir_bdfl').attachEvent('onItemClick', cmd_subir_bdfl_click)
|
$$('cmd_subir_bdfl').attachEvent('onItemClick', cmd_subir_bdfl_click)
|
||||||
$$('up_bdfl').attachEvent('onUploadComplete', up_bdfl_upload_complete)
|
$$('up_bdfl').attachEvent('onUploadComplete', up_bdfl_upload_complete)
|
||||||
|
|
|
@ -41,14 +41,6 @@ function get_series(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get_forma_pago(){
|
|
||||||
webix.ajax().get('/values/formapago', {key: true}, function(text, data){
|
|
||||||
var values = data.json()
|
|
||||||
$$('lst_forma_pago').getList().parse(values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function get_monedas(){
|
function get_monedas(){
|
||||||
webix.ajax().get('/values/monedas', function(text, data){
|
webix.ajax().get('/values/monedas', function(text, data){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
|
@ -105,7 +97,7 @@ function default_config(){
|
||||||
table_taxes.insert(values)
|
table_taxes.insert(values)
|
||||||
})
|
})
|
||||||
get_series()
|
get_series()
|
||||||
get_forma_pago()
|
get_forma_pago('lst_forma_pago')
|
||||||
get_monedas()
|
get_monedas()
|
||||||
get_uso_cfdi()
|
get_uso_cfdi()
|
||||||
get_regimen_fiscal()
|
get_regimen_fiscal()
|
||||||
|
@ -116,8 +108,11 @@ function default_config(){
|
||||||
|
|
||||||
webix.ajax().sync().get('/values/configtimbrar', function(text, data){
|
webix.ajax().sync().get('/values/configtimbrar', function(text, data){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
|
//~ showvar(values)
|
||||||
show('chk_cfdi_anticipo', values.cfdi_anticipo)
|
show('chk_cfdi_anticipo', values.cfdi_anticipo)
|
||||||
show('chk_cfdi_donativo', values.cfdi_donativo)
|
show('chk_cfdi_donativo', values.cfdi_donativo)
|
||||||
|
show('lst_metodo_pago', values.cfdi_metodo_pago)
|
||||||
|
show('txt_condicion_pago', values.cfdi_condicion_pago)
|
||||||
if(!values.cfdi_ine || values.cfdi_ine == '0'){
|
if(!values.cfdi_ine || values.cfdi_ine == '0'){
|
||||||
$$('tv_invoice').getTabbar().hideOption('INE')
|
$$('tv_invoice').getTabbar().hideOption('INE')
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -9,7 +9,16 @@ function configuracion_inicial(){
|
||||||
webix.ajax().get('/values/main', function(text, data){
|
webix.ajax().get('/values/main', function(text, data){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
$$('lbl_title_main').setValue(values.empresa)
|
$$('lbl_title_main').setValue(values.empresa)
|
||||||
|
//~ showvar()
|
||||||
|
if(values.punto_de_venta){
|
||||||
|
var node = {
|
||||||
|
id: 'app_tickets',
|
||||||
|
icon: 'money',
|
||||||
|
value: 'Punto de venta'}
|
||||||
|
$$('main_sidebar').add(node, 4)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,15 +49,7 @@ var controllers = {
|
||||||
$$("es_proveedor").attachEvent( "onChange", is_supplier_change)
|
$$("es_proveedor").attachEvent( "onChange", is_supplier_change)
|
||||||
$$("rfc").attachEvent( "onBlur", rfc_lost_focus)
|
$$("rfc").attachEvent( "onBlur", rfc_lost_focus)
|
||||||
$$('multi').attachEvent('onViewChange', multi_change)
|
$$('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)
|
|
||||||
$$("clave_sat").attachEvent('onSearchIconClick', clave_sat_icon_click)
|
|
||||||
//~ Invoices
|
//~ Invoices
|
||||||
$$('cmd_new_invoice').attachEvent("onItemClick", cmd_new_invoice_click)
|
$$('cmd_new_invoice').attachEvent("onItemClick", cmd_new_invoice_click)
|
||||||
$$('cmd_refacturar').attachEvent("onItemClick", cmd_refacturar_click)
|
$$('cmd_refacturar').attachEvent("onItemClick", cmd_refacturar_click)
|
||||||
|
@ -86,7 +87,9 @@ var controllers = {
|
||||||
|
|
||||||
webix.extend($$('grid_invoices'), webix.ProgressBar)
|
webix.extend($$('grid_invoices'), webix.ProgressBar)
|
||||||
|
|
||||||
|
products_controllers.init()
|
||||||
bancos_controllers.init()
|
bancos_controllers.init()
|
||||||
|
tickets_controllers.init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +198,14 @@ function multi_change(prevID, nextID){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(nextID == 'app_tickets'){
|
||||||
|
active = $$('multi_tickets').getActiveId()
|
||||||
|
if(active == 'tickets_home'){
|
||||||
|
configuracion_inicial_ticket()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if(nextID == 'app_invoices'){
|
if(nextID == 'app_invoices'){
|
||||||
active = $$('multi_invoices').getActiveId()
|
active = $$('multi_invoices').getActiveId()
|
||||||
if(active == 'invoices_home'){
|
if(active == 'invoices_home'){
|
||||||
|
|
|
@ -155,7 +155,7 @@ function cmd_save_partner_click(id, e, node){
|
||||||
if (values.ok) {
|
if (values.ok) {
|
||||||
update_grid_partner(values)
|
update_grid_partner(values)
|
||||||
} else {
|
} else {
|
||||||
msg_error(msg)
|
msg_error(values.msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
$$("chk_automatica").attachEvent("onChange", chk_automatica_change)
|
||||||
|
$$("valor_unitario").attachEvent("onChange", valor_unitario_change)
|
||||||
|
//~ $$("clave_sat").attachEvent('onSearchIconClick', clave_sat_icon_click)
|
||||||
|
$$('precio_con_impuestos').attachEvent('onChange', precio_con_impuestos_change)
|
||||||
|
$$('precio_con_impuestos').attachEvent('onTimedKeyPress', precio_con_impuestos_key_up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function configurar_productos(){
|
function configurar_productos(){
|
||||||
webix.ajax().get('/config', {'fields': 'productos'}, {
|
webix.ajax().get('/config', {'fields': 'productos'}, {
|
||||||
error: function(text, data, xhr) {
|
error: function(text, data, xhr) {
|
||||||
|
@ -10,6 +26,10 @@ function configurar_productos(){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
//~ showvar(values)
|
//~ showvar(values)
|
||||||
show('cuenta_predial', values.chk_config_cuenta_predial)
|
show('cuenta_predial', values.chk_config_cuenta_predial)
|
||||||
|
show('codigo_barras', values.chk_config_codigo_barras)
|
||||||
|
show('precio_con_impuestos', values.chk_config_precio_con_impuestos)
|
||||||
|
$$('unidad').setValue(values.default_unidad)
|
||||||
|
$$('grid_product_taxes').select(values.default_tax)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -228,6 +248,49 @@ function valor_unitario_change(new_value, old_value){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function clave_sat_icon_click(){
|
function precio_con_impuestos_change(new_value, old_value){
|
||||||
show('Buscar SAT')
|
if(!isFinite(new_value)){
|
||||||
|
this.config.value = old_value
|
||||||
|
this.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~ function clave_sat_icon_click(){
|
||||||
|
//~ show('Buscar SAT')
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
|
@ -0,0 +1,617 @@
|
||||||
|
var query = []
|
||||||
|
var msg = ''
|
||||||
|
|
||||||
|
|
||||||
|
var tickets_controllers = {
|
||||||
|
init: function(){
|
||||||
|
$$('cmd_nuevo_ticket').attachEvent('onItemClick', cmd_nuevo_ticket_click)
|
||||||
|
$$('cmd_ticket_to_invoice').attachEvent('onItemClick', cmd_ticket_to_invoice_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)
|
||||||
|
$$('tsearch_product_key').attachEvent('onKeyPress', tsearch_product_key_press)
|
||||||
|
$$('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)
|
||||||
|
$$('filter_year_ticket').attachEvent('onChange', filter_year_ticket_change)
|
||||||
|
$$('filter_month_ticket').attachEvent('onChange', filter_month_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)
|
||||||
|
|
||||||
|
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 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 configuracion_inicial_ticket(){
|
||||||
|
current_dates_tickets()
|
||||||
|
get_tickets()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_nuevo_ticket_click(){
|
||||||
|
configuracion_inicial_nuevo_ticket()
|
||||||
|
$$('multi_tickets').setValue('tickets_new')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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]['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'])
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = new Object()
|
||||||
|
data['opt'] = 'add'
|
||||||
|
data['productos'] = rows
|
||||||
|
data['forma_pago'] = values.forma_pago
|
||||||
|
|
||||||
|
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')
|
||||||
|
}else{
|
||||||
|
msg_error(values.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_generar_ticket_click(){
|
||||||
|
var form = this.getFormView();
|
||||||
|
|
||||||
|
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 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']
|
||||||
|
grid.add(producto)
|
||||||
|
}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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function buscar_producto_key(key){
|
||||||
|
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')
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function send_timbrar_invoice(id){
|
||||||
|
webix.ajax().get('/values/timbrar', {id: id}, 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)
|
||||||
|
$$('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['client'] = values.id_partner
|
||||||
|
data['tickets'] = tickets
|
||||||
|
data['is_invoice_day'] = chk.getValue()
|
||||||
|
data['opt'] = 'invoice'
|
||||||
|
|
||||||
|
msg = 'Todos los datos son correctos.<BR><BR>¿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(){
|
||||||
|
$$('grid_tickets_active').eachRow(
|
||||||
|
function(row){
|
||||||
|
this.copy(row, -1, $$('grid_tickets_invoice'))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
$$('grid_tickets_active').clearAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_move_tickets_left_click(){
|
||||||
|
$$('grid_tickets_invoice').eachRow(
|
||||||
|
function(row){
|
||||||
|
this.copy(row, -1, $$('grid_tickets_active'))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
$$('grid_tickets_invoice').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)
|
||||||
|
}
|
|
@ -33,6 +33,18 @@ var months = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
function get_icon(tipo){
|
||||||
|
icons = {
|
||||||
|
xml: 'fa-file-code-o',
|
||||||
|
pdf: 'fa-file-pdf-o',
|
||||||
|
zip: 'fa-file-zip-o',
|
||||||
|
email: 'fa-envelope-o',
|
||||||
|
print: 'fa-print',
|
||||||
|
}
|
||||||
|
return "<span class='webix_icon " + icons[tipo] + "'></span>"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function focus(name){
|
function focus(name){
|
||||||
webix.UIManager.setFocus(name)
|
webix.UIManager.setFocus(name)
|
||||||
}
|
}
|
||||||
|
@ -43,6 +55,11 @@ function showvar(values){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function showtype(values){
|
||||||
|
webix.message(typeof(values))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function show(nombre, value){
|
function show(nombre, value){
|
||||||
if(value == '0'){
|
if(value == '0'){
|
||||||
value = false
|
value = false
|
||||||
|
@ -84,7 +101,7 @@ String.prototype.to_float = function(){
|
||||||
|
|
||||||
|
|
||||||
function get_float(value){
|
function get_float(value){
|
||||||
return parseFloat(value.replace('$', '').replace(',', '').trim()).round(2)
|
return parseFloat(value.replace('$', '').replace(',', '').trim()).round(DECIMALES)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,12 +129,17 @@ webix.protoUI({
|
||||||
}, webix.ui.text)
|
}, webix.ui.text)
|
||||||
|
|
||||||
|
|
||||||
webix.ui.datafilter.rowCount = webix.extend({
|
//~ webix.ui.datafilter.rowCount = webix.extend({
|
||||||
|
//~ refresh:function(master, node, value){
|
||||||
|
//~ node.firstChild.innerHTML = master.count();
|
||||||
|
//~ }
|
||||||
|
//~ }, webix.ui.datafilter.summColumn)
|
||||||
|
|
||||||
|
webix.ui.datafilter.countRows = webix.extend({
|
||||||
refresh:function(master, node, value){
|
refresh:function(master, node, value){
|
||||||
node.firstChild.innerHTML = master.count();
|
node.firstChild.innerHTML = master.count();
|
||||||
}
|
}
|
||||||
}, webix.ui.datafilter.summColumn)
|
}, webix.ui.datafilter.summColumn);
|
||||||
|
|
||||||
|
|
||||||
function validate_rfc(value){
|
function validate_rfc(value){
|
||||||
rfc = value.trim().toUpperCase();
|
rfc = value.trim().toUpperCase();
|
||||||
|
@ -279,3 +301,11 @@ webix.DataDriver.plainjs = webix.extend({
|
||||||
return this.hash2tree(hash, 0);
|
return this.hash2tree(hash, 0);
|
||||||
}
|
}
|
||||||
}, webix.DataDriver.json)
|
}, 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)
|
||||||
|
})
|
||||||
|
}
|
|
@ -426,7 +426,7 @@ var controls_correo = [
|
||||||
|
|
||||||
var form_folios = {
|
var form_folios = {
|
||||||
type: 'space',
|
type: 'space',
|
||||||
responsive: true,
|
//~ responsive: true,
|
||||||
cols: [{
|
cols: [{
|
||||||
view: 'form',
|
view: 'form',
|
||||||
id: 'form_folios',
|
id: 'form_folios',
|
||||||
|
@ -451,12 +451,13 @@ var form_correo = {
|
||||||
view: 'form',
|
view: 'form',
|
||||||
id: 'form_correo',
|
id: 'form_correo',
|
||||||
complexData: true,
|
complexData: true,
|
||||||
|
scroll: true,
|
||||||
elements: controls_correo,
|
elements: controls_correo,
|
||||||
elementsConfig: {
|
elementsConfig: {
|
||||||
labelWidth: 150,
|
labelWidth: 150,
|
||||||
labelAlign: 'right'
|
labelAlign: 'right'
|
||||||
},
|
},
|
||||||
autoheight: true
|
//~ autoheight: true
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +487,14 @@ var options_templates = [
|
||||||
|
|
||||||
var options_admin_otros = [
|
var options_admin_otros = [
|
||||||
{maxHeight: 15},
|
{maxHeight: 15},
|
||||||
|
{template: 'Facturación', type: 'section'},
|
||||||
|
{cols: [{maxWidth: 15},
|
||||||
|
{view: 'checkbox', id: 'chk_config_ocultar_metodo_pago', labelWidth: 0,
|
||||||
|
labelRight: 'Ocultar método de pago'},
|
||||||
|
{view: 'checkbox', id: 'chk_config_ocultar_condiciones_pago', labelWidth: 0,
|
||||||
|
labelRight: 'Ocultar condiciones de pago'},
|
||||||
|
{}]},
|
||||||
|
{maxHeight: 20},
|
||||||
{template: 'Ayudas varias', type: 'section'},
|
{template: 'Ayudas varias', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_anticipo', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_anticipo', labelWidth: 0,
|
||||||
|
@ -496,7 +505,11 @@ var options_admin_otros = [
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_cuenta_predial', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_cuenta_predial', labelWidth: 0,
|
||||||
labelRight: 'Mostrar cuenta predial'},
|
labelRight: 'Mostrar cuenta predial'},
|
||||||
{}]},
|
{view: 'checkbox', id: 'chk_config_codigo_barras', labelWidth: 0,
|
||||||
|
labelRight: 'Mostrar código de barras'},
|
||||||
|
{view: 'checkbox', id: 'chk_config_precio_con_impuestos', labelWidth: 0,
|
||||||
|
labelRight: 'Mostrar precio con impuestos'},
|
||||||
|
]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 20},
|
||||||
{template: 'Complementos', type: 'section'},
|
{template: 'Complementos', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
|
@ -504,13 +517,24 @@ var options_admin_otros = [
|
||||||
labelRight: 'Mostrar el complemento INE al facturar'},
|
labelRight: 'Mostrar el complemento INE al facturar'},
|
||||||
{}]},
|
{}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 20},
|
||||||
|
{template: 'Punto de venta', type: 'section'},
|
||||||
|
{cols: [{maxWidth: 15},
|
||||||
|
{view: 'checkbox', id: 'chk_usar_punto_de_venta', labelWidth: 0,
|
||||||
|
labelRight: 'Usar punto de venta'},
|
||||||
|
{}]},
|
||||||
|
|
||||||
|
{maxHeight: 20},
|
||||||
{}]
|
{}]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var body_admin_otros = {
|
||||||
|
view: 'scrollview', body: {rows: options_admin_otros},
|
||||||
|
}
|
||||||
|
|
||||||
var tab_options = {
|
var tab_options = {
|
||||||
view: 'tabview',
|
view: 'tabview',
|
||||||
id: 'tab_options',
|
id: 'tab_options',
|
||||||
multiview: true,
|
|
||||||
animate: true,
|
animate: true,
|
||||||
cells: [
|
cells: [
|
||||||
{id: 'Plantillas', rows: options_templates},
|
{id: 'Plantillas', rows: options_templates},
|
||||||
|
@ -696,8 +720,8 @@ var suggest_sat_moneda = {
|
||||||
name: 'grid_moneda_found',
|
name: 'grid_moneda_found',
|
||||||
body: {
|
body: {
|
||||||
autoConfig: false,
|
autoConfig: false,
|
||||||
scroll:true,
|
scroll: true,
|
||||||
autoheight:false,
|
autoheight: false,
|
||||||
header: true,
|
header: true,
|
||||||
yCount: 10,
|
yCount: 10,
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -935,7 +959,6 @@ var app_correo = {
|
||||||
{view: 'template', id: 'th_correo', type: 'header',
|
{view: 'template', id: 'th_correo', type: 'header',
|
||||||
template: 'Configuración de correo'},
|
template: 'Configuración de correo'},
|
||||||
form_correo,
|
form_correo,
|
||||||
{},
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
var grid_cfdi_cliente_cols = [
|
var grid_cfdi_cliente_cols = [
|
||||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||||
footer: {content: 'rowCount', colspan: 3, css: 'right'}},
|
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||||
{id: "id", header:"ID", hidden:true},
|
{id: "id", header:"ID", hidden:true},
|
||||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "header",
|
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "header",
|
||||||
sort:"string"},
|
sort:"string"},
|
||||||
|
@ -180,20 +180,9 @@ var toolbar_invoices_filter = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
function get_icon(tipo){
|
|
||||||
icons = {
|
|
||||||
xml: 'fa-file-code-o',
|
|
||||||
pdf: 'fa-file-pdf-o',
|
|
||||||
zip: 'fa-file-zip-o',
|
|
||||||
email: 'fa-envelope-o',
|
|
||||||
}
|
|
||||||
return "<span class='webix_icon " + icons[tipo] + "'></span>"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var grid_invoices_cols = [
|
var grid_invoices_cols = [
|
||||||
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||||
footer: {content: 'rowCount', colspan: 3, css: 'right'}},
|
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||||
{id: "id", header:"ID", hidden:true},
|
{id: "id", header:"ID", hidden:true},
|
||||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
|
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
|
||||||
sort:"string"},
|
sort:"string"},
|
||||||
|
@ -227,6 +216,13 @@ var grid_invoices = {
|
||||||
resizeColumn: true,
|
resizeColumn: true,
|
||||||
headermenu: true,
|
headermenu: true,
|
||||||
columns: grid_invoices_cols,
|
columns: grid_invoices_cols,
|
||||||
|
scheme:{
|
||||||
|
$change:function(item){
|
||||||
|
if (item.estatus == 'Cancelada'){
|
||||||
|
item.$css = 'cancel'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
on:{
|
on:{
|
||||||
'data->onStoreUpdated':function(){
|
'data->onStoreUpdated':function(){
|
||||||
this.data.each(function(obj, i){
|
this.data.each(function(obj, i){
|
||||||
|
@ -317,6 +313,7 @@ var suggest_partners = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var suggest_products = {
|
var suggest_products = {
|
||||||
view: 'gridsuggest',
|
view: 'gridsuggest',
|
||||||
id: 'grid_products_found',
|
id: 'grid_products_found',
|
||||||
|
|
|
@ -5,12 +5,13 @@ var menu_data = [
|
||||||
{id: 'app_partners', icon: 'users', value: 'Clientes y Proveedores'},
|
{id: 'app_partners', icon: 'users', value: 'Clientes y Proveedores'},
|
||||||
{id: 'app_products', icon: 'server', value: 'Productos y Servicios'},
|
{id: 'app_products', icon: 'server', value: 'Productos y Servicios'},
|
||||||
{id: 'app_bancos', icon: 'university', value: 'Bancos'},
|
{id: 'app_bancos', icon: 'university', value: 'Bancos'},
|
||||||
{id: 'app_invoices', icon: 'cart-plus', value: 'Facturas'},
|
{id: 'app_invoices', icon: 'file-code-o', value: 'Facturas'},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
var sidebar = {
|
var sidebar = {
|
||||||
view: 'sidebar',
|
view: 'sidebar',
|
||||||
|
id: 'main_sidebar',
|
||||||
data: menu_data,
|
data: menu_data,
|
||||||
ready: function(){
|
ready: function(){
|
||||||
this.select('app_home');
|
this.select('app_home');
|
||||||
|
@ -36,6 +37,7 @@ var multi_main = {
|
||||||
app_partners,
|
app_partners,
|
||||||
app_products,
|
app_products,
|
||||||
app_bancos,
|
app_bancos,
|
||||||
|
app_tickets,
|
||||||
app_invoices,
|
app_invoices,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -60,7 +62,7 @@ var ui_main = {
|
||||||
{view: 'toolbar', padding: 3, elements: [
|
{view: 'toolbar', padding: 3, elements: [
|
||||||
{view: 'button', type: 'icon', icon: 'bars',
|
{view: 'button', type: 'icon', icon: 'bars',
|
||||||
width: 37, align: 'left', css: 'app_button', click: function(){
|
width: 37, align: 'left', css: 'app_button', click: function(){
|
||||||
$$('$sidebar1').toggle()
|
$$('main_sidebar').toggle()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{view: 'label', id: 'lbl_title_main', label: '<b>Empresa Libre</b>'},
|
{view: 'label', id: 'lbl_title_main', label: '<b>Empresa Libre</b>'},
|
||||||
|
|
|
@ -12,7 +12,7 @@ var toolbar_partners = [
|
||||||
|
|
||||||
var grid_partners_cols = [
|
var grid_partners_cols = [
|
||||||
{id: 'index', header:'#', css: 'right',
|
{id: 'index', header:'#', css: 'right',
|
||||||
footer: {content: 'rowCount', colspan: 2, css: 'right'}},
|
footer: {content: 'countRows', colspan: 2, css: 'right'}},
|
||||||
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
|
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
|
||||||
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
|
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
|
||||||
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
|
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
|
||||||
|
@ -143,7 +143,7 @@ var toolbar_contacts = [
|
||||||
|
|
||||||
var grid_contacts_cols = [
|
var grid_contacts_cols = [
|
||||||
{id: 'index', header: '#', adjust:'data', css:'right',
|
{id: 'index', header: '#', adjust:'data', css:'right',
|
||||||
footer: {content: 'rowCount'}},
|
footer: {content: 'countRows'}},
|
||||||
{id: 'id', header: '', hidden: true},
|
{id: 'id', header: '', hidden: true},
|
||||||
{id: 'title', header: 'Título', adjust:'data', sort: 'string',
|
{id: 'title', header: 'Título', adjust:'data', sort: 'string',
|
||||||
footer: 'Contactos'},
|
footer: 'Contactos'},
|
||||||
|
|
|
@ -13,7 +13,7 @@ var toolbar_products = [
|
||||||
var grid_products_cols = [
|
var grid_products_cols = [
|
||||||
{ id: "id", header: "ID", width: 75, hidden: true},
|
{ id: "id", header: "ID", width: 75, hidden: true},
|
||||||
{ id: "clave", header: ["Clave", {content: "textFilter"}], width: 100,
|
{ id: "clave", header: ["Clave", {content: "textFilter"}], width: 100,
|
||||||
sort: 'string', footer: {content: 'rowCount', css: 'right'}},
|
sort: 'string', footer: {content: 'countRows', css: 'right'}},
|
||||||
{ id: "descripcion", header: ["Descripción", {content: "textFilter"}],
|
{ id: "descripcion", header: ["Descripción", {content: "textFilter"}],
|
||||||
fillspace:true, sort: 'string', footer: 'Productos y Servicios'},
|
fillspace:true, sort: 'string', footer: 'Productos y Servicios'},
|
||||||
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
|
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
|
||||||
|
@ -123,10 +123,16 @@ var controls_generals = [
|
||||||
labelAlign: 'right', label: 'Etiquetas',
|
labelAlign: 'right', label: 'Etiquetas',
|
||||||
placeholder: 'Separadas por comas'}
|
placeholder: 'Separadas por comas'}
|
||||||
]},
|
]},
|
||||||
{cols: [{view: "currency", type: "text", id: "valor_unitario",
|
{cols: [
|
||||||
|
{view: "currency", type: "text", id: "valor_unitario",
|
||||||
name: "valor_unitario", label: "Valor Unitario", width: 300,
|
name: "valor_unitario", label: "Valor Unitario", width: 300,
|
||||||
labelWidth: 130, labelAlign: "right", required: true,
|
labelWidth: 130, labelAlign: "right", required: true,
|
||||||
invalidMessage: "Captura un valor númerico", inputAlign: "right" },{}]},
|
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: [
|
{cols: [
|
||||||
{view: 'checkbox', id: 'inventario', name: 'inventario', hidden: true,
|
{view: 'checkbox', id: 'inventario', name: 'inventario', hidden: true,
|
||||||
label: 'Inventario', labelAlign: 'right', labelWidth: 130},
|
label: 'Inventario', labelAlign: 'right', labelWidth: 130},
|
||||||
|
|
|
@ -0,0 +1,421 @@
|
||||||
|
|
||||||
|
|
||||||
|
var toolbar_tickets = [
|
||||||
|
{view: 'button', id: 'cmd_nuevo_ticket', label: 'Nuevo', type: 'iconButton',
|
||||||
|
autowidth: true, icon: 'plus'},
|
||||||
|
{view: 'button', id: 'cmd_ticket_to_invoice', label: 'Facturar',
|
||||||
|
type: 'iconButton', autowidth: true, icon: 'file-code-o'},
|
||||||
|
{},
|
||||||
|
{view: 'button', id: 'cmd_cancelar_ticket', label: 'Cancelar',
|
||||||
|
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var toolbar_tickets_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: "data",
|
||||||
|
sort:"string", hidden: true},
|
||||||
|
{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'},
|
||||||
|
{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: 'I', adjust: 'data', template: get_icon('print')},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var grid_tickets = {
|
||||||
|
view: 'datatable',
|
||||||
|
id: 'grid_tickets',
|
||||||
|
select: 'row',
|
||||||
|
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', adjust: 'data'},
|
||||||
|
{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", 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},
|
||||||
|
{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',
|
||||||
|
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'}},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
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 controls_generate_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},
|
||||||
|
]},
|
||||||
|
]},
|
||||||
|
{view: 'label', label: 'Detalle', height: 30, align: 'left'},
|
||||||
|
grid_tdetails,
|
||||||
|
{minHeight: 20, maxHeight: 20},
|
||||||
|
{margin: 20, cols: [{},
|
||||||
|
{view: 'button', id: 'cmd_generar_ticket', label: 'Generar',
|
||||||
|
icon: 'ticket', type: 'iconButton', autowidth: true, align: 'center'},
|
||||||
|
{}]
|
||||||
|
},
|
||||||
|
{rows: [
|
||||||
|
{template: '', type: 'section'},
|
||||||
|
{margin: 10, cols: [{},
|
||||||
|
{view: 'button', id: 'cmd_cerrar_ticket', label: 'Cerrar',
|
||||||
|
type: 'danger', autowidth: true, align: 'center'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var toolbar_ticket_invoice = {view: 'toolbar', elements: [{},
|
||||||
|
{view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150,
|
||||||
|
labelRight: 'Es factura del día'},
|
||||||
|
{}]}
|
||||||
|
|
||||||
|
|
||||||
|
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", hidden: true},
|
||||||
|
{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',
|
||||||
|
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", hidden: true},
|
||||||
|
{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',
|
||||||
|
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'},
|
||||||
|
{}]
|
||||||
|
},
|
||||||
|
{rows: [
|
||||||
|
{template: '', type: 'section'},
|
||||||
|
{margin: 10, cols: [{},
|
||||||
|
{view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar',
|
||||||
|
type: 'danger', autowidth: true, align: 'center'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var controls_new_ticket = [
|
||||||
|
{
|
||||||
|
view: 'tabview',
|
||||||
|
id: 'tv_new_ticket',
|
||||||
|
animate: true,
|
||||||
|
cells: [
|
||||||
|
{id: 'Generar', rows: controls_generate_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
|
||||||
|
],
|
||||||
|
}
|
|
@ -8,12 +8,14 @@
|
||||||
<script src="/static/js/ui/partners.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/products.js" type="text/javascript" ></script>
|
||||||
<script src="/static/js/ui/bancos.js" type="text/javascript" ></script>
|
<script src="/static/js/ui/bancos.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/invoices.js" type="text/javascript" ></script>
|
||||||
<script src="/static/js/ui/main.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/partners.js" type="text/javascript" ></script>
|
||||||
<script src="/static/js/controller/products.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/bancos.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/invoices.js" type="text/javascript" ></script>
|
||||||
<script src="/static/js/controller/main.js" type="text/javascript" ></script>
|
<script src="/static/js/controller/main.js" type="text/javascript" ></script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue