diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 7fe8bff..12dbe98 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -100,7 +100,7 @@ def get_sat_key(table, key): def now(): - return datetime.datetime.now() + return datetime.datetime.now().replace(microsecond=0) def get_token(): diff --git a/source/app/models/db.py b/source/app/models/db.py index 80fac0d..102bab4 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -18,7 +18,7 @@ class StorageEngine(object): return main.get_cp(values['cp']) def _get_formapago(self, values): - return main.SATFormaPago.get_activos() + return main.SATFormaPago.get_activos(values) def _get_categorias(self, values): return main.Categorias.get_all() @@ -45,7 +45,7 @@ class StorageEngine(object): return main.Emisor.get_regimenes() def _get_usocfdi(self, values): - return main.SATUsoCfdi.get_activos() + return main.SATUsoCfdi.get_activos(values) def delete(self, table, id): if table == 'partner': @@ -89,6 +89,8 @@ class StorageEngine(object): def get_invoices(self, values): return main.Facturas.get_(values) + def _get_timbrar(self, values): + return main.Facturas.timbrar(int(values['id'])) diff --git a/source/app/models/main.py b/source/app/models/main.py index aaf4ac3..fb93947 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -122,6 +122,7 @@ class SATRegimenes(BaseModel): class Emisor(BaseModel): rfc = TextField(index=True) nombre = TextField() + nombre_comercial = TextField() calle = TextField(default='') no_exterior = TextField(default='') no_interior = TextField(default='') @@ -174,7 +175,7 @@ class Certificado(BaseModel): class Folios(BaseModel): - serie = TextField() + serie = TextField(unique=True) inicio = IntegerField(default=1) default = BooleanField(default=False) usar_con = TextField(default='') @@ -262,11 +263,12 @@ class SATFormaPago(BaseModel): ) @classmethod - def get_activos(cls): + def get_activos(cls, values): + field = SATFormaPago.id + if values: + field = SATFormaPago.key.alias('id') rows = (SATFormaPago - .select( - SATFormaPago.key.alias('id'), - SATFormaPago.name.alias('value')) + .select(field, SATFormaPago.name.alias('value')) .where(SATFormaPago.activo==True) .dicts() ) @@ -346,10 +348,13 @@ class SATUsoCfdi(BaseModel): ) @classmethod - def get_activos(cls): + def get_activos(cls, values): + field = SATUsoCfdi.id + if values: + field = SATUsoCfdi.key.alias('id') rows = (SATUsoCfdi .select( - SATUsoCfdi.key.alias('id'), + field, SATUsoCfdi.name.alias('value'), SATUsoCfdi.fisica, SATUsoCfdi.moral, @@ -416,6 +421,7 @@ class Socios(BaseModel): fields['rfc'] = fields['rfc'].upper() fields['nombre'] = util.spaces(fields['nombre']) fields['slug'] = util.to_slug(fields['nombre']) + fields['uso_cfdi'] = fields.pop('uso_cfdi_socio') fb = ('dias_habiles', 'es_activo', 'es_cliente', 'es_proveedor', 'es_ong') for name in fb: @@ -427,6 +433,7 @@ class Socios(BaseModel): if values: id = int(values['id']) row = Socios.select().where(Socios.id==id).dicts()[0] + row['uso_cfdi_socio'] = row.pop('uso_cfdi') return row rows = Socios.select(Socios.id, Socios.rfc, Socios.nombre).dicts() @@ -438,7 +445,11 @@ class Socios(BaseModel): if id: row = (Socios .select( - Socios.id, Socios.nombre, Socios.rfc) + Socios.id, Socios.nombre, Socios.rfc, + SATFormaPago.key.alias('forma_pago'), + SATUsoCfdi.key.alias('uso_cfdi')) + .join(SATFormaPago).switch(Socios) + .join(SATUsoCfdi).switch(Socios) .where( (Socios.id==id) & (Socios.es_cliente==True)) .dicts() @@ -450,7 +461,11 @@ class Socios(BaseModel): name = values.get('name', '') if name: rows = (Socios - .select(Socios.id, Socios.nombre, Socios.rfc) + .select(Socios.id, Socios.nombre, Socios.rfc, + SATFormaPago.key.alias('forma_pago'), + SATUsoCfdi.key.alias('uso_cfdi')) + .join(SATFormaPago).switch(Socios) + .join(SATUsoCfdi).switch(Socios) .where((Socios.es_cliente==True) & (Socios.rfc.contains(name) | Socios.nombre.contains(name))) @@ -561,11 +576,15 @@ class Productos(BaseModel): name = values.get('name', '') if name: - rows = (Products - .select(Products.id, Products.key, Products.description, - SATUnidades.name.alias('unit'), Products.price) - .join(SATUnidades).switch(Products) - .where(Products.description.contains(name)).dicts()) + rows = (Productos + .select( + Productos.id, Productos.clave, Productos.descripcion, + SATUnidades.name.alias('unidad'), Productos.valor_unitario) + .join(SATUnidades) + .switch(Productos) + .where(Productos.descripcion.contains(name)) + .dicts() + ) return tuple(rows) return {'ok': False} @@ -846,10 +865,156 @@ class Facturas(BaseModel): obj.total_mn = totals['total_mn'] obj.save() - #~ obj.xml = self._make_xml(obj, emisor) - #~ obj.save() - msg = 'Factura guardada correctamente. Enviando a timbrar' + row = { + 'id': obj.id, + 'serie': obj.serie, + 'folio': obj.folio, + 'uuid': obj.uuid, + 'fecha': obj.fecha, + 'tipo_comprobante': obj.tipo_comprobante, + 'estatus': obj.estatus, + 'total_mn': obj.total_mn, + 'cliente': obj.cliente.nombre, + } + data = {'ok': True, 'row': row, 'new': True, 'error': False, 'msg': msg} + return data + + def _make_xml(self, invoice): + emisor = Emisor.select()[0] + certificado = Certificado.select()[0] + comprobante = {} + if invoice.serie: + comprobante['Serie'] = invoice.serie + if invoice.condiciones_pago: + comprobante['CondicionesDePago'] = invoice.condiciones_pago + if invoice.descuento: + comprobante['Descuento'] = invoice.descuento + + comprobante['Folio'] = str(invoice.folio) + comprobante['Fecha'] = invoice.fecha.isoformat()[:19] + comprobante['FormaPago'] = invoice.forma_pago + comprobante['NoCertificado'] = certificado.serie + comprobante['Certificado'] = certificado.cer_txt + comprobante['SubTotal'] = FORMAT.format(invoice.subtotal) + comprobante['Moneda'] = invoice.moneda + comprobante['TipoCambio'] = '1' + if comprobante['Moneda'] != 'MXN': + comprobante['TipoCambio'] = FORMAT.format(invoice.tipo_cambio) + comprobante['Total'] = FORMAT.format(invoice.total) + comprobante['TipoDeComprobante'] = invoice.tipo_comprobante + comprobante['MetodoPago'] = invoice.metodo_pago + comprobante['LugarExpedicion'] = invoice.lugar_expedicion + + emisor = { + 'Rfc': emisor.rfc, + 'Nombre': emisor.nombre, + 'RegimenFiscal': invoice.regimen_fiscal, + } + + receptor = { + 'Rfc': invoice.cliente.rfc, + 'Nombre': invoice.cliente.name, + 'UsoCFDI': invoice.uso_cfdi, + } + + conceptos = [] + rows = Details.select().where(Details.invoice==invoice) + for row in rows: + concepto = { + 'ClaveProdServ': row.product.key_sat, + 'NoIdentificacion': row.product.key, + 'Cantidad': FORMAT.format(row.cant), + 'ClaveUnidad': row.product.unit.key, + 'Unidad': row.product.unit.name, + 'Descripcion': row.product.description, + 'ValorUnitario': FORMAT.format(row.price), + 'Importe': FORMAT.format(row.importe), + } + + taxes = {} + traslados = [] + retenciones = [] + + impuestos = (ProductsTaxes + .select() + .where(ProductsTaxes.product==row.product)) + + for impuesto in impuestos: + if impuesto.tax.tipo == 'E': + continue + import_tax = round(impuesto.tax.tasa * row.importe, 2) + tipo_factor = 'Tasa' + if impuesto.tax.factor != 'T': + tipo_factor = 'Cuota' + tax = { + "Base": FORMAT.format(row.importe), + "Impuesto": impuesto.tax.key, + "TipoFactor": tipo_factor, + "TasaOCuota": str(impuesto.tax.tasa), + "Importe": FORMAT.format(import_tax), + } + if impuesto.tax.tipo == 'T': + traslados.append(tax) + else: + retenciones.append(tax) + + taxes['traslados'] = traslados + taxes['retenciones'] = retenciones + concepto['impuestos'] = taxes + conceptos.append(concepto) + + impuestos = {} + traslados = [] + retenciones = [] + if not invoice.total_trasladados is None: + impuestos['TotalImpuestosTrasladados'] = \ + FORMAT.format(invoice.total_trasladados) + if not invoice.total_retenciones is None: + impuestos['TotalImpuestosRetenidos'] = \ + FORMAT.format(invoice.total_retenciones) + + taxes = (InvoicesTaxes + .select() + .where(InvoicesTaxes.invoice==invoice)) + for tax in taxes: + tipo_factor = 'Tasa' + if tax.tax.factor != 'T': + tipo_factor = 'Cuota' + if tax.tax.tipo == 'T': + traslado = { + "Impuesto": tax.tax.key, + "TipoFactor": tipo_factor, + "TasaOCuota": str(tax.tax.tasa), + "Importe": FORMAT.format(tax.importe), + } + traslados.append(traslado) + else: + retencion = { + "Impuesto": tax.tax.key, + "Importe": FORMAT.format(tax.importe), + } + retenciones.append(retencion) + + impuestos['traslados'] = traslados + impuestos['retenciones'] = retenciones + + data = { + 'comprobante': comprobante, + 'emisor': emisor, + 'receptor': receptor, + 'conceptos': conceptos, + 'impuestos': impuestos, + } + return util.make_xml(data, certificado) + + @classmethod + def timbrar(cls, id): + obj = Facturas.get(Facturas.id == id) + obj.xml = cls._make_xml(cls, obj) + obj.estatus = 'Generada' + obj.save() + #~ error = False #~ result = util.timbra_xml(obj.xml) #~ if result['ok']: @@ -864,20 +1029,7 @@ class Facturas(BaseModel): #~ obj.estatus = 'Error' #~ obj.error = msg #~ obj.save() - - row = { - 'id': obj.id, - 'serie': obj.serie, - 'folio': obj.folio, - 'uuid': obj.uuid, - 'fecha': obj.fecha, - 'tipo_comprobante': obj.tipo_comprobante, - 'estatus': obj.estatus, - 'total_mn': obj.total_mn, - 'cliente': obj.cliente.nombre, - } - data = {'ok': True, 'row': row, 'new': True, 'error': False, 'msg': msg} - return data + return class FacturasDetalle(BaseModel): diff --git a/source/static/js/controller/admin.js b/source/static/js/controller/admin.js index def8b71..ae942b7 100644 --- a/source/static/js/controller/admin.js +++ b/source/static/js/controller/admin.js @@ -1,4 +1,5 @@ - +var reg = /^[a-z]+$/i +//~ reg.test("somethingELSE") var controllers = { init: function(){ diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js index 1a243ad..5ee58a7 100644 --- a/source/static/js/controller/invoices.js +++ b/source/static/js/controller/invoices.js @@ -25,11 +25,11 @@ function get_series(){ function get_forma_pago(){ - webix.ajax().get('/values/formapago', function(text, data){ + webix.ajax().get('/values/formapago', {key: true}, function(text, data){ var values = data.json() - pre = values[0] + //~ pre = values[0] $$('lst_forma_pago').getList().parse(values) - $$('lst_forma_pago').setValue(pre.id) + //~ $$('lst_forma_pago').setValue(pre.id) }) } @@ -49,9 +49,9 @@ function get_monedas(){ function get_uso_cfdi(){ - query = table_usocfdi.chain().find({fisica: true}).data() + get_uso_cfdi_to_table({key: true}) + query = table_usocfdi.chain().data() $$('lst_uso_cfdi').getList().parse(query) - $$('lst_uso_cfdi').setValue(query[0].id) } @@ -168,6 +168,22 @@ function validate_invoice(values){ return false } + var uso_cfdi = $$('lst_uso_cfdi').getValue() + if(uso_cfdi.trim() == ""){ + webix.UIManager.setFocus('lst_uso_cfdi') + msg = 'El Uso del CFDI es requerido' + msg_error(msg) + return false + } + + var forma_pago = $$('lst_forma_pago').getValue() + if(forma_pago.trim() == ""){ + webix.UIManager.setFocus('lst_forma_pago') + msg = 'La Forma de pago es requerida' + msg_error(msg) + return false + } + var tipo_cambio = $$('txt_tipo_cambio').getValue() if(tipo_cambio.trim() == ""){ webix.UIManager.setFocus('txt_tipo_cambio') @@ -198,6 +214,7 @@ function validate_invoice(values){ return false } + return true } @@ -210,6 +227,22 @@ function update_grid_invoices(values){ } } +function send_timbrar(id){ + webix.ajax().get('/values/timbrar', {id: id}, function(text, data){ + var values = data.json() + if(values.ok){ + msg_sucess(values.msg) + }else{ + webix.alert({ + title: 'Error al Timbrar', + text: values.msg, + type: 'alert-error' + }) + } + }) + +} + function save_invoice(data){ var result = false @@ -224,6 +257,7 @@ function save_invoice(data){ values = data.json(); if(values.ok){ update_grid_invoices(values) + send_timbrar(values.row['id']) result = true }else{ webix.message({type:'error', text:values.msg}) @@ -239,16 +273,6 @@ function save_invoice(data){ } - if(values.error){ - webix.alert({ - title: 'Error al Timbrar', - text: values.msg, - type: 'alert-error' - }) - }else{ - msg_sucess(values.msg) - } - return result } @@ -327,9 +351,9 @@ function search_client_by_id(id){ function set_client(row){ var form = $$('form_invoice') var html = '' - form.setValues({ - id_partner:row.id, search_client_id:'', search_client_name:''}, true) + id_partner:row.id, search_client_id:'', search_client_name:'', + forma_pago: row.forma_pago, uso_cfdi: row.uso_cfdi}, true) html += row.nombre + ' (' + row.rfc + ')' $$('lbl_client').setValue(html) form.focus('search_product_id') diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js index c6b083d..c44d63b 100644 --- a/source/static/js/controller/main.js +++ b/source/static/js/controller/main.js @@ -42,16 +42,13 @@ var controllers = { $$('grid_details').attachEvent('onHeaderClick', grid_details_header_click) $$('grid_details').attachEvent('onBeforeEditStart', grid_details_before_edit_start) $$('grid_details').attachEvent('onBeforeEditStop', grid_details_before_edit_stop) - - get_uso_cfdi_to_table() } } -function get_uso_cfdi_to_table(){ - webix.ajax().get('/values/usocfdi', function(text, data){ +function get_uso_cfdi_to_table(args){ + webix.ajax().sync().get('/values/usocfdi', args, function(text, data){ var values = data.json() - pre = values[0] table_usocfdi.clear() table_usocfdi.insert(values) }) diff --git a/source/static/js/controller/partners.js b/source/static/js/controller/partners.js index d9ba384..284e972 100644 --- a/source/static/js/controller/partners.js +++ b/source/static/js/controller/partners.js @@ -8,9 +8,9 @@ function cmd_new_partner_click(id, e, node){ $$('multi_partners').setValue('partners_new') $$('tab_partner').setValue('Datos Fiscales') + get_uso_cfdi_to_table({}) query = table_usocfdi.chain().find({fisica: true}).data() $$('lst_uso_cfdi_socio').getList().parse(query) - } @@ -30,14 +30,24 @@ function cmd_edit_partner_click(id, e, node){ return } - webix.ajax().get("/partners", {id:row['id']}, { + webix.ajax().get("/partners", {id: row['id']}, { error: function(text, data, xhr) { webix.message({type:"error", text: "Error al consultar"}) }, success: function(text, data, xhr){ - var values = data.json(); + var values = data.json() $$('form_partner').setValues(values) $$('forma_pago').getList().load('/values/formapago') + + get_uso_cfdi_to_table({}) + if(values.tipo_persona == 1){ + query = table_usocfdi.chain().find({fisica: true}).data() + }else if(values.tipo_persona == 2){ + query = table_usocfdi.chain().find({moral: true}).data() + }else{ + query = [{id: 'P01', value: 'Por definir'}] + } + $$('lst_uso_cfdi_socio').getList().parse(query) } }) diff --git a/source/static/js/ui/admin.js b/source/static/js/ui/admin.js index 71f3a8c..30e89cc 100644 --- a/source/static/js/ui/admin.js +++ b/source/static/js/ui/admin.js @@ -2,7 +2,7 @@ var menu_data = [ {id: 'app_home', icon: 'dashboard', value: 'Inicio'}, {id: 'app_emisor', icon: 'user-circle', value: 'Emisor'}, - {id: 'app_cert', icon: 'key', value: 'Certificado'}, + {id: 'app_folios', icon: 'sort-numeric-asc', value: 'Folios'}, ] @@ -18,7 +18,250 @@ var sidebar = { $$('multi').setValue(id) } } -}; +} + + +var emisor_datos_fiscales = [ + {template: 'Datos SAT', type: 'section'}, + {cols: [{view: 'text', id: 'emisor_rfc', name: 'emisor_rfc', label: 'RFC: ', + width: 300, required: true, invalidMessage: 'RFC inválido', + readonly: true, attributes: {maxlength: 13}}, {}]}, + {view: 'text', id: 'emisor_nombre', name: 'emisor_nombre', + label: 'Razón Social: ', required: true, + invalidMessage: 'La Razón Social es requerida'}, + {cols: [ + {view: 'search', id: 'emisor_cp', name: 'emisor_cp', width: 300, + label: 'C.P.: ', required: true, attributes: {maxlength: 5}}, + {view: 'text', id: 'emisor_cp2', name: 'emisor_cp2', width: 300, + label: 'C.P. de Expedición: ', attributes: {maxlength: 5}}, + {}]}, + {cols: [ + {view: 'label', label: 'Regimenes Fiscales *', required: true}, {}]}, + {cols: [{view: 'list', id: 'lst_emisor_regimen', select: 'multiselect', + name: 'lst_emisor_regimen', width: 600, height: 100, required: true, + data: []}, {}]}, + {template: 'Dirección Fiscal', type: 'section'}, + {view: 'text', id: 'emisor_calle', name: 'emisor_calle', label: 'Calle: '}, + {cols: [{view: 'text', id: 'emisor_no_exterior', name: 'emisor_no_exterior', + width: 300, label: 'No Exterior: '},{}]}, + {cols: [{view: 'text', id: 'emisor_no_interior', name: 'emisor_no_interior', + width: 300, label: 'No Interior: '},{}]}, + {view: 'text', id: 'emisor_colonia', name: 'emisor_colonia', + label: 'Colonia: '}, + {view: 'text', id: 'emisor_municipio', name: 'emisor_municipio', + label: 'Municipio: '}, + {view: 'text', id: 'emisor_estado', name: 'emisor_estado', + label: 'Estado: '}, + {view: 'text', id: 'emisor_pais', name: 'emisor_pais', label: 'País: ', + value: 'México', readonly: true}, + {template: '', type: 'section', minHeight: 25}, +] + + +var emisor_otros_datos= [ + {template: 'Generales', type: 'section'}, + {view: 'text', id: 'emisor_nombre_comercial', + name: 'emisor_nombre_comercial', label: 'Nombre comercial: '}, + {view: 'text', id: 'emisor_telefono', name: 'emisor_telefono', + label: 'Teléfonos: '}, + {view: 'text', id: 'emisor_correo', name: 'emisor_correo', + label: 'Correos: '}, + {view: 'text', id: 'emisor_web', name: 'emisor_web', + label: 'Página Web: '}, + {template: 'Escuela', type: 'section'}, + {cols: [{view: 'checkbox', id: 'chk_escuela', name: 'es_escuela', + label: 'Es Escuela'}, + {view: 'button', id: 'cmd_niveles', label: 'Niveles', type: 'form', + align: 'center', autowidth: true, disabled: true}, {}, {}]}, + {template: 'ONG', type: 'section'}, + {view: 'checkbox', id: 'chk_ong', name: 'es_ong', label: 'Es ONG'}, + {cols: [{view: 'text', id: 'ong_autorizacion', name: 'ong_autorizacion', + label: 'Autorización: ', disabled: true, + placeholder: 'Número de autorización del SAT'}, {}]}, + {cols: [{view: 'datepicker', id: 'ong_fecha', name: 'ong_fecha', + label: 'Fecha de Autorización: ', disabled: true, + placeholder: 'Fecha de autorización en el SAT'}, {}]}, + {cols: [{view: 'datepicker', id: 'ong_fecha_dof', name: 'ong_fecha_dof', + label: 'Fecha de DOF: ', disabled: true, + placeholder: 'Fecha de publicación en el DOF'}, {}]}, +] + + +var emisor_certificado = [ + {template: 'Certificado actual', type: 'section'}, + {view: 'form', id: 'form_cert', rows: [ + {cols: [{view: 'text', id: 'cert_rfc', name: 'cert_rfc', + label: 'RFC: ', readonly: true, placeholder: 'Ninguno'}, {}]}, + {cols: [{view: 'text', id: 'cert_serie', name: 'cert_serie', + label: 'Serie: ', readonly: true, placeholder: 'Ninguno'}, {}]}, + {cols: [{view: 'text', id: 'cert_desde', name: 'cert_desde', + label: 'Vigente desde: ', readonly: true}, {}]}, + {cols: [{view: 'text', id: 'cert_hasta', name: 'cert_hasta', + label: 'Vigente hasta: ', readonly: true}, {}]}, + ]}, + {template: 'Cargar Certificado', type: 'section'}, + {view: 'form', id: 'form_upload', rows: [ + {cols: [{}, + {view: 'uploader', id: 'up_cert', autosend:false, link: 'lst_cert', + value: 'Seleccionar certificado', upload: '/values/cert'}, {}]}, + {cols: [{}, + {view: 'list', id: 'lst_cert', type: 'uploader', autoheight:true, + borderless: true}, {}]}, + {cols: [{}, + {view: 'text', id: 'txt_contra', label: 'Contraseña KEY', + labelPosition: 'top', labelAlign: 'center', type: 'password', + required: true}, {}]}, + {cols: [{}, {view: 'button', id: 'cmd_subir_certificado', + label: 'Subir certificado'}, {}]}, + ]}, +] + + +var controls_emisor = [ + { + view: 'tabview', + id: 'tab_emisor', + tabbar: {options: [ + 'Datos Fiscales', + 'Otros Datos', + 'Certificado']}, + animate: true, + cells: [ + {id: 'Datos Fiscales', rows: emisor_datos_fiscales}, + {id: 'Otros Datos', rows: emisor_otros_datos}, + {id: 'Certificado', rows: emisor_certificado}, + {}, + ] + } +] + + +var form_emisor = { + type: 'space', + cols: [{ + view: 'form', + id: 'form_emisor', + complexData: true, + elements: controls_emisor, + elementsConfig: { + labelWidth: 150, + labelAlign: 'right' + }, + autoheight: true, + rules: { + emisor_nombre: function(value){return value.trim() != ''}, + } + }] +} + + +var options_usarcon = [ + {id: 'S', value: 'Todos'}, + {id: 'I', value: 'Ingreso'}, + {id: 'E', value: 'Egreso'}, + {id: 'T', value: 'Traslado'}, +] + + +var grid_folios_cols = [ + {id: 'delete', header: '', width: 30, css: 'delete'}, + {id: 'serie', header: 'Serie', fillspace: 1}, + {id: 'inicio', header: 'Inicio', fillspace: 1}, + {id: 'usarcon', header: 'Usar Con', fillspace: 1}, + {id: 'default', header: 'Predeterminado', fillspace: 1} +] + + +var grid_folios = { + view: 'datatable', + id: 'grid_folios', + select: 'row', + adjust: true, + headermenu: true, + columns: grid_folios_cols +} + + +var emisor_folios = [ + {template: 'Nueva serie', type: 'section'}, + {cols: [ + {view: 'text', id: 'folio_serie', name: 'folio_serie', label: 'Serie: ', + required: true, attributes: {maxlength: 15}}, + {view: 'counter', id: 'folio_inicio', name: 'folio_inicio', value: 1, + required: true, label: 'Inicio: ', step: 5, min: 1}, + {view: 'richselect', id: 'folio_usarcon', name: 'folio_usarcon', + label: 'Usar Con: ', value: 'S', required: true, + options: options_usarcon}, + ]}, + {maxHeight: 20}, + {cols: [{}, + {view: 'button', id: 'cmd_agregar_serie', label: 'Agregar Serie', + autowidth: true, type: 'form'}, + {}]}, + {template: 'Series guardadas', type: 'section'}, + grid_folios +] + + +var controls_folios = [ + { + view: 'tabview', + id: 'tab_folios', + tabbar: {options: ['Folios']}, + animate: true, + cells: [ + {id: 'Folios', rows: emisor_folios}, + {}, + ] + } +] + + +var form_folios = { + type: 'space', + cols: [{ + view: 'form', + id: 'form_folios', + complexData: true, + elements: controls_folios, + elementsConfig: { + labelWidth: 100, + labelAlign: 'right' + }, + autoheight: true, + rules: { + serie: function(value){return value.trim() != ''}, + } + }] +} + + +var app_emisor = { + id: 'app_emisor', + rows:[ + {view: 'template', id: 'th_emisor', type: 'header', + template: 'Emisor'}, + form_emisor, + {maxHeight: 20}, + {margin: 10, cols: [{}, + {view: 'button', id: 'cmd_save_emisor', label: 'Guardar' , + type: 'form', autowidth: true, align: 'center'}, + {}] + }, + {}, + ] +} + + +var app_folios = { + id: 'app_folios', + rows:[ + {view: 'template', id: 'th_folios', type: 'header', + template: 'Folios'}, + form_folios, + {}, + ] +} var multi_main = { @@ -29,10 +272,11 @@ var multi_main = { id: 'app_home', view: 'template', template: 'HOME' - } - //~ app_emisor, + }, + app_emisor, + app_folios, ] -}; +} var menu_user = { diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js index 10ffb09..528e13f 100644 --- a/source/static/js/ui/invoices.js +++ b/source/static/js/ui/invoices.js @@ -109,7 +109,10 @@ var suggest_partners = { columns: [ {id: 'id', hidden: true}, {id: 'nombre', adjust: 'data'}, - {id: 'rfc', 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) @@ -129,10 +132,11 @@ var suggest_products = { header: true, columns: [ {id: 'id', hidden: true}, - {id: 'key', adjust: 'data'}, - {id: 'description', adjust: 'data'}, - {id: 'unit', adjust: 'data'}, - {id: 'price', adjust: 'data', format: webix.i18n.priceFormat} + {id: 'clave', adjust: 'data'}, + {id: 'descripcion', adjust: 'data'}, + {id: 'unidad', adjust: 'data'}, + {id: 'valor_unitario', adjust: 'data', + format: webix.i18n.priceFormat} ], dataFeed:function(text){ if (text.length > 2){ @@ -145,35 +149,31 @@ var suggest_products = { } -var body_comprobante = {cols: [ - { - view: 'richselect', - id: 'lst_tipo_comprobante', - label: 'Tipo', - labelPosition: 'top', - required: true, - value: 'I', - options: [ - {id: 'I', value: 'Ingreso'}, - {id: 'E', value: 'Egreso'}, - {id: 'T', value: 'Traslado'} - ] - }, - { - view: 'richselect', - id: 'lst_serie', - label: 'Serie', - labelPosition: 'top', - options: [], - //~ options: '/values/series', - //~ on: { - //~ onAfterRender: webix.once(function(){ - //~ this.getPopup().getList().waitData.then(webix.bind(function(){ - //~ this.setValue(this.getPopup().getList().getFirstId()) - //~ }, this)) - //~ }), - //~ } - } +var body_comprobante = {rows: [{ + cols: [ + { + view: 'richselect', + id: 'lst_tipo_comprobante', + label: 'Tipo', + labelPosition: 'top', + required: true, + value: 'I', + options: [ + {id: 'I', value: 'Ingreso'}, + {id: 'E', value: 'Egreso'}, + {id: 'T', value: 'Traslado'} + ] + }, + { + view: 'richselect', + id: 'lst_serie', + label: 'Serie', + labelPosition: 'top', + options: [], + }, + ]}, + {view: 'richselect', id: 'lst_uso_cfdi', name: 'uso_cfdi', required: true, + labelPosition: 'top', label: 'Uso del CFDI', options: []}, ]} @@ -184,8 +184,9 @@ var opt_metodo_pago = [ var body_opciones = {rows: [ - {view: 'richselect', id: 'lst_forma_pago', label: 'Forma de Pago', - labelPosition: 'top', required: true, options: []}, + {view: 'richselect', id: 'lst_forma_pago', name: 'forma_pago', + label: 'Forma de Pago', labelPosition: 'top', required: true, + options: []}, {view: 'richselect', id: 'lst_metodo_pago', label: 'Método de Pago', labelPosition: 'top', options: opt_metodo_pago, readonly: true, value: 'PUE', @@ -205,14 +206,6 @@ var body_moneda = {cols: [ ]} -var body_uso_cfdi = { - view: 'richselect', - id: 'lst_uso_cfdi', - required: true, - options: [] -} - - var body_regimen_fiscal = { view: 'richselect', id: 'lst_regimen_fiscal', @@ -259,7 +252,6 @@ var controls_generate = [ {view: 'fieldset', label: 'Comprobante', body: body_comprobante}, {view: 'fieldset', label: 'Opciones de Pago', body: body_opciones}, {view: 'fieldset', id: 'fs_moneda', label: 'Moneda', body: body_moneda}, - {view: 'fieldset', label: 'Uso del CFDI', body: body_uso_cfdi}, {view: 'fieldset', id: 'fs_regimen_fiscal', label: 'Regimen Fiscal', body: body_regimen_fiscal}, ]} @@ -323,6 +315,6 @@ var app_invoices = { {view: "template", id: "th_invoices", type: "header", template:"Administración de Facturas" }, multi_invoices ] -}; +} diff --git a/source/static/js/ui/partners.js b/source/static/js/ui/partners.js index 472826d..9c031af 100644 --- a/source/static/js/ui/partners.js +++ b/source/static/js/ui/partners.js @@ -275,7 +275,7 @@ var controls_partner = [ {}] }, ]} -]; +] var form_partner = { @@ -295,7 +295,7 @@ var form_partner = { rfc: validate_rfc, } }] -}; +} var multi_partners = {