import { BaseDecoder } from '../base/base.decoder.js'; import { InvoiceFormat } from '../../interfaces/common.js'; import { FormatDetector } from '../utils/format.detector.js'; // Import specific decoders import { XRechnungDecoder } from '../ubl/xrechnung/xrechnung.decoder.js'; import { FacturXDecoder } from '../cii/facturx/facturx.decoder.js'; import { ZUGFeRDDecoder } from '../cii/zugferd/zugferd.decoder.js'; import { ZUGFeRDV1Decoder } from '../cii/zugferd/zugferd.v1.decoder.js'; /** * Factory to create the appropriate decoder based on the XML format */ export class DecoderFactory { /** * Creates a decoder for the specified XML content * @param xml XML content to decode * @returns Appropriate decoder instance */ public static createDecoder(xml: string): BaseDecoder { const format = FormatDetector.detectFormat(xml); switch (format) { case InvoiceFormat.UBL: case InvoiceFormat.XRECHNUNG: return new XRechnungDecoder(xml); case InvoiceFormat.CII: // For now, use Factur-X decoder for generic CII return new FacturXDecoder(xml); case InvoiceFormat.ZUGFERD: // Determine if it's ZUGFeRD v1 or v2 based on root element if (xml.includes('CrossIndustryDocument') || xml.includes('urn:ferd:CrossIndustryDocument:invoice:1p0') || (xml.includes('ZUGFeRD') && !xml.includes('CrossIndustryInvoice'))) { return new ZUGFeRDV1Decoder(xml); } else { return new ZUGFeRDDecoder(xml); } case InvoiceFormat.FACTURX: return new FacturXDecoder(xml); case InvoiceFormat.FATTURAPA: // return new FatturaPADecoder(xml); throw new Error('FatturaPA decoder not yet implemented'); default: // If format is unknown but contains CrossIndustryInvoice, try ZUGFeRD decoder if (xml.includes('CrossIndustryInvoice')) { return new ZUGFeRDDecoder(xml); } // If format is unknown but contains CrossIndustryDocument, try ZUGFeRD v1 decoder if (xml.includes('CrossIndustryDocument')) { return new ZUGFeRDV1Decoder(xml); } throw new Error(`Unsupported invoice format: ${format}`); } } }