var query = [] var grid = null var msg = '' function get_series(){ webix.ajax().get('/values/series', function(text, data){ var values = data.json() table_series.clear() table_series.insert(values) pre = values[0] $$('lst_serie').getList().parse(values) $$('lst_serie').setValue(pre.id) if(pre.usar_con){ $$('lst_tipo_comprobante').setValue(pre.usar_con) $$('lst_tipo_comprobante').config.readonly = true $$('lst_tipo_comprobante').refresh() } if(values.length == 1){ $$('lst_serie').config.readonly = true $$('lst_serie').refresh() } }) } function get_forma_pago(){ webix.ajax().get('/values/formapago', {key: true}, function(text, data){ var values = data.json() //~ pre = values[0] $$('lst_forma_pago').getList().parse(values) //~ $$('lst_forma_pago').setValue(pre.id) }) } function get_monedas(){ webix.ajax().get('/values/monedas', function(text, data){ var values = data.json() pre = values[0] $$('lst_moneda').getList().parse(values) $$('lst_moneda').setValue(pre.id) if(values.length == 1){ $$('fs_moneda').hide() $$('fs_moneda').refresh() } }) } function get_uso_cfdi(){ get_uso_cfdi_to_table({key: true}) query = table_usocfdi.chain().data() $$('lst_uso_cfdi').getList().parse(query) } function get_regimen_fiscal(){ webix.ajax().get('/values/regimenes', function(text, data){ var values = data.json() pre = values[0] $$('lst_regimen_fiscal').getList().parse(values) $$('lst_regimen_fiscal').setValue(pre.id) if(values.length == 1){ $$('fs_regimen_fiscal').hide() $$('fs_regimen_fiscal').refresh() } }) } function default_config(){ webix.ajax().sync().get('/values/taxes', function(text, data){ var values = data.json() table_taxes.clear() table_taxes.insert(values) }) get_series() get_forma_pago() get_monedas() get_uso_cfdi() get_regimen_fiscal() table_pt.clear() table_totals.clear() } function cmd_new_invoice_click(id, e, node){ var form = $$('form_invoice') var grid_totals = $$('grid_totals') grid = $$('grid_details') default_config() 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}) $$('multi_invoices').setValue('invoices_new') form.focus('search_client_id') } function cmd_edit_invoice_click(id, e, node){ $$("multi_invoices").setValue("invoices_new") } function delete_invoice(id){ webix.ajax().del('/invoices', {id: id}, function(text, xml, xhr){ if(xhr.status == 200){ $$('grid_invoices').remove(id) msg_sucess('Factura eliminada correctamente') }else{ msg_error('No se pudo eliminar') } }) } function cmd_delete_invoice_click(id, e, node){ var row = $$('grid_invoices').getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if(!row['uuid']==null){ msg_error('Solo se pueden eliminar facturas sin timbrar') return } var msg = '¿Estás seguro de eliminar la siguiente Factura?

' msg += '(' + row['folio'] + ') ' + row['cliente'] msg += '

ESTA ACCIÓN NO SE PUEDE DESHACER' webix.confirm({ title:'Eliminar Factura', ok:'Si', cancel:'No', type:'confirm-error', text:msg, callback:function(result){ if (result){ delete_invoice(row['id']) } } }) } function validate_invoice(values){ if(values.id_partner == 0){ webix.UIManager.setFocus('search_client_name') msg = 'Selecciona un cliente' msg_error(msg) return false } if(!grid.count()){ webix.UIManager.setFocus('search_product_id') msg = 'Agrega al menos un producto o servicio' msg_error(msg) 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') msg = 'El Tipo de Cambio es requerido' msg_error(msg) return false } if(isNaN(tipo_cambio * 1)){ webix.UIManager.setFocus('txt_tipo_cambio') msg = 'El Tipo de Cambio debe ser un valor númerico' msg_error(msg) return false } var moneda = $$('lst_moneda').getValue() if(moneda == 'MXN' && tipo_cambio != 1){ webix.UIManager.setFocus('txt_tipo_cambio') msg = 'Si la moneda es MXN, el Tipo de Cambio debe ser 1.00' msg_error(msg) return false } if(moneda != 'MXN' && tipo_cambio == 1){ webix.UIManager.setFocus('txt_tipo_cambio') msg = 'Si la moneda no es MXN, el Tipo de Cambio debe ser diferente de 1.00' msg_error(msg) return false } return true } function update_grid_invoices(values){ if(values.new){ $$('grid_invoices').add(values.row) }else{ $$("grid_invoices").updateItem(values.row['id'], values.row) } } 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 var values = NaN webix.ajax().sync().post('invoices', 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){ update_grid_invoices(values) send_timbrar(values.row['id']) result = true }else{ webix.message({type:'error', text: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(); if(!form.validate()) { webix.message({type:'error', text:'Valores inválidos'}) return } var values = form.getValues(); if(!validate_invoice(values)){ return } var rows = grid.data.getRange() for (i = 0; i < rows.length; i++) { delete rows[i]['delete'] delete rows[i]['clave'] delete rows[i]['descripcion'] 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_invoice(data)){ return } form.setValues({id_partner: 0, lbl_partner: 'Ninguno'}) $$('multi_invoices').setValue('invoices_home') } function cmd_close_invoice_click(id, e, node){ $$('multi_invoices').setValue('invoices_home') } function search_client_by_id(id){ var msg = '' webix.ajax().get('/values/client', {'id': id}, { error: function(text, data, xhr) { webix.message({type: 'error', text: 'Error al consultar'}) }, success: function(text, data, xhr){ var values = data.json() if (values.ok){ set_client(values.row) }else{ msg = 'No se encontró un cliente con la clave: ' + id webix.message({type:'error', text: msg}) } } }) } function set_client(row){ var form = $$('form_invoice') var html = '' form.setValues({ 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') } function grid_clients_found_click(obj){ set_client(obj) } function search_client_id_key_press(code, e){ var value = this.getValue() if(code == 13 && value.length > 0){ var id = parseInt(value, 10) if (isNaN(id)){ webix.message({type:'error', text:'Captura una clave válida'}); }else{ search_client_by_id(id) } } } function calculate_taxes(){ var tmp = null table_totals.clear() var subtotal = 0 var total_iva = 0 var id = 2 var grid_totals = $$('grid_totals') grid_totals.clearAll() grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0}) grid.eachRow(function(row){ var product = grid.getItem(row) subtotal += parseFloat(product.importe) query = table_pt.chain().find({'product': product.id}).data() for(var tax of query){ tmp = table_totals.findOne({'tax': tax.tax}) if(tmp === null){ table_totals.insert( {'tax': tax.tax, 'importe': parseFloat(product.importe)}) tmp = table_totals.findOne({'tax': tax.tax}) }else{ tmp.importe += parseFloat(product.importe) table_totals.update(tmp) } } }) var tax = null var tipo = 'Traslado ' var concepto = '' var total_tax = 0 query = table_totals.chain().data() for(var t of query){ tax = table_taxes.findOne({'id': t.tax}) if(tax.tipo == 'E' || tax.tipo == 'R'){ continue } concepto = tipo + tax.name + ' (' + tax.tasa + ')' total_tax = (tax.tasa * t.importe).round(DECIMALES) grid_totals.add({id: id, concepto: concepto, importe: total_tax}) id += 1 if(tax.name == 'IVA'){ total_iva += total_tax } } tipo = 'Retención ' for(var t of query){ tax = table_taxes.findOne({'id': t.tax}) if(tax.tipo == 'E' || tax.tipo == 'T'){ continue } concepto = tipo + tax.name + ' (' + tax.tasa + ')' if(tax.tasa == (2/3).round(6)){ total_tax = (tax.tasa * total_iva * -1).round(DECIMALES) concepto = tipo + tax.name + ' (2/3)' }else{ total_tax = (tax.tasa * t.importe * -1).round(DECIMALES) } grid_totals.add({id: id, concepto: concepto, importe: total_tax}) id += 1 } var row = {importe: subtotal} grid_totals.updateItem(1, row) } function set_product(values){ var taxes = values.taxes var values = values.row var form = $$('form_invoice') var row = grid.getItem(values.id) values['delete'] = '-' if (row == undefined){ values['cantidad'] = 1 values['importe'] = values['valor_unitario'] grid.add(values) } else { values['cantidad'] = parseFloat(row.cantidad) + 1 values['importe'] = values['valor_unitario'] * values['cantidad'] grid.updateItem(row.id, values) } form.setValues({search_product_id:'', search_product_name:''}, true) for(var v of taxes){ var pt = table_pt.findOne(v) if(pt === null){ table_pt.insert(v) } } calculate_taxes() } function grid_products_found_click(obj){ search_product_by_id(obj.id) } function search_product_by_id(id){ var msg = '' webix.ajax().get('/values/product', {'id': id}, { error: function(text, data, xhr) { webix.message({type: 'error', text: 'Error al consultar'}) }, success: function(text, data, xhr){ var values = data.json() if (values.ok){ set_product(values) } else { msg = 'No se encontró un producto con la clave: ' + id webix.message({type: 'error', text: msg}) } } }) } function search_product_id_key_press(code, e){ var value = this.getValue() if(code == 13 && value.length > 0){ var id = parseInt(value, 10) if (isNaN(id)){ webix.message({type: 'error', text: 'Captura una clave válida'}); }else{ search_product_by_id(id) } } } function grid_details_before_edit_start(id){ var columns = ['', 'descripcion', 'cantidad', 'valor_unitario'] if(!columns.indexOf(id.column)){ return !this.getItem(id.row)[id.column] } } function grid_details_before_edit_stop(state, editor){ var row = grid.getItem(editor.row) if(editor.column == 'descripcion'){ if(!state.value.trim()){ msg = 'La descripción no puede estar vacía' webix.message({type:'error', text: msg}) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } state.value = state.value.trim() return true } if(editor.column == 'cantidad'){ var cantidad = parseFloat(state.value) if(isNaN(cantidad)){ msg = 'La cantidad debe ser un número' webix.message({type:'error', text: msg}) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } var valor_unitario = row['valor_unitario'] } if(editor.column == 'valor_unitario'){ var valor_unitario = parseFloat(state.value) if(isNaN(valor_unitario)){ msg = 'El valor unitario debe ser un número' webix.message({type:'error', text: msg}) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } var cantidad = row['cantidad'] } row['importe'] = (cantidad * valor_unitario).round(DECIMALES) grid.refresh() calculate_taxes() } function grid_details_click(id, e, node){ if(id.column != 'delete'){ return } grid.remove(id.row) calculate_taxes() } function grid_details_header_click(id){ if(id.column != 'delete'){ return } var msg = '¿Estás seguro de quitar todos los productos?' webix.confirm({ title: 'Quitar todos', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if (result){ grid.clearAll() calculate_taxes() } } }) }