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.

282 lines 28.4 kB
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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