@fin.cx/einvoice
Version:
A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.
282 lines • 28.4 kB
JavaScript
import * as plugins from '../plugins.js';
/**
* A class to convert a given ILetter with invoice data
* into an XInvoice/XRechnung compliant XML (based on UBL).
*
* XRechnung is the German implementation of the European standard EN16931
* for electronic invoices to the German public sector.
*/
export class XInvoiceEncoder {
constructor() { }
/**
* Creates an XInvoice compliant XML based on the provided letter data.
*/
createXInvoiceXml(letterArg) {
// Use SmartXml for XML creation
const smartxmlInstance = new plugins.smartxml.SmartXml();
if (!letterArg?.content?.invoiceData) {
throw new Error('Letter does not contain invoice data.');
}
const invoice = letterArg.content.invoiceData;
const billedBy = invoice.billedBy;
const billedTo = invoice.billedTo;
// Create the XML document
const doc = smartxmlInstance
.create({ version: '1.0', encoding: 'UTF-8' })
.ele('Invoice', {
'xmlns': 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2',
'xmlns:cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
'xmlns:cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance'
});
// UBL Version ID
doc.ele('cbc:UBLVersionID').txt('2.1').up();
// CustomizationID for XRechnung
doc.ele('cbc:CustomizationID').txt('urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0').up();
// ID - Invoice number
doc.ele('cbc:ID').txt(invoice.id).up();
// Issue date
const issueDate = new Date(letterArg.date);
const issueDateStr = `${issueDate.getFullYear()}-${String(issueDate.getMonth() + 1).padStart(2, '0')}-${String(issueDate.getDate()).padStart(2, '0')}`;
doc.ele('cbc:IssueDate').txt(issueDateStr).up();
// Due date
const dueDate = new Date(letterArg.date);
dueDate.setDate(dueDate.getDate() + invoice.dueInDays);
const dueDateStr = `${dueDate.getFullYear()}-${String(dueDate.getMonth() + 1).padStart(2, '0')}-${String(dueDate.getDate()).padStart(2, '0')}`;
doc.ele('cbc:DueDate').txt(dueDateStr).up();
// Invoice type code
const invoiceTypeCode = invoice.type === 'creditnote' ? '381' : '380';
doc.ele('cbc:InvoiceTypeCode').txt(invoiceTypeCode).up();
// Note - optional invoice note
if (invoice.notes && invoice.notes.length > 0) {
doc.ele('cbc:Note').txt(invoice.notes[0]).up();
}
// Document currency code
doc.ele('cbc:DocumentCurrencyCode').txt(invoice.currency).up();
// Tax currency code - same as document currency in this case
doc.ele('cbc:TaxCurrencyCode').txt(invoice.currency).up();
// Accounting supplier party (seller)
const supplierParty = doc.ele('cac:AccountingSupplierParty');
const supplierPartyDetails = supplierParty.ele('cac:Party');
// Seller VAT ID
if (billedBy.type === 'company' && billedBy.registrationDetails?.vatId) {
const partyTaxScheme = supplierPartyDetails.ele('cac:PartyTaxScheme');
partyTaxScheme.ele('cbc:CompanyID').txt(billedBy.registrationDetails.vatId).up();
partyTaxScheme.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up();
}
// Seller name
supplierPartyDetails.ele('cac:PartyName')
.ele('cbc:Name').txt(billedBy.name).up()
.up();
// Seller postal address
const supplierAddress = supplierPartyDetails.ele('cac:PostalAddress');
supplierAddress.ele('cbc:StreetName').txt(billedBy.address.streetName).up();
if (billedBy.address.houseNumber) {
supplierAddress.ele('cbc:BuildingNumber').txt(billedBy.address.houseNumber).up();
}
supplierAddress.ele('cbc:CityName').txt(billedBy.address.city).up();
supplierAddress.ele('cbc:PostalZone').txt(billedBy.address.postalCode).up();
supplierAddress.ele('cac:Country')
.ele('cbc:IdentificationCode').txt(billedBy.address.country || 'DE').up()
.up();
// Seller contact
const supplierContact = supplierPartyDetails.ele('cac:Contact');
if (billedBy.email) {
supplierContact.ele('cbc:ElectronicMail').txt(billedBy.email).up();
}
if (billedBy.phone) {
supplierContact.ele('cbc:Telephone').txt(billedBy.phone).up();
}
supplierParty.up(); // Close AccountingSupplierParty
// Accounting customer party (buyer)
const customerParty = doc.ele('cac:AccountingCustomerParty');
const customerPartyDetails = customerParty.ele('cac:Party');
// Buyer VAT ID
if (billedTo.type === 'company' && billedTo.registrationDetails?.vatId) {
const partyTaxScheme = customerPartyDetails.ele('cac:PartyTaxScheme');
partyTaxScheme.ele('cbc:CompanyID').txt(billedTo.registrationDetails.vatId).up();
partyTaxScheme.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up();
}
// Buyer name
customerPartyDetails.ele('cac:PartyName')
.ele('cbc:Name').txt(billedTo.name).up()
.up();
// Buyer postal address
const customerAddress = customerPartyDetails.ele('cac:PostalAddress');
customerAddress.ele('cbc:StreetName').txt(billedTo.address.streetName).up();
if (billedTo.address.houseNumber) {
customerAddress.ele('cbc:BuildingNumber').txt(billedTo.address.houseNumber).up();
}
customerAddress.ele('cbc:CityName').txt(billedTo.address.city).up();
customerAddress.ele('cbc:PostalZone').txt(billedTo.address.postalCode).up();
customerAddress.ele('cac:Country')
.ele('cbc:IdentificationCode').txt(billedTo.address.country || 'DE').up()
.up();
// Buyer contact
if (billedTo.email || billedTo.phone) {
const customerContact = customerPartyDetails.ele('cac:Contact');
if (billedTo.email) {
customerContact.ele('cbc:ElectronicMail').txt(billedTo.email).up();
}
if (billedTo.phone) {
customerContact.ele('cbc:Telephone').txt(billedTo.phone).up();
}
}
customerParty.up(); // Close AccountingCustomerParty
// Payment means
if (billedBy.sepaConnection) {
const paymentMeans = doc.ele('cac:PaymentMeans');
paymentMeans.ele('cbc:PaymentMeansCode').txt('58').up(); // 58 = SEPA credit transfer
paymentMeans.ele('cbc:PaymentID').txt(invoice.id).up();
// IBAN
if (billedBy.sepaConnection.iban) {
const payeeAccount = paymentMeans.ele('cac:PayeeFinancialAccount');
payeeAccount.ele('cbc:ID').txt(billedBy.sepaConnection.iban).up();
// BIC
if (billedBy.sepaConnection.bic) {
payeeAccount.ele('cac:FinancialInstitutionBranch')
.ele('cbc:ID').txt(billedBy.sepaConnection.bic).up()
.up();
}
}
}
// Payment terms
const paymentTerms = doc.ele('cac:PaymentTerms');
paymentTerms.ele('cbc:Note').txt(`Payment due in ${invoice.dueInDays} days`).up();
// Tax summary
// Group items by VAT rate
const vatRates = {};
// Collect items by VAT rate
invoice.items.forEach(item => {
if (!vatRates[item.vatPercentage]) {
vatRates[item.vatPercentage] = [];
}
vatRates[item.vatPercentage].push(item);
});
// Calculate tax subtotals for each rate
Object.entries(vatRates).forEach(([rate, items]) => {
const taxRate = parseFloat(rate);
// Calculate base amount for this rate
let taxableAmount = 0;
items.forEach(item => {
taxableAmount += item.unitNetPrice * item.unitQuantity;
});
// Calculate tax amount
const taxAmount = taxableAmount * (taxRate / 100);
// Create tax subtotal
const taxSubtotal = doc.ele('cac:TaxTotal')
.ele('cbc:TaxAmount').txt(taxAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
taxSubtotal.ele('cac:TaxSubtotal')
.ele('cbc:TaxableAmount')
.txt(taxableAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up()
.ele('cbc:TaxAmount')
.txt(taxAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up()
.ele('cac:TaxCategory')
.ele('cbc:ID').txt('S').up() // Standard rate
.ele('cbc:Percent').txt(taxRate.toFixed(2)).up()
.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up()
.up()
.up();
});
// Calculate invoice totals
let lineExtensionAmount = 0;
let taxExclusiveAmount = 0;
let taxInclusiveAmount = 0;
let totalVat = 0;
// Sum all items
invoice.items.forEach(item => {
const net = item.unitNetPrice * item.unitQuantity;
const vat = net * (item.vatPercentage / 100);
lineExtensionAmount += net;
taxExclusiveAmount += net;
totalVat += vat;
});
taxInclusiveAmount = taxExclusiveAmount + totalVat;
// Legal monetary total
const legalMonetaryTotal = doc.ele('cac:LegalMonetaryTotal');
legalMonetaryTotal.ele('cbc:LineExtensionAmount')
.txt(lineExtensionAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
legalMonetaryTotal.ele('cbc:TaxExclusiveAmount')
.txt(taxExclusiveAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
legalMonetaryTotal.ele('cbc:TaxInclusiveAmount')
.txt(taxInclusiveAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
legalMonetaryTotal.ele('cbc:PayableAmount')
.txt(taxInclusiveAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
// Invoice lines
invoice.items.forEach((item, index) => {
const invoiceLine = doc.ele('cac:InvoiceLine');
invoiceLine.ele('cbc:ID').txt((index + 1).toString()).up();
// Quantity
invoiceLine.ele('cbc:InvoicedQuantity')
.txt(item.unitQuantity.toString())
.att('unitCode', this.mapUnitType(item.unitType))
.up();
// Line extension amount (net)
const lineAmount = item.unitNetPrice * item.unitQuantity;
invoiceLine.ele('cbc:LineExtensionAmount')
.txt(lineAmount.toFixed(2))
.att('currencyID', invoice.currency)
.up();
// Item details
const itemEle = invoiceLine.ele('cac:Item');
itemEle.ele('cbc:Description').txt(item.name).up();
itemEle.ele('cbc:Name').txt(item.name).up();
// Classified tax category
itemEle.ele('cac:ClassifiedTaxCategory')
.ele('cbc:ID').txt('S').up() // Standard rate
.ele('cbc:Percent').txt(item.vatPercentage.toFixed(2)).up()
.ele('cac:TaxScheme')
.ele('cbc:ID').txt('VAT').up()
.up()
.up();
// Price
invoiceLine.ele('cac:Price')
.ele('cbc:PriceAmount')
.txt(item.unitNetPrice.toFixed(2))
.att('currencyID', invoice.currency)
.up()
.up();
});
// Return the formatted XML
return doc.end({ prettyPrint: true });
}
/**
* Helper: Map your custom 'unitType' to an ISO code.
*/
mapUnitType(unitType) {
switch (unitType.toLowerCase()) {
case 'hour':
case 'hours':
return 'HUR';
case 'day':
case 'days':
return 'DAY';
case 'piece':
case 'pieces':
return 'C62';
default:
return 'C62'; // fallback for unknown unit types
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGludm9pY2UuZW5jb2Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2Zvcm1hdHMveGludm9pY2UuZW5jb2Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUV6Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUUxQixnQkFBZSxDQUFDO0lBRWhCOztPQUVHO0lBQ0ksaUJBQWlCLENBQUMsU0FBMkM7UUFDbEUsZ0NBQWdDO1FBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXpELElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQXFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQ2hGLE1BQU0sUUFBUSxHQUFzQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ3JFLE1BQU0sUUFBUSxHQUFzQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBRXJFLDBCQUEwQjtRQUMxQixNQUFNLEdBQUcsR0FBRyxnQkFBZ0I7YUFDekIsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUM7YUFDN0MsR0FBRyxDQUFDLFNBQVMsRUFBRTtZQUNkLE9BQU8sRUFBRSx3REFBd0Q7WUFDakUsV0FBVyxFQUFFLDBFQUEwRTtZQUN2RixXQUFXLEVBQUUsc0VBQXNFO1lBQ25GLFdBQVcsRUFBRSwyQ0FBMkM7U0FDekQsQ0FBQyxDQUFDO1FBRUwsaUJBQWlCO1FBQ2pCLEdBQUcsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFF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