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.

112 lines 7.63 kB
import { BaseValidator } from '../base/base.validator.js'; import { ValidationLevel } from '../../interfaces/common.js'; import { UBLDocumentType } from './ubl.types.js'; import { DOMParser, xpath } from '../../plugins.js'; /** * Base validator for UBL-based invoice formats */ export class UBLBaseValidator extends BaseValidator { constructor(xml) { super(xml); try { // Parse XML document this.doc = new DOMParser().parseFromString(xml, 'application/xml'); // Set up namespaces for XPath queries this.namespaces = { cbc: 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', cac: 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' }; // Create XPath selector with namespaces this.select = xpath.useNamespaces(this.namespaces); } catch (error) { this.addError('UBL-PARSE', `Failed to parse XML: ${error}`, '/'); } } /** * Validates UBL XML against the specified level of validation * @param level Validation level * @returns Result of validation */ validate(level = ValidationLevel.SYNTAX) { // Reset errors this.errors = []; // Check if document was parsed successfully if (!this.doc) { return { valid: false, errors: this.errors, level: level }; } // Perform validation based on level let valid = true; if (level === ValidationLevel.SYNTAX) { valid = this.validateSchema(); } else if (level === ValidationLevel.SEMANTIC) { valid = this.validateSchema() && this.validateStructure(); } else if (level === ValidationLevel.BUSINESS) { valid = this.validateSchema() && this.validateStructure() && this.validateBusinessRules(); } return { valid, errors: this.errors, level }; } /** * Validates UBL XML against schema * @returns True if schema validation passed */ validateSchema() { // Basic schema validation (simplified for now) if (!this.doc) return false; // Check for root element const root = this.doc.documentElement; if (!root || (root.nodeName !== UBLDocumentType.INVOICE && root.nodeName !== UBLDocumentType.CREDIT_NOTE)) { this.addError('UBL-SCHEMA-1', `Root element must be ${UBLDocumentType.INVOICE} or ${UBLDocumentType.CREDIT_NOTE}`, '/'); return false; } return true; } /** * Gets a text value from an XPath expression * @param xpath XPath expression * @param context Optional context node * @returns Text value or empty string if not found */ getText(xpathExpr, context) { const node = this.select(xpathExpr, context || this.doc)[0]; return node ? (node.textContent || '') : ''; } /** * Gets a number value from an XPath expression * @param xpath XPath expression * @param context Optional context node * @returns Number value or 0 if not found or not a number */ getNumber(xpathExpr, context) { const text = this.getText(xpathExpr, context); const num = parseFloat(text); return isNaN(num) ? 0 : num; } /** * Checks if a node exists * @param xpath XPath expression * @param context Optional context node * @returns True if node exists */ exists(xpathExpr, context) { const nodes = this.select(xpathExpr, context || this.doc); if (Array.isArray(nodes)) { return nodes.length > 0; } return false; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWJsLnZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvdWJsL3VibC52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUU3RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVwRDs7R0FFRztBQUNILE1BQU0sT0FBZ0IsZ0JBQWlCLFNBQVEsYUFBYTtJQUsxRCxZQUFZLEdBQVc7UUFDckIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRVgsSUFBSSxDQUFDO1lBQ0gscUJBQXFCO1lBQ3JCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFFbkUsc0NBQXNDO1lBQ3RDLElBQUksQ0FBQyxVQUFVLEdBQUc7Z0JBQ2hCLEdBQUcsRUFBRSxzRUFBc0U7Z0JBQzNFLEdBQUcsRUFBRSwwRUFBMEU7YUFDaEYsQ0FBQztZQUVGLHdDQUF3QztZQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsd0JBQXdCLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25FLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFFBQVEsQ0FBQyxRQUF5QixlQUFlLENBQUMsTUFBTTtRQUM3RCxlQUFlO1FBQ2YsSUFBSSxDQUFD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