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 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_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)
$$('cmd_invoice_timbrar').attachEvent('onItemClick', cmd_invoice_timbrar_click)
$$('cmd_invoice_sat').attachEvent('onItemClick', cmd_invoice_sat_click)
$$('cmd_invoice_cancelar').attachEvent('onItemClick', cmd_invoice_cancelar_click)
$$('grid_invoices').attachEvent('onItemClick', grid_invoices_click)
$$('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_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_serie').attachEvent('onChange', lst_serie_change)
$$('cmd_cfdi_notes').attachEvent('onItemClick', cmd_cfdi_notes_click)
webix.extend($$('grid_invoices'), webix.ProgressBar)
}
}
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().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')
}
cfg_invoice['open_pdf'] = values.cfdi_open_pdf
if(values.cfdi_show_pedimento){
$$('grid_details').showColumn('pedimento')
}
})
}
function cmd_new_invoice_click(id, e, node){
var form = $$('form_invoice')
var grid_totals = $$('grid_totals')
grid = $$('grid_details')
default_config()
form.adjust()
form.setValues({id: 0, id_partner: 0, lbl_client: 'Ninguno', 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')
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.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){
if(values.id_partner == 0){
webix.UIManager.setFocus('search_client_name')
msg = 'Selecciona un cliente'
msg_error(msg)
return false
}
if(!grid.count()){
webix.UIManager.setFocus('search_product_id')
msg = 'Agrega al menos un producto o servicio'
msg_error(msg)
return false
}
var uso_cfdi = $$('lst_uso_cfdi').getValue()
if(uso_cfdi.trim() == ""){
webix.UIManager.setFocus('lst_uso_cfdi')
msg = 'El Uso del CFDI es requerido'
msg_error(msg)
return false
}
var forma_pago = $$('lst_forma_pago').getValue()
if(forma_pago.trim() == ""){
webix.UIManager.setFocus('lst_forma_pago')
msg = 'La Forma de pago es requerida'
msg_error(msg)
return false
}
var tipo_cambio = $$('txt_tipo_cambio').getValue()
if(tipo_cambio.trim() == ""){
webix.UIManager.setFocus('txt_tipo_cambio')
msg = 'El Tipo de Cambio es requerido'
msg_error(msg)
return false
}
if(isNaN(tipo_cambio * 1)){
webix.UIManager.setFocus('txt_tipo_cambio')
msg = 'El Tipo de Cambio debe ser un valor númerico'
msg_error(msg)
return false
}
var moneda = $$('lst_moneda').getValue()
if(moneda == 'MXN' && tipo_cambio != 1){
webix.UIManager.setFocus('txt_tipo_cambio')
msg = 'Si la moneda es MXN, el Tipo de Cambio debe ser 1.00'
msg_error(msg)
return false
}
if(moneda != 'MXN' && tipo_cambio == 1){
webix.UIManager.setFocus('txt_tipo_cambio')
msg = 'Si la moneda no es MXN, el Tipo de Cambio debe ser diferente de 1.00'
msg_error(msg)
return false
}
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 ser 6 digitos'
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().get('/values/timbrar', {id: id}, function(text, data){
var values = data.json()
if(values.ok){
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]['delete']
delete rows[i]['clave']
delete rows[i]['clave_sat']
delete rows[i]['unidad']
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['relacionados'] = ids
data['tipo_relacion'] = tipo_relacion
data['anticipo'] = anticipo
data['donativo'] = donativo
data['notas'] = values.notas
var usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){
var valores = {
TipoProceso: $$('lst_ine_tipo_proceso').getValue(),
TipoComite: $$('lst_ine_tipo_comite').getValue(),
IdContabilidad: $$('txt_ine_idcontabilidad').getValue(),
}
data['ine'] = valores
}
if(!save_invoice(data)){
return
}
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
}
//~ showvar(values)
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
'
}
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){
var form = $$('form_invoice')
var html = ''
form.setValues({
id_partner:row.id, search_client_id:'', search_client_name:'',
forma_pago: row.forma_pago, uso_cfdi: row.uso_cfdi}, true)
html += row.nombre + ' (' + row.rfc + ')'
$$('lbl_client').setValue(html)
$$('cmd_cfdi_relacionados').enable()
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 calculate_taxes(){
var tmp = null
table_totals.clear()
var subtotal = 0
var total_iva = 0
var id = 2
var grid_totals = $$('grid_totals')
grid_totals.clearAll()
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
grid.eachRow(function(row){
var product = grid.getItem(row)
subtotal += parseFloat(product.importe)
query = table_pt.chain().find({'product': product.id}).data()
for(var tax of query){
tmp = table_totals.findOne({'tax': tax.tax})
if(tmp === null){
table_totals.insert(
{'tax': tax.tax, 'importe': parseFloat(product.importe)})
tmp = table_totals.findOne({'tax': tax.tax})
}else{
tmp.importe += parseFloat(product.importe)
table_totals.update(tmp)
}
}
})
var tax = null
var tipo = 'Traslado '
var concepto = ''
var total_tax = 0
query = table_totals.chain().data()
for(var t of query){
tax = table_taxes.findOne({'id': t.tax})
if(tax.tipo == 'E' || tax.tipo == 'R'){
continue
}
concepto = tipo + tax.name + ' (' + tax.tasa + ')'
total_tax = (tax.tasa * t.importe).round(DECIMALES)
grid_totals.add({id: id, concepto: concepto, importe: total_tax})
id += 1
if(tax.name == 'IVA'){
total_iva += total_tax
}
}
tipo = 'Retención '
for(var t of query){
tax = table_taxes.findOne({'id': t.tax})
if(tax.tipo == 'E' || tax.tipo == 'T'){
continue
}
concepto = tipo + tax.name + ' (' + tax.tasa + ')'
if(tax.tasa == (2/3).round(6)){
total_tax = (tax.tasa * total_iva * -1).round(DECIMALES)
concepto = tipo + tax.name + ' (2/3)'
}else{
total_tax = (tax.tasa * t.importe * -1).round(DECIMALES)
}
grid_totals.add({id: id, concepto: concepto, importe: total_tax})
id += 1
}
var row = {importe: subtotal}
grid_totals.updateItem(1, row)
}
function calcular_impuestos(){
var tmp = null
var subtotal = 0
var id = 2
var grid_totals = $$('grid_totals')
var impuesto_producto = 0
var impuesto = null
table_totals.clear()
grid_totals.clearAll()
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
grid.eachRow(function(row){
var product = grid.getItem(row)
var importe = parseFloat(product.importe)
subtotal += importe
query = table_pt.chain().find({'product': product.id}).data()
for(var tax of query){
impuesto = table_taxes.findOne({'id': tax.tax})
if(impuesto.tipo == 'E'){
continue
}
var base = importe
if(impuesto.tipo == 'R'){
base = (importe * -1).round(DECIMALES)
}
impuesto_producto = (impuesto.tasa * base).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)
}
function set_product(values){
var taxes = values.taxes
var values = values.row
var form = $$('form_invoice')
var row = grid.getItem(values.id)
values['delete'] = '-'
if (row == undefined){
values['cantidad'] = 1
values['importe'] = values['valor_unitario']
grid.add(values)
} else {
values['cantidad'] = parseFloat(row.cantidad) + 1
values['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)
for(var v of taxes){
var pt = table_pt.findOne(v)
if(pt === null){
table_pt.insert(v)
}
}
//~ calculate_taxes()
calcular_impuestos()
}
function grid_products_found_click(obj){
search_product_by_key(obj.clave)
}
//~ function search_product_by_id(id){
//~ webix.ajax().get('/values/product', {'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_product(values)
//~ } else {
//~ msg = 'No se encontró un producto con la clave: ' + id
//~ msg_error(msg)
//~ }
//~ }
//~ })
//~ }
function search_product_by_key(key){
webix.ajax().get('/values/productokey', {'key': key}, {
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 = ['', 'descripcion', 'pedimento','cantidad', 'valor_unitario', 'descuento']
if(!columns.indexOf(id.column)){
return !this.getItem(id.row)[id.column]
}
}
function grid_details_before_edit_stop(state, editor){
var row = grid.getItem(editor.row)
if(editor.column == 'descripcion'){
if(!state.value.trim()){
msg = 'La descripción no puede estar vacía'
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. Edita estalo 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
}
var valor_unitario = parseFloat(row['valor_unitario'])
var descuento = parseFloat(row['descuento'])
}
if(editor.column == 'valor_unitario'){
var valor_unitario = parseFloat(state.value)
if(isNaN(valor_unitario)){
msg = 'El valor unitario debe ser un número'
msg_error(msg)
grid.blockEvent()
state.value = state.old
grid.editCancel()
grid.unblockEvent()
return true
}
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
}
var cantidad = parseFloat(row['cantidad'])
var valor_unitario = parseFloat(row['valor_unitario'])
}
var precio_final = valor_unitario - descuento
row['importe'] = (cantidad * precio_final).round(DECIMALES)
grid.refresh()
//~ calculate_taxes()
calcular_impuestos()
}
function grid_details_click(id, e, node){
if(id.column != 'delete'){
return
}
grid.remove(id.row)
//~ calculate_taxes()
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()
//~ calculate_taxes()
calcular_impuestos()
}
}
})
}
function cmd_refacturar_click(){
showvar('Refacturar')
}
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.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){
//~ location = '/doc/pdf/' + id
window.open('/doc/pdf/' + 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 == 'zip'){
location = '/doc/zip/' + row.id
}else if(id.column == 'email'){
enviar_correo(row)
}
}
function send_cancel(id){
webix.ajax().get('/values/cancelinvoice', {id: id}, function(text, data){
var values = data.json()
if(values.ok){
msg_ok(values.msg)
gi.updateItem(id, values.row)
}else{
webix.alert({
title: 'Error al Cancelar',
text: values.msg,
type: 'alert-error'
})
}
})
}
function cmd_invoice_cancelar_click(){
if(gi.count() == 0){
return
}
var row = gi.getSelectedItem()
if (row == undefined){
msg_error('Selecciona una factura')
return
}
if(!row.uuid){
msg_error('La factura no esta timbrada, solo es posible cancelar \
facturas timbradas')
return
}
if(row.estatus == 'Cancelada'){
msg_error('La factura ya esta cancelada')
return
}
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_cancel(row.id)
}
}
})
}
function get_invoices(rango){
if(rango == undefined){
var fy = $$('filter_year')
var fm = $$('filter_month')
var y = fy.getValue()
var m = fm.getValue()
rango = {'year': y, 'month': m}
}
var grid = $$('grid_invoices')
grid.showProgress({type: 'icon'})
webix.ajax().get('/invoices', 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 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(range)
}
}
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.uuid){
msg_error('La factura no esta timbrada, solo es posible consultar \
el estatus en el SAT de facturas timbradas')
return
}
webix.ajax().get('/values/statussat', {id: row.id}, function(text, data){
var values = data.json()
showvar(values)
})
}
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]['delete']
delete rows[i]['clave']
delete rows[i]['unidad']
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()
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()
}
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)
}
//~ calculate_taxes()
calcular_impuestos()
$$('tv_invoice').getTabbar().setValue('Generar')
}
})
}
function cmd_facturar_preinvoice_click(id, e, node){
var grid = $$('grid_preinvoices')
if(grid.count() == 0){
return
}
var row = grid.getSelectedItem()
if (row == undefined){
msg_error('Selecciona una prefactura')
return
}
var msg = '¿Estás seguro de facturar la siguiente PREFactura?
'
msg += '(' + row['folio'] + ') ' + row['cliente']
webix.confirm({
title: 'Generar Factura',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if (result){
refacturar_preinvoice(row['id'])
}
}
})
}
function enviar_prefactura(id){
msg = '¿Estás seguro de enviar por correo esta prefactura?'
webix.confirm({
title: 'Enviar Factura',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if(result){
webix.ajax().post('/values/enviarprefac', {'id': id.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 grid_preinvoices_click(id, e, node){
//~ var row = this.getItem(id)
if(id.column == 'pdf'){
//~ location = '/doc/pre/' + row.id
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_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').setValue('I')
$$('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')
}
function cmd_invoice_save_note_click(){
var value = $$('invoice_notes').getValue()
$$('form_invoice').setValues({notas: value}, true)
$$('win_invoice_notes').close()
}
function cmd_invoice_report_pdf_click(){
webix.toPDF($$('grid_invoices'), {
ignore: {'xml': true, 'pdf': true, 'zip': true, 'mail': true},
filename: 'Reporte_de_Facturas',
width: 612,
height: 792,
autowidth: true,
columns:{
index: true,
serie: {width: 50},
folio: {width: 50},
fecha: {width: 125},
tipo_comprobante: {width: 25},
estatus: true,
total_mn: {css: 'right'},
cliente: true,
}
})
}
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,
})
}