facturacionelectronicapy-recibo-xmlgen
Version:
API Node JS para generar el archivo XML del Recibo similar al exigido por la SET en base a JSON
855 lines (854 loc) • 87.5 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const xml2js = __importStar(require("xml2js"));
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 reciboXmlAlgoritmos_service_1 = __importDefault(require("./reciboXmlAlgoritmos.service"));
const reciboXmlTotales_service_1 = __importDefault(require("./reciboXmlTotales.service"));
const JsonReciboDocumentoAsociado_service_1 = __importDefault(require("./JsonReciboDocumentoAsociado.service"));
const JsonReciboValidate_service_1 = __importDefault(require("./JsonReciboValidate.service"));
class ReciboXmlMainService {
constructor() {
this.codigoSeguridad = null;
this.codigoControl = null;
this.json = {};
this.validateError = true;
}
generateReciboXMLDE(params, data, config) {
return new Promise((resolve, reject) => {
try {
let defaultConfig = {
defaultValues: true,
//arrayValuesSeparator : ', ',
errorSeparator: '; ',
errorLimit: 10,
// redondeoSedeco: true,
decimals: 2,
pygDecimals: 0,
};
defaultConfig = Object.assign(defaultConfig, config);
resolve(this.generateXMLReciboService(params, data, defaultConfig));
}
catch (error) {
reject(error);
}
});
}
/**
* Metodo principal de generacion de XML del DE
* @param params
* @param data
* @returns
*/
generateXMLReciboService(params, data, config) {
this.removeUnderscoreAndPutCamelCase(data);
this.addDefaultValues(data);
if (this.validateError) {
JsonReciboValidate_service_1.default.validateValues(Object.assign({}, params), Object.assign({}, data), config);
}
this.json = {};
this.generateCodigoControlRecibo(params, data); //Luego genera el código de Control
this.generateRte(params);
this.json['rDE']['recibo'] = this.generateRecibo(params, data);
//---
this.generateDatosOperacion(params, data);
this.generateDatosTimbrado(params, data);
this.generateDatosGenerales(params, data, config);
//---
if (!this.json['rDE']['recibo']['gDtipDE']) {
this.json['rDE']['recibo']['gDtipDE'] = {};
}
if (data['condicion'] && data['condicion']['tipo']) {
this.generateDatosCondicionOperacionDE(params, data);
}
this.json['rDE']['recibo']['gTotSub'] = reciboXmlTotales_service_1.default.generateDatosTotalesRecibo(params, data, config); //Marcos
if (data['concepto']) {
this.json['rDE']['recibo']['gDatGralOpe']['concepto'] = data['concepto'];
}
if (data['documentoAsociado']) {
this.json['rDE']['recibo']['gCamDEAsoc'] = JsonReciboDocumentoAsociado_service_1.default.generateDocumentosAsociados(params, data, config);
//
if (Array.isArray(this.json['rDE']['recibo']['gCamDEAsoc']) &&
this.json['rDE']['recibo']['gCamDEAsoc'].length > 0) {
let arrayItems = new Array();
for (let i = 0; i < this.json['rDE']['recibo']['gCamDEAsoc'].length; i++) {
arrayItems.push(i + 1);
}
this.json['rDE']['recibo']['item'] = arrayItems;
}
else {
this.json['rDE']['recibo']['item'] = 1;
}
}
else {
//Si no hay documento Asociado si o si debe agregar un concepto.
this.json['rDE']['recibo']['item'] = 1;
}
var builder = new xml2js.Builder({
xmldec: {
version: '1.0',
encoding: 'UTF-8',
standalone: false,
},
});
var xml = builder.buildObject(this.json);
return this.normalizeXML(xml); //Para firmar tiene que estar normalizado
}
/**
* Genera el CDC para el Recibo
* Corresponde al Id del Recibo
*
* @param params
* @param data
*/
generateCodigoControlRecibo(params, data) {
if (data.cdc && (data.cdc + '').length == 44) {
//Caso ya se le pase el CDC
this.codigoSeguridad = data.cdc.substring(34, 43);
this.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 = this.codigoControl.substring(0, 2);
const establecimientoCDC = this.codigoControl.substring(11, 14);
const puntoCDC = this.codigoControl.substring(14, 17);
const numeroCDC = this.codigoControl.substring(17, 24);
const fechaCDC = this.codigoControl.substring(25, 33);
const tipoEmisionCDC = this.codigoControl.substring(33, 34);
const establecimiento = StringUtil_service_1.default.leftZero(data['establecimiento'], 3);
const punto = StringUtil_service_1.default.leftZero(data['punto'], 3);
const numero = StringUtil_service_1.default.leftZero(data['numero'], 7);
const fecha = (data['fecha'] + '').substring(0, 4) +
(data['fecha'] + '').substring(5, 7) +
(data['fecha'] + '').substring(8, 10);
}
else {
this.codigoSeguridad = StringUtil_service_1.default.leftZero(data.codigoSeguridadAleatorio, 9);
this.codigoControl = reciboXmlAlgoritmos_service_1.default.generateCodigoControl(params, data, this.codigoSeguridad);
}
}
/**
* Si los valores vienen en underscore, crea los valores en formato variableJava que
* sera utilizado dentro del proceso,
*
* Ej. si viene tipo_documento crea una variable tipoDocumento, con el mismo valor.
*
* @param data
*/
removeUnderscoreAndPutCamelCase(data) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
if (data.tipo_documento) {
data.tipoDocumento = data.tipo_documento;
}
if (data.condicion_tipo_cambio) {
data.condicionTipoCambio = data.condicion_tipo_cambio;
}
if (data.descuento_global) {
data.descuentoGlobal = data.descuento_global;
}
//Objeto Cliente
if ((_a = data.cliente) === null || _a === void 0 ? void 0 : _a.razon_social) {
data.cliente.razonSocial = data.cliente.razon_social;
}
if ((_b = data.cliente) === null || _b === void 0 ? void 0 : _b.nombre_fantasia) {
data.cliente.nombreFantasia = data.cliente.nombre_fantasia;
}
if ((_c = data.cliente) === null || _c === void 0 ? void 0 : _c.tipo_operacion) {
data.cliente.tipoOperacion = data.cliente.tipo_operacion;
}
//Campo que puede ser un numero = 0, hay que validar de esta forma
if (typeof data.cliente != 'undefined' && typeof data.cliente.numero_casa != 'undefined') {
data.cliente.numeroCasa = data.cliente.numero_casa + '';
}
if ((_d = data.cliente) === null || _d === void 0 ? void 0 : _d.tipo_contribuyente) {
data.cliente.tipoContribuyente = data.cliente.tipo_contribuyente;
}
if ((_e = data.cliente) === null || _e === void 0 ? void 0 : _e.documento_tipo) {
data.cliente.documentoTipo = data.cliente.documento_tipo;
}
if ((_f = data.cliente) === null || _f === void 0 ? void 0 : _f.documento_numero) {
data.cliente.documentoNumero = data.cliente.documento_numero;
}
//Usuario
if ((_g = data.usuario) === null || _g === void 0 ? void 0 : _g.documento_tipo) {
data.usuario.documentoTipo = data.usuario.documento_tipo;
}
if ((_h = data.usuario) === null || _h === void 0 ? void 0 : _h.documento_numero) {
data.usuario.documentoNumero = data.usuario.documento_numero;
}
//Documento Asociado
if (data.documento_asociado) {
/*if (!Array.isArray(data.documento_asociado)) {
data.documentoAsociado = [...data.documento_asociado ];
} else {
data.documentoAsociado = [ ...data.documento_asociado ];
}*/
data.documentoAsociado = [...data.documento_asociado];
}
if (data.documentoAsociado && Array.isArray(data.documentoAsociado)) {
for (let i = 0; i < data.documentoAsociado.length; i++) {
let docAso = data.documentoAsociado[i];
if (docAso.numero_retencion) {
docAso.numeroRetencion = docAso.numero_retencion;
delete docAso.numero_retencion;
}
if (docAso.resolucion_credito_fiscal) {
docAso.resolucionCreditoFiscal = docAso.resolucion_credito_fiscal;
delete docAso.resolucion_credito_fiscal;
}
if (docAso.tipo_documento_impreso) {
docAso.tipoDocumentoImpreso = docAso.tipo_documento_impreso;
delete docAso.tipo_documento_impreso;
}
if (docAso.constancia_tipo) {
docAso.constanciaTipo = docAso.constancia_tipo;
delete docAso.constancia_tipo;
}
if (docAso.constancia_numero) {
docAso.constanciaNumero = docAso.constancia_numero;
delete docAso.constancia_numero;
}
if (docAso.constancia_control) {
docAso.constanciaControl = docAso.constancia_control;
delete docAso.constancia_control;
}
if (typeof docAso.monto_retencion_iva != 'undefined') {
docAso.montoRetencionIva = docAso.monto_retencion_iva;
delete docAso.monto_retencion_iva;
}
if (typeof docAso.monto_retencion_renta != 'undefined') {
docAso.montoRetencionRenta = docAso.monto_retencion_renta;
delete docAso.monto_retencion_renta;
}
if (docAso.ruc_fusionado) {
docAso.rucFusionado = docAso.ruc_fusionado;
delete docAso.ruc_fusionado;
}
}
}
if (data.documento_asociado) {
delete data.documento_asociado;
}
//Condicion entregas
if (((_j = data.condicion) === null || _j === void 0 ? void 0 : _j.entregas) && ((_k = data.condicion) === null || _k === void 0 ? void 0 : _k.entregas.length) > 0) {
for (let i = 0; i < data.condicion.entregas.length; i++) {
const entrega = data.condicion.entregas[i];
if (entrega.info_tarjeta) {
entrega.infoTarjeta = Object.assign({}, entrega.info_tarjeta);
}
if ((_l = entrega.infoTarjeta) === null || _l === void 0 ? void 0 : _l.razon_social) {
entrega.infoTarjeta.razonSocial = entrega.infoTarjeta.razon_social;
}
if ((_m = entrega.infoTarjeta) === null || _m === void 0 ? void 0 : _m.medio_pago) {
entrega.infoTarjeta.medioPago = entrega.infoTarjeta.medio_pago;
}
if ((_o = entrega.infoTarjeta) === null || _o === void 0 ? void 0 : _o.codigo_autorizacion) {
entrega.infoTarjeta.codigoAutorizacion = entrega.infoTarjeta.codigo_autorizacion;
}
if (entrega.info_cheque) {
entrega.infoCheque = Object.assign({}, entrega.info_cheque);
}
if ((_p = entrega.infoCheque) === null || _p === void 0 ? void 0 : _p.numero_cheque) {
entrega.infoCheque.numeroCheque = entrega.infoCheque.numero_cheque;
}
}
}
if (((_q = data.condicion) === null || _q === void 0 ? void 0 : _q.credito) && ((_r = data.condicion) === null || _r === void 0 ? void 0 : _r.credito.length) > 0) {
for (let i = 0; i < data.condicion.credito.length; i++) {
const credito = data.condicion.credito[i];
if (credito.monto_entrega) {
credito.montoEntrega = credito.monto_entrega;
}
if (credito.info_cuotas) {
credito.infoCuotas = Object.assign({}, credito.info_cuotas);
}
}
}
}
/**
* Añade algunos valores por defecto al JSON de entrada, valido para
* todas las operaciones
* @param data
*/
addDefaultValues(data) {
if (!data['moneda']) {
data['moneda'] = 'PYG';
}
}
generateRte(params) {
this.json = {
rDE: {
/*$: {
xmlns: 'http://ekuatia.set.gov.py/sifen/xsd',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation': 'http://ekuatia.set.gov.py/sifen/xsd siRecepDE_v150.xsd',
},*/
dVerFor: params.version,
},
};
}
generateRecibo(params, data) {
if (params['ruc'].indexOf('-') == -1) {
//throw new Error('RUC debe contener dígito verificador en params.ruc');
}
const rucEmisor = params['ruc'].split('-')[0];
const dvEmisor = params['ruc'].split('-')[1];
if (this.validateError) {
var reg = new RegExp(/^\d+$/);
if (!reg.test(rucEmisor)) {
//throw new Error("El RUC '" + rucEmisor + "' debe ser numérico");
}
if (!reg.test(dvEmisor)) {
//throw new Error("El DV del RUC '" + dvEmisor + "' debe ser numérico");
}
}
const id = this.codigoControl;
const fechaFirmaDigital = new Date(params.fechaFirmaDigital);
let digitoVerificadorString = this.codigoControl + '';
const jsonResult = {
$: {
Id: id,
},
dDVId: digitoVerificadorString.substring(digitoVerificadorString.length - 1, digitoVerificadorString.length),
dFecFirma: FechaUtil_service_1.default.convertToJSONFormat(new Date()),
dSisFact: 1,
};
return jsonResult;
}
/**
* Datos inerentes a la operacion
* <gOpeDE>
<iTipEmi>1</iTipEmi>
<dDesTipEmi>Normal</dDesTipEmi>
<dCodSeg>000000023</dCodSeg>
<dInfoEmi>1</dInfoEmi>
<dInfoFisc>Información de interés del Fisco respecto al DE</dInfoFisc>
</gOpeDE>
* @param params
* @param data
* @param options
*/
generateDatosOperacion(params, data) {
if (params['ruc'].indexOf('-') == -1) {
//throw new Error('RUC debe contener dígito verificador en params.ruc');
}
const rucEmisor = params['ruc'].split('-')[0];
const dvEmisor = params['ruc'].split('-')[1];
const id = reciboXmlAlgoritmos_service_1.default.generateCodigoControl(params, data, this.codigoSeguridad);
const digitoVerificador = reciboXmlAlgoritmos_service_1.default.calcularDigitoVerificador(rucEmisor, 11);
if (id.length != 44) {
}
const codigoSeguridadAleatorio = this.codigoSeguridad;
this.json['rDE']['recibo']['gOpeDE'] = {
dCodSeg: codigoSeguridadAleatorio,
};
if (data['observacion'] && data['observacion'].length > 0) {
this.json['rDE']['recibo']['gOpeDE']['dInfoEmi'] = data['observacion'];
}
if (data['descripcion'] && data['descripcion'].length > 0) {
this.json['rDE']['recibo']['gOpeDE']['dInfoFisc'] = data['descripcion'];
}
}
/**
* Genera los datos del timbrado
*
* @param params
* @param data
* @param options
*/
generateDatosTimbrado(params, data) {
this.json['rDE']['recibo']['gTimb'] = {
iTiDE: 55,
dDesTiDE: 'Recibo',
dNumTim: params['timbradoNumero'],
dEst: StringUtil_service_1.default.leftZero(data['establecimiento'], 3),
dPunExp: StringUtil_service_1.default.leftZero(data['punto'], 3),
dNumDoc: StringUtil_service_1.default.leftZero(data['numero'], 7),
//dSerieNum : null,
dFeIniT: params['timbradoFecha'].substring(0, 10),
};
if (data['numeroSerie']) {
this.json['rDE']['recibo']['gTimb']['dSerieNum'] = data['numeroSerie'];
}
}
/**
* Genera los campos generales, divide las actividades en diferentes metodos
*
* <gDatGralOpe>
<dFeEmiDE>2020-05-07T15:03:57</dFeEmiDE>
</gDatGralOpe>
*
* @param params
* @param data
* @param options
*/
generateDatosGenerales(params, data, config) {
this.json['rDE']['recibo']['gDatGralOpe'] = {
dFeEmiDE: data['fecha'],
};
this.generateDatosGeneralesInherentesOperacion(params, data, config);
this.generateDatosGeneralesEmisorDE(params, data);
if (data['usuario']) {
//No es obligatorio
this.generateDatosGeneralesResponsableGeneracionDE(params, data);
}
this.generateDatosGeneralesReceptorDE(params, data);
}
/**
* D1. Campos inherentes a la operación comercial (D010-D099)
* Pertenece al grupo de datos generales
*
* <gOpeCom>
<iTipTra>1</iTipTra>
<dDesTipTra>Venta de mercadería</dDesTipTra>
<iTImp>1</iTImp>
<dDesTImp>IVA</dDesTImp>
<cMoneOpe>PYG</cMoneOpe>
<dDesMoneOpe>Guarani</dDesMoneOpe>
</gOpeCom>
* @param params
* @param data
* @param options
*/
generateDatosGeneralesInherentesOperacion(params, data, config) {
let moneda = data['moneda'];
if (!moneda && config.defaultValues === true) {
moneda = 'PYG';
}
this.json['rDE']['recibo']['gDatGralOpe']['gOpeCom'] = {};
this.json['rDE']['recibo']['gDatGralOpe']['gOpeCom']['cMoneOpe'] = moneda; //D015
this.json['rDE']['recibo']['gDatGralOpe']['gOpeCom']['dDesMoneOpe'] = constants_service_1.default.monedas.filter((m) => m.codigo == moneda)[0]['descripcion'];
if (moneda != 'PYG') {
//Obligatorio informar dCondTiCam D017
this.json['rDE']['recibo']['gDatGralOpe']['gOpeCom']['dCondTiCam'] = data['condicionTipoCambio'];
}
if (data['condicionTipoCambio'] == 1 && moneda != 'PYG') {
//Obligatorio informar dCondTiCam D018
this.json['rDE']['recibo']['gDatGralOpe']['gOpeCom']['dTiCam'] = data['cambio'];
}
}
/**
* D2. Campos que identifican al emisor del Documento Electrónico DE (D100-D129)
* Pertenece al grupo de datos generales
*
* @param params
* @param data
* @param options
*/
generateDatosGeneralesEmisorDE(params, data) {
if (!(params && params.establecimientos)) {
//throw new Error('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);
this.json['rDE']['recibo']['gDatGralOpe']['gEmis'] = {
dRucEm: params['ruc'].split('-')[0],
dDVEmi: params['ruc'].split('-')[1],
iTipCont: params['tipoContribuyente'],
cTipReg: params['tipoRegimen'],
dNomEmi: params['razonSocial'],
dNomFanEmi: params['nombreFantasia'],
dDirEmi: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['direccion'],
dNumCas: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['numeroCasa'],
dCompDir1: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['complementoDireccion1'],
dCompDir2: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['complementoDireccion2'],
cDepEmi: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['departamento'],
dDesDepEmi: constants_service_1.default.departamentos.filter((td) => td.codigo === params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['departamento'])[0]['descripcion'],
cDisEmi: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['distrito'],
dDesDisEmi: constants_service_1.default.distritos.filter((td) => td.codigo === params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['distrito'])[0]['descripcion'],
cCiuEmi: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['ciudad'],
dDesCiuEmi: constants_service_1.default.ciudades.filter((td) => td.codigo === params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['ciudad'])[0]['descripcion'],
dTelEmi: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['telefono'],
dEmailE: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['email'],
dDenSuc: params['establecimientos'].filter((e) => e.codigo === establecimiento)[0]['denominacion'],
};
if (params['actividadesEconomicas'] && params['actividadesEconomicas'].length > 0) {
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gActEco'] = [];
for (let i = 0; i < params['actividadesEconomicas'].length; i++) {
const actividadEconomica = params['actividadesEconomicas'][i];
const gActEco = {
cActEco: actividadEconomica.codigo,
dDesActEco: actividadEconomica.descripcion,
};
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gActEco'].push(gActEco);
}
}
else {
//throw new Error('Debe proveer el array de actividades económicas en params.actividadesEconomicas');
}
}
/**
* Datos generales del responsable de generacion del DE
*
* @param params
* @param data
* @param options
*/
generateDatosGeneralesResponsableGeneracionDE(params, data) {
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gRespDE'] = {
iTipIDRespDE: data['usuario']['documentoTipo'],
dDTipIDRespDE: constants_service_1.default.tiposDocumentosIdentidades.filter((td) => td.codigo === data['usuario']['documentoTipo'])[0]['descripcion'],
};
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gRespDE']['dNumIDRespDE'] = data['usuario']['documentoNumero'];
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gRespDE']['dNomRespDE'] = data['usuario']['nombre'];
this.json['rDE']['recibo']['gDatGralOpe']['gEmis']['gRespDE']['dCarRespDE'] = data['usuario']['cargo'];
}
/**
* Datos generales del receptor del documento electrónico
* Pertenece al grupo de datos generales
*
*
* @param params
* @param data
* @param options
*/
generateDatosGeneralesReceptorDE(params, data) {
var regExpOnlyNumber = new RegExp(/^\d+$/);
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec'] = {
iNatRec: data['cliente']['contribuyente'] ? 1 : 2,
//iTiOpe: data['cliente']['tipoOperacion'],
cPaisRec: data['cliente']['pais'],
dDesPaisRe: constants_service_1.default.paises.filter((pais) => pais.codigo === data['cliente']['pais'])[0]['descripcion'],
};
if (data['cliente']['contribuyente']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['iTiContRec'] = data['cliente']['tipoContribuyente'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dRucRec'] = (data['cliente']['ruc'].split('-')[0] + '').trim();
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDVRec'] = (data['cliente']['ruc'].split('-')[1] + '').trim();
}
if (!data['cliente']['contribuyente']) {
//Obligatorio completar D210
if (this.validateError) {
if (!data['cliente']['contribuyente']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['iTipIDRec'] = data['cliente']['documentoTipo'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDTipIDRec'] =
constants_service_1.default.tiposDocumentosReceptor.filter((tdr) => tdr.codigo === data['cliente']['documentoTipo'])[0]['descripcion'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dNumIDRec'] = data['cliente']['documentoNumero'].trim();
}
if (+data['cliente']['documentoTipo'] === 5) {
//Si es innominado completar con cero
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dNumIDRec'] = '0';
}
}
}
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dNomRec'] = data['cliente']['razonSocial'].trim();
//if (data['cliente']['documentoTipo'] === 5) {
if (data['cliente']['nombreFantasia']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dNomFanRec'] = data['cliente']['nombreFantasia'].trim();
}
//}
if (data['cliente']['direccion']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDirRec'] = data['cliente']['direccion'].trim();
}
if (data['cliente']['numeroCasa']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dNumCasRec'] = (data['cliente']['numeroCasa'] + '').trim();
}
if (data['cliente']['direccion']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['cDepRec'] = +data['cliente']['departamento'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDesDepRec'] = constants_service_1.default.departamentos.filter((td) => td.codigo === +data['cliente']['departamento'])[0]['descripcion'];
}
if (data['cliente']['direccion']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['cDisRec'] = +data['cliente']['distrito'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDesDisRec'] = constants_service_1.default.distritos.filter((td) => td.codigo === +data['cliente']['distrito'])[0]['descripcion'];
}
if (data['cliente']['direccion']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['cCiuRec'] = +data['cliente']['ciudad'];
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dDesCiuRec'] = constants_service_1.default.ciudades.filter((td) => td.codigo === +data['cliente']['ciudad'])[0]['descripcion'];
}
if (data['cliente']['telefono']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec'].dTelRec = data['cliente']['telefono'].trim();
}
if (data['cliente']['celular']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec'].dCelRec = data['cliente']['celular'].trim();
}
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 la SET no acepta Comas
email = email.split(',')[0].trim();
}
//Verificar espacios
if (email.indexOf(' ') > -1) {
//throw new Error("El valor '" + email + "' en data.cliente.email no puede poseer espacios");
}
if (!(email.length >= 3 && email.length <= 80)) {
//throw new Error("El valor '" + email + "' en data.cliente.email debe tener una longitud de 3 a 80 caracteres");
}
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec'].dEmailRec = email.trim();
}
if (data['cliente']['codigo']) {
this.json['rDE']['recibo']['gDatGralOpe']['gDatRec']['dCodCliente'] = (data['cliente']['codigo'] + '').trim();
}
}
/**
* E7. Campos que describen la condición de la operación (E600-E699)
* @param params
* @param data
* @param options
*/
generateDatosCondicionOperacionDE(params, data) {
this.json['rDE']['recibo']['gDtipDE']['gCamCond'] = {
iCondOpe: data['condicion']['tipo'],
dDCondOpe: constants_service_1.default.condicionesOperaciones.filter((co) => co.codigo === data['condicion']['tipo'])[0]['descripcion'],
};
//if (data['condicion']['tipo'] === 1) {
this.generateDatosCondicionOperacionDE_Contado(params, data);
//}
if (data['condicion']['tipo'] === 2) {
this.generateDatosCondicionOperacionDE_Credito(params, data);
}
}
/**
* E7.1. Campos que describen la forma de pago de la operación al contado o del monto
* de la entrega inicial (E605-E619)
* @param params
* @param data
* @param options
*/
generateDatosCondicionOperacionDE_Contado(params, data) {
if (data['condicion']['tipo'] === 1) {
if (!(data['condicion']['entregas'] && data['condicion']['entregas'].length > 0)) {
/*throw new Error(
'El Tipo de Condición es 1 en data.condicion.tipo pero no se encontraron entregas en data.condicion.entregas',
);*/
}
}
if (data['condicion']['entregas'] && data['condicion']['entregas'].length > 0) {
const entregas = [];
for (let i = 0; i < data['condicion']['entregas'].length; i++) {
const dataEntrega = data['condicion']['entregas'][i];
if (constants_service_1.default.condicionesTiposPagos.filter((um) => um.codigo === dataEntrega['tipo']).length == 0) {
/*throw new Error(
"Condición de Tipo de Pago '" +
dataEntrega['tipo'] +
"' en data.condicion.entregas[" +
i +
'].tipo no encontrado. Valores: ' +
constanteService.condicionesTiposPagos.map((a: any) => a.codigo + '-' + a.descripcion),
);*/
}
const cuotaInicialEntrega = {
iTiPago: dataEntrega['tipo'],
dDesTiPag: constants_service_1.default.condicionesTiposPagos.filter((co) => co.codigo === dataEntrega['tipo'])[0]['descripcion'],
dMonTiPag: dataEntrega['monto'],
};
if (!dataEntrega['moneda']) {
//throw new Error('Moneda es obligatorio en data.condicion.entregas[' + i + '].moneda');
}
if (constants_service_1.default.monedas.filter((um) => um.codigo === dataEntrega['moneda']).length == 0) {
/*throw new Error("Moneda '" + dataEntrega['moneda']) +
"' data.condicion.entregas[" +
i +
'].moneda no válido. Valores: ' +
constanteService.monedas.map((a) => a.codigo + '-' + a.descripcion);*/
}
cuotaInicialEntrega['cMoneTiPag'] = dataEntrega['moneda'];
cuotaInicialEntrega['dDMoneTiPag'] = constants_service_1.default.monedas.filter((m) => m.codigo == dataEntrega['moneda'])[0]['descripcion'];
if (dataEntrega['moneda'] != 'PYG') {
if (dataEntrega['cambio']) {
cuotaInicialEntrega['dTiCamTiPag'] = dataEntrega['cambio'];
}
}
//Verificar si el Pago es con Tarjeta de crédito
if (dataEntrega['tipo'] === 3 || dataEntrega['tipo'] === 4) {
if (!dataEntrega['infoTarjeta']) {
/*throw new Error(
'Debe informar sobre la tarjeta en data.condicion.entregas[' +
i +
'].infoTarjeta si la forma de Pago es a Tarjeta',
);*/
}
if (constants_service_1.default.condicionesOperaciones.filter((um) => um.codigo === dataEntrega['infoTarjeta']['tipo']).length == 0) {
/*throw new Error(
"Tipo de Tarjeta de Crédito '" +
dataEntrega['infoTarjeta']['tipo'] +
"' en data.condicion.entregas[" +
i +
'].infoTarjeta.tipo no encontrado. Valores: ' +
constanteService.condicionesOperaciones.map((a: any) => a.codigo + '-' + a.descripcion),
);*/
}
if (dataEntrega['infoTarjeta']['ruc'].indexOf('-') == -1) {
/*throw new Error(
'Ruc de Proveedor de Tarjeta debe contener digito verificador en data.condicion.entregas[' +
i +
'].infoTarjeta.ruc',
);*/
}
cuotaInicialEntrega['gPagTarCD'] = {
iDenTarj: dataEntrega['infoTarjeta']['tipo'],
dDesDenTarj: dataEntrega['infoTarjeta']['tipo'] === 99
? dataEntrega['infoTarjeta']['tipoDescripcion']
: constants_service_1.default.tarjetasCreditosTipos.filter((co) => co.codigo === dataEntrega['infoTarjeta']['tipo'])[0]['descripcion'],
};
if (dataEntrega['infoTarjeta']['razonSocial'] && dataEntrega['infoTarjeta']['ruc']) {
//Solo si se envia éste dato
cuotaInicialEntrega['gPagTarCD']['dRSProTar'] = dataEntrega['infoTarjeta']['razonSocial'];
cuotaInicialEntrega['gPagTarCD']['dRUCProTar'] = dataEntrega['infoTarjeta']['ruc'].split('-')[0];
cuotaInicialEntrega['gPagTarCD']['dDVProTar'] = dataEntrega['infoTarjeta']['ruc'].split('-')[1];
}
cuotaInicialEntrega['gPagTarCD']['iForProPa'] = dataEntrega['infoTarjeta']['medioPago'];
if (dataEntrega['infoTarjeta']['codigoAutorizacion']) {
if (!((dataEntrega['infoTarjeta']['codigoAutorizacion'] + '').length >= 6 &&
(dataEntrega['infoTarjeta']['codigoAutorizacion'] + '').length <= 10)) {
/*throw new Error(
'El código de Autorización en data.condicion.entregas[' +
i +
'].infoTarjeta.codigoAutorizacion debe tener de 6 y 10 caracteres',
);*/
}
cuotaInicialEntrega['gPagTarCD']['dCodAuOpe'] = +dataEntrega['infoTarjeta']['codigoAutorizacion'];
}
if (dataEntrega['infoTarjeta']['titular']) {
cuotaInicialEntrega['gPagTarCD']['dNomTit'] = dataEntrega['infoTarjeta']['titular'];
}
if (dataEntrega['infoTarjeta']['numero']) {
if (!((dataEntrega['infoTarjeta']['numero'] + '').length == 4)) {
/*throw new Error(
'El código de Autorización en data.condicion.entregas[' +
i +
'].infoTarjeta.numero debe tener de 4 caracteres',
);*/
}
cuotaInicialEntrega['gPagTarCD']['dNumTarj'] = dataEntrega['infoTarjeta']['numero'];
}
}
//Verificar si el Pago es con Cheque
if (dataEntrega['tipo'] === 2) {
if (!dataEntrega['infoCheque']) {
/*throw new Error(
'Debe informar sobre el cheque en data.condicion.entregas[' +
i +
'].infoCheque si la forma de Pago es 2-Cheques',
);*/
}
cuotaInicialEntrega['gPagCheq'] = {
dNumCheq: StringUtil_service_1.default.leftZero(dataEntrega['infoCheque']['numeroCheque'], 8),
dBcoEmi: dataEntrega['infoCheque']['banco'],
};
}
entregas.push(cuotaInicialEntrega);
}
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPaConEIni'] = entregas; //Array de Entregas
}
}
/**
* E7.2. Campos que describen la operación a crédito (E640-E649)
*
* @param params
* @param data
* @param options
*/
generateDatosCondicionOperacionDE_Credito(params, data) {
if (!data['condicion']['credito']['tipo']) {
/*throw new Error(
'El tipo de Crédito en data.condicion.credito.tipo es obligatorio si la condición posee créditos',
);*/
}
if (constants_service_1.default.condicionesCreditosTipos.filter((um) => um.codigo === data['condicion']['credito']['tipo'])
.length == 0) {
/*throw new Error(
"Tipo de Crédito '" +
data['condicion']['credito']['tipo'] +
"' en data.condicion.credito.tipo no encontrado. Valores: " +
constanteService.condicionesCreditosTipos.map((a: any) => a.codigo + '-' + a.descripcion),
);*/
}
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred'] = {
iCondCred: data['condicion']['credito']['tipo'],
dDCondCred: constants_service_1.default.condicionesCreditosTipos.filter((co) => co.codigo === +data['condicion']['credito']['tipo'])[0]['descripcion'],
};
if (+data['condicion']['credito']['tipo'] === 1) {
//Plazo
if (!data['condicion']['credito']['plazo']) {
/*throw new Error(
'El tipo de Crédito en data.condicion.credito.tipo es 1 entonces data.condicion.credito.plazo es obligatorio',
);*/
}
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred']['dPlazoCre'] =
data['condicion']['credito']['plazo'];
}
if (+data['condicion']['credito']['tipo'] === 2) {
//Cuota
if (!data['condicion']['credito']['cuotas']) {
/*throw new Error(
'El tipo de Crédito en data.condicion.credito.tipo es 2 entonces data.condicion.credito.cuotas es obligatorio',
);*/
}
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred']['dCuotas'] =
+data['condicion']['credito']['cuotas'];
}
if (data['condicion']['entregas'] && data['condicion']['entregas'].length > 0) {
let sumaEntregas = 0;
//Obtiene la sumatoria
for (let i = 0; i < data['condicion']['entregas'].length; i++) {
const entrega = data['condicion']['entregas'][i];
sumaEntregas += entrega['monto']; //Y cuando es de moneda diferente ? como hace?
}
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred']['dMonEnt'] = sumaEntregas;
}
//Recorrer array de infoCuotas e informar en el JSON
if (data['condicion']['credito']['tipo'] === 2) {
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred']['gCuotas'] = [];
//A Cuotas
if (data['condicion']['credito']['infoCuotas'] && data['condicion']['credito']['infoCuotas'].length > 0) {
for (let i = 0; i < data['condicion']['credito']['infoCuotas'].length; i++) {
const infoCuota = data['condicion']['credito']['infoCuotas'][i];
if (constants_service_1.default.monedas.filter((um) => um.codigo === infoCuota['moneda']).length == 0) {
/*throw new Error(
"Moneda '" +
infoCuota['moneda'] +
"' en data.condicion.credito.infoCuotas[" +
i +
'].moneda no encontrado. Valores: ' +
constanteService.monedas.map((a: any) => a.codigo + '-' + a.descripcion),
);*/
}
const gCuotas = {
cMoneCuo: infoCuota['moneda'],
dDMoneCuo: constants_service_1.default.monedas.filter((co) => co.codigo === infoCuota['moneda'])[0]['descripcion'],
dMonCuota: infoCuota['monto'],
dVencCuo: infoCuota['vencimiento'],
};
this.json['rDE']['recibo']['gDtipDE']['gCamCond']['gPagCred']['gCuotas'].push(gCuotas);
}
}
else {
//throw new Error('Debe proporcionar data.condicion.credito.infoCuotas[]');
}
}
}
normalizeXML(xml) {
xml = xml.split('\r\n').join('');
xml = xml.split('\n').join('');
xml = xml.split('\t').join('');
xml = xml.split(' ').join('');
xml = xml.split('> <').join('><');
xml = xml.split('> <').join('><');
xml = xml.replace(/\r?\n|\r/g, '');
return xml;
}
}
exports.default = new ReciboXmlMainService();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjaWJvWG1sTWFpbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL3JlY2lib1htbE1haW4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFFakMsOEVBQXFEO0FBQ3JELDRFQUFtRDtBQUNuRCw0RUFBbUQ7QUFDbkQsZ0dBQThEO0FBQzlELDBGQUEwRDtBQUMxRCxnSEFBbUY7QUFDbkYsOEZBQThEO0FBRzlELE1BQU0sb0JBQW9CO0lBQTFCO1FBQ0Usb0JBQWUsR0FBUSxJQUFJLENBQUM7UUFDNUIsa0JBQWEsR0FBUSxJQUFJLENBQUM7UUFDMUIsU0FBSSxHQUFRLEVBQUUsQ0FBQztRQUNmLGtCQUFhLEdBQUcsSUFBSSxDQUFDO0lBcytCdkIsQ0FBQztJQXArQlEsbUJBQW1CLENBQUMsTUFBVyxFQUFFLElBQVMsRUFBRSxNQUFxQjtRQUN0RSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsSUFBSSxhQUFhLEdBQWlCO29CQUNoQyxhQUFhLEVBQUUsSUFBSTtvQkFDbkIsOEJBQThCO29CQUM5QixjQUFjLEVBQUUsSUFBSTtvQkFDcEIsVUFBVSxFQUFFLEVBQUU7b0JBQ2QsaUNBQWlDO29CQUNqQyxRQUFRLEVBQUUsQ0FBQztvQkFDWCxXQUFXLEVBQUUsQ0FBQztpQkFDZixDQUFDO2dCQUVGLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFFckQsT0FBTyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7YUFDckU7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDZjtRQUNI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