@ocelotlstudio/cfdi-pdf
Version:
Creates a pdf based on an XML CFDI
313 lines (301 loc) • 13.7 kB
text/typescript
import { exists, existsValue } from '../utils/check';
export class Retencion {
impuesto: string;
tipoFactor: string;
tasaOCuota: string;
importe: string;
base?: string;
}
export class Traslado {
impuesto: string;
tipoFactor: string;
tasaOCuota: string;
importe: string;
base?: string;
}
export class DoctoRelacionado {
uuid: string;
moneda: string;
tipoCambio: string;
metodoPago: string;
numParcialidad: string;
saldoAnterior: string;
importePagado: string;
saldoInsoluto: string;
}
export class ComplementoPago {
fecha: string;
formaPago: string;
moneda: string;
tipoCambio: string;
monto: string;
doctoRelacionados: Array<DoctoRelacionado>;
}
export class TimbreFiscalDigital {
uuid: string;
fechaTimbrado: string;
selloSAT: string;
selloCFD: string;
noCertificadoSAT: string;
version: string;
}
export class CfdiRelacionado {
tipoRelacion: string;
uuid: string;
}
export class Concepto {
clave: string;
noIdentificacion: string;
cantidad: string;
valorUnitario: string;
claveUnidad: string;
unidad: string;
importe: string;
descripcion: string;
descuento: string;
traslados: Array<Traslado>;
retenciones: Array<Retencion>;
}
export class Receptor {
rfc: string;
nombre: string;
residenciaFiscal: string;
numRegIdTrib: string;
usoCFDI: string;
}
export class Emisor {
rfc: string;
nombre: string;
regimenFiscal: string;
}
export class Cfdi {
version: string;
serie: string;
folio: string;
fecha: string;
noCertificado: string;
lugar: string;
tipoDeComprobante: string;
moneda: string;
formaPago: string;
tipoCambio: string;
metodoPago: string;
condicionesDePago: string;
confirmacion: string;
emisor: Emisor;
receptor: Receptor;
conceptos: Array<Concepto>;
cfdiRelacionado: CfdiRelacionado;
timbreFiscalDigital?: TimbreFiscalDigital;
pagos?: Array<ComplementoPago>;
subTotal: string;
descuento: string;
total: string;
traslados: Array<Traslado>;
retenciones: Array<Retencion>;
totalImpuestosRetenidos?: string;
totalImpuestosTrasladados?: string;
cadenaOriginalCC?: string;
}
export const dataToCfdi = (xmlData: any): Promise<Cfdi> => {
return new Promise<Cfdi>((resolve, reject) => {
const obj: Cfdi = new Cfdi();
try {
const comprobante = xmlData['cfdi:Comprobante'];
// obtener datos generales
obj.version = exists(comprobante.$.Version);
obj.serie = exists(comprobante.$.Serie);
obj.folio = exists(comprobante.$.Folio);
obj.fecha = exists(comprobante.$.Fecha);
obj.noCertificado = exists(comprobante.$.NoCertificado);
obj.lugar = exists(comprobante.$.LugarExpedicion);
obj.tipoDeComprobante = exists(comprobante.$.TipoDeComprobante);
obj.moneda = exists(comprobante.$.Moneda);
obj.formaPago = exists(comprobante.$.FormaPago);
obj.tipoCambio = exists(comprobante.$.TipoCambio);
obj.metodoPago = exists(comprobante.$.MetodoPago);
obj.condicionesDePago = exists(comprobante.$.CondicionesDePago);
obj.confirmacion = exists(comprobante.$.Confirmacion);
// initializar el objeto emisor
obj.emisor = new Emisor();
// obtner emisor del comprobante
const comprobanteEmisor = comprobante['cfdi:Emisor'];
if (comprobanteEmisor) {
// generar objeto emisor
obj.emisor.rfc = exists(comprobanteEmisor[0].$.Rfc);
obj.emisor.nombre = exists(comprobanteEmisor[0].$.Nombre);
obj.emisor.regimenFiscal = exists(comprobanteEmisor[0].$.RegimenFiscal);
}
// inicializar objeto receptor
obj.receptor = new Receptor();
// obtener receptor del comprobante
const comprobanteReceptor = comprobante['cfdi:Receptor'];
if (comprobanteReceptor) {
// generar objeto receptor
obj.receptor.rfc = exists(comprobanteReceptor[0].$.Rfc);
obj.receptor.nombre = exists(comprobanteReceptor[0].$.Nombre);
obj.receptor.residenciaFiscal = exists(comprobanteReceptor[0].$.ResidenciaFiscal);
obj.receptor.numRegIdTrib = exists(comprobanteReceptor[0].$.NumRegIdTrib);
obj.receptor.usoCFDI = exists(comprobanteReceptor[0].$.UsoCFDI);
}
// inicializar arreglo de conceptos
obj.conceptos = [];
// obtener conceptos del comprobante
const comprobanteConceptos = comprobante['cfdi:Conceptos'];
if (comprobanteConceptos) {
const comprobanteConcepto = comprobanteConceptos[0]['cfdi:Concepto'];
if (comprobanteConcepto) {
obj.conceptos = comprobanteConcepto.map((concepto: any): Concepto => {
let trasladosArr: Array<Traslado> = [];
let retencionesArr: Array<Retencion> = [];
const impuestos = concepto['cfdi:Impuestos'];
if (impuestos) {
const traslados = impuestos[0]['cfdi:Traslados'];
const retenciones = impuestos[0]['cfdi:Retenciones'];
if (traslados) {
const traslado = traslados[0]['cfdi:Traslado'];
trasladosArr = traslado.map((elem: any) => {
return {
impuesto: elem.$.Impuesto,
tipoFactor: elem.$.TipoFactor,
tasaOCuota: elem.$.TasaOCuota,
importe: elem.$.Importe,
};
});
}
if (retenciones) {
const retencion = retenciones[0]['cfdi:Retencion'];
retencionesArr = retencion.map((elem: any) => {
return {
impuesto: elem.$.Impuesto,
tipoFactor: elem.$.TipoFactor,
tasaOCuota: elem.$.TasaOCuota,
importe: elem.$.Importe,
};
});
}
}
return {
clave: exists(concepto.$.ClaveProdServ),
noIdentificacion: exists(concepto.$.NoIdentificacion),
cantidad: existsValue(concepto.$.Cantidad),
valorUnitario: existsValue(concepto.$.ValorUnitario),
claveUnidad: exists(concepto.$.ClaveUnidad),
unidad: exists(concepto.$.Unidad),
importe: existsValue(concepto.$.Importe),
descripcion: exists(concepto.$.Descripcion),
descuento: existsValue(concepto.$.Descuento),
traslados: trasladosArr,
retenciones: retencionesArr,
};
});
}
}
// obtener cfdiRelacionado del comprobante
const comprobanteCfdiRelacionados = comprobante['cfdi:CfdiRelacionados'];
if (comprobanteCfdiRelacionados) {
const comprobanteCfdiRelacionado = comprobanteCfdiRelacionados[0]['cfdi:CfdiRelacionado'];
if (comprobanteCfdiRelacionado) {
// inicializar objeto cfdiRelacionado
obj.cfdiRelacionado = new CfdiRelacionado();
// generar objeto CfdiRelacionado
obj.cfdiRelacionado.tipoRelacion = exists(comprobanteCfdiRelacionados[0].$.TipoRelacion);
obj.cfdiRelacionado.uuid = exists(comprobanteCfdiRelacionado[0].$.UUID);
}
}
// obtener complemento del comprobante
const comprobanteComplemento = comprobante['cfdi:Complemento'];
if (comprobanteComplemento) {
// obtener el timbre fiscal digital del comprobante
const comprobanteTimbreFiscalDigital = comprobanteComplemento[0]['tfd:TimbreFiscalDigital'];
if (comprobanteTimbreFiscalDigital) {
// inicializar objeto timbreFiscalDigital
obj.timbreFiscalDigital = new TimbreFiscalDigital();
// generar objecto timbreFiscalDigital
obj.timbreFiscalDigital.uuid = exists(comprobanteTimbreFiscalDigital[0].$.UUID);
obj.timbreFiscalDigital.fechaTimbrado = exists(comprobanteTimbreFiscalDigital[0].$.FechaTimbrado);
obj.timbreFiscalDigital.selloSAT = exists(comprobanteTimbreFiscalDigital[0].$.SelloSAT);
obj.timbreFiscalDigital.selloCFD = exists(comprobanteTimbreFiscalDigital[0].$.SelloCFD);
obj.timbreFiscalDigital.noCertificadoSAT = exists(
comprobanteTimbreFiscalDigital[0].$.NoCertificadoSAT,
);
obj.timbreFiscalDigital.version = exists(comprobanteTimbreFiscalDigital[0].$.Version);
}
// inizializar arreglo de pagos
obj.pagos = [];
// obtener pagos
const comprobantePagos = comprobanteComplemento[0]['pago10:Pagos'];
if (comprobantePagos) {
const comprobantePago = comprobantePagos[0]['pago10:Pago'];
if (comprobantePago) {
obj.pagos = comprobantePago.map((pago: any) => {
const doctoRelacionado = pago['pago10:DoctoRelacionado'];
const pagoObj = new ComplementoPago();
pagoObj.fecha = pago.$.FechaPago;
pagoObj.formaPago = pago.$.FormaDePagoP;
pagoObj.moneda = pago.$.MonedaP;
pagoObj.tipoCambio = exists(pago.$.TipoCambioP);
pagoObj.monto = pago.$.Monto;
pagoObj.doctoRelacionados = [];
if (doctoRelacionado) {
pagoObj.doctoRelacionados = doctoRelacionado.map((doc: any) => ({
uuid: doc.$.IdDocumento,
moneda: doc.$.MonedaDR,
tipoCambio: exists(doc.$.TipoCambioDR),
metodoPago: doc.$.MetodoDePagoDR,
numParcialidad: doc.$.NumParcialidad,
saldoAnterior: doc.$.ImpSaldoAnt,
importePagado: doc.$.ImpPagado,
saldoInsoluto: doc.$.ImpSaldoInsoluto,
}));
}
return pagoObj;
});
}
}
}
// obtener subtotal
obj.subTotal = existsValue(comprobante.$.SubTotal);
// obtener descuento
obj.descuento = existsValue(comprobante.$.Descuento);
// obtener total
obj.total = existsValue(comprobante.$.Total);
// inizializar arreglos de Impuestos
obj.traslados = [];
obj.retenciones = [];
// obtener impuestos del comprobante
const comprobanteImpuestos = comprobante['cfdi:Impuestos'];
if (comprobanteImpuestos) {
const traslados = comprobanteImpuestos[0]['cfdi:Traslados'];
const retenciones = comprobanteImpuestos[0]['cfdi:Retenciones'];
if (traslados) {
const traslado = traslados[0]['cfdi:Traslado'];
obj.traslados = traslado.map((elem: any) => {
return {
impuesto: elem.$.Impuesto,
tipoFactor: elem.$.TipoFactor,
tasaOCuota: elem.$.TasaOCuota,
importe: elem.$.Importe,
};
});
}
if (retenciones) {
const retencion = retenciones[0]['cfdi:Retencion'];
obj.retenciones = retencion.map((elem: any) => {
return {
impuesto: elem.$.Impuesto,
tipoFactor: elem.$.TipoFactor,
tasaOCuota: elem.$.TasaOCuota,
importe: elem.$.Importe,
};
});
}
obj.totalImpuestosRetenidos = existsValue(comprobanteImpuestos[0].$.TotalImpuestosRetenidos);
obj.totalImpuestosTrasladados = existsValue(comprobanteImpuestos[0].$.TotalImpuestosTrasladados);
}
resolve(obj);
} catch (e) {
reject('CFDI no valido');
}
});
};