xinvoice/ts/classes.decoder.ts

152 lines
3.8 KiB
TypeScript

import * as plugins from './plugins.js';
/**
* A class to convert a given ZUGFeRD XML string
* into a structured ILetter with invoice data.
*
* Handles different invoice XML formats:
* - ZUGFeRD/Factur-X (CII)
* - UBL
* - FatturaPA
*/
export class ZUGFeRDXmlDecoder {
private xmlString: string;
private xmlFormat: string;
constructor(xmlString: string) {
if (!xmlString) {
throw new Error('No XML string provided to decoder');
}
this.xmlString = xmlString;
// Simple format detection based on string contents
this.xmlFormat = this.detectFormat();
}
/**
* Detects the XML invoice format using simple string checks
*/
private detectFormat(): string {
// ZUGFeRD/Factur-X (CII format)
if (this.xmlString.includes('CrossIndustryInvoice') ||
this.xmlString.includes('un/cefact') ||
this.xmlString.includes('rsm:')) {
return 'CII';
}
// UBL format
if (this.xmlString.includes('Invoice') ||
this.xmlString.includes('oasis:names:specification:ubl')) {
return 'UBL';
}
// FatturaPA format
if (this.xmlString.includes('FatturaElettronica') ||
this.xmlString.includes('fatturapa.gov.it')) {
return 'FatturaPA';
}
// Default to generic
return 'unknown';
}
/**
* Converts XML to a structured letter object
*/
public async getLetterData(): Promise<plugins.tsclass.business.ILetter> {
try {
// Try using SmartXml from plugins as a fallback
const smartxmlInstance = new plugins.smartxml.SmartXml();
return smartxmlInstance.parseXmlToObject(this.xmlString);
} catch (error) {
console.error('Error converting XML to letter data:', error);
// If all else fails, return a minimal letter object
return this.createDefaultLetter();
}
}
/**
* Creates a default letter object with minimal data
*/
private createDefaultLetter(): plugins.tsclass.business.ILetter {
// Create a default seller
const seller: plugins.tsclass.business.IContact = {
name: 'Unknown Seller',
type: 'company',
address: {
streetName: 'Unknown',
city: 'Unknown',
country: 'Unknown',
postalCode: 'Unknown',
},
};
// Create a default buyer
const buyer: plugins.tsclass.business.IContact = {
name: 'Unknown Buyer',
type: 'company',
address: {
streetName: 'Unknown',
city: 'Unknown',
country: 'Unknown',
postalCode: 'Unknown',
},
};
// Create default invoice data
const invoiceData: plugins.tsclass.business.IInvoiceData = {
id: 'Unknown',
status: null,
type: 'invoice',
billedBy: seller,
billedTo: buyer,
deliveryDate: Date.now(),
dueInDays: 30,
periodOfPerformance: null,
printResult: null,
currency: 'EUR',
notes: [],
items: [
{
name: 'Unknown Item',
unitQuantity: 1,
unitNetPrice: 0,
vatPercentage: 0,
position: 0,
unitType: 'units',
}
],
reverseCharge: false,
};
// Return a default letter
return {
versionInfo: {
type: 'extracted',
version: '1.0.0',
},
type: 'invoice',
date: Date.now(),
subject: `Extracted Invoice (${this.xmlFormat} format)`,
from: seller,
to: buyer,
content: {
invoiceData: invoiceData,
textData: null,
timesheetData: null,
contractData: null,
},
needsCoverSheet: false,
objectActions: [],
pdf: null,
incidenceId: null,
language: null,
legalContact: null,
logoUrl: null,
pdfAttachments: null,
accentColor: null,
};
}
}