UNPKG

facturacionelectronicapy-xmlgen

Version:

API Node JS para generar el archivo XML del Documento electrónico exigido por SIFEN en base a JSON

886 lines 245 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const StringUtil_service_1 = __importDefault(require("./StringUtil.service")); const FechaUtil_service_1 = __importDefault(require("./FechaUtil.service")); const constants_service_1 = __importDefault(require("./constants.service")); const jsonDteItemValidate_service_1 = __importDefault(require("./jsonDteItemValidate.service")); class JSonDeMainValidateService { constructor() { this.errors = new Array(); } /** * Valida los datos ingresados en el data * A. Campos firmados del Documento Electrónico (A001-A099) * 1 - Validacion automática * 2 - Se realiza en el SIFEN, pero puede ser realizado en la API de integración * 3 - Se realiza en el SIFEN, pero puede ser realizado en la API de integración * 4 - Validacion automática * 5 - Se realiza en el SIFEN, la fecha/hora del servidor debe sincronizarse con el SIFEN * 6 - Falta, pero es AO * * B. Campos inherentes a la operación comercial de los Documentos Electrónicos (B001 -B099) * 7 - Falta * 8 - Validacion automática, via constante.service * * C. Campos de datos del Timbrado (C001 - C099) * 9 - Validacion automática, via constante.service * 10 - Se realiza en el SIFEN, se valida solo la primera vez * 11 - Se realiza en el SIFEN, se valida solo la primera vez * 12 - Se realiza en el SIFEN, se valida solo la primera vez * 13 - Se realiza en el SIFEN, se valida solo la primera vez * 14 - Se realiza en el SIFEN, se valida solo la primera vez * 15 - Se realiza en el SIFEN, se valida solo la primera vez * 16 - Se realiza en el SIFEN, pero puede ser realizado en la API de integración * * @param data */ validateValues(params, data, config) { this.errors = new Array(); if (constants_service_1.default.tiposDocumentos.filter((um) => um.codigo === +data['tipoDocumento']).length == 0) { this.errors.push("Tipo de Documento '" + data['tipoDocumento'] + "' en data.tipoDocumento no válido. Valores: " + constants_service_1.default.tiposDocumentos.map((a) => a.codigo + '-' + a.descripcion)); } if (typeof data['cliente'] == 'undefined') { this.errors.push('Debe especificar los datos del Cliente en data.cliente'); } if (data['cliente']) { if (typeof data['cliente']['contribuyente'] == 'undefined') { this.errors.push('Debe indicar si el Cliente es o no un Contribuyente true|false en data.cliente.contribuyente'); } if (typeof data['cliente']['contribuyente'] == 'undefined') { this.errors.push('Debe indicar si el Cliente es o no un Contribuyente true|false en data.cliente.contribuyente'); } if (!(data['cliente']['contribuyente'] === true || data['cliente']['contribuyente'] === false)) { this.errors.push('data.cliente.contribuyente debe ser true|false'); } } this.generateCodigoControlValidate(params, data); this.datosEmisorValidate(params, data); this.generateDatosOperacionValidate(params, data); this.generateDatosGeneralesValidate(params, data, config); this.generateDatosEspecificosPorTipoDEValidate(params, data); if (data['tipoDocumento'] == 4) { this.generateDatosAutofacturaValidate(params, data); } if (data['tipoDocumento'] == 1 || data['tipoDocumento'] == 4) { this.generateDatosCondicionOperacionDEValidate(params, data); } this.errors = jsonDteItemValidate_service_1.default.generateDatosItemsOperacionValidate(params, data, config, this.errors); this.generateDatosComplementariosComercialesDeUsoEspecificosValidate(params, data); if (data['tipoDocumento'] == 1 || data['tipoDocumento'] == 7) { //1 Opcional, 7 Obligatorio if (data['tipoDocumento'] == 7) { if (!data['detalleTransporte']) { this.errors.push('Debe especificar el detalle de transporte en data.transporte para el Tipo de Documento = 7'); } else { this.generateDatosTransporteValidate(params, data); } } else { //Es por que tipoDocumento = 1 if (data['detalleTransporte']) { this.generateDatosTransporteValidate(params, data); } } } if (data['tipoDocumento'] != 7) { this.generateDatosTotalesValidate(params, data, config); } if (data['complementarios']) { this.generateDatosComercialesUsoGeneralValidate(params, data); } if (data['moneda'] != 'PYG' && data['condicionTipoCambio'] == 1) { if (!data['cambio']) { this.errors.push('Debe especificar el valor del Cambio en data.cambio cuando moneda != PYG y la Cotización es Global'); } } if (data['tipoDocumento'] == 4 || data['tipoDocumento'] == 5 || data['tipoDocumento'] == 6) { if (!data['documentoAsociado']) { this.errors.push('Documento asociado es obligatorio para el tipo de documento electrónico (' + data['tipoDocumento'] + ') seleccionado'); } } if (data['tipoDocumento'] == 1 || data['tipoDocumento'] == 4 || data['tipoDocumento'] == 5 || data['tipoDocumento'] == 6 || data['tipoDocumento'] == 7) { if (data['documentoAsociado']) { if (!Array.isArray(data['documentoAsociado'])) { this.generateDatosDocumentoAsociadoValidate(params, data['documentoAsociado'], data); } else { //Caso sea un array. for (var i = 0; i < data['documentoAsociado'].length; i++) { const dataDocumentoAsociado = data['documentoAsociado'][i]; this.generateDatosDocumentoAsociadoValidate(params, dataDocumentoAsociado, data); } } } } //Tratamiento Final, del Envio del Error, no tocar if (this.errors.length > 0) { let errorExit = new Error(); let msgErrorExit = ''; let recorrerHasta = this.errors.length; if ((config.errorLimit || 3) < recorrerHasta) { recorrerHasta = config.errorLimit || 3; } for (let i = 0; i < recorrerHasta; i++) { const error = this.errors[i]; msgErrorExit += error; if (i < recorrerHasta - 1) { msgErrorExit += config.errorSeparator + ''; } } errorExit.message = msgErrorExit; /*errorExit.firstMessage = this.errors[0]; errorExit.errorsArray = this.errors;*/ throw errorExit; } } generateCodigoControlValidate(params, data) { if (data.cdc && (data.cdc + '').length == 44) { //Caso ya se le pase el CDC //const codigoSeguridad = data.cdc.substring(34, 43); const codigoControl = data.cdc; //Como se va utilizar el CDC enviado como parametro, va a verificar que todos los datos del XML coincidan con el CDC. const tipoDocumentoCDC = codigoControl.substring(0, 2); //const rucCDC = this.codigoControl.substring(2, 10); //const dvCDC = this.codigoControl.substring(10, 11); const establecimientoCDC = codigoControl.substring(11, 14); const puntoCDC = codigoControl.substring(14, 17); const numeroCDC = codigoControl.substring(17, 24); //const tipoContribuyenteCDC = this.codigoControl.substring(24, 25); const fechaCDC = codigoControl.substring(25, 33); const tipoEmisionCDC = codigoControl.substring(33, 34); if (+data['tipoDocumento'] != +tipoDocumentoCDC) { this.errors.push("El Tipo de Documento '" + data['tipoDocumento'] + "' en data.tipoDocumento debe coincidir con el CDC re-utilizado (" + +tipoDocumentoCDC + ')'); } const establecimiento = StringUtil_service_1.default.leftZero(data['establecimiento'], 3); if (establecimiento != establecimientoCDC) { this.errors.push("El Establecimiento '" + establecimiento + "'en data.establecimiento debe coincidir con el CDC reutilizado (" + establecimientoCDC + ')'); } const punto = StringUtil_service_1.default.leftZero(data['punto'], 3); if (punto != puntoCDC) { this.errors.push("El Punto '" + punto + "' en data.punto debe coincidir con el CDC reutilizado (" + puntoCDC + ')'); } const numero = StringUtil_service_1.default.leftZero(data['numero'], 7); if (numero != numeroCDC) { this.errors.push("El Numero de Documento '" + numero + "'en data.numero debe coincidir con el CDC reutilizado (" + numeroCDC + ')'); } /*if (+data['tipoContribuyente'] != +tipoContribuyenteCDC) { this.errors.push("El Tipo de Contribuyente '" + data['tipoContribuyente'] + "' en data.tipoContribuyente debe coincidir con el CDC reutilizado (" + tipoContribuyenteCDC + ")"); }*/ const fecha = (data['fecha'] + '').substring(0, 4) + (data['fecha'] + '').substring(5, 7) + (data['fecha'] + '').substring(8, 10); if (fecha != fechaCDC) { this.errors.push("La fecha '" + fecha + "' en data.fecha debe coincidir con el CDC reutilizado (" + fechaCDC + ')'); } if (+data['tipoEmision'] != +tipoEmisionCDC) { this.errors.push("El Tipo de Emisión '" + data['tipoEmision'] + "' en data.tipoEmision debe coincidir con el CDC reutilizado (" + tipoEmisionCDC + ')'); } } } datosEmisorValidate(params, data) { if (params['ruc'].indexOf('-') == -1) { this.errors.push('RUC debe contener dígito verificador en params.ruc'); } let rucEmisor = params['ruc'].split('-')[0]; const dvEmisor = params['ruc'].split('-')[1]; var reg = new RegExp(/^\d+$/); /*if (!reg.test(rucEmisor)) { this.errors.push("La parte que corresponde al RUC '" + params['ruc'] + "' en params.ruc debe ser numérico"); }*/ if (rucEmisor.length > 8) { this.errors.push("La parte que corresponde al RUC '" + params['ruc'] + "' en params.ruc debe contener de 1 a 8 caracteres"); } if (!reg.test(dvEmisor)) { this.errors.push("La parte que corresponde al DV del RUC '" + params['ruc'] + "' en params.ruc debe ser numérico"); } if (dvEmisor > 9) { this.errors.push("La parte que corresponde al DV del RUC '" + params['ruc'] + "' en params.ruc debe ser del 1 al 9"); } if (!((params['timbradoNumero'] + '').length == 8)) { this.errors.push('Debe especificar un Timbrado de 8 caracteres en params.timbradoNumero'); } if (!FechaUtil_service_1.default.isIsoDate(params['timbradoFecha'])) { this.errors.push("Valor de la Fecha '" + params['timbradoFecha'] + "' en params.fecha no válido. Formato: yyyy-MM-dd"); } if (params['tipoRegimen']) { if (constants_service_1.default.tiposRegimenes.filter((um) => um.codigo === params['tipoRegimen']).length == 0) { this.errors.push("Tipo de Regimen '" + data['tipoRegimen'] + "' en params.tipoRegimen no válido. Valores: " + constants_service_1.default.tiposRegimenes.map((a) => a.codigo + '-' + a.descripcion)); } } if (!params['razonSocial']) { this.errors.push('La razon social del emisor en params.razonSocial no puede ser vacio'); } else { if (!((params['razonSocial'] + '').length >= 4 && (params['razonSocial'] + '').length <= 250)) { this.errors.push("La razon Social del Emisor '" + params['razonSocial'] + "' en params.razonSocial debe tener de 4 a 250 caracteres"); } } if (params['nombreFantasia'] && (params['nombreFantasia'] + '').length > 0) { if (!((params['nombreFantasia'] + '').length >= 4 && (params['nombreFantasia'] + '').length <= 250)) { this.errors.push("El nombre de Fantasia del Emisor '" + params['nombreFantasia'] + "' en params.nombreFantasia debe tener de 4 a 250 caracteres"); } } //Aqui hay que verificar los datos de las sucursales if (!(params['establecimientos'] && Array.isArray(params['establecimientos']))) { this.errors.push('Debe especificar un array de establecimientos en params.establecimientos'); } else { for (let i = 0; i < params['establecimientos'].length; i++) { const establecimiento = params['establecimientos'][i]; if (!establecimiento.codigo) { this.errors.push('Debe especificar el código del establecimiento en params.establecimientos[' + i + '].codigo'); } if (establecimiento['telefono']) { if (!(establecimiento['telefono'].length >= 6 && establecimiento['telefono'].length <= 15)) { this.errors.push("El valor '" + establecimiento['telefono'] + "' en params.establecimientos[" + i + '].telefono debe tener una longitud de 6 a 15 caracteres'); } else { if ((establecimiento['telefono'] + '').includes('(') || (establecimiento['telefono'] + '').includes(')') || (establecimiento['telefono'] + '').includes('[') || (establecimiento['telefono'] + '').includes(']')) { /*this.errors.push( "El valor '" + establecimiento['telefono'] + "' en params.establecimientos[" + i + '].telefono no puede contener () o []', );*/ //Finalmente no da error en SIFEN por esto } } } } } } generateDatosOperacionValidate(params, data) { /*if (params['ruc'].indexOf('-') == -1) { //removido temporalmente, parece que no hace falta this.errors.push('RUC debe contener dígito verificador en params.ruc'); }*/ if (constants_service_1.default.tiposEmisiones.filter((um) => um.codigo === data['tipoEmision']).length == 0) { this.errors.push("Tipo de Emisión '" + data['tipoEmision'] + "' en data.tipoEmision no válido. Valores: " + constants_service_1.default.tiposEmisiones.map((a) => a.codigo + '-' + a.descripcion)); } //Validar aqui "dInfoFisc" if (data['tipoDocumento'] == 7) { //Nota de Remision if (!(data['descripcion'] && (data['descripcion'] + '').trim().length > 0)) { //Segun dicen en TDE no es obligatorio, entonces se retira la validacion. //this.errors.push('Debe informar la Descripción en data.descripcion para el Documento Electrónico'); } } } generateDatosGeneralesValidate(params, data, config) { this.generateDatosGeneralesInherentesOperacionValidate(params, data); this.generateDatosGeneralesEmisorDEValidate(params, data); if (config.userObjectRemove == false) { //Si está TRUE no crea el objeto usuario if (data['usuario']) { //No es obligatorio this.generateDatosGeneralesResponsableGeneracionDEValidate(params, data); } } this.generateDatosGeneralesReceptorDEValidate(params, data); } generateDatosGeneralesInherentesOperacionValidate(params, data) { if (data['tipoDocumento'] == 7) { //C002 return; //No informa si el tipo de documento es 7 } if (!FechaUtil_service_1.default.isIsoDateTime(data['fecha'])) { this.errors.push("Valor de la Fecha '" + data['fecha'] + "' en data.fecha no válido. Formato: yyyy-MM-ddTHH:mm:ss"); } if (!data['tipoImpuesto']) { this.errors.push('Debe especificar el Tipo de Impuesto en data.tipoImpuesto'); } else { if (constants_service_1.default.tiposImpuestos.filter((um) => um.codigo === +data['tipoImpuesto']).length == 0) { this.errors.push("Tipo de Impuesto '" + data['tipoImpuesto'] + "' en data.tipoImpuesto no válido. Valores: " + constants_service_1.default.tiposImpuestos.map((a) => a.codigo + '-' + a.descripcion)); } } let moneda = data['moneda']; if (!moneda) { moneda = 'PYG'; } if (constants_service_1.default.monedas.filter((um) => um.codigo === moneda).length == 0) { this.errors.push("Moneda '" + moneda + "' en data.moneda no válido. Valores: " + constants_service_1.default.monedas.map((a) => a.codigo + '-' + a.descripcion)); } if (data['condicionAnticipo']) { if (constants_service_1.default.globalPorItem.filter((um) => um.codigo === data['condicionAnticipo']).length == 0) { this.errors.push("Condición de Anticipo '" + data['condicionAnticipo'] + "' en data.condicionAnticipo no válido. Valores: " + constants_service_1.default.globalPorItem.map((a) => a.codigo + '-Anticipo ' + a.descripcion)); } } else { //condicionAnticipo - si no tiene condicion anticipo, pero tipo transaccion es 9, que de un error. } if (constants_service_1.default.tiposTransacciones.filter((um) => um.codigo === data['tipoTransaccion']).length == 0) { this.errors.push("Tipo de Transacción '" + data['tipoTransaccion'] + "' en data.tipoTransaccion no válido. Valores: " + constants_service_1.default.tiposTransacciones.map((a) => a.codigo + '-' + a.descripcion)); } if (data['tipoDocumento'] == 1 || data['tipoDocumento'] == 4) { //Obligatorio informar iTipTra D011 if (!data['tipoTransaccion']) { this.errors.push('Debe proveer el Tipo de Transacción en data.tipoTransaccion'); } } if (moneda != 'PYG') { if (!data['condicionTipoCambio']) { this.errors.push('Debe informar el tipo de Cambio en data.condicionTipoCambio'); } } if (data['condicionTipoCambio'] == 1 && moneda != 'PYG') { if (!(data['cambio'] && data['cambio'] > 0)) { this.errors.push('Debe informar el valor del Cambio en data.cambio'); } } if (data['obligaciones']) { if (!Array.isArray(data['obligaciones'])) { this.errors.push('El valor de data.obligaciones debe ser un Array'); } else { for (let i = 0; i < data['obligaciones'].length; i++) { let obligacion = data['obligaciones'][i]; if (!obligacion.codigo) { this.errors.push('No fue especificado un código en data.obligaciones[' + i + '].codigo'); } else { //Verificar cada item if (constants_service_1.default.obligaciones.filter((um) => um.codigo === +obligacion.codigo).length == 0) { this.errors.push("Obligación '" + obligacion.codigo + "' en data.obligaciones[" + i + '].codigo no válido. Valores: ' + constants_service_1.default.obligaciones.map((a) => a.codigo + '-' + a.descripcion)); } } } } } } generateDatosGeneralesEmisorDEValidate(params, data) { const regExpOnlyNumber = new RegExp(/^\d+$/); if (!(params && params.establecimientos)) { this.errors.push('Debe proveer un Array con la información de los establecimientos en params'); } //Validar si el establecimiento viene en params let establecimiento = StringUtil_service_1.default.leftZero(data['establecimiento'], 3); //let punto = stringUtilService.leftZero(data['punto'], 3); if (params.establecimientos.filter((um) => um.codigo === establecimiento).length == 0) { this.errors.push("Establecimiento '" + establecimiento + "' no encontrado en params.establecimientos*.codigo. Valores: " + params.establecimientos.map((a) => a.codigo + '-' + a.denominacion)); } /*if (params['ruc'].indexOf('-') == -1) { //Removido temporalmente, al parecer no hace falta this.errors.push('RUC debe contener dígito verificador en params.ruc'); }*/ if (!(params['actividadesEconomicas'] && params['actividadesEconomicas'].length > 0)) { this.errors.push('Debe proveer el array de actividades económicas en params.actividadesEconomicas'); } //Validacion de algunos datos de la sucursal const establecimientoUsado = params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]; if (!establecimientoUsado) { this.errors.push('Debe especificar los datos del Establecimiento "' + establecimiento + '" en params.establecimientos*'); } else { if (!establecimientoUsado.ciudad) { this.errors.push('Debe proveer la Ciudad del establecimiento en params.establecimientos*.ciudad'); } if (!establecimientoUsado.distrito) { this.errors.push('Debe proveer la Distrito del establecimiento en params.establecimientos*.distrito'); } if (!establecimientoUsado.departamento) { this.errors.push('Debe proveer la Departamento del establecimiento en params.establecimientos*.departamento'); } constants_service_1.default.validateDepartamentoDistritoCiudad('params.establecimientos*', +establecimientoUsado.departamento, +establecimientoUsado.distrito, +establecimientoUsado.ciudad, this.errors); if (establecimientoUsado['numeroCasa']) { if (!regExpOnlyNumber.test(establecimientoUsado['numeroCasa'])) { this.errors.push('El Número de Casa en params.establecimientos*.numeroCasa debe ser numérico'); } } } } generateDatosGeneralesResponsableGeneracionDEValidate(params, data) { if (constants_service_1.default.tiposDocumentosIdentidades.filter((um) => um.codigo === +data['usuario']['documentoTipo']) .length == 0) { this.errors.push("Tipo de Documento '" + data['usuario']['documentoTipo'] + "' no encontrado en data.usuario.documentoTipo. Valores: " + constants_service_1.default.tiposDocumentosIdentidades.map((a) => a.codigo + '-' + a.descripcion)); } if (!data['usuario']['documentoNumero']) { this.errors.push('El Documento del Responsable en data.usuario.documentoNumero no puede ser vacio'); } if (!data['usuario']['nombre']) { this.errors.push('El Nombre del Responsable en data.usuario.nombre no puede ser vacio'); } if (!data['usuario']['cargo']) { this.errors.push('El Cargo del Responsable en data.usuario.cargo no puede ser vacio'); } } generateDatosGeneralesReceptorDEValidate(params, data) { if (!data['cliente']) { return; //El error de cliente vacio, ya fue validado arriba } if (!data['cliente']['tipoOperacion']) { this.errors.push('Tipo de Operación del Cliente en data.cliente.tipoOperacion es requerido > 0'); } else { if (constants_service_1.default.tiposOperaciones.filter((um) => um.codigo === +data['cliente']['tipoOperacion']).length == 0) { this.errors.push("Tipo de Operación '" + data['cliente']['tipoOperacion'] + "' del Cliente en data.cliente.tipoOperacion no encontrado. Valores: " + constants_service_1.default.tiposOperaciones.map((a) => a.codigo + '-' + a.descripcion)); } } if (!data['cliente']['contribuyente'] && data['cliente']['tipoOperacion'] != 4) { if (constants_service_1.default.tiposDocumentosReceptor.filter((um) => um.codigo === +data['cliente']['documentoTipo']) .length == 0) { this.errors.push("Tipo de Documento '" + data['cliente']['documentoTipo'] + "' del Cliente en data.cliente.documentoTipo no encontrado. Valores: " + constants_service_1.default.tiposDocumentosReceptor.map((a) => a.codigo + '-' + a.descripcion)); if (+data['cliente']['documentoTipo'] == 9) { if (!data['cliente']['documentoTipoDescripcion']) { this.errors.push('Debe especificar la Descripción para el tipo de Documento en data.cliente.documentoTipoDescripcion para documentoTipo=9'); } } } } var regExpOnlyNumber = new RegExp(/^\d+$/); if (data['cliente']['contribuyente']) { if (!data['cliente']['ruc']) { this.errors.push('Debe proporcionar el RUC en data.cliente.ruc'); } else { if (data['cliente']['ruc'].indexOf('-') == -1) { this.errors.push('RUC debe contener dígito verificador en data.cliente.ruc'); } const rucCliente = data['cliente']['ruc'].split('-'); //Un RUC puede ser alphanumerico /*if (!regExpOnlyNumber.test((rucCliente[0] + '').trim())) { this.errors.push( "La parte del RUC del Cliente '" + data['cliente']['ruc'] + "' en data.cliente.ruc debe ser numérico", ); }*/ if (!regExpOnlyNumber.test((rucCliente[1] + '').trim())) { this.errors.push("La parte del DV del RUC del Cliente '" + data['cliente']['ruc'] + "' en data.cliente.ruc debe ser numérico"); } if (!(rucCliente[0].length >= 3 && rucCliente[0].length <= 8)) { this.errors.push("La parte del RUC '" + data['cliente']['ruc'] + "' en data.cliente.ruc debe contener de 3 a 8 caracteres"); } if (rucCliente[1] > 9) { this.errors.push("La parte del DV del RUC '" + data['cliente']['ruc'] + "' en data.cliente.ruc debe ser del 1 al 9"); } } if (!data['cliente']['tipoContribuyente']) { this.errors.push('Debe proporcionar el Tipo de Contribuyente en data.cliente.tipoContribuyente'); } } if (!data['cliente']['razonSocial']) { this.errors.push('La razon social del receptor en data.cliente.razonSocial no puede ser vacio'); } else { if (!((data['cliente']['razonSocial'] + '').length >= 4 && (data['cliente']['razonSocial'] + '').length <= 250)) { this.errors.push("La razon Social del Cliente '" + data['cliente']['razonSocial'] + "' en data.cliente.razonSocial debe tener de 4 a 250 caracteres"); } } if (data['cliente']['nombreFantasia'] && (data['cliente']['nombreFantasia'] + '').length > 0) { if (!((data['cliente']['nombreFantasia'] + '').length >= 4 && (data['cliente']['nombreFantasia'] + '').length <= 250)) { this.errors.push("El nombre de Fantasia del Cliente '" + data['cliente']['nombreFantasia'] + "' en data.cliente.nombreFantasia debe tener de 4 a 250 caracteres"); } } if (constants_service_1.default.paises.filter((pais) => pais.codigo === data['cliente']['pais']).length == 0) { this.errors.push("Pais '" + data['cliente']['pais'] + "' del Cliente en data.cliente.pais no encontrado."); } if (data['tipoDocumento'] == 4) { if (data['cliente']['tipoOperacion'] != 2) { this.errors.push('El Tipo de Operación debe ser 2-B2C para el Tipo de Documento AutoFactura'); } } if (!data['cliente']['contribuyente'] && data['cliente']['tipoOperacion']) { //No es contribuyente //Obligatorio completar D210 if (!data['cliente']['contribuyente'] && data['cliente']['tipoOperacion'] != 4) { if (!data['cliente']['documentoTipo']) { //Val.: 59 this.errors.push('Debe informar el Tipo de Documento del Cliente en data.cliente.documentoTipo'); } else { let documentoTipoDS = constants_service_1.default.tiposDocumentosReceptor.filter((tdr) => tdr.codigo === +data['cliente']['documentoTipo']); if (documentoTipoDS.length <= 0) { this.errors.push('Tipo de Documento del Cliente en data.cliente.documentoTipo no válido'); } } //Cuando el campo puede ser un número, y se admite el valor cero, mejor preguntar de ésta forma if (typeof data['cliente']['documentoNumero'] == 'undefined') { //Val.: 65 this.errors.push('Debe informar el número de documento en data.cliente.documentoNumero'); } else { //Validar que documentoNumero no tenga . if ((data['cliente']['documentoNumero'] + '').indexOf('.') > -1) { this.errors.push('El valor "' + data['cliente']['documentoNumero'] + '" en data.cliente.documentoNumero no es válido '); } //Validar que documentoNumero no tenga / if ((data['cliente']['documentoNumero'] + '').indexOf('/') > -1) { this.errors.push('El valor "' + data['cliente']['documentoNumero'] + '" en data.cliente.documentoNumero no es válido '); } } } } //Este es solo una validacion por si coloca un documentoTipo erróneo, independientemente asi tiene que tener o no el campo if (data['cliente']['documentoTipo']) { let documentoTipoDS = constants_service_1.default.tiposDocumentosReceptor.filter((tdr) => tdr.codigo === +data['cliente']['documentoTipo']); if (documentoTipoDS.length <= 0) { this.errors.push('Tipo de Documento del Cliente ' + data['cliente']['documentoTipo'] + ' en data.cliente.documentoTipo no válido'); } } if (!data['cliente']['contribuyente'] && data['tipoDocumento'] != 4 && data['cliente']['tipoOperacion'] != 2 && data['cliente']['tipoOperacion'] != 4) { //Val.: 46. parrafo 1 this.errors.push('El tipo de Operación debe ser 2-B2C o 4-B2F para el Receptor "No Contribuyente"'); } if (data['cliente']['tipoOperacion'] == 4 && data['cliente']['contribuyente'] == true) { //Val.: 46. parrafo 2 this.errors.push('La naturaleza del Receptor debe ser "No contribuyente" para el Tipo de Operación = 4-B2F'); } //Temporal Mercosys /*if (data['tipoDocumento'] === 7 || data['cliente']['tipoOperacion'] === 4) { if (!data['cliente']['direccion']) { this.errors.push('data.cliente.direccion es Obligatorio para Tipo de Documento 7 o Tipo de Operación 4'); } }*/ if (data['tipoDocumento'] === 7) { if (!data['cliente']['direccion']) { this.errors.push('data.cliente.direccion es Obligatorio para Tipo de Documento 7'); } } if (data['cliente']['direccion']) { //Si tiene dirección hay que completar numero de casa. if (!((data['cliente']['direccion'] + '').trim().length >= 1 && (data['cliente']['direccion'] + '').trim().length <= 255)) { this.errors.push("La dirección del Receptor '" + data['cliente']['direccion'] + "' en data.cliente.direccion debe tener de 1 a 255 caracteres"); } if (data['cliente']['numeroCasa'] == null) { this.errors.push('Debe informar el Número de casa del Receptor en data.cliente.numeroCasa'); } if (!((data['cliente']['numeroCasa'] + '').length > 0)) { this.errors.push('Debe informar el Número de casa del Receptor en data.cliente.numeroCasa'); } //Nueva forma de validar campos numericos /* if ( ! ( data['cliente']['numeroCasa'] != null && (data['cliente']['numeroCasa'] + '').length > 0 && regExpOnlyNumber.test(data['cliente']['numeroCasa']) ) ) { this.errors.push('Debe informar el Número de casa del Receptor en data.cliente.numeroCasa'); } */ } if (data['cliente']['numeroCasa']) { if (!regExpOnlyNumber.test(data['cliente']['numeroCasa'])) { this.errors.push('El Número de Casa en data.cliente.numeroCasa debe ser numérico'); } } if (data['cliente']['direccion'] && data['cliente']['tipoOperacion'] != 4) { if (!data['cliente']['ciudad']) { this.errors.push('Obligatorio especificar la Ciudad en data.cliente.ciudad para Tipo de Operación != 4'); } else { if (constants_service_1.default.ciudades.filter((ciudad) => ciudad.codigo === +data['cliente']['ciudad']).length == 0) { this.errors.push("Ciudad '" + data['cliente']['ciudad'] + "' del Cliente en data.cliente.ciudad no encontrado. Valores: " + constants_service_1.default.ciudades.map((a) => a.codigo + '-' + a.descripcion)); } //De acuerdo a la Ciudad pasada como parametro, buscar el distrito y departamento y asignar dichos //valores de forma predeterminada, aunque este valor sera sobre-escrito caso el usuario envie //data['cliente']['distrito'] y data['cliente']['departamento'] let objCiudad = constants_service_1.default.ciudades.filter((ciu) => ciu.codigo === +data['cliente']['ciudad']); if (objCiudad && objCiudad[0]) { let objDistrito = constants_service_1.default.distritos.filter((dis) => dis.codigo === +objCiudad[0]['distrito']); let objDepartamento = constants_service_1.default.departamentos.filter((dep) => dep.codigo === +objDistrito[0]['departamento']); data['cliente']['distrito'] = objDistrito[0]['codigo']; data['cliente']['departamento'] = objDepartamento[0]['codigo']; } } if (!data['cliente']['distrito']) { this.errors.push('Obligatorio especificar el Distrito en data.cliente.distrito para Tipo de Operación != 4'); } else if (constants_service_1.default.distritos.filter((distrito) => distrito.codigo === +data['cliente']['distrito']).length == 0) { this.errors.push("Distrito '" + data['cliente']['distrito'] + "' del Cliente en data.cliente.distrito no encontrado. Valores: " + constants_service_1.default.distritos.map((a) => a.codigo + '-' + a.descripcion)); } if (!data['cliente']['departamento']) { this.errors.push('Obligatorio especificar el Departamento en data.cliente.departamento para Tipo de Operación != 4'); } else if (constants_service_1.default.departamentos.filter((departamento) => departamento.codigo === +data['cliente']['departamento']).length == 0) { this.errors.push("Departamento '" + data['cliente']['departamento'] + "' del Cliente en data.cliente.departamento no encontrado. Valores: " + constants_service_1.default.departamentos.map((a) => a.codigo + '-' + a.descripcion)); } //console.log("distrito", data['cliente']['distrito'], "ciudad", data['cliente']['ciudad'], "departamento", data['cliente']['departamento']); constants_service_1.default.validateDepartamentoDistritoCiudad('data.cliente', +data['cliente']['departamento'], +data['cliente']['distrito'], +data['cliente']['ciudad'], this.errors); } if (data['cliente']['tipoOperacion'] == 4) { if (data['cliente']['pais'] == 'PRY') { this.errors.push('El tipo de Operación = 4-B2F requiere un pais diferente a PRY'); } } if (data['cliente']['telefono']) { if (!(data['cliente']['telefono'].length >= 6 && data['cliente']['telefono'].length <= 15)) { this.errors.push("El valor '" + data['cliente']['telefono'] + "' en data.cliente.telefono debe tener una longitud de 6 a 15 caracteres"); } else { if ((data['cliente']['telefono'] + '').includes('(') || (data['cliente']['telefono'] + '').includes(')') || (data['cliente']['telefono'] + '').includes('[') || (data['cliente']['telefono'] + '').includes(']')) { /*this.errors.push( "El valor '" + data['cliente']['telefono'] + "' en data.cliente.telefono no puede contener () o []", );*/ //Finalmente no da error en SIFEN por esto } } } const validateNumeroCelular = (celular, errors) => { if (!(celular.length >= 10 && celular.length <= 20)) { errors.push("El valor '" + celular + "' en data.cliente.celular debe tener una longitud de 10 a 20 caracteres"); } else { if ((celular + '').includes('(') || (celular + '').includes(')') || (celular + '').includes('[') || (celular + '').includes(']') || (celular + '').includes(';') || (celular + '').includes('=') || (celular + '').includes('/') || (celular + '').includes('\\')) { errors.push("El valor '" + celular + "' en data.cliente.celular no puede contener (), [] o ;"); } } }; if (data['cliente']['celular']) { //Primero verificar si el celular tiene comas if ((data['cliente']['celular'] + '').includes(',')) { let celulares = data['cliente']['celular'].split(','); for (let i = 0; i < celulares.lenght; i++) { validateNumeroCelular(celulares[i], this.errors); } } else { validateNumeroCelular(data['cliente']['celular'], this.errors); } } if (data['cliente']['email']) { let email = new String(data['cliente']['email']); //Hace una copia, para no alterar. //Verificar si tiene varios correos. if (email.indexOf(',') > -1) { //Si el Email tiene , (coma) entonces va enviar solo el primer valor, ya que SIFEN no acepta Comas email = email.split(',')[0].trim(); } //Verificar espacios if (email.indexOf(' ') > -1) { this.errors.push("El valor '" + email + "' en data.cliente.email no puede poseer espacios"); } if (!(email.length >= 3 && email.length <= 80)) { this.errors.push("El valor '" + email + "' en data.cliente.email debe tener una longitud de 3 a 80 caracteres"); } //se valida el mail var regExEmail = new RegExp(/^[A-Za-z0-9_!#$%&'*+\/=?`{|}~^.-]+@[A-Za-z0-9.-]+$/gm); if (!regExEmail.test(email + '')) { this.errors.push("El valor '" + email + "' en data.cliente.email es inválido"); } } if (data['cliente']['codigo']) { if (!((data['cliente']['codigo'] + '').length >= 3 && (data['cliente']['codigo'] + '').length <= 15)) { this.errors.push("El código del Cliente '" + data['cliente']['codigo'] + "' en data.cliente.codigo debe tener de 3 a 15 caracteres"); } } } generateDatosEspecificosPorTipoDEValidate(params, data) { if (data['tipoDocumento'] === 1) { this.generateDatosEspecificosPorTipoDE_FacturaElectronicaValidate(params, data); } if (data['tipoDocumento'] === 4) { this.generateDatosEspecificosPorTipoDE_AutofacturaValidate(params, data); } if (data['tipoDocumento'] === 5 || data['tipoDocumento'] === 6) { this.generateDatosEspecificosPorTipoDE_NotaCreditoDebitoValidate(params, data); } if (data['tipoDocumento'] === 7) { this.generateDatosEspecificosPorTipoDE_RemisionElectronicaValidate(params, data); } } generateDatosEspecificosPorTipoDE_FacturaElectronicaValidate(params, data) { if (!data['factura']) { this.errors.push('Debe indicar los datos especificos de la Factura en data.factura'); return; // Termina el metodos } if (constants_service_1.default.indicadoresPresencias.filter((um) => um.codigo === +data['factura']['presencia']).length == 0) { this.errors.push("Indicador de Presencia '" + data['factura']['presencia'] + "' en data.factura.presencia no encontrado. Valores: " + constants_service_1.default.indicadoresPresencias.map((a) => a.codigo + '-' + a.descripcion)); } if (data['factura']['fechaEnvio']) { let fechaFactura = new Date(data['fecha']); let fechaEnvio = new Date(data['factura']['fechaEnvio']); if (fechaFactura.getTime() > fechaEnvio.getTime()) { this.errors.push("La Fecha de envío '" + data['factura']['fechaEnvio'] + "'en data.factura.fechaEnvio, debe ser despues de la fecha de Factura"); } } if (data['cliente']['tipoOperacion'] === 3) { this.generateDatosEspecificosPorTipoDE_ComprasPublicasValidate(params, data); } } /** * Datos especificos cuando el tipo de operacion del receptor es B2G (Campo D202) * Dentro de la factura electronica * * @param params * @param data * @param options */ generateDatosEspecificosPorTipoDE_ComprasPublicasValidate(params, data) { if (!(data['dncp'] && data['dncp']['modalidad'] && (data['dncp']['modalidad'] + '').length == 2)) { this.errors.push('Debe informar la modalidad de Contratación DNCP (2 digitos) en data.dncp.modalidad'); } /*if ( !(data['dncp'] && data['dncp']['entidad'] && +data['dncp']['entidad'] > 9999 && +data['dncp']['entidad'] < 100000) ) {*/ if (!(data['dncp'] && data['dncp']['entidad'] && (data['dncp']['entidad'] + '').length == 5)) { this.errors.push('Debe informar la entidad de Contratación DNCP (5 digitos) en data.dncp.entidad'); } //if (!(data['dncp'] && data['dncp']['año'] && +data['dncp']['año'] > 0 && +data['dncp']['año'] < 100)) { if (!(data['dncp'] && data['dncp']['año'] && (data['dncp']['año'] + '').length == 2)) { this.errors.push('Debe informar el año de Contratación DNCP (2 digitos) en data.dncp.año'); } /*if ( !( data['dncp'] && data['dncp']['secuencia'] && +data['dncp']['secuencia'] > 999999 && +data['dncp']['secuencia'] < 10000000 ) ) { this.errors.push('Debe informar la secuencia de Contratación DNCP (7 digitos) en data.dncp.secuencia'); }*/ if (!(data['dncp'] && data['dncp']['secuencia'] && (data['dncp']['secuencia'] + '').length == 7)) { this.errors.push('Debe informar la secuencia de Contratación DNCP (7 digitos) en data.dncp.secuencia'); } if (!(data['dncp'] && data['dncp']['fecha'] && (data['dncp']['fecha'] + '').length > 0)) { this.errors.push('Debe informar la fecha de emisión de código de Contratación DNCP en data.dncp.fecha'); } else { if (!FechaUtil_service_1.default.isIsoDate(data['dncp']['fecha'])) { this.errors.push("Fecha DNCP '" + data['dncp']['fecha'] + "' en data.dncp.fecha no válida. Formato: yyyy-MM-dd"); } } } generateDatosEspecificosPorTipoDE_AutofacturaValidate(params, data) { if (!data['autoFactura']) { this.errors.push('Para tipoDocumento = 4 debe proveer los datos de Autofactura en data.autoFactura'); } if (!data['autoFactura']['ubicacion']) { this.errors.push('Para tipoDocumento = 4 debe proveer los datos del Lugar de Transacción de la Autofactura en data.autoFactura.ubicacion'); } if (!data['autoFactura']['tipoVendedor']) { this.errors.push('Debe especificar la Naturaleza del Vendedor en data.autoFactura.tipoVendedor'); } if (!data['autoFactura']['documentoTipo']) { this.errors.push('Debe especificar el Tipo de Documento del Vendedor en data.autoFactura.documentoTipo'); } if (constants_service_1.default.naturalezaVendedorAutofactura.filter((um) => um.codigo === data['autoFactura']['tipoVendedor']).length == 0) { this.errors.push("Tipo de Vendedor '" + data['autoFactura']['tipoVendedor'] + "' en data.autoFactura.tipoVendedor no encontrado. Valores: " + constants_service_1.default.naturalezaVendedorAutofactura.map((a) => a.codigo + '-' + a.descripcion)); } if (constants_service_1.default.tiposDocumentosIdentidades.filter((um) => um.codigo === data['autoFactura']['documentoTipo']).length == 0) { this.errors.push("Tipo de Documento '" + data['autoFactura']['documentoTipo'] + "' en data.autoFactura.documentoTipo no encontrado. Valores: " + constants_service_1.default.tiposDocumentosIdentidades.map((a) => a.codigo + '-' + a.descripcion)); } if (!data['autoFactura']['ubicacion']) { this.errors.push('Debe especificar la ubicación de la transacción en data.autoF