empresa-libre/source/static/js/controller/invoices.js

2906 lines
79 KiB
JavaScript

//~ 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 <http://www.gnu.org/licenses/>.
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?<BR><BR>'
msg += '(' + row['folio'] + ') ' + row['cliente']
msg += '<BR><BR>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<BR><BR>'
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<BR>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?<BR><BR>'
if(query.length > 0){
msg += 'La factura tiene CFDI relacionados<BR><BR>'
}
if(anticipo){
msg += 'La factura es un Anticipo<BR><BR>'
}
if(donativo){
msg += 'La factura es un Donativo'
if($$('lst_forma_pago').getValue()=='12'){
msg += ' en Especie'
}
msg += '<BR><BR>'
}
usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){
msg += 'Estas usando el complemento INE<BR><BR>'
}
if($$('chk_cfdi_usar_comercioe').getValue()){
msg += 'Estas usando el complemento Comercio Exterior<BR><BR>'
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<BR><BR>'
}
if(cfg_invoice['leyendasfiscales']){
var rows = $$('grid_leyendas_fiscales').getSelectedId(true, true)
if(rows.length == 0){
msg += 'No se agregará ninguna leyenda fiscal<BR><BR>'
}else if(rows.length == 1){
msg += 'Se agregará una leyenda fiscal<BR><BR>'
}else{
msg += 'Se agregarán ' + rows.length + ' leyendas fiscales<BR><BR>'
}
}
msg += '¿Estás seguro de timbrar esta factura?<BR><BR>'
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 = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
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 + ')</span>'
$$('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<BR><BR>' + 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. <BR>'
msg += '<BR>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. <BR>'
msg += '<BR>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?<BR><BR>'
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 <BR>¿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?<BR><BR>'
msg += '(' + row['folio'] + ') ' + row['cliente']
msg += '<BR><BR>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?<BR><BR>'
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<BR><BR>'
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.<BR><BR>'
msg += '¿Estás seguro de enviar a cancelar esta factura?<BR><BR> \
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?<BR><BR> \
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()
}