//~ Empresa Libre //~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net) //~ //~ This program is free software: you can redistribute it and/or modify //~ it under the terms of the GNU General Public License as published by //~ the Free Software Foundation, either version 3 of the License, or //~ (at your option) any later version. //~ //~ This program is distributed in the hope that it will be useful, //~ but WITHOUT ANY WARRANTY; without even the implied warranty of //~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //~ GNU General Public License for more details. //~ //~ You should have received a copy of the GNU General Public License //~ along with this program. If not, see . var query = [] var grid = null var msg = '' var result = false var tipo_relacion = '' var anticipo = false var donativo = false var cfg_invoice = new Object() var values_comercioe = null function init_config_invoices(){ var multi_currency = get_config('multi_currency') var g = $$('grid_invoices') if(multi_currency){ g.showColumn('total') g.showColumn('currency') } } var invoices_controllers = { init: function(){ //~ Invoices $$('cmd_new_invoice').attachEvent("onItemClick", cmd_new_invoice_click) $$('cmd_refacturar').attachEvent("onItemClick", cmd_refacturar_click) $$('cmd_invoice_report_pdf').attachEvent('onItemClick', cmd_invoice_report_pdf_click) $$('cmd_invoice_report_xls').attachEvent('onItemClick', cmd_invoice_report_xls_click) $$('cmd_delete_invoice').attachEvent("onItemClick", cmd_delete_invoice_click) $$('cmd_timbrar').attachEvent('onItemClick', cmd_timbrar_click) $$('cmd_close_invoice').attachEvent('onItemClick', cmd_close_invoice_click) $$('search_client_id').attachEvent('onKeyPress', search_client_id_key_press) $$('grid_clients_found').attachEvent('onValueSuggest', grid_clients_found_click) $$('search_product_id').attachEvent('onKeyPress', search_product_id_key_press) $$('grid_products_found').attachEvent('onValueSuggest', grid_products_found_click) $$('grid_students_found').attachEvent('onValueSuggest', grid_students_found_click) $$('grid_details').attachEvent('onItemClick', grid_details_click) $$('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) $$('grid_details').attachEvent('onAfterEditStop', grid_details_after_edit_stop) $$('cmd_invoice_timbrar').attachEvent('onItemClick', cmd_invoice_timbrar_click) $$('cmd_invoice_sat').attachEvent('onItemClick', cmd_invoice_sat_click) $$('cmd_invoice_verify_sat').attachEvent('onItemClick', cmd_invoice_verify_sat_click) $$('cmd_invoice_ask_cancel').attachEvent('onItemClick', cmd_invoice_ask_cancel_click) $$('grid_invoices').attachEvent('onItemClick', grid_invoices_click) $$('grid_invoices').attachEvent('onSelectChange', grid_invoices_on_select_change) $$('grid_invoices').attachEvent('onHeaderClick', grid_invoices_on_header_click) $$('grid_invoices').attachEvent('onSubViewCreate', grid_invoices_on_subview_create) $$('filter_year').attachEvent('onChange', filter_year_change) $$('filter_month').attachEvent('onChange', filter_month_change) $$('filter_dates').attachEvent('onChange', filter_dates_change) $$('cmd_prefactura').attachEvent('onItemClick', cmd_prefactura_click) $$('cmd_preinvoice_generate_delete').attachEvent('onItemClick', cmd_preinvoice_generate_delete_click) $$('cmd_cfdi_relacionados').attachEvent('onItemClick', cmd_cfdi_relacionados_click) $$('lst_metodo_pago').attachEvent('onChange', lst_metodo_pago_change) $$('lst_moneda').attachEvent('onChange', lst_moneda_change) $$('lst_tipo_comprobante').attachEvent('onChange', lst_tipo_comprobante_change) $$('lst_serie').attachEvent('onChange', lst_serie_change) $$('txt_tipo_cambio').attachEvent('onBlur', txt_tipo_cambio_lost_focus) $$('cmd_cfdi_notes').attachEvent('onItemClick', cmd_cfdi_notes_click) $$('cmd_admin_invoice_notes').attachEvent('onItemClick', cmd_admin_invoice_notes_click) $$('cmd_import_invoice').attachEvent('onItemClick', cmd_import_invoice_click) $$('txt_folio_custom').attachEvent('onKeyPress', txt_folio_custom_key_press); $$('txt_folio_custom').attachEvent('onBlur', txt_folio_custom_lost_focus); $$('search_by').attachEvent('onKeyPress', search_by_key_press) $$('search_by').attachEvent('onItemClick', search_by_click) tv_invoice = $$('tv_invoice').getTabbar() tv_invoice.attachEvent('onChange', tv_invoice_change) $$('grid_carta_mercancias').attachEvent('onItemClick', grid_carta_mercancias_click) $$('grid_carta_ubicaciones').attachEvent('onBeforeEditStop', grid_carta_ubicaciones_before_edit_stop) $$('cmd_carta_add_product').attachEvent('onItemClick', cmd_carta_add_product_click) $$('cmd_carta_copy_from_invoice').attachEvent('onItemClick', cmd_carta_copy_from_invoice_click) $$('cmd_carta_import_json').attachEvent('onItemClick', cmd_carta_import_json_click) $$('cmd_import_json_comercioe').attachEvent('onItemClick', cmd_import_json_comercioe_click) webix.extend($$('grid_invoices'), webix.ProgressBar) init_config_invoices() focus('search_client_name') } } function get_condicion_pago(){ webix.ajax().get('/values/condicionespago', { error: function(text, data, xhr) { }, success: function(text, data, xhr) { var values = data.json(); $$('txt_condicion_pago').define('suggest', values) $$('txt_condicion_pago').refresh() } }) } function get_series(){ webix.ajax().sync().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.usarcon){ $$('lst_tipo_comprobante').setValue(pre.usarcon) $$('lst_tipo_comprobante').config.readonly = true $$('lst_tipo_comprobante').refresh() } if(values.length == 1){ $$('lst_serie').config.readonly = true $$('lst_serie').refresh() } }) } 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() } }) } 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() } }) } function validar_timbrar(){ webix.ajax().sync().get('/values/validartimbrar', function(text, data){ var values = data.json() if(!values.ok){ msg_error(values.msg) $$('cmd_timbrar').disable() }else{ if(values.msg){ msg_error(values.msg) } $$('cmd_timbrar').enable() } }) } 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('lst_forma_pago') get_monedas() get_uso_cfdi() get_regimen_fiscal() table_pt.clear() table_totals.clear() validar_timbrar() webix.ajax().sync().get('/values/configtimbrar', function(text, data){ var values = data.json() //~ showvar(values) show('chk_cfdi_anticipo', values.cfdi_anticipo) 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){ $$('tv_invoice').getTabbar().hideOption('INE') }else{ $$('tv_invoice').getTabbar().showOption('INE') } if(!values.cfdi_leyendasfiscales){ $$('tv_invoice').getTabbar().hideOption('Leyendas Fiscales') }else{ get_leyendas_fiscales() $$('tv_invoice').getTabbar().showOption('Leyendas Fiscales') } if(!values.cfdi_carta_porte){ $$('tv_invoice').getTabbar().hideOption('Carta Porte') }else{ $$('tv_invoice').getTabbar().showOption('Carta Porte') } if(!values.cfdi_comercioe){ $$('tv_invoice').getTabbar().hideOption('Comercio Exterior') }else{ $$('tv_invoice').getTabbar().showOption('Comercio Exterior') } cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales cfg_invoice['edu'] = values.cfdi_edu cfg_invoice['carta_porte'] = values.cfdi_carta_porte cfg_invoice['comercioe'] = values.cfdi_comercioe cfg_invoice['open_pdf'] = values.cfdi_open_pdf cfg_invoice['tax_locales'] = values.cfdi_tax_locales cfg_invoice['tax_decimals'] = values.cfdi_tax_decimals cfg_invoice['with_taxes'] = values.cfdi_with_taxes cfg_invoice['add_same_product'] = values.cfdi_add_same_product cfg_invoice['tax_locales_truncate'] = values.cfdi_tax_locales_truncate cfg_invoice['decimales_precios'] = get_config('decimales_precios') if(values.cfdi_show_pedimento){ $$('grid_details').showColumn('pedimento') } if(values.cfdi_edu){ $$('grid_details').showColumn('student') } show('fs_students', values.cfdi_edu) show('fs_divisas', values.cfdi_divisas) show('txt_folio_custom', values.cfdi_folio_custom) show('txt_total_cant', values.cfdi_show_total_cant) }) } function price_without_taxes(price, id){ var final_price = price query = table_pt.chain().find({'product': id}).data() for(var tax of query){ impuesto = table_taxes.findOne({'id': tax.tax}) if(impuesto.tipo == 'E'){ continue } var tasa = 1.00 + impuesto.tasa.to_float() if(impuesto.tipo == 'T' && impuesto.name == 'IVA'){ final_price = (price / tasa).round(cfg_invoice['decimales_precios']) } } return final_price } function cmd_new_invoice_click(){ 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', notas: ''}) get_condicion_pago() grid.clearAll() grid_totals.clearAll() grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0}) $$('cmd_cfdi_relacionados').disable() $$('multi_invoices').setValue('invoices_new') var lst = $$('lst_invoice_client_regimen') lst.setValue('') lst.getList().clearAll() form.focus('search_client_name') } 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){ gi.remove(id) msg_ok('Factura eliminada correctamente') }else{ msg_error('No se pudo eliminar') } }) } function cmd_delete_invoice_click(id, e, node){ if(gi.count() == 0){ return } var row = gi.getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if (row instanceof Array){ msg_error('Selecciona solo una factura') return } if(row.uuid){ msg_error('Solo se pueden eliminar facturas sin timbrar') return } 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){ var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue() if(usar_cartaporte){ value = $$('lst_carta_UnidadPeso').getValue() if(!value){ msg = 'Es necesario seleccionar una Unidad de Peso' msg_error(msg) return false } } var tipo_comprobante = $$('lst_tipo_comprobante').getValue() if(tipo_comprobante != 'T'){ if(values.id_partner == 0){ focus('search_client_name') msg = 'Selecciona un cliente' msg_error(msg) return false } } var regimen_fiscal = $$('lst_invoice_client_regimen').getValue() if(!regimen_fiscal){ msg = 'El Regimen Fiscal del Cliente es obligatorio.' 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 } anticipo = $$('chk_cfdi_anticipo').getValue() if(anticipo){ var mp = $$('lst_metodo_pago').getValue() if(mp != 'PUE'){ msg = 'En anticipos, el método de pago debe ser: Pago en una sola exhibición' msg_error(msg) return false } if(grid.count() != 1){ msg = 'Los anticipos solo llevan un concepto' msg_error(msg) return false } var r = grid.data.getRange() if(r[0].clave_sat != CLAVE_ANTICIPOS){ msg = 'La clave del SAT para anticipos debe ser: ' + CLAVE_ANTICIPOS msg_error(msg) return false } query = table_relaciones.chain().data() if(query.length > 0){ msg = 'Los anticipos no deben llevar CFDI relacionados' msg_error(msg) return false } } donativo = $$('chk_cfdi_donativo').getValue() if(donativo){ query = table_totals.chain().data() for(var t of query){ tax = table_taxes.findOne({'id': t.tax}) if(tax.tipo != 'E'){ msg = 'Los donativos deben de ser exentos' msg_error(msg) return false } } } usar_ine = $$('chk_cfdi_usar_ine').getValue() if(usar_ine){ var id_contabilidad = $$('txt_ine_idcontabilidad').getValue().trim() if(!id_contabilidad){ $$('tv_invoice').getTabbar().setValue('INE') msg = 'El ID de contabilidad es requerido si se usa el complemento INE' msg_error(msg) return false } if(!id_contabilidad.is_number()){ $$('tv_invoice').getTabbar().setValue('INE') msg = 'El ID de contabilidad deben ser solo digitos' msg_error(msg) return false } if(id_contabilidad.length > 6){ $$('tv_invoice').getTabbar().setValue('INE') msg = 'El ID de contabilidad deben tener máximo seis digitos' msg_error(msg) return false } } var rows = grid.data.getRange() for (i = 0; i < rows.length; i++) { var importe = rows[i]['importe'] if(!importe){ var msg = 'No es posible facturar importes en cero, revisa la línea: ' + (i + 1) msg_error(msg) return false } } return true } function update_grid_invoices(values){ if(values.new){ gi.add(values.row) }else{ gi.updateItem(values.row['id'], values.row) } } function send_anticipo_egreso(id){ webix.ajax().get('/values/anticipoegreso', {id: id}, function(text, data){ var values = data.json() if(values.ok){ msg_ok(values.msg) gi.add(values.row) }else{ webix.alert({ title: 'Error al Timbrar', text: values.msg, type: 'alert-error' }) } }) } function generar_anticipo_egreso(id){ msg = 'La factura tiene un CFDI de anticipo relacionado

' msg += '¿Deseas generar la factura de egreso correspondiente?' webix.confirm({ title: 'Generar Egreso', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ send_anticipo_egreso(id) } } }) } function send_timbrar(id){ webix.ajax().post('invoices', {opt: 'timbrar', id: id}, function(text, data){ var values = data.json() if(values.ok){ cmd_update_timbres_click() msg_ok(values.msg) gi.updateItem(id, values.row) if(values.anticipo){ //~ generar_anticipo_egreso(id) //~ show('Generar egreso de anticipo') } if(cfg_invoice.open_pdf){ get_pdf(id) } }else{ webix.alert({ title: 'Error al Timbrar', text: values.msg, type: 'alert-error' }) gi.updateItem(id, values.row) } }) } 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){ msg_ok('Factura guardada correctamente
Enviando a timbrar...') update_grid_invoices(values) gi.select(values.row['id'], false) send_timbrar(values.row['id']) result = true }else{ msg_error(values.msg) } } }) if(result){ table_pt.clear() table_totals.clear() grid.clearAll() $$('grid_totals').clearAll() } return result } 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_ok('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 guardar_y_timbrar(values){ query = table_relaciones.chain().data() var ids = [] if(query.length > 0){ for (i = 0; i < query.length; i++) { ids.push(query[i]['id']) } } var rows = grid.data.getRange() for (i = 0; i < rows.length; i++) { delete rows[i]['id'] delete rows[i]['delete'] delete rows[i]['clave'] delete rows[i]['clave_sat'] delete rows[i]['importe'] delete rows[i]['student'] rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario']) rows[i]['descuento'] = parseFloat(rows[i]['descuento']) } 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() data['receptor_regimen'] = $$('lst_invoice_client_regimen').getValue() data['relacionados'] = ids data['tipo_relacion'] = tipo_relacion data['anticipo'] = anticipo data['donativo'] = donativo data['notas'] = values.notas data['folio_custom'] = $$('txt_folio_custom').getValue() data['divisas'] = $$('opt_divisas').getValue() data['leyendas_fiscales'] = $$('grid_leyendas_fiscales').getSelectedId(true, true) $$('grid_leyendas_fiscales').unselectAll() var usar_ine = $$('chk_cfdi_usar_ine').getValue() if(usar_ine){ ine_type_comite = $$('lst_ine_tipo_comite').getValue() var valores = { TipoProceso: $$('lst_ine_tipo_proceso').getValue(), IdContabilidad: $$('txt_ine_idcontabilidad').getValue(), ClaveEntidad: $$('lst_ine_key_entidad').getValue(), Ambito: $$('lst_ine_ambito').getValue(), } if(ine_type_comite){ valores['TipoComite'] = ine_type_comite } data['ine'] = valores } var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue() if(usar_cartaporte){ //~ var total_distance = 0.00 //~ var total_weight = 0.00 var cartaporte = { TranspInternac: $$('lst_carta_TranspInternac').getValue(), //~ TotalDistRec: total_distance, } var ubicaciones = $$('grid_carta_ubicaciones').data.getRange() ubicaciones.forEach(function(row, index){ delete row['id'] delete row['delete'] //~ if(row['DistanciaRecorrida']){ //~ total_distance += parseFloat(row['DistanciaRecorrida']) //~ } }) //~ cartaporte['TotalDistRec'] = total_distance cartaporte['ubicaciones'] = ubicaciones var row = $$('grid_carta_autotransporte').data.getRange()[0] var autotransporte = { PermSCT: row['PermSCT'], NumPermisoSCT: row['NumPermisoSCT'], identificacion: { ConfigVehicular: row['ConfigVehicular'], PlacaVM: row['PlacaVM'], AnioModeloVM: row['AnioModeloVM'], }, seguros: { AseguraRespCivil: row['AseguraRespCivil'], PolizaRespCivil: row['PolizaRespCivil'], }, remolque: { SubTipoRem: row['SubTipoRem'], Placa: row['Placa'], } } var mercancias = $$('grid_carta_mercancias').data.getRange() mercancias.forEach(function(row, index){ delete row['id'] delete row['delete'] row['Cantidad'] = String(row['Cantidad']) //~ row['ValorMercancia'] = String(row['ValorMercancia']) //~ if(row['PesoEnKg']){ //~ total_weight += parseFloat(row['PesoEnKg']) //~ } }) var mercancias = { 'PesoBrutoTotal': 0.00, 'UnidadPeso': $$('lst_carta_UnidadPeso').getValue(), 'NumTotalMercancias': String(mercancias.length), mercancias: mercancias, autotransporte: autotransporte, } cartaporte['mercancias'] = mercancias var tiposfigura = $$('grid_carta_tipos_figuras').data.getRange() tiposfigura.forEach(function(row, index){ delete row['id'] }) cartaporte['tiposfigura'] = tiposfigura data['cartaporte'] = cartaporte } var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue() if(usar_comercioe){ data['comercioe'] = values_comercioe } if(!save_invoice(data)){ return } values_comercioe = null $$('chk_cfdi_usar_comercioe').setValue(false) table_relaciones.clear() tipo_relacion = '' anticipo = false $$('chk_cfdi_anticipo').setValue(0) $$('chk_cfdi_donativo').setValue(0) $$('chk_cfdi_usar_ine').setValue(0) $$('form_invoice').setValues({id_partner: 0, lbl_partner: 'Ninguno', notas:''}) $$('multi_invoices').setValue('invoices_home') } function cmd_timbrar_click(id, e, node){ var form = this.getFormView(); if(!form.validate()) { msg_error('Valores inválidos') return } var values = form.getValues() if(!validate_invoice(values)){ return } var tipo_comprobante = $$('lst_tipo_comprobante').getValue() query = table_relaciones.chain().data() msg = '¿Todos los datos son correctos?

' if(query.length > 0){ msg += 'La factura tiene CFDI relacionados

' } if(anticipo){ msg += 'La factura es un Anticipo

' } if(donativo){ msg += 'La factura es un Donativo' if($$('lst_forma_pago').getValue()=='12'){ msg += ' en Especie' } msg += '

' } usar_ine = $$('chk_cfdi_usar_ine').getValue() if(usar_ine){ msg += 'Estas usando el complemento INE

' } if($$('chk_cfdi_usar_comercioe').getValue()){ msg += 'Estas usando el complemento Comercio Exterior

' if(values_comercioe === null){ msg = 'El complemento de Comercio Exterior esta vacío' msg_error(msg) return } } if(tipo_comprobante == 'T'){ msg += 'El Tipo de Comprobante es Traslado, el total será puesto a 0 (Cero), asegurate de que sea el tipo de comprobante correcto

' } if(cfg_invoice['leyendasfiscales']){ var rows = $$('grid_leyendas_fiscales').getSelectedId(true, true) if(rows.length == 0){ msg += 'No se agregará ninguna leyenda fiscal

' }else if(rows.length == 1){ msg += 'Se agregará una leyenda fiscal

' }else{ msg += 'Se agregarán ' + rows.length + ' leyendas fiscales

' } } msg += '¿Estás seguro de timbrar esta factura?

' webix.confirm({ title: 'Timbrar Factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ guardar_y_timbrar(values) } } }) } 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) { msg_error('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 msg_error(msg) } } }) } function set_client(row){ if(!row.codigo_postal){ msg = 'El cliente no tiene capturado su Código Postal, es obligatorio.' msg_error(msg) return } 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, notas: row.notas}, true) html += row.nombre + ' (' + row.rfc + ')' $$('lbl_client').setValue(html) $$('cmd_cfdi_relacionados').enable() var lst = $$('lst_invoice_client_regimen') lst.getList().clearAll() if(row.regimenes==undefined){ var options = {opt: 'by_id', id: row.id} webix.ajax().sync().get('/sociosregimenes', options, function(text, data){ var values = data.json() lst.getList().parse(values) }) }else{ lst.getList().parse(row.regimenes) } lst.setValue(lst.getPopup().getList().getFirstId()) 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)){ msg_error('Captura una clave válida') }else{ search_client_by_id(id) } } } function calcular_impuestos(){ var tmp = null var subtotal = 0 var id = 2 var grid_totals = $$('grid_totals') var impuesto_producto = 0 var impuesto = null var total_cant = 0 table_totals.clear() grid_totals.clearAll() grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0}) var tc = $$('lst_tipo_comprobante').getValue() if(tc=='T'){ return } grid.eachRow(function(row){ var product = grid.getItem(row) var valor_unitario = parseFloat(product.valor_unitario) var cantidad = parseFloat(product.cantidad) var import2 = (valor_unitario * cantidad).round(DECIMALES) var importe = parseFloat(product.importe) subtotal += importe total_cant += cantidad query = table_pt.chain().find({'product': product.id_product}).data() for(var tax of query){ impuesto = table_taxes.findOne({'id': tax.tax}) if(impuesto.tipo == 'E'){ continue } var base = importe if(cfg_invoice['tax_locales'] && impuesto.key == '000'){ base = import2 } if(cfg_invoice.tax_decimals){ impuesto_producto = (impuesto.tasa * base).round(DECIMALES_TAX) }else{ impuesto_producto = (impuesto.tasa * base).round(DECIMALES) } if(cfg_invoice['tax_locales_truncate'] && impuesto.key == '000'){ impuesto_producto = Math.trunc(impuesto.tasa * base * 100) / 100 } if(impuesto.tipo == 'R'){ impuesto_producto = (impuesto_producto * -1).round(DECIMALES) } tmp = table_totals.findOne({'tax': tax.tax}) if(tmp === null){ table_totals.insert({'tax': tax.tax, 'importe': impuesto_producto}) }else{ tmp.importe += impuesto_producto table_totals.update(tmp) } } }) var tipo = '' var concepto = '' query = table_totals.chain().data() for(var t of query){ tax = table_taxes.findOne({'id': t.tax}) if(tax.tipo == 'E'){ continue } tipo = 'Traslado ' if(tax.tipo == 'R'){ tipo = 'Retención ' } concepto = tipo + tax.name + ' (' + tax.tasa + ')' grid_totals.add({id: id, concepto: concepto, importe: t.importe}) id += 1 } var row = {importe: subtotal} grid_totals.updateItem(1, row) $$('txt_total_cant').setValue(format_decimal_2(total_cant)) } function set_product(data){ var taxes = data.taxes var values = data.row var form = $$('form_invoice') var row = undefined if(!cfg_invoice['add_same_product']){ for(var id in grid.data.pull){ if(grid.getItem(id).id_product == values.id_product){ row = grid.getItem(id) break } } } values['delete'] = '-' if (row == undefined){ values['cantidad'] = 1 values['importe'] = values['valor_unitario'] //~ grid.add(values) } else { values['cantidad'] = parseFloat(row.cantidad) + 1 values['descuento'] = parseFloat(row.descuento) values['valor_unitario'] = parseFloat(row.valor_unitario) var precio_final = values['valor_unitario'] - values['descuento'] values['importe'] = (precio_final * values['cantidad']).round(DECIMALES) //~ grid.updateItem(row.id, values) } form.setValues({search_product_id: '', search_product_name: ''}, true) //~ Validate stock if(values.inventario){ if(values.cantidad > values.existencia){ msg_error('No hay suficiente existencia de este producto') return } } if(row == undefined){ grid.add(values) }else{ grid.updateItem(row.id, values) } for(var v of taxes){ var pt = table_pt.findOne(v) if(pt === null){ table_pt.insert(v) } } calcular_impuestos() } function grid_products_found_click(obj){ search_product_by_key(obj.clave) } function grid_students_found_click(obj){ var form = $$('form_invoice') var row = grid.getSelectedItem() if (row == undefined){ msg = 'Selecciona un registro primero' msg_error(msg) return } var values = { id_student: obj.id, student: obj.nombre + ' ' + obj.paterno + ' ' + obj.materno, } grid.updateItem(row.id, values) form.setValues({search_student: ''}, true) } function search_product_by_key(key){ var filters = { opt: 'by_key', key: key, } webix.ajax().get('/products', filters, { error: function(text, data, xhr) { msg_error('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

' + key msg_error(msg) } } }) } function search_product_id_key_press(code, e){ var value = this.getValue().trim() if(code == 13 && value.length > 0){ search_product_by_key(value) } } function grid_details_before_edit_start(id){ var columns = ['', 'unidad', 'descripcion', 'pedimento','cantidad', 'valor_unitario', 'descuento'] if(!columns.indexOf(id.column)){ return !this.getItem(id.row)[id.column] } var tc = $$('lst_tipo_comprobante').getValue() if(tc=='T' && id.column=='descuento'){ return false } } function grid_carta_ubicaciones_before_edit_stop(state, editor){ var g = $$('grid_carta_ubicaciones') var row = g.getItem(editor.row) if(editor.column != 'CodigoPostal'){ if(editor.column == 'DistanciaRecorrida' && row['TipoUbicacion'] == 'Origen'){ msg = 'En el Origen, la distancia recorrida debe estar vacía' msg_error(msg) g.blockEvent() state.value = '' g.editCancel() g.unblockEvent() } return true } var cp = state.value.trim() if(!cp){ msg = 'El Código Postal no puede estar vacío' msg_error(msg) g.blockEvent() state.value = state.old g.editCancel() g.unblockEvent() return true } if(cp.length != 5){ msg = 'El Código Postal debe ser de 5 digitos' msg_error(msg) g.blockEvent() state.value = state.old g.editCancel() g.unblockEvent() return true } if(cp.match(/\d/) == null){ msg = 'El Código Postal deben ser solo digitos' msg_error(msg) g.blockEvent() state.value = state.old g.editCancel() g.unblockEvent() return true } webix.ajax().get('/values/cp', {cp: cp}, { error: function(text, data, xhr) { msg_error('Error al consultar el C.P.') }, success: function(text, data, xhr) { var values = data.json(); if (values.estado == undefined){ msg = 'No se encontró el C.P., asegurate de que sea correcto' msg_error(msg) } else { //~ row['Estado'] = opt_carta_estados.find(x => x.value === values.estado).id row['Estado'] = values.key_estado row['Municipio'] = values.key_municipio g.refresh() msg_ok('Municipio:\n' + values.municipio) } } }) } function grid_details_before_edit_stop(state, editor){ var row = grid.getItem(editor.row) if(editor.column == 'unidad'){ return true } if(editor.column == 'descripcion'){ if(!state.value.trim()){ msg = 'La descripción no puede estar vacía' msg_error(msg) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } state.value = state.value.trim() if(state.value.length > 1000){ msg = 'La descripción tiene más de 1000 caracteres, esta ' msg += 'descripción será rechazada por el SAT. Edita esta ' msg += 'descripción hasta que ya no veas este mensaje.
' msg += '
Caracteres: ' + state.value.length msg_error(msg) } return true } if(editor.column == 'pedimento'){ state.value = state.value.trim() if(state.value.length != 21){ msg = 'El Pedimento debe ser de 21 caracteres, será ' msg += 'rechazado por el SAT. Editalo hasta que ya ' msg += 'no veas este mensaje de error.
' msg += '
Caracteres: ' + state.value.length msg_error(msg) } if(state.value){ if(!validate_pedimento(state.value)){ msg = 'El formato del Pedimento es erroneo, será rechazado por el SAT' msg_error(msg) } } return true } 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 } cantidad = cantidad.round(DECIMALES) //~ Validate stock if(row['inventario']){ if(cantidad > row['existencia']){ msg = 'No hay suficiente existencia de este producto' msg_error(msg) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } } grid.blockEvent() state.value = cantidad grid.unblockEvent() var valor_unitario = parseFloat(row['valor_unitario']) var descuento = parseFloat(row['descuento']) } if(editor.column == 'valor_unitario'){ if(isNaN(state.value)){ msg = 'El valor unitario debe ser un número' msg_error(msg) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } if(cfg_invoice['with_taxes']){ var valor_unitario = price_without_taxes(parseFloat(state.value), row.id_product) }else{ //~ var valor_unitario = parseFloat(state.value).round(DECIMALES) var valor_unitario = parseFloat(state.value).round(cfg_invoice['decimales_precios']) } grid.blockEvent() state.value = valor_unitario grid.unblockEvent() 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 } //~ descuento = descuento.round(DECIMALES) descuento = descuento.round(cfg_invoice['decimales_precios']) var cantidad = parseFloat(row['cantidad']) var valor_unitario = parseFloat(row['valor_unitario']) if(descuento>=valor_unitario){ msg = 'El descuento debe ser menor al Valor Unitario' msg_error(msg) grid.blockEvent() state.value = state.old grid.editCancel() grid.unblockEvent() return true } grid.blockEvent() state.value = descuento grid.unblockEvent() } var precio_final = valor_unitario - descuento row['importe'] = (cantidad * precio_final).round(DECIMALES) grid.refresh() } function grid_details_after_edit_stop(state, editor, ignoreUpdate){ var columns = ['', 'cantidad', 'valor_unitario', 'descuento'] if(columns.indexOf(editor.column) > 0){ calcular_impuestos() } } function grid_details_click(id, e, node){ if(id.column != 'delete'){ return } grid.remove(id.row) calcular_impuestos() } 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() calcular_impuestos() } } }) } function set_invoice(row){ $$('lst_serie').setValue(row.serie) $$('lst_tipo_comprobante').setValue(row.tipo_comprobante) $$('lst_uso_cfdi').setValue(row.uso_cfdi) $$('lst_metodo_pago').setValue(row.metodo_pago) $$('lst_forma_pago').setValue(row.forma_pago) $$('txt_condicion_pago').setValue(row.condicion_pago) } function set_products_reinvoice(values){ var rows = [] for(var product of values){ var row = product.row rows.push(row) var taxes = product.taxes for(var v of taxes){ var pt = table_pt.findOne(v) if(pt === null){ table_pt.insert(v) } } } grid.parse(rows, 'json') } function refacturar_invoice(id){ filters = {id: id, opt: 'reinvoice'} webix.ajax().get('/invoices', filters, { error: function(text, data, xhr) { msg_error('Error al consultar') }, success: function(text, data, xhr) { var values = data.json(); cmd_new_invoice_click() pause(500) set_client(values.receptor) set_invoice(values.invoice) set_products_reinvoice(values.products) calcular_impuestos() } }) } function cmd_refacturar_click(){ if(gi.count() == 0){ return } var row = gi.getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if (row instanceof Array){ msg_error('Selecciona solo una factura') return } var msg = '¿Estás seguro de refacturar la siguiente factura?

' msg += '(' + row['serie'] + '-' + row['folio'] + ') ' + row['cliente'] webix.confirm({ title: 'Refacturar', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if (result){ refacturar_invoice(row['id']) } } }) } function cmd_invoice_timbrar_click(){ if(gi.count() == 0){ return } var row = gi.getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if (row instanceof Array){ msg_error('Selecciona solo una factura') return } if(row.uuid){ msg_error('La factura ya esta timbrada') return } msg = '¿Estás seguro de enviar a timbrar esta factura?' webix.confirm({ title: 'Timbrar Factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ send_timbrar(row.id) } } }) } function enviar_correo(row){ if(!row.uuid){ msg_error('La factura no esta timbrada') return } msg = '¿Estás seguro de enviar por correo esta factura?' webix.confirm({ title: 'Enviar Factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ webix.ajax().post('/values/sendmail', {'id': row.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_ok(values.msg) }else{ msg_error(values.msg) } } }) } } }) } function get_pdf(id){ window.open('/doc/pdf/' + id, '_blank') } function get_html(id){ window.open('/doc/html/' + id, '_blank') } function grid_invoices_click(id, e, node){ var row = this.getItem(id) if(id.column == 'xml'){ location = '/doc/xml/' + row.id }else if(id.column == 'pdf'){ get_pdf(row.id) }else if(id.column == 'html'){ get_html(row.id) }else if(id.column == 'ods'){ location = '/doc/ods/' + row.id }else if(id.column == 'zip'){ location = '/doc/zip/' + row.id }else if(id.column == 'email'){ enviar_correo(row) } } function get_filters_invoices(){ var filters = $$('filter_dates').getValue() if(filters['start'] && !filters['end']){ msg = 'No seleccionaste la fecha final' msg_error(msg) } filters['year'] = $$('filter_year').getValue() filters['month'] = $$('filter_month').getValue() filters['client'] = $$('grid_invoices').getFilter('cliente').value return filters } function get_invoices(){ var filters = get_filters_invoices() filters['by'] = 'dates' var grid = $$('grid_invoices') grid.showProgress({type: 'icon'}) webix.ajax().get('/invoices', 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_change(nv, ov){ get_invoices() } function filter_month_change(nv, ov){ get_invoices() } function filter_dates_change(range){ if(range.start != null && range.end != null){ get_invoices() } } function invoice_uncancel(id){ var options = {opt: 'uncancel', id: id} webix.ajax().put('/invoices', options, function(text, data){ var result = data.json() if(result['result']){ gi.updateItem(id, result['values']) msg_ok(result['msg']) }else{ msg_error(result['msg']) } }) } function ask_invoice_uncancel(id){ var msg = 'La factura seleccionada esta Vigente en el SAT, pero Cancelada en el sistema
¿Deseas cambiar su estatus?' webix.confirm({ title: 'Cambiar estatus de factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if (result){ invoice_uncancel(id) } } }) } function cmd_invoice_sat_click(){ if(gi.count() == 0){ return } var row = gi.getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if (row instanceof Array){ msg_error('Selecciona solo una factura') return } if(!row.uuid){ msg_error('La factura no esta timbrada, solo es posible consultar \ el estatus en el SAT de facturas timbradas') return } var options = {opt: 'statussat', id: row.id} webix.ajax().get('/invoices', options, function(text, data){ var value = data.json() if(value == 'Vigente'){ msg_ok(value) }else if(value == 'uncancel'){ ask_invoice_uncancel(row.id) }else{ msg_error(value) } }) } 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() $$('cmd_cfdi_relacionados').disable() form.focus('search_client_name') } function cmd_prefactura_click(){ var form = this.getFormView() if(!form.validate()) { msg_error('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]['id'] delete rows[i]['delete'] delete rows[i]['clave'] 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['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() data['notas'] = values.notas if(!save_preinvoice(data)){ return } reset_invoice() $$('tv_invoice').getTabbar().setValue('PreFacturas') } function lst_metodo_pago_change(nv, ov){ if(nv == 'PPD'){ $$('lst_forma_pago').setValue('99') } } function lst_moneda_change(nv, ov){ if(nv == 'MXN'){ $$('txt_tipo_cambio').setValue('1.00') $$('txt_tipo_cambio').config.readonly = true }else{ $$('txt_tipo_cambio').config.readonly = false } $$('txt_tipo_cambio').refresh() select_all('txt_tipo_cambio') } function txt_tipo_cambio_lost_focus(prev){ var tipo_cambio = $$('txt_tipo_cambio').getValue() 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) $$('txt_tipo_cambio').setValue('1.00') }else{ $$('txt_tipo_cambio').setValue(parseFloat(tipo_cambio).round(4)) } } 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) { 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 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_ok('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 agregar_preproducto(values){ var taxes = values.taxes var values = values.row var form = $$('form_invoice') var row = grid.getItem(values.id) values['delete'] = '-' if (row == undefined){ grid.add(values) } else { values['cantidad'] = parseFloat(row.cantidad) + parseFloat(values['cantidad']) values['valor_unitario'] = parseFloat(row.valor_unitario) values['descuento'] = parseFloat(row.descuento) var precio_final = values['valor_unitario'] - values['descuento'] values['importe'] = (precio_final * values['cantidad']).round(DECIMALES) grid.updateItem(row.id, values) } for(var v of taxes){ var pt = table_pt.findOne(v) if(pt === null){ table_pt.insert(v) } } } function refacturar_preinvoice(id){ webix.ajax().get('/values/preproductos', {'id': id}, { error: function(text, data, xhr) { msg_error('Error al consultar') }, success: function(text, data, xhr){ var values = data.json() set_client(values.receptor) for(var p of values.rows){ agregar_preproducto(p) } calcular_impuestos() $$('tv_invoice').getTabbar().setValue('Generar') } }) } function cmd_facturar_preinvoice_click(){ 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.row}, { 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) }else{ msg_error(values.msg) } } }) } } }) } function generate_pdf(id){ webix.ajax().get('/values/canopenpre', {id: id}, { error: function(text, data, xhr) { }, success: function(text, data, xhr) { var value = data.json(); //~ if(value){ window.open('/doc/pre/' + id, '_blank') //~ }else{ //~ msg_ok('Generando prefactura...') //~ } } }) } function grid_preinvoices_click(id, e, node){ if(id.column == 'pdf'){ //~ generate_pdf(id.row) window.open('/doc/pre/' + id, '_blank') }else if(id.column == 'email'){ enviar_prefactura(id) } } function get_facturas_por_cliente(){ var values = $$('form_invoice').getValues() var id = values.id_partner var y = $$('filter_cfdi_year').getValue() var m = $$('filter_cfdi_month').getValue() var ids = [] var rows = $$('grid_relacionados').data.getRange() for (i = 0; i < rows.length; i++) { ids.push(rows[i]['id']) } filters = { 'year': y, 'month': m, 'id_cliente': id, 'cfdis': ids, 'anticipo': $$('chk_relacionados_anticipo').getValue(), 'folio': $$('filter_cfdi_folio').getValue(), 'uuid': $$('filter_cfdi_uuid').getValue(), 'opt': 'relacionados' } var grid = $$('grid_cfdi_cliente') webix.ajax().get('/invoices', 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 get_info_cfdi_relacionados(){ webix.ajax().get('/values/tiporelacion', {key: true}, function(text, data){ var values = data.json() $$('lst_tipo_relacion').getList().parse(values) $$('lst_tipo_relacion').setValue(tipo_relacion) }) query = table_relaciones.chain().data() $$('grid_relacionados').parse(query) get_facturas_por_cliente() } function cmd_cfdi_relacionados_click(){ var d = new Date() ui_invoice.init() var fy = $$('filter_cfdi_year') var fm = $$('filter_cfdi_month') fy.blockEvent() fm.blockEvent() $$('lbl_cfdi_cliente').setValue($$('lbl_client').getValue()) data = $$('filter_year').getList().data fy.getList().data.sync(data) fy.setValue(d.getFullYear()) fm.setValue(d.getMonth() + 1) fy.unblockEvent() fm.unblockEvent() get_info_cfdi_relacionados() $$('win_cfdi_relacionados').show() } function cmd_limpiar_relacionados_click(){ msg = '¿Estás seguro de quitar todas las relaciones

' msg += 'ESTA ACCION NO SE PUEDE DESHACER' webix.confirm({ title: 'Limpiar relaciones', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ $$('lst_tipo_relacion').setValue('') $$('grid_relacionados').clearAll() table_relaciones.clear() tipo_relacion = '' msg_ok('Las relaciones han sido eliminadas') } } }) } function cmd_guardar_relacionados_click(){ var grid = $$('grid_relacionados') var value = $$('lst_tipo_relacion').getValue() if(value == '' || value == '-'){ msg_error('Selecciona el tipo de relación') return } if(grid.count() == 0){ msg_error('Agrega al menos un CFDI a relacionar') return } var data = grid.data.getRange() table_relaciones.clear() table_relaciones.insert(data) tipo_relacion = value msg_ok('Relaciones guardadas correctamente') } function cmd_filter_relacionados_click(){ get_facturas_por_cliente() } function filter_cfdi_year_change(nv, ov){ cmd_filter_relacionados_click() } function filter_cfdi_month_change(nv, ov){ cmd_filter_relacionados_click() } function lst_tipo_relacion_change(nv, ov){ $$('chk_relacionados_anticipo').setValue(0) $$('chk_relacionados_anticipo').disable() if(nv=='07'){ $$('chk_relacionados_anticipo').enable() $$('chk_relacionados_anticipo').setValue(1) cmd_filter_relacionados_click() } } function lst_tipo_comprobante_change(nv, ov){ if(nv=='T'){ grid.eachRow(function(row){ var p = grid.getItem(row) p.descuento = 0.0 p.importe = (p.cantidad * p.valor_unitario).round(DECIMALES) grid.updateItem(row, p) }) } if(nv=='T' || ov=='T'){ calcular_impuestos() } } function lst_serie_change(nv, ov){ query = table_series.chain().find({id: nv}).data()[0] if(query.usarcon){ $$('lst_tipo_comprobante').setValue(query.usarcon) $$('lst_tipo_comprobante').config.readonly = true }else{ $$('lst_tipo_comprobante').config.readonly = false } $$('lst_tipo_comprobante').refresh() } function cmd_cfdi_notes_click(){ win_invoice_notes.init() var values = $$('form_invoice').getValues() $$('invoice_notes').setValue(values.notas) $$('win_invoice_notes').show() to_end('invoice_notes') cfg_invoice['notes'] = false } function save_invoice_notes(notes){ var row = $$('grid_invoices').getSelectedId() webix.ajax().post('/values/invoicenotes', {id: row.id, notes: notes}, { error:function(text, data, XmlHttpRequest){ }, success:function(text, data, XmlHttpRequest){ values = data.json(); if(values.ok){ msg_ok(values.msg) }else{ msg_error(values.msg) } } }) } function cmd_invoice_save_note_click(){ var value = $$('invoice_notes').getValue() if(cfg_invoice['notes']){ save_invoice_notes(value) }else{ $$('form_invoice').setValues({notas: value}, true) } $$('win_invoice_notes').close() } function cmd_invoice_report_pdf_click(){ var d = new Date() var ds = d.toISOString().slice(0,10).replace(/-/g, "_") webix.toPDF($$('grid_invoices'), { ignore: {'xml': true, 'pdf': true, 'zip': true, 'mail': true}, filename: 'Reporte_de_Facturas_' + ds, width: 612, height: 792, //~ autowidth: true, filterHTML: true, fontSize: 8, padding: 5, header:{ textAlign: 'center', fontSize: 9, }, table:{ fontSize: 8, }, row:{ padding: 0, }, columns:{ index: true, serie: {width: 40}, folio: {width: 30}, fecha: {width: 95}, tipo_comprobante: {width: 20}, estatus: {width: 50}, total_mn: {width: 70}, cliente: {width: 200}, } }) } function cmd_invoice_report_xls_click(){ webix.toExcel($$('grid_invoices'), { filename: 'Reporte_de_Facturas', name: 'Facturas', ignore: {'xml': true, 'pdf': true, 'zip': true, 'mail': true}, rawValues: true, }) } function grid_invoices_on_select_change(){ var g = $$('grid_invoices') var rows = g.getSelectedItem(true) var total = 0 for (i = 0; i < rows.length; i++) { if(typeof(rows[i].total_mn) == 'string'){ total += rows[i].total_mn.to_float() }else{ total += rows[i].total_mn } } g.getColumnConfig('cliente').footer[0].text = webix.i18n.priceFormat(total) g.refreshColumns() $$('cmd_admin_invoice_notes').disable() if(rows.length==1){ $$('cmd_admin_invoice_notes').enable() } } function grid_invoices_on_header_click(id){ if(id.column != 'index'){ return } var g = $$('grid_invoices') var rows = g.getSelectedItem(true) if(rows.length){ g.unselectAll() }else{ g.selectAll() } } function get_invoice_notes(row){ webix.ajax().sync().get('/values/invoicenotes', {id: row.id}, function(text, data){ var values = data.json() return values.notes }) } function cmd_admin_invoice_notes_click(){ var row = $$('grid_invoices').getSelectedId() win_invoice_notes.init() webix.ajax().sync().get('/values/invoicenotes', {id: row.id}, function(text, data){ var values = data.json() $$('invoice_notes').setValue(values.notes) $$('win_invoice_notes').show() to_end('invoice_notes') }) cfg_invoice['notes'] = true } function cmd_import_invoice_click(){ win_import_invoice.init() $$('win_import_invoice').show() } function cmd_upload_invoice_click(){ var form = $$('form_upload_invoice') var values = form.getValues() if(!$$('lst_upload_invoice').count()){ $$('win_import_invoice').close() return } if($$('lst_upload_invoice').count() > 1){ msg = 'Selecciona solo un archivo' msg_error(msg) return } var template = $$('up_invoice').files.getItem($$('up_invoice').files.getFirstId()) if(template.type.toLowerCase() != 'ods'){ msg = 'Archivo inválido.\n\nSe requiere un archivo ODS' msg_error(msg) return } msg = '¿Estás seguro de importar este archivo?' webix.confirm({ title: 'Importar Factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ $$('up_invoice').send() } } }) } function add_import_product_taxes(taxes){ for(var v of taxes){ var pt = table_pt.findOne(v) if(pt === null){ table_pt.insert(v) } } } function up_invoice_upload_complete(response){ if(response.status != 'server'){ msg = 'Ocurrio un error al subir el archivo' msg_error(msg) return } msg = 'Archivo subido correctamente.\n\nComenzando importación.' msg_ok(msg) $$('win_import_invoice').close() webix.ajax().get('/values/importinvoice', { error: function(text, data, xhr) { msg_error('Error al consultar') }, success: function(text, data, xhr){ var values = data.json() if (values.ok){ for(var p of values.rows){ add_import_product_taxes(p.taxes) } grid.clearAll() grid.parse(values.rows, 'json') grid.refresh() calcular_impuestos() }else{ webix.alert({ title: 'Error al importar', text: values.msg, type: 'alert-error', }) } } }) } function cmd_invoice_verify_sat_click(){ var rows = gi.getSelectedItem(true) if (rows.length == 0){ msg_error('Selecciona una factura') return } if (rows.length > 1){ msg_error('Selecciona solo una factura') return } if(!rows[0].uuid){ msg_error('La factura no esta timbrada, solo es posible verificar \ en el SAT, facturas timbradas') return } webix.ajax().get('/values/verifysat', {id: rows[0].id}, function(text, data){ var values = data.json() window.open(values.url, '_blank') }) } function grid_invoices_on_subview_create(view, item){ var values = {'opt': 'detalle', 'id': item.id} webix.ajax().get('/invoices', values, { error: function(text, data, xhr) { msg_error('Error al consultar') }, success: function(text, data, xhr) { view.parse(data.json(), 'json') } }); } function cmd_preinvoice_generate_delete_click(){ } function txt_folio_custom_key_press(code, e){ var data = [8, 9, 37, 39, 46] if ( data.indexOf(code) >= 0 ){ return true; } if ( code < 48 || code > 57){ return false; } } function validate_folio_exists(folio){ var serie = $$('lst_serie').getText() var values = {'opt': 'foliocustom', 'folio': folio, 'serie': serie} webix.ajax().get('/invoices', values, { error: function(text, data, xhr) { msg_error('Error al consultar') }, success: function(text, data, xhr) { var result = data.json() if(result.ok){ msg_error(result.msg) focus('txt_folio_custom') }else{ msg_ok(result.msg) } return result.ok } }) } function txt_folio_custom_lost_focus(prev){ if(prev.getValue()){ validate_folio_exists(prev.getValue()) } } function search_by(value){ var filters = get_filters_invoices() filters['by'] = 'notes' filters['notes'] = value var grid = $$('grid_invoices') grid.showProgress({type: 'icon'}) webix.ajax().get('/invoices', 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 search_by_key_press(code, e){ var value = this.getValue().trim() if(code == 13 && value.length > 3){ search_by(value) } } function search_by_click(){ var value = this.getValue().trim() if(value.length > 3){ search_by(value) } } function get_leyendas_fiscales(){ webix.ajax().get('/leyendasfiscales', {'opt': 'active'}, { error:function(text, data, XmlHttpRequest){ msg = 'Ocurrio un error, consulta a soporte técnico' msg_error(msg) }, success:function(text, data, XmlHttpRequest){ var values = data.json() var grid = $$('grid_leyendas_fiscales') grid.clearAll() grid.parse(values) grid.refresh() } }) } //~ Delete function _tab_carta_porte(){ } function tv_invoice_change(nv, ov){ if(nv=='Carta Porte'){ //~ _tab_carta_porte() } } function send_invoice_cancel(id, reason='', uuid=''){ var args = { opt: 'cancel', values: { id: id, reason: reason, uuid: uuid, } } webix.ajax().post('invoices', args, function(text, data){ var values = data.json() if(values.ok){ msg_ok(values.msg) gi.updateItem(id, values.row) }else{ msg_error('No fue posible cancelar') webix.alert({ title: 'Error al Cancelar', text: values.msg, type: 'alert-error' }) } }) } function cmd_invoice_cancel_click(){ var row = $$('grid_invoices').getSelectedItem() var reason = $$('lst_reasons_cancel').getValue() var uuid = $$('txt_cancel_uuid').getValue() if(!reason){ msg = 'Selecciona un motivo para esta cancelación' msg_error(msg) return } if(reason=='01' & !uuid){ msg = 'Debes de capturar el UUID que reemplaza a este CFDI' msg_error(msg) return } send_invoice_cancel(row.id, reason, uuid) $$('win_invoice_cancel').close() } function cmd_win_cancel_close_click(){ $$('win_invoice_cancel').close() } function cmd_invoice_ask_cancel_click(){ var g = $$('grid_invoices') if(g.count() == 0){ return } var row = g.getSelectedItem() if (row == undefined){ msg_error('Selecciona una factura') return } if (row instanceof Array){ msg_error('Selecciona solo una factura') return } if(row.estatus == 'Cancelada'){ msg_error('La factura ya esta cancelada') return } msg = '' if(row.uuid){ win_invoice_cancel.init() $$('win_invoice_cancel').show() }else{ msg = 'La factura NO esta timbrada, asegurate de que efectivamente NO este timbrada.

' msg += '¿Estás seguro de enviar a cancelar esta factura?

\ ESTA ACCIÓN NO SE PUEDE DESHACER' webix.confirm({ title: 'Cancelar Factura', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ send_invoice_cancel(row.id) } } }) } } function cmd_carta_add_product_click(){ var g = $$('grid_carta_mercancias') g.add({delete: '-'}) } function _copy_from_invoice(){ var g1 = $$('grid_details') var g2 = $$('grid_carta_mercancias') if(!g1.count()){ msg = 'Agrega primero "todos" los productos a trasladar' msg_error(msg) return } g2.clearAll() g1.eachRow(function(row){ const r = g1.getItem(row) var data = new Object() data['delete'] = '-' data['BienesTransp'] = r.clave_sat data['Descripcion'] = r.descripcion data['Cantidad'] = r.cantidad data['ClaveUnidad'] = r.unidad //~ data['ValorMercancia'] = r.importe g2.add(data) }) } function cmd_carta_copy_from_invoice_click(){ msg = '¿Estás seguro de copiar los productos?

\ Esto reemplazara todos los datos actuales de las mercancías.' webix.confirm({ title: 'Copiar productos', ok: 'Si', cancel: 'No', type: 'confirm-error', text: msg, callback:function(result){ if(result){ _copy_from_invoice() } } }) } function grid_carta_mercancias_click(id, e, node){ if(id.column != 'delete'){ return } this.remove(id.row) } function _set_carta_porte_from_json(data){ try{ var values = JSON.parse(data) }catch(e){ msg_error('Revisa el archivo JSON') webix.alert({ title: 'Error al cargar JSON', text: e.message, type: 'alert-error' }) return } var mercancias = values['mercancias'] var ubicaciones = values['ubicaciones'] var autotransporte = values['autotransporte'] var operador = values['operador'] $$('lst_carta_UnidadPeso').setValue(values['unidad_de_peso']) var grid = $$('grid_carta_mercancias') grid.clearAll() mercancias.forEach(function(row, index){ var data = new Object() data['delete'] = '-' data['BienesTransp'] = row.clave_sat data['Descripcion'] = row.descripcion data['Cantidad'] = row.cantidad data['ClaveUnidad'] = row.clave_unidad data['PesoEnKg'] = row.peso_en_kg grid.add(data) }) var grid = $$('grid_carta_ubicaciones') grid.clearAll() ubicaciones.forEach(function(row, index){ var data = new Object() data['delete'] = '-' data['TipoUbicacion'] = row.tipo data['RFCRemitenteDestinatario'] = row.rfc data['NombreRemitenteDestinatario'] = row.nombre data['FechaHoraSalidaLlegada'] = new Date(row.fecha) if('distancia' in row){ data['DistanciaRecorrida'] = row.distancia } data['Municipio'] = row.municipio data['Estado'] = row.estado data['Pais'] = 'MEX' data['CodigoPostal'] = row.codigo_postal grid.add(data) }) var grid = $$('grid_carta_autotransporte') grid.clearAll() var data = new Object() data['PermSCT'] = autotransporte.tipo_permiso data['NumPermisoSCT'] = autotransporte.numero data['ConfigVehicular'] = autotransporte.clave data['PlacaVM'] = autotransporte.placa data['AnioModeloVM'] = autotransporte.modelo if('remolque' in autotransporte){ data['SubTipoRem'] = autotransporte.remolque data['Placa'] = autotransporte.placa_remolque } data['AseguraRespCivil'] = autotransporte.aseguradora data['PolizaRespCivil'] = autotransporte.poliza grid.add(data) var grid = $$('grid_carta_tipos_figuras') grid.clearAll() var data = new Object() data['TipoFigura'] = '01' if('tipo' in operador){ data['TipoFigura'] = operador.tipo } data['RFCFigura'] = operador.rfc data['NombreFigura'] = operador.nombre data['NumLicencia'] = operador.licencia grid.add(data) $$('chk_cfdi_usar_cartaporte').setValue(1) } function cmd_carta_import_json_click(){ win_carta_import_json.init() $$('win_carta_import_json').show() } function up_invoice_json_on_after_file_add(obj){ let reader = new FileReader() reader.readAsText(obj.file) reader.onload = function(){ _set_carta_porte_from_json(reader.result) } $$('win_carta_import_json').close() } function _set_from_json_comercioe(data){ try{ values_comercioe = JSON.parse(data) }catch(e){ msg_error('Revisa el archivo JSON') webix.alert({ title: 'Error al cargar JSON', text: e.message, type: 'alert-error' }) return } msg = 'Valores cargados correctamente' msg_ok(msg) } function cmd_import_json_comercioe_click(){ win_import_json_comercioe.init() $$('win_import_json_comercioe').show() } function up_invoice_json_comercioe_on_after_file_add(obj){ let reader = new FileReader() reader.readAsText(obj.file) reader.onload = function(){ _set_from_json_comercioe(reader.result) } $$('win_import_json_comercioe').close() }