UNPKG

@fin.cx/einvoice

Version:

A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.

78 lines 6.54 kB
import { InvoiceFormat } from '../interfaces.js'; import { BaseValidator } from './base.validator.js'; import { FacturXValidator } from './facturx.validator.js'; import { UBLValidator } from './ubl.validator.js'; import { DOMParser } from 'xmldom'; /** * Factory to create the appropriate validator based on the XML format */ export class ValidatorFactory { /** * Creates a validator for the specified XML content * @param xml XML content to validate * @returns Appropriate validator instance */ static createValidator(xml) { const format = ValidatorFactory.detectFormat(xml); switch (format) { case InvoiceFormat.UBL: case InvoiceFormat.XRECHNUNG: return new UBLValidator(xml); case InvoiceFormat.CII: case InvoiceFormat.ZUGFERD: case InvoiceFormat.FACTURX: return new FacturXValidator(xml); // FatturaPA and other formats would be implemented here default: throw new Error(`Unsupported invoice format: ${format}`); } } /** * Detects the invoice format from XML content * @param xml XML content to analyze * @returns Detected invoice format */ static detectFormat(xml) { try { const doc = new DOMParser().parseFromString(xml, 'application/xml'); const root = doc.documentElement; if (!root) { return InvoiceFormat.UNKNOWN; } // UBL detection (Invoice or CreditNote root element) if (root.nodeName === 'Invoice' || root.nodeName === 'CreditNote') { // Check if it's XRechnung by looking at CustomizationID const customizationNodes = root.getElementsByTagName('cbc:CustomizationID'); if (customizationNodes.length > 0) { const customizationId = customizationNodes[0].textContent || ''; if (customizationId.includes('xrechnung') || customizationId.includes('XRechnung')) { return InvoiceFormat.XRECHNUNG; } } return InvoiceFormat.UBL; } // Factur-X/ZUGFeRD detection (CrossIndustryInvoice root element) if (root.nodeName === 'rsm:CrossIndustryInvoice' || root.nodeName === 'CrossIndustryInvoice') { // Check for profile to determine if it's Factur-X or ZUGFeRD const profileNodes = root.getElementsByTagName('ram:ID'); for (let i = 0; i < profileNodes.length; i++) { const profileText = profileNodes[i].textContent || ''; if (profileText.includes('factur-x') || profileText.includes('Factur-X')) { return InvoiceFormat.FACTURX; } if (profileText.includes('zugferd') || profileText.includes('ZUGFeRD')) { return InvoiceFormat.ZUGFERD; } } // If no specific profile found, default to CII return InvoiceFormat.CII; } // FatturaPA detection would be implemented here return InvoiceFormat.UNKNOWN; } catch (error) { return InvoiceFormat.UNKNOWN; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yLmZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9mb3JtYXRzL3ZhbGlkYXRvci5mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFbkM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQzNCOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsZUFBZSxDQUFDLEdBQVc7UUFDdkMsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWxELFFBQVEsTUFBTSxFQUFFLENBQUM7WUFDZixLQUFLLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDdkIsS0FBSyxhQUFhLENBQUMsU0FBUztnQkFDMUIsT0FBTyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUUvQixLQUFLLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDdkIsS0FBSyxhQUFhLENBQUMsT0FBTyxDQUFDO1lBQzNCLEtBQUssYUFBYSxDQUFDLE9BQU87Z0JBQ3hCLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVuQyx3REFBd0Q7WUFFeEQ7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQVc7UUFDckMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDcEUsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLGVBQWUsQ0FBQztZQUVqQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ1YsT0FBTyxhQUFhLENBQUMsT0FBTyxDQUFDO1lBQy9CLENBQUM7WUFFRCxxREFBcUQ7WUFDckQsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFlBQVksRUFBRSxDQUFDO2dCQUNsRSx3REFBd0Q7Z0JBQ3hELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBQzVFLElBQUksa0JBQWtCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUNsQyxNQUFNLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO29CQUNoRSxJQUFJLGVBQWUsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksZUFBZSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO3dCQUNuRixPQUFPLGFBQWEsQ0FBQyxTQUFTLENBQUM7b0JBQ2pDLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxPQUFPLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDM0IsQ0FBQztZQUVELGlFQUFpRTtZQUNqRSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssMEJBQTBCLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxzQkFBc0IsRUFBRSxDQUFDO2dCQUM3Riw2REFBNkQ7Z0JBQzdELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDekQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDN0MsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7b0JBRXRELElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7d0JBQ3pFLE9BQU8sYUFBYSxDQUFDLE9BQU8sQ0FBQztvQkFDL0IsQ0FBQztvQkFFRCxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO3dCQUN2RSxPQUFPLGFBQWEsQ0FBQyxPQUFPLENBQUM7b0JBQy9CLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCwrQ0FBK0M7Z0JBQy9DLE9BQU8sYUFBYSxDQUFDLEdBQUcsQ0FBQztZQUMzQixDQUFDO1lBRUQsZ0RBQWdEO1lBRWhELE9BQU8sYUFBYSxDQUFDLE9BQU8sQ0FBQztRQUMvQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sYUFBYSxDQUFDLE9BQU8sQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztDQUNGIn0=