@fin.cx/einvoice
Version:
A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.
111 lines • 7.86 kB
JavaScript
import { BaseDecoder } from '../base/base.decoder.js';
import { CII_NAMESPACES, CIIProfile } from './cii.types.js';
import { DOMParser, xpath } from '../../plugins.js';
/**
* Base decoder for CII-based invoice formats
*/
export class CIIBaseDecoder extends BaseDecoder {
constructor(xml, skipValidation = false) {
super(xml, skipValidation);
this.profile = CIIProfile.EN16931;
// Parse XML document
this.doc = new DOMParser().parseFromString(xml, 'application/xml');
// Set up namespaces for XPath queries
this.namespaces = {
rsm: CII_NAMESPACES.RSM,
ram: CII_NAMESPACES.RAM,
udt: CII_NAMESPACES.UDT
};
// Create XPath selector with namespaces
this.select = xpath.useNamespaces(this.namespaces);
// Detect profile
this.detectProfile();
}
/**
* Decodes CII XML into a TInvoice object
* @returns Promise resolving to a TInvoice object
*/
async decode() {
// Determine if it's a credit note or debit note based on type code
const typeCode = this.getText('//ram:TypeCode');
if (typeCode === '381') { // Credit note type code
return this.decodeCreditNote();
}
else {
return this.decodeDebitNote();
}
}
/**
* Detects the CII profile from the XML
*/
detectProfile() {
// Look for profile identifier
const profileNode = this.select('string(//rsm:ExchangedDocumentContext/ram:GuidelineSpecifiedDocumentContextParameter/ram:ID)', this.doc);
if (profileNode) {
const profileText = profileNode.toString();
if (profileText.includes('BASIC')) {
this.profile = CIIProfile.BASIC;
}
else if (profileText.includes('EN16931')) {
this.profile = CIIProfile.EN16931;
}
else if (profileText.includes('EXTENDED')) {
this.profile = CIIProfile.EXTENDED;
}
else if (profileText.includes('MINIMUM')) {
this.profile = CIIProfile.MINIMUM;
}
else if (profileText.includes('COMFORT')) {
this.profile = CIIProfile.COMFORT;
}
}
}
/**
* 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;
}
/**
* Gets a date value from an XPath expression
* @param xpath XPath expression
* @param context Optional context node
* @returns Date timestamp or current time if not found or invalid
*/
getDate(xpathExpr, context) {
const text = this.getText(xpathExpr, context);
if (!text)
return Date.now();
const date = new Date(text);
return isNaN(date.getTime()) ? Date.now() : date.getTime();
}
/**
* 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lpLmRlY29kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9mb3JtYXRzL2NpaS9jaWkuZGVjb2Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXBEOztHQUVHO0FBQ0gsTUFBTSxPQUFnQixjQUFlLFNBQVEsV0FBVztJQU10RCxZQUFZLEdBQVcsRUFBRSxpQkFBMEIsS0FBSztRQUN0RCxLQUFLLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBSG5CLFlBQU8sR0FBZSxVQUFVLENBQUMsT0FBTyxDQUFDO1FBS2pELHFCQUFxQjtRQUNyQixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRW5FLHNDQUFzQztRQUN0QyxJQUFJLENBQUMsVUFBVSxHQUFHO1lBQ2hCLEdBQUcsRUFBRSxjQUFjLENBQUMsR0FBRztZQUN2QixHQUFHLEVBQUUsY0FBYyxDQUFDLEdBQUc7WUFDdkIsR0FBRyxFQUFFLGNBQWMsQ0FBQyxHQUFHO1NBQ3hCLENBQUM7UUFFRix3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUVuRCxpQkFBaUI7UUFDakIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsTUFBTTtRQUNqQixtRUFBbUU7UUFDbkUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0Is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