| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import type { InfoTributaria, InfoFactura, DetalleItem, TotalImpuesto } from "@/types/factura"
- import { formatDateForSRI } from "@/utils/factura/validations"
- export class XmlGenerator {
- static generateFacturaXml(
- infoTributaria: InfoTributaria,
- infoFactura: InfoFactura,
- detalles: DetalleItem[],
- totalesImpuestos: TotalImpuesto[]
- ): string {
- let xml = `<?xml version="1.0" encoding="UTF-8"?>
- <factura id="comprobante" version="1.1.0">
- <infoTributaria>
- <ambiente>${infoTributaria.ambiente}</ambiente>
- <tipoEmision>${infoTributaria.tipoEmision}</tipoEmision>
- <razonSocial>${infoTributaria.razonSocial}</razonSocial>
- <nombreComercial>${infoTributaria.nombreComercial}</nombreComercial>
- <ruc>${infoTributaria.ruc}</ruc>
- <claveAcceso>${infoTributaria.claveAcceso}</claveAcceso>
- <codDoc>01</codDoc>
- <estab>${infoTributaria.estab}</estab>
- <ptoEmi>${infoTributaria.ptoEmi}</ptoEmi>
- <secuencial>${infoTributaria.secuencial}</secuencial>
- <dirMatriz>${infoTributaria.dirMatriz}</dirMatriz>
- </infoTributaria>
- <infoFactura>
- <fechaEmision>${formatDateForSRI(infoFactura.fechaEmision)}</fechaEmision>
- <dirEstablecimiento>${infoFactura.dirEstablecimiento}</dirEstablecimiento>
- <obligadoContabilidad>${infoTributaria.obligadoContabilidad}</obligadoContabilidad>
- <tipoIdentificacionComprador>${infoFactura.tipoIdentificacionComprador}</tipoIdentificacionComprador>
- <razonSocialComprador>${infoFactura.razonSocialComprador}</razonSocialComprador>
- <identificacionComprador>${infoFactura.identificacionComprador}</identificacionComprador>
- <totalSinImpuestos>${infoFactura.totalSinImpuestos}</totalSinImpuestos>
- <totalDescuento>${infoFactura.totalDescuento}</totalDescuento>
-
- <totalConImpuestos>`
- // Agregar múltiples impuestos según los detalles
- totalesImpuestos.forEach(impuesto => {
- xml += `
- <totalImpuesto>
- <codigo>${impuesto.codigo}</codigo>
- <codigoPorcentaje>${impuesto.codigoPorcentaje}</codigoPorcentaje>
- <baseImponible>${impuesto.baseImponible}</baseImponible>
- <valor>${impuesto.valor}</valor>
- </totalImpuesto>`
- })
- xml += `
- </totalConImpuestos>
- <propina>0.00</propina>
- <importeTotal>${infoFactura.importeTotal}</importeTotal>
- <moneda>DOLAR</moneda>
-
- <pagos>
- <pago>
- <formaPago>${infoFactura.formaPago}</formaPago>
- <total>${infoFactura.importeTotal}</total>
- <plazo>${infoFactura.plazo}</plazo>
- <unidadTiempo>${infoFactura.unidadTiempo}</unidadTiempo>
- </pago>
- </pagos>
- </infoFactura>
-
- <detalles>`
- detalles.forEach(item => {
- // Si codigoAuxiliar está vacío, usar el codigoPrincipal como fallback
- const codigoAux = item.codigoAuxiliar?.trim() || item.codigoPrincipal || '001'
- xml += `
- <detalle>
- <codigoPrincipal>${item.codigoPrincipal}</codigoPrincipal>
- <codigoAuxiliar>${codigoAux}</codigoAuxiliar>
- <descripcion>${item.descripcion}</descripcion>
- <cantidad>${item.cantidad}</cantidad>
- <precioUnitario>${parseFloat(item.precioUnitario).toFixed(6)}</precioUnitario>
- <descuento>${item.descuento}</descuento>
- <precioTotalSinImpuesto>${item.precioTotalSinImpuesto}</precioTotalSinImpuesto>
- <impuestos>
- <impuesto>
- <codigo>2</codigo>
- <codigoPorcentaje>${item.codigoPorcentaje}</codigoPorcentaje>
- <tarifa>${item.tarifa}</tarifa>
- <baseImponible>${item.baseImponible}</baseImponible>
- <valor>${item.valorImpuesto}</valor>
- </impuesto>
- </impuestos>
- </detalle>`
- })
- xml += `
- </detalles>
-
- <infoAdicional>
- <campoAdicional nombre="Direccion">${infoFactura.direccionComprador}</campoAdicional>
- <campoAdicional nombre="Email">${infoFactura.emailComprador}</campoAdicional>
- <campoAdicional nombre="Telefono">${infoFactura.telefonoComprador}</campoAdicional>
- </infoAdicional>
- </factura>`
- return xml
- }
- }
|