diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py
index 88b911b..721a503 100644
--- a/source/app/controllers/main.py
+++ b/source/app/controllers/main.py
@@ -80,6 +80,8 @@ class AppValues(object):
req.context['result'] = self._db.validate_email(values)
elif table == 'sendmail':
req.context['result'] = self._db.send_email(values, session)
+ elif table == 'enviarprefac':
+ req.context['result'] = self._db.enviar_prefac(values)
else:
req.context['result'] = self._db.validate_cert(values, session)
else:
@@ -189,6 +191,29 @@ class AppInvoices(object):
resp.status = falcon.HTTP_204
+class AppPreInvoices(object):
+
+ def __init__(self, db):
+ self._db = db
+
+ def on_get(self, req, resp):
+ values = req.params
+ req.context['result'] = self._db.get_preinvoices(values)
+ resp.status = falcon.HTTP_200
+
+ def on_post(self, req, resp):
+ values = req.params
+ req.context['result'] = self._db.preinvoice(values)
+ resp.status = falcon.HTTP_200
+
+ def on_delete(self, req, resp):
+ values = req.params
+ if self._db.delete('preinvoice', values['id']):
+ resp.status = falcon.HTTP_200
+ else:
+ resp.status = falcon.HTTP_204
+
+
class AppEmisor(object):
def __init__(self, db):
diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py
index 54bc86d..cbf8825 100644
--- a/source/app/controllers/util.py
+++ b/source/app/controllers/util.py
@@ -512,6 +512,7 @@ class LIBO(object):
self._init_values()
def _init_values(self):
+ self._es_pre = False
self._ctx = None
self._sm = None
self._desktop = None
@@ -764,6 +765,9 @@ class LIBO(object):
return
def _timbre(self, data):
+ if self._es_pre:
+ return
+
for k, v in data.items():
self._set_cell('{timbre.%s}' % k, v)
pd = self._sheet.getDrawPage()
@@ -779,6 +783,7 @@ class LIBO(object):
def _render(self, data):
self._set_search()
+ self._es_pre = data.pop('es_pre', False)
self._comprobante(data['comprobante'])
self._emisor(data['emisor'])
self._receptor(data['receptor'])
diff --git a/source/app/main.py b/source/app/main.py
index 9329f90..e6a6710 100644
--- a/source/app/main.py
+++ b/source/app/main.py
@@ -15,7 +15,7 @@ from models.db import StorageEngine
from controllers.main import (
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
- AppDocumentos, AppFiles
+ AppDocumentos, AppFiles, AppPreInvoices
)
from settings import DEBUG
@@ -44,6 +44,7 @@ api.add_route('/doc/{type_doc}/{id_doc}', AppDocumentos(db))
api.add_route('/partners', AppPartners(db))
api.add_route('/products', AppProducts(db))
api.add_route('/invoices', AppInvoices(db))
+api.add_route('/preinvoices', AppPreInvoices(db))
if DEBUG:
diff --git a/source/app/models/db.py b/source/app/models/db.py
index dc4138e..eb2bacd 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -38,6 +38,9 @@ class StorageEngine(object):
def send_email(self, values, session):
return main.Facturas.send(values['id'], session['rfc'])
+ def enviar_prefac(self, values):
+ return main.PreFacturas.enviar(values['id'])
+
def _get_cancelinvoice(self, values):
return main.Facturas.cancel(values['id'])
@@ -45,7 +48,9 @@ class StorageEngine(object):
return main.Facturas.get_status_sat(values['id'])
def _get_filteryears(self, values):
- return main.Facturas.filter_years()
+ years1 = main.Facturas.filter_years()
+ years2 = main.PreFacturas.filter_years()
+ return [years1, years2]
def _get_cert(self, values):
return main.Certificado.get_data()
@@ -101,6 +106,8 @@ class StorageEngine(object):
return main.Facturas.remove(id)
if table == 'folios':
return main.Folios.remove(id)
+ if table == 'preinvoice':
+ return main.PreFacturas.remove(id)
return False
def _get_client(self, values):
@@ -133,9 +140,18 @@ class StorageEngine(object):
return main.Facturas.actualizar(values, id)
return main.Facturas.add(values)
+ def preinvoice(self, values):
+ id = int(values.pop('id', '0'))
+ #~ if id:
+ #~ return main.PreFacturas.actualizar(values, id)
+ return main.PreFacturas.add(values)
+
def get_invoices(self, values):
return main.Facturas.get_(values)
+ def get_preinvoices(self, values):
+ return main.PreFacturas.get_(values)
+
def _get_timbrar(self, values):
return main.Facturas.timbrar(int(values['id']))
@@ -155,11 +171,15 @@ class StorageEngine(object):
if type_doc == 'xml':
data, file_name = main.Facturas.get_xml(id)
content_type = 'application/xml'
- if type_doc == 'pdf':
+ elif type_doc == 'pdf':
data, file_name = main.Facturas.get_pdf(id, rfc)
content_type = 'application/pdf'
- if type_doc == 'zip':
+ elif type_doc == 'zip':
data, file_name = main.Facturas.get_zip(id, rfc)
content_type = 'application/octet-stream'
+ elif type_doc == 'pdf2':
+ data, file_name = main.PreFacturas.get_pdf(id)
+ content_type = 'application/pdf'
+
return data, file_name, content_type
diff --git a/source/app/models/main.py b/source/app/models/main.py
index b4039f2..58a648a 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -1655,6 +1655,307 @@ class PreFacturas(BaseModel):
class Meta:
order_by = ('fecha',)
+ @classmethod
+ def enviar(cls, id):
+ values = Configuracion.get_({'fields': 'correo'})
+ if not values:
+ msg = 'No esta configurado el servidor de correo de salida'
+ return {'ok': False, 'msg': msg}
+
+ obj = PreFacturas.get(PreFacturas.id==id)
+ if not obj.cliente.correo_facturas:
+ msg = 'El cliente no tiene configurado el correo para facturas'
+ return {'ok': False, 'msg': msg}
+
+ files = (cls.get_pdf(id),)
+
+ invoice = PreFacturas.select().where(PreFacturas.id==id).dicts()[0]
+ fields = {
+ 'receptor_nombre': obj.cliente.nombre,
+ 'receptor_rfc': obj.cliente.rfc,
+ }
+ fields.update(invoice)
+
+ asunto = 'Enviamos la prefactura: PRE-{}'.format(obj.folio)
+ server = {
+ 'servidor': values['correo_servidor'],
+ 'puerto': values['correo_puerto'],
+ 'ssl': bool(int(values['correo_ssl'])),
+ 'usuario': values['correo_usuario'],
+ 'contra': values['correo_contra'],
+ }
+ options = {
+ 'para': obj.cliente.correo_facturas,
+ 'copia': values['correo_copia'],
+ 'asunto': asunto,
+ 'mensaje': util.make_info_mail(values['correo_mensaje'], fields),
+ 'files': files,
+ }
+ data= {
+ 'server': server,
+ 'options': options,
+ }
+ result = util.send_mail(data)
+ if not result['ok'] or result['msg']:
+ return {'ok': False, 'msg': result['msg']}
+
+ msg = 'Pre Factura enviada correctamente'
+ return {'ok': True, 'msg': msg}
+
+ def _get_info_to_pdf(self, id):
+ data = {}
+ obj = PreFacturas.select().where(PreFacturas.id==id).dicts()[0]
+ regimen = SATRegimenes.get(SATRegimenes.key==obj['regimen_fiscal'])
+ usocfdi = SATUsoCfdi.get(SATUsoCfdi.key==obj['uso_cfdi'])
+ formapago = SATFormaPago.get(SATFormaPago.key==obj['forma_pago'])
+ moneda = SATMonedas.get(SATMonedas.key==obj['moneda'])
+
+ emisor = util.get_dict(Emisor.select().dicts()[0])
+ emisor['nointerior'] = emisor['no_interior']
+ emisor['noexterior'] = emisor['no_exterior']
+ emisor['codigopostal'] = emisor['codigo_postal']
+ emisor['regimenfiscal'] = str(regimen)
+
+ receptor = Socios.select().where(Socios.id==obj['cliente']).dicts()[0]
+ receptor['usocfdi'] = str(usocfdi)
+ receptor['nointerior'] = receptor['no_interior']
+ receptor['noexterior'] = receptor['no_exterior']
+ receptor['codigopostal'] = receptor['codigo_postal']
+
+ data['es_pre'] = True
+ data['cancelada'] = False
+
+ tipos = {
+ 'I': 'ingreso',
+ 'E': 'egreso',
+ 'T': 'traslado',
+ }
+ mp = {
+ 'PUE': 'Pago en una sola exhibición',
+ 'PPD': 'Pago en parcialidades o diferido',
+ }
+
+ data['comprobante'] = obj
+ data['comprobante']['version'] = CURRENT_CFDI
+ data['comprobante']['folio'] = '{}-{}'.format(
+ data['comprobante']['serie'], data['comprobante']['folio'])
+ data['comprobante']['fecha'] = str(data['comprobante']['fecha'])
+ data['comprobante']['tipodecomprobante'] = tipos.get(
+ data['comprobante']['tipo_comprobante'])
+ data['comprobante']['lugarexpedicion'] = \
+ 'C.P. de Expedición: {}'.format(
+ data['comprobante']['lugar_expedicion'])
+ data['comprobante']['metododepago'] = 'Método de Pago: ({}) {}'.format(
+ obj['metodo_pago'], mp[obj['metodo_pago']])
+ data['comprobante']['formadepago'] = str(formapago)
+ data['comprobante']['condicionesdepago'] = \
+ data['comprobante']['condiciones_pago']
+ data['comprobante']['tipocambio'] = 'Tipo de Cambio: $ {:0.2f}'.format(
+ data['comprobante']['tipo_cambio'])
+ data['comprobante']['totalenletras'] = util.to_letters(
+ data['comprobante']['total'], data['comprobante']['moneda'])
+ data['comprobante']['moneda'] = str(moneda)
+
+ data['emisor'] = emisor
+ data['receptor'] = receptor
+
+ data['conceptos'] = PreFacturasDetalle.get_(id)
+ data['totales'] = {}
+ data['totales']['moneda'] = data['comprobante']['moneda']
+ data['totales']['subtotal'] = str(data['comprobante']['subtotal'])
+ data['totales']['total'] = str(data['comprobante']['total'])
+
+ taxes = PreFacturasImpuestos.get_(id)
+ data['totales']['traslados'] = taxes['traslados']
+ data['totales']['retenciones'] = taxes['retenciones']
+ data['totales']['taxlocales'] = taxes['taxlocales']
+ data['timbre'] = {}
+
+ return data
+
+ @classmethod
+ def get_pdf(cls, id):
+ obj = PreFacturas.get(PreFacturas.id==id)
+ name = '{}{}_{}.pdf'.format(obj.serie, obj.folio, obj.cliente.rfc)
+ data = cls._get_info_to_pdf(cls, id)
+ doc = util.to_pdf(data)
+ return doc, name
+
+ @classmethod
+ def remove(cls, id):
+ obj = PreFacturas.get(PreFacturas.id==id)
+
+ q = PreFacturasDetalle.delete().where(
+ PreFacturasDetalle.factura==obj)
+ q.execute()
+ q = PreFacturasImpuestos.delete().where(
+ PreFacturasImpuestos.factura==obj)
+ q.execute()
+ q = PreFacturasRelacionadas.delete().where(
+ PreFacturasRelacionadas.factura==obj)
+ q.execute()
+ return bool(obj.delete_instance())
+
+ @classmethod
+ def filter_years(cls):
+ data = [{'id': -1, 'value': 'Todos'}]
+ rows = (PreFacturas
+ .select(PreFacturas.fecha.year)
+ .group_by(PreFacturas.fecha.year)
+ .order_by(PreFacturas.fecha.year)
+ .scalar(as_tuple=True)
+ )
+ if not rows is None:
+ data += [{'id': int(row), 'value': int(row)} for row in rows]
+ return tuple(data)
+
+ @classmethod
+ def get_(cls, values):
+ if values['year'] == '-1':
+ fy = (PreFacturas.fecha.year > 0)
+ else:
+ fy = (PreFacturas.fecha.year == int(values['year']))
+ if values['month'] == '-1':
+ fm = (PreFacturas.fecha.month > 0)
+ else:
+ fm = (PreFacturas.fecha.month == int(values['month']))
+ filters = (fy & fm)
+
+ rows = tuple(PreFacturas
+ .select(
+ PreFacturas.id,
+ PreFacturas.folio,
+ PreFacturas.fecha,
+ PreFacturas.tipo_comprobante,
+ PreFacturas.total_mn,
+ Socios.nombre.alias('cliente'))
+ .where(filters)
+ .join(Socios)
+ .switch(PreFacturas).dicts()
+ )
+ return {'ok': True, 'rows': rows}
+
+ def _get_folio(self, serie):
+ inicio = (PreFacturas
+ .select(fn.Max(PreFacturas.folio).alias('mf'))
+ .where(PreFacturas.serie==serie)
+ .order_by(SQL('mf'))
+ .scalar())
+
+ if inicio is None:
+ inicio = 1
+ else:
+ inicio += 1
+
+ return inicio
+
+ def _calculate_totals(self, invoice, products):
+ subtotal = 0
+ totals_tax = {}
+ total_trasladados = None
+ total_retenciones = None
+ total_iva = 0
+
+ for product in products:
+ id_product = product.pop('id')
+ p = Productos.get(Productos.id==id_product)
+ #~ product['descripcion'] = p.descripcion
+ product['unidad'] = p.unidad.key
+ product['clave'] = p.clave
+ product['clave_sat'] = p.clave_sat
+
+ product['factura'] = invoice.id
+ product['producto'] = id_product
+ product['importe'] = round(
+ float(product['cantidad']) * float(product['valor_unitario']), 2)
+ subtotal += product['importe']
+
+ PreFacturasDetalle.create(**product)
+ for tax in p.impuestos:
+ if tax.id in totals_tax:
+ totals_tax[tax.id].importe += product['importe']
+ else:
+ tax.importe = product['importe']
+ totals_tax[tax.id] = tax
+ #~ totals_tax[tax.id]['importe'] = product['importe']
+
+ for tax in totals_tax.values():
+ if tax.tipo == 'E' or tax.tipo == 'R':
+ continue
+ import_tax = round(float(tax.tasa) * tax.importe, 2)
+ total_trasladados = (total_trasladados or 0) + import_tax
+ if tax.name == 'IVA':
+ total_iva += import_tax
+
+ invoice_tax = {
+ 'factura': invoice.id,
+ 'impuesto': tax.id,
+ 'base': tax.importe,
+ 'importe': import_tax,
+ }
+ PreFacturasImpuestos.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, 2)
+ else:
+ import_tax = round(float(tax.tasa) * tax.importe, 2)
+ total_retenciones = (total_retenciones or 0) + import_tax
+
+ invoice_tax = {
+ 'factura': invoice.id,
+ 'impuesto': tax['id'],
+ 'base': tax['importe'],
+ 'importe': import_tax,
+ }
+ PreFacturasImpuestos.create(**invoice_tax)
+
+ total = subtotal + (total_trasladados or 0) - (total_retenciones or 0)
+ total_mn = round(total * invoice.tipo_cambio, 2)
+ data = {
+ 'subtotal': subtotal,
+ 'total': total,
+ 'total_mn': total_mn,
+ 'total_trasladados': total_trasladados,
+ 'total_retenciones': total_retenciones,
+ }
+ return data
+
+ @classmethod
+ def add(cls, values):
+ print ('VALUES', values)
+ productos = util.loads(values.pop('productos'))
+
+ emisor = Emisor.select()[0]
+ values['serie'] = 'PRE'
+ values['folio'] = cls._get_folio(cls, values['serie'])
+ values['tipo_cambio'] = float(values['tipo_cambio'])
+ values['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
+
+ with database_proxy.atomic() as txn:
+ obj = PreFacturas.create(**values)
+ totals = cls._calculate_totals(cls, obj, productos)
+ obj.subtotal = totals['subtotal']
+ obj.total_trasladados = totals['total_trasladados']
+ obj.total_retenciones = totals['total_retenciones']
+ obj.total = totals['total']
+ obj.total_mn = totals['total_mn']
+ obj.save()
+
+ msg = 'Factura guardada correctamente'
+ row = {
+ 'id': obj.id,
+ 'folio': obj.folio,
+ 'fecha': obj.fecha,
+ 'tipo_comprobante': obj.tipo_comprobante,
+ 'total_mn': obj.total_mn,
+ 'cliente': obj.cliente.nombre,
+ }
+ data = {'ok': True, 'row': row, 'new': True, 'error': False, 'msg': msg}
+ return data
+
class FacturasRelacionadas(BaseModel):
factura = ForeignKeyField(Facturas, related_name='original')
@@ -1705,6 +2006,7 @@ class FacturasDetalle(BaseModel):
class PreFacturasDetalle(BaseModel):
factura = ForeignKeyField(PreFacturas)
producto = ForeignKeyField(Productos, null=True)
+ descripcion = TextField(default='')
cantidad = DecimalField(default=0.0, max_digits=18, decimal_places=6,
auto_round=True)
valor_unitario = DecimalField(default=0.0, max_digits=18, decimal_places=6,
@@ -1727,6 +2029,27 @@ class PreFacturasDetalle(BaseModel):
class Meta:
order_by = ('factura',)
+ @classmethod
+ def get_(cls, id):
+ data = []
+
+ productos = PreFacturasDetalle.select().where(
+ PreFacturasDetalle.factura==id)
+
+ for p in productos:
+ producto = {}
+ producto['noidentificacion'] = '{}\n(SAT {})'.format(
+ p.producto.clave, p.producto.clave_sat)
+ producto['descripcion'] = p.descripcion
+ producto['unidad'] = '{}\n({})'.format(
+ p.producto.unidad.name, p.producto.unidad.key)
+ producto['cantidad'] = str(p.cantidad)
+ producto['valorunitario'] = str(p.valor_unitario)
+ producto['importe'] = str(p.importe)
+ data.append(producto)
+
+ return data
+
class FacturasImpuestos(BaseModel):
factura = ForeignKeyField(Facturas)
@@ -1757,6 +2080,29 @@ class PreFacturasImpuestos(BaseModel):
(('factura', 'impuesto'), True),
)
+ @classmethod
+ def get_(cls, id):
+ data = {
+ 'traslados': [],
+ 'retenciones': [],
+ 'taxlocales': [],
+ }
+
+ taxes = PreFacturasImpuestos.select().where(
+ PreFacturasImpuestos.factura==id)
+
+ for tax in taxes:
+ if tax.impuesto.tipo == 'T':
+ title = 'Traslado {} {}'.format(
+ tax.impuesto.name, str(tax.impuesto.tasa))
+ data['traslados'].append((title, str(tax.importe)))
+ elif tax.impuesto.tipo == 'R':
+ title = 'Retención {} {}'.format(
+ tax.impuesto.name, str(tax.impuesto.tasa))
+ data['retenciones'].append((title, str(tax.importe)))
+
+ return data
+
def authenticate(args):
respuesta = {'login': False, 'msg': 'No Autorizado', 'user': ''}
@@ -1840,6 +2186,7 @@ def test_correo(values):
def _init_values(rfc):
data = (
{'clave': 'version', 'valor': VERSION},
+ {'clave': 'migracion', 'valor': '0'},
{'clave': 'rfc_publico', 'valor': 'XAXX010101000'},
{'clave': 'rfc_extranjero', 'valor': 'XEXX010101000'},
{'clave': 'decimales', 'valor': '2'},
diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js
index 5733ff9..7fa0fd2 100644
--- a/source/static/js/controller/invoices.js
+++ b/source/static/js/controller/invoices.js
@@ -293,6 +293,38 @@ function save_invoice(data){
}
+function save_preinvoice(data){
+ var result = false
+ var values = NaN
+
+ webix.ajax().sync().post('preinvoices', 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_sucess('Pre Factura generada correctamente')
+ result = true
+ }else{
+ msg_error(values.msg)
+ }
+ }
+ })
+
+ if(result){
+ table_pt.clear()
+ table_totals.clear()
+ grid.clearAll()
+ $$('grid_totals').clearAll()
+
+ }
+
+ return result
+}
+
+
function cmd_timbrar_click(id, e, node){
var form = this.getFormView();
@@ -830,6 +862,23 @@ function cmd_invoice_sat_click(){
}
+function reset_invoice(){
+ var form = $$('form_invoice')
+ var grid_totals = $$('grid_totals')
+
+ form.adjust()
+ form.setValues({id: 0, id_partner: 0, lbl_client: 'Ninguno'})
+ grid.clearAll()
+ grid_totals.clearAll()
+ grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
+
+ table_pt.clear()
+ table_totals.clear()
+ form.focus('search_client_name')
+
+}
+
+
function cmd_prefactura_click(){
var form = this.getFormView()
@@ -842,7 +891,36 @@ function cmd_prefactura_click(){
if(!validate_invoice(values)){
return
}
- show('PreFactura')
+
+ var rows = grid.data.getRange()
+ for (i = 0; i < rows.length; i++) {
+ delete rows[i]['delete']
+ delete rows[i]['clave']
+ delete rows[i]['unidad']
+ delete rows[i]['importe']
+ rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario'])
+ }
+
+ var data = new Object()
+ data['id'] = values.id
+ data['cliente'] = values.id_partner
+ data['productos'] = rows
+ data['serie'] = $$('lst_serie').getText()
+ data['forma_pago'] = $$('lst_forma_pago').getValue()
+ data['condiciones_pago'] = $$('txt_condicion_pago').getValue().trim()
+ data['moneda'] = $$('lst_moneda').getValue()
+ data['tipo_cambio'] = $$('txt_tipo_cambio').getValue()
+ data['tipo_comprobante'] = $$('lst_tipo_comprobante').getValue()
+ data['metodo_pago'] = $$('lst_metodo_pago').getValue()
+ data['uso_cfdi'] = $$('lst_uso_cfdi').getValue()
+ data['regimen_fiscal'] = $$('lst_regimen_fiscal').getValue()
+
+ if(!save_preinvoice(data)){
+ return
+ }
+
+ reset_invoice()
+ $$('tv_invoice').getTabbar().setValue('PreFacturas')
}
@@ -851,3 +929,164 @@ function lst_metodo_pago_change(nv, ov){
$$('lst_forma_pago').setValue('99')
}
}
+
+
+function get_prefacturas(){
+ var fy = $$('prefilter_year')
+ var fm = $$('prefilter_month')
+
+ var y = fy.getValue()
+ var m = fm.getValue()
+ rango = {'year': y, 'month': m}
+
+ var grid = $$('grid_preinvoices')
+ webix.ajax().get('/preinvoices', rango, {
+ error: function(text, data, xhr) {
+ webix.message({type: 'error', text: 'Error al consultar'})
+ },
+ success: function(text, data, xhr) {
+ var values = data.json();
+ grid.clearAll();
+ if (values.ok){
+ grid.parse(values.rows, 'json')
+ }
+ }
+ })
+}
+
+
+function tb_invoice_change(nv, ov){
+ if(nv == 'PreFacturas'){
+ get_prefacturas()
+ }
+}
+
+
+function prefilter_year_change(nv, ov){
+ get_prefacturas()
+}
+
+
+function prefilter_month_change(nv, ov){
+ get_prefacturas()
+}
+
+
+function delete_preinvoice(id){
+ webix.ajax().del('/preinvoices', {id: id}, function(text, xml, xhr){
+ if(xhr.status == 200){
+ $$('grid_preinvoices').remove(id)
+ msg_sucess('PreFactura eliminada correctamente')
+ }else{
+ msg_error('No se pudo eliminar')
+ }
+ })
+}
+
+
+function cmd_delete_preinvoice_click(id, e, node){
+ var grid = $$('grid_preinvoices')
+
+ if(grid.count() == 0){
+ return
+ }
+
+ var row = grid.getSelectedItem()
+ if (row == undefined){
+ msg_error('Selecciona una prefactura')
+ return
+ }
+
+ var msg = '¿Estás seguro de eliminar la siguiente PREFactura?
'
+ msg += '(' + row['folio'] + ') ' + row['cliente']
+ msg += '
ESTA ACCIÓN NO SE PUEDE DESHACER'
+ webix.confirm({
+ title:'Eliminar Pre Factura',
+ ok:'Si',
+ cancel:'No',
+ type:'confirm-error',
+ text:msg,
+ callback:function(result){
+ if (result){
+ delete_preinvoice(row['id'])
+ }
+ }
+ })
+}
+
+
+function refacturar_preinvoice(id){
+ $$('tv_invoice').getTabbar().setValue('Generar')
+}
+
+
+function cmd_facturar_preinvoice_click(id, e, node){
+ var grid = $$('grid_preinvoices')
+
+ if(grid.count() == 0){
+ return
+ }
+
+ var row = grid.getSelectedItem()
+ if (row == undefined){
+ msg_error('Selecciona una prefactura')
+ return
+ }
+
+ var msg = '¿Estás seguro de facturar la siguiente PREFactura?
'
+ msg += '(' + row['folio'] + ') ' + row['cliente']
+ webix.confirm({
+ title: 'Generar Factura',
+ ok: 'Si',
+ cancel: 'No',
+ type: 'confirm-error',
+ text: msg,
+ callback:function(result){
+ if (result){
+ refacturar_preinvoice(row['id'])
+ }
+ }
+ })
+}
+
+
+function enviar_prefactura(id){
+ msg = '¿Estás seguro de enviar por correo esta prefactura?'
+ webix.confirm({
+ title: 'Enviar Factura',
+ ok: 'Si',
+ cancel: 'No',
+ type: 'confirm-error',
+ text: msg,
+ callback:function(result){
+ if(result){
+ webix.ajax().post('/values/enviarprefac', {'id': id}, {
+ 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_sucess(values.msg)
+ }else{
+ msg_error(values.msg)
+ }
+ }
+ })
+ }
+ }
+ })
+}
+
+
+function grid_preinvoices_click(id, e, node){
+ var row = this.getItem(id)
+
+ if(id.column == 'pdf'){
+ location = '/doc/pdf2/' + row.id
+ }else if(id.column == 'email'){
+ enviar_prefactura(row.id)
+ }
+
+}
diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js
index db3c2b8..449a9f0 100644
--- a/source/static/js/controller/main.js
+++ b/source/static/js/controller/main.js
@@ -53,6 +53,14 @@ var controllers = {
$$('filter_dates').attachEvent('onChange', filter_dates_change)
$$('cmd_prefactura').attachEvent('onItemClick', cmd_prefactura_click)
$$('lst_metodo_pago').attachEvent('onChange', lst_metodo_pago_change)
+
+ var tb_invoice = $$('tv_invoice').getTabbar()
+ tb_invoice.attachEvent('onChange', tb_invoice_change)
+ $$('prefilter_year').attachEvent('onChange', prefilter_year_change)
+ $$('prefilter_month').attachEvent('onChange', prefilter_month_change)
+ $$('cmd_delete_preinvoice').attachEvent('onItemClick', cmd_delete_preinvoice_click)
+ $$('cmd_facturar_preinvoice').attachEvent('onItemClick', cmd_facturar_preinvoice_click)
+ $$('grid_preinvoices').attachEvent('onItemClick', grid_preinvoices_click)
}
}
@@ -110,20 +118,29 @@ function menu_user_click(id, e, node){
function current_dates(){
var fy = $$('filter_year')
var fm = $$('filter_month')
+ var pfy = $$('prefilter_year')
+ var pfm = $$('prefilter_month')
var d = new Date()
fy.blockEvent()
fm.blockEvent()
+ pfy.blockEvent()
+ pfm.blockEvent()
fm.setValue(d.getMonth() + 1)
+ pfm.setValue(d.getMonth() + 1)
webix.ajax().sync().get('/values/filteryears', function(text, data){
var values = data.json()
- fy.getList().parse(values)
+ fy.getList().parse(values[0])
+ pfy.getList().parse(values[1])
fy.setValue(d.getFullYear())
+ pfy.setValue(d.getFullYear())
})
fy.unblockEvent()
fm.unblockEvent()
+ pfy.unblockEvent()
+ pfm.unblockEvent()
}
diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js
index 02f5600..e98e36d 100644
--- a/source/static/js/ui/invoices.js
+++ b/source/static/js/ui/invoices.js
@@ -310,7 +310,15 @@ var controls_generate = [
{view: "button", id: 'cmd_prefactura', label: "PreFactura",
type: "form", autowidth: true, align:"center"},
{}]
- }
+ },
+ {rows: [
+ {template:"", type: "section" },
+ {margin: 10, cols: [{},
+ {view: 'button', id: 'cmd_close_invoice', label: 'Cancelar',
+ type: 'danger', autowidth: true, align: 'center'}
+ ]
+ },
+ ]}
]
@@ -355,6 +363,7 @@ var grid_preinvoices = {
adjust: true,
footer: true,
resizeColumn: true,
+ autoheight: true,
headermenu: true,
columns: grid_preinvoices_cols,
}
@@ -370,25 +379,19 @@ var controls_prefactura = [
var controls_invoices = [
{
view: 'tabview',
+ id: 'tv_invoice',
tabbar: {options: ['Generar', 'PreFacturas']}, animate: true,
cells: [
{id: 'Generar', rows: controls_generate},
{id: 'PreFacturas', rows: controls_prefactura},
]
},
- {rows: [
- {template:"", type: "section" },
- {margin: 10, cols: [{},
- {view: 'button', id: 'cmd_close_invoice', label: 'Cancelar',
- type: 'danger', autowidth: true, align: 'center'}
- ]
- },
- ]}
]
var form_invoice = {
type: 'space',
+ responsive: true,
cols: [{
view: 'form',
id: 'form_invoice',