@fin.cx/einvoice 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.decoder.d.ts +40 -0
- package/dist_ts/classes.decoder.js +320 -0
- package/dist_ts/classes.encoder.d.ts +51 -0
- package/dist_ts/classes.encoder.js +293 -0
- package/dist_ts/classes.xinvoice.d.ts +136 -0
- package/dist_ts/classes.xinvoice.js +352 -0
- package/dist_ts/einvoice.d.ts +217 -0
- package/dist_ts/einvoice.js +505 -0
- package/dist_ts/errors.d.ts +121 -0
- package/dist_ts/errors.js +241 -0
- package/dist_ts/formats/base/base.decoder.d.ts +32 -0
- package/dist_ts/formats/base/base.decoder.js +52 -0
- package/dist_ts/formats/base/base.encoder.d.ts +13 -0
- package/dist_ts/formats/base/base.encoder.js +7 -0
- package/dist_ts/formats/base/base.validator.d.ts +44 -0
- package/dist_ts/formats/base/base.validator.js +39 -0
- package/dist_ts/formats/base.decoder.d.ts +19 -0
- package/dist_ts/formats/base.decoder.js +130 -0
- package/dist_ts/formats/base.validator.d.ts +44 -0
- package/dist_ts/formats/base.validator.js +39 -0
- package/dist_ts/formats/cii/cii.decoder.d.ts +61 -0
- package/dist_ts/formats/cii/cii.decoder.js +111 -0
- package/dist_ts/formats/cii/cii.encoder.d.ts +43 -0
- package/dist_ts/formats/cii/cii.encoder.js +48 -0
- package/dist_ts/formats/cii/cii.types.d.ts +31 -0
- package/dist_ts/formats/cii/cii.types.js +40 -0
- package/dist_ts/formats/cii/cii.validator.d.ts +56 -0
- package/dist_ts/formats/cii/cii.validator.js +146 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.js +207 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +82 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.js +400 -0
- package/dist_ts/formats/cii/facturx/facturx.types.d.ts +10 -0
- package/dist_ts/formats/cii/facturx/facturx.types.js +15 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.d.ts +32 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.js +138 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +218 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +97 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +550 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.d.ts +10 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.js +15 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +49 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +229 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.d.ts +16 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.js +29 -0
- package/dist_ts/formats/decoder.factory.d.ts +15 -0
- package/dist_ts/formats/decoder.factory.js +46 -0
- package/dist_ts/formats/factories/decoder.factory.d.ts +13 -0
- package/dist_ts/formats/factories/decoder.factory.js +56 -0
- package/dist_ts/formats/factories/encoder.factory.d.ts +14 -0
- package/dist_ts/formats/factories/encoder.factory.js +40 -0
- package/dist_ts/formats/factories/validator.factory.d.ts +12 -0
- package/dist_ts/formats/factories/validator.factory.js +110 -0
- package/dist_ts/formats/factorx.decoder.d.ts +18 -0
- package/dist_ts/formats/factorx.decoder.js +178 -0
- package/dist_ts/formats/factorx.encoder.d.ts +51 -0
- package/dist_ts/formats/factorx.encoder.js +293 -0
- package/dist_ts/formats/facturx.decoder.d.ts +18 -0
- package/dist_ts/formats/facturx.decoder.js +210 -0
- package/dist_ts/formats/facturx.encoder.d.ts +51 -0
- package/dist_ts/formats/facturx.encoder.js +293 -0
- package/dist_ts/formats/facturx.validator.d.ts +67 -0
- package/dist_ts/formats/facturx.validator.js +266 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.d.ts +14 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.js +68 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.d.ts +92 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.js +319 -0
- package/dist_ts/formats/pdf/extractors/index.d.ts +4 -0
- package/dist_ts/formats/pdf/extractors/index.js +5 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.d.ts +13 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.js +74 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.d.ts +45 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.js +151 -0
- package/dist_ts/formats/pdf/pdf.embedder.d.ts +69 -0
- package/dist_ts/formats/pdf/pdf.embedder.js +183 -0
- package/dist_ts/formats/pdf/pdf.extractor.d.ts +49 -0
- package/dist_ts/formats/pdf/pdf.extractor.js +98 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +40 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.js +324 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.d.ts +18 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.js +169 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +151 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.js +892 -0
- package/dist_ts/formats/ubl/ubl.decoder.d.ts +61 -0
- package/dist_ts/formats/ubl/ubl.decoder.js +95 -0
- package/dist_ts/formats/ubl/ubl.encoder.d.ts +38 -0
- package/dist_ts/formats/ubl/ubl.encoder.js +46 -0
- package/dist_ts/formats/ubl/ubl.types.d.ts +16 -0
- package/dist_ts/formats/ubl/ubl.types.js +21 -0
- package/dist_ts/formats/ubl/ubl.validator.d.ts +50 -0
- package/dist_ts/formats/ubl/ubl.validator.js +112 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +34 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +424 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +75 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +555 -0
- package/dist_ts/formats/ubl/xrechnung.validator.d.ts +15 -0
- package/dist_ts/formats/ubl/xrechnung.validator.js +107 -0
- package/dist_ts/formats/ubl.validator.d.ts +82 -0
- package/dist_ts/formats/ubl.validator.js +306 -0
- package/dist_ts/formats/utils/format.detector.d.ts +62 -0
- package/dist_ts/formats/utils/format.detector.js +249 -0
- package/dist_ts/formats/validation/en16931.validator.d.ts +23 -0
- package/dist_ts/formats/validation/en16931.validator.js +119 -0
- package/dist_ts/formats/validator.factory.d.ts +18 -0
- package/dist_ts/formats/validator.factory.js +78 -0
- package/dist_ts/formats/xinvoice.decoder.d.ts +28 -0
- package/dist_ts/formats/xinvoice.decoder.js +332 -0
- package/dist_ts/formats/xinvoice.encoder.d.ts +19 -0
- package/dist_ts/formats/xinvoice.encoder.js +282 -0
- package/dist_ts/index.d.ts +51 -0
- package/dist_ts/index.js +90 -0
- package/dist_ts/interfaces/common.d.ts +79 -0
- package/dist_ts/interfaces/common.js +24 -0
- package/dist_ts/interfaces.d.ts +87 -0
- package/dist_ts/interfaces.js +23 -0
- package/dist_ts/plugins.d.ts +14 -0
- package/dist_ts/plugins.js +31 -0
- package/npmextra.json +35 -0
- package/package.json +71 -0
- package/readme.hints.md +1107 -0
- package/readme.howtofixtests.md +38 -0
- package/readme.literature.md +1 -0
- package/readme.md +998 -0
- package/readme.plan.md +481 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/einvoice.ts +603 -0
- package/ts/errors.ts +341 -0
- package/ts/formats/base/base.decoder.ts +68 -0
- package/ts/formats/base/base.encoder.ts +14 -0
- package/ts/formats/base/base.validator.ts +64 -0
- package/ts/formats/cii/cii.decoder.ts +139 -0
- package/ts/formats/cii/cii.encoder.ts +64 -0
- package/ts/formats/cii/cii.types.ts +44 -0
- package/ts/formats/cii/cii.validator.ts +171 -0
- package/ts/formats/cii/facturx/facturx.decoder.ts +243 -0
- package/ts/formats/cii/facturx/facturx.encoder.ts +483 -0
- package/ts/formats/cii/facturx/facturx.types.ts +18 -0
- package/ts/formats/cii/facturx/facturx.validator.ts +180 -0
- package/ts/formats/cii/zugferd/zugferd.decoder.ts +256 -0
- package/ts/formats/cii/zugferd/zugferd.encoder.ts +661 -0
- package/ts/formats/cii/zugferd/zugferd.types.ts +18 -0
- package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +267 -0
- package/ts/formats/cii/zugferd/zugferd.validator.ts +31 -0
- package/ts/formats/factories/decoder.factory.ts +62 -0
- package/ts/formats/factories/encoder.factory.ts +47 -0
- package/ts/formats/factories/validator.factory.ts +134 -0
- package/ts/formats/pdf/extractors/associated.extractor.ts +78 -0
- package/ts/formats/pdf/extractors/base.extractor.ts +355 -0
- package/ts/formats/pdf/extractors/index.ts +4 -0
- package/ts/formats/pdf/extractors/standard.extractor.ts +86 -0
- package/ts/formats/pdf/extractors/text.extractor.ts +162 -0
- package/ts/formats/pdf/pdf.embedder.ts +242 -0
- package/ts/formats/pdf/pdf.extractor.ts +141 -0
- package/ts/formats/ubl/en16931.ubl.validator.ts +216 -0
- package/ts/formats/ubl/generic/ubl.encoder.ts +1041 -0
- package/ts/formats/ubl/ubl.decoder.ts +121 -0
- package/ts/formats/ubl/ubl.encoder.ts +63 -0
- package/ts/formats/ubl/ubl.types.ts +22 -0
- package/ts/formats/ubl/ubl.validator.ts +133 -0
- package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +471 -0
- package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +619 -0
- package/ts/formats/ubl/xrechnung.validator.ts +185 -0
- package/ts/formats/utils/format.detector.ts +306 -0
- package/ts/formats/validation/en16931.validator.ts +135 -0
- package/ts/index.ts +164 -0
- package/ts/interfaces/common.ts +90 -0
- package/ts/interfaces.ts +98 -0
- package/ts/plugins.ts +61 -0
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
import { UBLBaseEncoder } from '../ubl.encoder.js';
|
|
2
|
+
import { UBLDocumentType } from '../ubl.types.js';
|
|
3
|
+
import { DOMParser, XMLSerializer } from '../../../plugins.js';
|
|
4
|
+
/**
|
|
5
|
+
* UBL Encoder implementation
|
|
6
|
+
* Provides encoding functionality for UBL 2.1 invoice and credit note documents
|
|
7
|
+
*/
|
|
8
|
+
export class UBLEncoder extends UBLBaseEncoder {
|
|
9
|
+
/**
|
|
10
|
+
* Encodes a credit note into UBL XML
|
|
11
|
+
* @param creditNote Credit note to encode
|
|
12
|
+
* @returns UBL XML string
|
|
13
|
+
*/
|
|
14
|
+
async encodeCreditNote(creditNote) {
|
|
15
|
+
// Create XML document from template
|
|
16
|
+
const xmlString = this.createXmlRoot(UBLDocumentType.CREDIT_NOTE);
|
|
17
|
+
const doc = new DOMParser().parseFromString(xmlString, 'application/xml');
|
|
18
|
+
// Add common document elements
|
|
19
|
+
this.addCommonElements(doc, creditNote, UBLDocumentType.CREDIT_NOTE);
|
|
20
|
+
// Add credit note specific data
|
|
21
|
+
this.addCreditNoteSpecificData(doc, creditNote);
|
|
22
|
+
// Serialize to string
|
|
23
|
+
return new XMLSerializer().serializeToString(doc);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Encodes a debit note (invoice) into UBL XML
|
|
27
|
+
* @param debitNote Debit note to encode
|
|
28
|
+
* @returns UBL XML string
|
|
29
|
+
*/
|
|
30
|
+
async encodeDebitNote(debitNote) {
|
|
31
|
+
// Create XML document from template
|
|
32
|
+
const xmlString = this.createXmlRoot(UBLDocumentType.INVOICE);
|
|
33
|
+
const doc = new DOMParser().parseFromString(xmlString, 'application/xml');
|
|
34
|
+
// Add common document elements
|
|
35
|
+
this.addCommonElements(doc, debitNote, UBLDocumentType.INVOICE);
|
|
36
|
+
// Add invoice specific data
|
|
37
|
+
this.addInvoiceSpecificData(doc, debitNote);
|
|
38
|
+
// Serialize to string
|
|
39
|
+
return new XMLSerializer().serializeToString(doc);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Adds common document elements to both invoice and credit note
|
|
43
|
+
* @param doc XML document
|
|
44
|
+
* @param invoice Invoice or credit note data
|
|
45
|
+
* @param documentType Document type (Invoice or CreditNote)
|
|
46
|
+
*/
|
|
47
|
+
addCommonElements(doc, invoice, documentType) {
|
|
48
|
+
const root = doc.documentElement;
|
|
49
|
+
// UBL Version ID (2.1 is standard for EN16931)
|
|
50
|
+
this.appendElement(doc, root, 'cbc:UBLVersionID', '2.1');
|
|
51
|
+
// Customization ID - using generic UBL
|
|
52
|
+
this.appendElement(doc, root, 'cbc:CustomizationID', 'urn:cen.eu:en16931:2017');
|
|
53
|
+
// Profile ID - standard billing
|
|
54
|
+
this.appendElement(doc, root, 'cbc:ProfileID', 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0');
|
|
55
|
+
// ID
|
|
56
|
+
this.appendElement(doc, root, 'cbc:ID', invoice.id);
|
|
57
|
+
// Issue Date
|
|
58
|
+
this.appendElement(doc, root, 'cbc:IssueDate', this.formatDate(invoice.date));
|
|
59
|
+
// Due Date - ensure invoice.date is a valid timestamp
|
|
60
|
+
const issueTimestamp = typeof invoice.date === 'number' ? invoice.date : Date.now();
|
|
61
|
+
const dueDate = new Date(issueTimestamp);
|
|
62
|
+
dueDate.setDate(dueDate.getDate() + (invoice.dueInDays || 30));
|
|
63
|
+
this.appendElement(doc, root, 'cbc:DueDate', this.formatDate(dueDate.getTime()));
|
|
64
|
+
// Document Type Code
|
|
65
|
+
const typeCode = documentType === UBLDocumentType.INVOICE ? '380' : '381';
|
|
66
|
+
this.appendElement(doc, root, 'cbc:InvoiceTypeCode', typeCode);
|
|
67
|
+
// Notes - include subject as first note if it exists
|
|
68
|
+
const allNotes = [];
|
|
69
|
+
if (invoice.subject && invoice.subject.trim()) {
|
|
70
|
+
allNotes.push(invoice.subject);
|
|
71
|
+
}
|
|
72
|
+
if (invoice.notes && invoice.notes.length > 0) {
|
|
73
|
+
allNotes.push(...invoice.notes);
|
|
74
|
+
}
|
|
75
|
+
// Write all notes
|
|
76
|
+
for (const note of allNotes) {
|
|
77
|
+
this.appendElement(doc, root, 'cbc:Note', note);
|
|
78
|
+
}
|
|
79
|
+
// Document Currency Code
|
|
80
|
+
this.appendElement(doc, root, 'cbc:DocumentCurrencyCode', invoice.currency);
|
|
81
|
+
// Add accounting supplier party (seller)
|
|
82
|
+
this.addParty(doc, root, 'cac:AccountingSupplierParty', invoice.from);
|
|
83
|
+
// Add accounting customer party (buyer)
|
|
84
|
+
this.addParty(doc, root, 'cac:AccountingCustomerParty', invoice.to);
|
|
85
|
+
// Add payment terms
|
|
86
|
+
this.addPaymentTerms(doc, root, invoice);
|
|
87
|
+
// Add tax summary
|
|
88
|
+
this.addTaxTotal(doc, root, invoice);
|
|
89
|
+
// Add monetary totals
|
|
90
|
+
this.addLegalMonetaryTotal(doc, root, invoice);
|
|
91
|
+
// Add line items
|
|
92
|
+
this.addInvoiceLines(doc, root, invoice);
|
|
93
|
+
// Preserve metadata if available
|
|
94
|
+
this.preserveMetadata(doc, root, invoice);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Adds credit note specific data to the document
|
|
98
|
+
* @param doc XML document
|
|
99
|
+
* @param creditNote Credit note data
|
|
100
|
+
*/
|
|
101
|
+
addCreditNoteSpecificData(doc, creditNote) {
|
|
102
|
+
// For now, there's no specific data to add for credit notes
|
|
103
|
+
// If needed, additional credit note specific fields would be added here
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Adds invoice specific data to the document
|
|
107
|
+
* @param doc XML document
|
|
108
|
+
* @param invoice Invoice data
|
|
109
|
+
*/
|
|
110
|
+
addInvoiceSpecificData(doc, invoice) {
|
|
111
|
+
// For now, there's no specific data to add for invoices that's not already covered
|
|
112
|
+
// If needed, additional invoice specific fields would be added here
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Adds party information (supplier or customer)
|
|
116
|
+
* @param doc XML document
|
|
117
|
+
* @param parentElement Parent element
|
|
118
|
+
* @param elementName Element name (AccountingSupplierParty or AccountingCustomerParty)
|
|
119
|
+
* @param party Party data
|
|
120
|
+
*/
|
|
121
|
+
addParty(doc, parentElement, elementName, party) {
|
|
122
|
+
const partyElement = doc.createElement(elementName);
|
|
123
|
+
parentElement.appendChild(partyElement);
|
|
124
|
+
const partyNode = doc.createElement('cac:Party');
|
|
125
|
+
partyElement.appendChild(partyNode);
|
|
126
|
+
// Party name
|
|
127
|
+
const partyNameNode = doc.createElement('cac:PartyName');
|
|
128
|
+
partyNode.appendChild(partyNameNode);
|
|
129
|
+
this.appendElement(doc, partyNameNode, 'cbc:Name', party.name);
|
|
130
|
+
// Postal address
|
|
131
|
+
const postalAddressNode = doc.createElement('cac:PostalAddress');
|
|
132
|
+
partyNode.appendChild(postalAddressNode);
|
|
133
|
+
if (party.address.streetName) {
|
|
134
|
+
this.appendElement(doc, postalAddressNode, 'cbc:StreetName', party.address.streetName);
|
|
135
|
+
}
|
|
136
|
+
if (party.address.houseNumber && party.address.houseNumber !== '0') {
|
|
137
|
+
this.appendElement(doc, postalAddressNode, 'cbc:BuildingNumber', party.address.houseNumber);
|
|
138
|
+
}
|
|
139
|
+
if (party.address.city) {
|
|
140
|
+
this.appendElement(doc, postalAddressNode, 'cbc:CityName', party.address.city);
|
|
141
|
+
}
|
|
142
|
+
if (party.address.postalCode) {
|
|
143
|
+
this.appendElement(doc, postalAddressNode, 'cbc:PostalZone', party.address.postalCode);
|
|
144
|
+
}
|
|
145
|
+
// Country
|
|
146
|
+
if (party.address.country || party.address.countryCode) {
|
|
147
|
+
const countryNode = doc.createElement('cac:Country');
|
|
148
|
+
postalAddressNode.appendChild(countryNode);
|
|
149
|
+
const countryCode = party.address.countryCode || this.getCountryCode(party.address.country);
|
|
150
|
+
this.appendElement(doc, countryNode, 'cbc:IdentificationCode', countryCode);
|
|
151
|
+
if (party.address.country) {
|
|
152
|
+
this.appendElement(doc, countryNode, 'cbc:Name', party.address.country);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Party tax scheme (VAT ID)
|
|
156
|
+
if (party.registrationDetails && party.registrationDetails.vatId) {
|
|
157
|
+
const partyTaxSchemeNode = doc.createElement('cac:PartyTaxScheme');
|
|
158
|
+
partyNode.appendChild(partyTaxSchemeNode);
|
|
159
|
+
this.appendElement(doc, partyTaxSchemeNode, 'cbc:CompanyID', party.registrationDetails.vatId);
|
|
160
|
+
const taxSchemeNode = doc.createElement('cac:TaxScheme');
|
|
161
|
+
partyTaxSchemeNode.appendChild(taxSchemeNode);
|
|
162
|
+
this.appendElement(doc, taxSchemeNode, 'cbc:ID', 'VAT');
|
|
163
|
+
}
|
|
164
|
+
// Party legal entity (registration information)
|
|
165
|
+
if (party.registrationDetails) {
|
|
166
|
+
const partyLegalEntityNode = doc.createElement('cac:PartyLegalEntity');
|
|
167
|
+
partyNode.appendChild(partyLegalEntityNode);
|
|
168
|
+
const registrationName = party.registrationDetails.registrationName || party.name;
|
|
169
|
+
this.appendElement(doc, partyLegalEntityNode, 'cbc:RegistrationName', registrationName);
|
|
170
|
+
if (party.registrationDetails.registrationId) {
|
|
171
|
+
this.appendElement(doc, partyLegalEntityNode, 'cbc:CompanyID', party.registrationDetails.registrationId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Contact information
|
|
175
|
+
if (party.contactDetails) {
|
|
176
|
+
const contactNode = doc.createElement('cac:Contact');
|
|
177
|
+
partyNode.appendChild(contactNode);
|
|
178
|
+
if (party.contactDetails.name) {
|
|
179
|
+
this.appendElement(doc, contactNode, 'cbc:Name', party.contactDetails.name);
|
|
180
|
+
}
|
|
181
|
+
if (party.contactDetails.telephone) {
|
|
182
|
+
this.appendElement(doc, contactNode, 'cbc:Telephone', party.contactDetails.telephone);
|
|
183
|
+
}
|
|
184
|
+
if (party.contactDetails.email) {
|
|
185
|
+
this.appendElement(doc, contactNode, 'cbc:ElectronicMail', party.contactDetails.email);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Adds payment terms information
|
|
191
|
+
* @param doc XML document
|
|
192
|
+
* @param parentElement Parent element
|
|
193
|
+
* @param invoice Invoice data
|
|
194
|
+
*/
|
|
195
|
+
addPaymentTerms(doc, parentElement, invoice) {
|
|
196
|
+
const paymentTermsNode = doc.createElement('cac:PaymentTerms');
|
|
197
|
+
parentElement.appendChild(paymentTermsNode);
|
|
198
|
+
// Payment terms note
|
|
199
|
+
this.appendElement(doc, paymentTermsNode, 'cbc:Note', `Due in ${invoice.dueInDays} days`);
|
|
200
|
+
// Add payment means if available
|
|
201
|
+
if (invoice.paymentOptions) {
|
|
202
|
+
this.addPaymentMeans(doc, parentElement, invoice);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Adds payment means information
|
|
207
|
+
* @param doc XML document
|
|
208
|
+
* @param parentElement Parent element
|
|
209
|
+
* @param invoice Invoice data
|
|
210
|
+
*/
|
|
211
|
+
addPaymentMeans(doc, parentElement, invoice) {
|
|
212
|
+
const paymentMeansNode = doc.createElement('cac:PaymentMeans');
|
|
213
|
+
parentElement.appendChild(paymentMeansNode);
|
|
214
|
+
// Payment means code - default to credit transfer
|
|
215
|
+
this.appendElement(doc, paymentMeansNode, 'cbc:PaymentMeansCode', '30');
|
|
216
|
+
// Payment due date - ensure invoice.date is a valid timestamp
|
|
217
|
+
const issueTimestamp = typeof invoice.date === 'number' ? invoice.date : Date.now();
|
|
218
|
+
const dueDate = new Date(issueTimestamp);
|
|
219
|
+
dueDate.setDate(dueDate.getDate() + (invoice.dueInDays || 30));
|
|
220
|
+
this.appendElement(doc, paymentMeansNode, 'cbc:PaymentDueDate', this.formatDate(dueDate.getTime()));
|
|
221
|
+
// Add payment channel code if available
|
|
222
|
+
if (invoice.paymentOptions.description) {
|
|
223
|
+
this.appendElement(doc, paymentMeansNode, 'cbc:InstructionNote', invoice.paymentOptions.description);
|
|
224
|
+
}
|
|
225
|
+
// Add payment ID information if available - use invoice ID as payment reference
|
|
226
|
+
this.appendElement(doc, paymentMeansNode, 'cbc:PaymentID', invoice.id);
|
|
227
|
+
// Add bank account information if available
|
|
228
|
+
if (invoice.paymentOptions.sepaConnection && invoice.paymentOptions.sepaConnection.iban) {
|
|
229
|
+
const payeeFinancialAccountNode = doc.createElement('cac:PayeeFinancialAccount');
|
|
230
|
+
paymentMeansNode.appendChild(payeeFinancialAccountNode);
|
|
231
|
+
this.appendElement(doc, payeeFinancialAccountNode, 'cbc:ID', invoice.paymentOptions.sepaConnection.iban);
|
|
232
|
+
// Add financial institution information if BIC is available
|
|
233
|
+
if (invoice.paymentOptions.sepaConnection.bic) {
|
|
234
|
+
const financialInstitutionNode = doc.createElement('cac:FinancialInstitutionBranch');
|
|
235
|
+
payeeFinancialAccountNode.appendChild(financialInstitutionNode);
|
|
236
|
+
this.appendElement(doc, financialInstitutionNode, 'cbc:ID', invoice.paymentOptions.sepaConnection.bic);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Adds tax total information
|
|
242
|
+
* @param doc XML document
|
|
243
|
+
* @param parentElement Parent element
|
|
244
|
+
* @param invoice Invoice data
|
|
245
|
+
*/
|
|
246
|
+
addTaxTotal(doc, parentElement, invoice) {
|
|
247
|
+
const taxTotalNode = doc.createElement('cac:TaxTotal');
|
|
248
|
+
parentElement.appendChild(taxTotalNode);
|
|
249
|
+
// Calculate total tax amount
|
|
250
|
+
let totalTaxAmount = 0;
|
|
251
|
+
const taxCategories = new Map(); // Map of VAT rate to net amount
|
|
252
|
+
// Calculate from items
|
|
253
|
+
if (invoice.items) {
|
|
254
|
+
for (const item of invoice.items) {
|
|
255
|
+
const itemNetAmount = item.unitNetPrice * item.unitQuantity;
|
|
256
|
+
const itemTaxAmount = itemNetAmount * (item.vatPercentage / 100);
|
|
257
|
+
const vatRate = item.vatPercentage;
|
|
258
|
+
totalTaxAmount += itemTaxAmount;
|
|
259
|
+
// Aggregate by VAT rate
|
|
260
|
+
const currentAmount = taxCategories.get(vatRate) || 0;
|
|
261
|
+
taxCategories.set(vatRate, currentAmount + itemNetAmount);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Add total tax amount
|
|
265
|
+
const taxAmountElement = doc.createElement('cbc:TaxAmount');
|
|
266
|
+
taxAmountElement.setAttribute('currencyID', invoice.currency);
|
|
267
|
+
taxAmountElement.textContent = totalTaxAmount.toFixed(2);
|
|
268
|
+
taxTotalNode.appendChild(taxAmountElement);
|
|
269
|
+
// Add tax subtotals
|
|
270
|
+
for (const [rate, baseAmount] of taxCategories.entries()) {
|
|
271
|
+
const taxSubtotalNode = doc.createElement('cac:TaxSubtotal');
|
|
272
|
+
taxTotalNode.appendChild(taxSubtotalNode);
|
|
273
|
+
// Taxable amount
|
|
274
|
+
const taxableAmountElement = doc.createElement('cbc:TaxableAmount');
|
|
275
|
+
taxableAmountElement.setAttribute('currencyID', invoice.currency);
|
|
276
|
+
taxableAmountElement.textContent = baseAmount.toFixed(2);
|
|
277
|
+
taxSubtotalNode.appendChild(taxableAmountElement);
|
|
278
|
+
// Tax amount
|
|
279
|
+
const taxAmount = baseAmount * (rate / 100);
|
|
280
|
+
const subtotalTaxAmountElement = doc.createElement('cbc:TaxAmount');
|
|
281
|
+
subtotalTaxAmountElement.setAttribute('currencyID', invoice.currency);
|
|
282
|
+
subtotalTaxAmountElement.textContent = taxAmount.toFixed(2);
|
|
283
|
+
taxSubtotalNode.appendChild(subtotalTaxAmountElement);
|
|
284
|
+
// Tax category
|
|
285
|
+
const taxCategoryNode = doc.createElement('cac:TaxCategory');
|
|
286
|
+
taxSubtotalNode.appendChild(taxCategoryNode);
|
|
287
|
+
// Determine tax category ID based on reverse charge
|
|
288
|
+
const categoryId = invoice.reverseCharge ? 'AE' : 'S';
|
|
289
|
+
this.appendElement(doc, taxCategoryNode, 'cbc:ID', categoryId);
|
|
290
|
+
// Add percent with 2 decimal places
|
|
291
|
+
this.appendElement(doc, taxCategoryNode, 'cbc:Percent', rate.toFixed(2));
|
|
292
|
+
// Add tax exemption reason if reverse charge
|
|
293
|
+
if (invoice.reverseCharge) {
|
|
294
|
+
this.appendElement(doc, taxCategoryNode, 'cbc:TaxExemptionReasonCode', 'VATEX-EU-IC');
|
|
295
|
+
this.appendElement(doc, taxCategoryNode, 'cbc:TaxExemptionReason', 'Reverse charge');
|
|
296
|
+
}
|
|
297
|
+
// Add tax scheme
|
|
298
|
+
const taxSchemeNode = doc.createElement('cac:TaxScheme');
|
|
299
|
+
taxCategoryNode.appendChild(taxSchemeNode);
|
|
300
|
+
this.appendElement(doc, taxSchemeNode, 'cbc:ID', 'VAT');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Adds legal monetary total information
|
|
305
|
+
* @param doc XML document
|
|
306
|
+
* @param parentElement Parent element
|
|
307
|
+
* @param invoice Invoice data
|
|
308
|
+
*/
|
|
309
|
+
addLegalMonetaryTotal(doc, parentElement, invoice) {
|
|
310
|
+
const legalMonetaryTotalNode = doc.createElement('cac:LegalMonetaryTotal');
|
|
311
|
+
parentElement.appendChild(legalMonetaryTotalNode);
|
|
312
|
+
// Calculate totals
|
|
313
|
+
let totalNetAmount = 0;
|
|
314
|
+
let totalTaxAmount = 0;
|
|
315
|
+
// Calculate from items
|
|
316
|
+
if (invoice.items) {
|
|
317
|
+
for (const item of invoice.items) {
|
|
318
|
+
const itemNetAmount = item.unitNetPrice * item.unitQuantity;
|
|
319
|
+
const itemTaxAmount = itemNetAmount * (item.vatPercentage / 100);
|
|
320
|
+
totalNetAmount += itemNetAmount;
|
|
321
|
+
totalTaxAmount += itemTaxAmount;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const totalGrossAmount = totalNetAmount + totalTaxAmount;
|
|
325
|
+
// Line extension amount (sum of line net amounts)
|
|
326
|
+
const lineExtensionAmountElement = doc.createElement('cbc:LineExtensionAmount');
|
|
327
|
+
lineExtensionAmountElement.setAttribute('currencyID', invoice.currency);
|
|
328
|
+
lineExtensionAmountElement.textContent = totalNetAmount.toFixed(2);
|
|
329
|
+
legalMonetaryTotalNode.appendChild(lineExtensionAmountElement);
|
|
330
|
+
// Tax exclusive amount
|
|
331
|
+
const taxExclusiveAmountElement = doc.createElement('cbc:TaxExclusiveAmount');
|
|
332
|
+
taxExclusiveAmountElement.setAttribute('currencyID', invoice.currency);
|
|
333
|
+
taxExclusiveAmountElement.textContent = totalNetAmount.toFixed(2);
|
|
334
|
+
legalMonetaryTotalNode.appendChild(taxExclusiveAmountElement);
|
|
335
|
+
// Tax inclusive amount
|
|
336
|
+
const taxInclusiveAmountElement = doc.createElement('cbc:TaxInclusiveAmount');
|
|
337
|
+
taxInclusiveAmountElement.setAttribute('currencyID', invoice.currency);
|
|
338
|
+
taxInclusiveAmountElement.textContent = totalGrossAmount.toFixed(2);
|
|
339
|
+
legalMonetaryTotalNode.appendChild(taxInclusiveAmountElement);
|
|
340
|
+
// Payable amount
|
|
341
|
+
const payableAmountElement = doc.createElement('cbc:PayableAmount');
|
|
342
|
+
payableAmountElement.setAttribute('currencyID', invoice.currency);
|
|
343
|
+
payableAmountElement.textContent = totalGrossAmount.toFixed(2);
|
|
344
|
+
legalMonetaryTotalNode.appendChild(payableAmountElement);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Adds invoice lines
|
|
348
|
+
* @param doc XML document
|
|
349
|
+
* @param parentElement Parent element
|
|
350
|
+
* @param invoice Invoice data
|
|
351
|
+
*/
|
|
352
|
+
addInvoiceLines(doc, parentElement, invoice) {
|
|
353
|
+
if (!invoice.items)
|
|
354
|
+
return;
|
|
355
|
+
for (const item of invoice.items) {
|
|
356
|
+
const invoiceLineNode = doc.createElement('cac:InvoiceLine');
|
|
357
|
+
parentElement.appendChild(invoiceLineNode);
|
|
358
|
+
// ID
|
|
359
|
+
this.appendElement(doc, invoiceLineNode, 'cbc:ID', item.position.toString());
|
|
360
|
+
// Invoiced quantity
|
|
361
|
+
const quantityElement = doc.createElement('cbc:InvoicedQuantity');
|
|
362
|
+
quantityElement.setAttribute('unitCode', item.unitType);
|
|
363
|
+
quantityElement.textContent = item.unitQuantity.toString();
|
|
364
|
+
invoiceLineNode.appendChild(quantityElement);
|
|
365
|
+
// Line extension amount (line net amount)
|
|
366
|
+
const itemNetAmount = item.unitNetPrice * item.unitQuantity;
|
|
367
|
+
const lineExtensionAmountElement = doc.createElement('cbc:LineExtensionAmount');
|
|
368
|
+
lineExtensionAmountElement.setAttribute('currencyID', invoice.currency);
|
|
369
|
+
lineExtensionAmountElement.textContent = itemNetAmount.toFixed(2);
|
|
370
|
+
invoiceLineNode.appendChild(lineExtensionAmountElement);
|
|
371
|
+
// Item information
|
|
372
|
+
const itemNode = doc.createElement('cac:Item');
|
|
373
|
+
invoiceLineNode.appendChild(itemNode);
|
|
374
|
+
// Description - use description field if available, otherwise use name
|
|
375
|
+
const description = item.description || item.name;
|
|
376
|
+
this.appendElement(doc, itemNode, 'cbc:Description', description);
|
|
377
|
+
this.appendElement(doc, itemNode, 'cbc:Name', item.name);
|
|
378
|
+
// Seller's item identification
|
|
379
|
+
if (item.articleNumber) {
|
|
380
|
+
const sellersItemIdentificationNode = doc.createElement('cac:SellersItemIdentification');
|
|
381
|
+
itemNode.appendChild(sellersItemIdentificationNode);
|
|
382
|
+
this.appendElement(doc, sellersItemIdentificationNode, 'cbc:ID', item.articleNumber);
|
|
383
|
+
}
|
|
384
|
+
// Item tax information
|
|
385
|
+
const classifiedTaxCategoryNode = doc.createElement('cac:ClassifiedTaxCategory');
|
|
386
|
+
itemNode.appendChild(classifiedTaxCategoryNode);
|
|
387
|
+
// Determine tax category ID based on reverse charge
|
|
388
|
+
const categoryId = invoice.reverseCharge ? 'AE' : 'S';
|
|
389
|
+
this.appendElement(doc, classifiedTaxCategoryNode, 'cbc:ID', categoryId);
|
|
390
|
+
// Tax percent with 2 decimal places
|
|
391
|
+
this.appendElement(doc, classifiedTaxCategoryNode, 'cbc:Percent', item.vatPercentage.toFixed(2));
|
|
392
|
+
// Tax scheme
|
|
393
|
+
const taxSchemeNode = doc.createElement('cac:TaxScheme');
|
|
394
|
+
classifiedTaxCategoryNode.appendChild(taxSchemeNode);
|
|
395
|
+
this.appendElement(doc, taxSchemeNode, 'cbc:ID', 'VAT');
|
|
396
|
+
// Price information
|
|
397
|
+
const priceNode = doc.createElement('cac:Price');
|
|
398
|
+
invoiceLineNode.appendChild(priceNode);
|
|
399
|
+
// Price amount
|
|
400
|
+
const priceAmountElement = doc.createElement('cbc:PriceAmount');
|
|
401
|
+
priceAmountElement.setAttribute('currencyID', invoice.currency);
|
|
402
|
+
priceAmountElement.textContent = item.unitNetPrice.toFixed(2);
|
|
403
|
+
priceNode.appendChild(priceAmountElement);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Helper method to append a simple element with text content
|
|
408
|
+
* @param doc XML document
|
|
409
|
+
* @param parentElement Parent element
|
|
410
|
+
* @param elementName Element name
|
|
411
|
+
* @param textContent Text content
|
|
412
|
+
*/
|
|
413
|
+
appendElement(doc, parentElement, elementName, textContent) {
|
|
414
|
+
const element = doc.createElement(elementName);
|
|
415
|
+
element.textContent = textContent;
|
|
416
|
+
parentElement.appendChild(element);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Helper method to get country code from country name
|
|
420
|
+
* Simple implementation that assumes the country name is already a code
|
|
421
|
+
* @param countryName Country name
|
|
422
|
+
* @returns Country code (2-letter ISO code)
|
|
423
|
+
*/
|
|
424
|
+
getCountryCode(countryName) {
|
|
425
|
+
// In a real implementation, this would map country names to ISO codes
|
|
426
|
+
// For now, just return the first 2 characters or "XX" as fallback
|
|
427
|
+
if (!countryName)
|
|
428
|
+
return 'XX';
|
|
429
|
+
return countryName.length >= 2 ? countryName.substring(0, 2).toUpperCase() : 'XX';
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Preserves metadata from invoice to enhance UBL XML output
|
|
433
|
+
* @param doc XML document
|
|
434
|
+
* @param root Root element
|
|
435
|
+
* @param invoice Invoice data
|
|
436
|
+
*/
|
|
437
|
+
preserveMetadata(doc, root, invoice) {
|
|
438
|
+
// Extract metadata if available
|
|
439
|
+
const metadata = invoice.metadata?.extensions;
|
|
440
|
+
if (!metadata)
|
|
441
|
+
return;
|
|
442
|
+
// Preserve business references
|
|
443
|
+
this.addBusinessReferencesToUBL(doc, root, metadata.businessReferences);
|
|
444
|
+
// Preserve payment information
|
|
445
|
+
this.enhancePaymentInformationUBL(doc, root, metadata.paymentInformation);
|
|
446
|
+
// Preserve date information
|
|
447
|
+
this.addDateInformationUBL(doc, root, metadata.dateInformation);
|
|
448
|
+
// Enhance party information with contact details
|
|
449
|
+
this.enhancePartyInformationUBL(doc, invoice);
|
|
450
|
+
// Enhance line items with metadata
|
|
451
|
+
this.enhanceLineItemsUBL(doc, invoice);
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Adds business references from metadata to UBL document
|
|
455
|
+
* @param doc XML document
|
|
456
|
+
* @param root Root element
|
|
457
|
+
* @param businessReferences Business references from metadata
|
|
458
|
+
*/
|
|
459
|
+
addBusinessReferencesToUBL(doc, root, businessReferences) {
|
|
460
|
+
if (!businessReferences)
|
|
461
|
+
return;
|
|
462
|
+
// Add BuyerReference
|
|
463
|
+
if (businessReferences.buyerReference && !root.getElementsByTagName('cbc:BuyerReference')[0]) {
|
|
464
|
+
const buyerRef = doc.createElement('cbc:BuyerReference');
|
|
465
|
+
buyerRef.textContent = businessReferences.buyerReference;
|
|
466
|
+
// Insert after DocumentCurrencyCode
|
|
467
|
+
const currencyCode = root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
|
|
468
|
+
if (currencyCode && currencyCode.parentNode) {
|
|
469
|
+
currencyCode.parentNode.insertBefore(buyerRef, currencyCode.nextSibling);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Add OrderReference
|
|
473
|
+
if (businessReferences.orderReference && !root.getElementsByTagName('cac:OrderReference')[0]) {
|
|
474
|
+
const orderRef = doc.createElement('cac:OrderReference');
|
|
475
|
+
const orderId = doc.createElement('cbc:ID');
|
|
476
|
+
orderId.textContent = businessReferences.orderReference;
|
|
477
|
+
orderRef.appendChild(orderId);
|
|
478
|
+
// Insert after BuyerReference or DocumentCurrencyCode
|
|
479
|
+
const buyerRef = root.getElementsByTagName('cbc:BuyerReference')[0];
|
|
480
|
+
const currencyCode = root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
|
|
481
|
+
const insertAfter = buyerRef || currencyCode;
|
|
482
|
+
if (insertAfter && insertAfter.parentNode) {
|
|
483
|
+
insertAfter.parentNode.insertBefore(orderRef, insertAfter.nextSibling);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// Add ContractDocumentReference
|
|
487
|
+
if (businessReferences.contractReference && !root.getElementsByTagName('cac:ContractDocumentReference')[0]) {
|
|
488
|
+
const contractRef = doc.createElement('cac:ContractDocumentReference');
|
|
489
|
+
const contractId = doc.createElement('cbc:ID');
|
|
490
|
+
contractId.textContent = businessReferences.contractReference;
|
|
491
|
+
contractRef.appendChild(contractId);
|
|
492
|
+
// Insert after OrderReference or DocumentCurrencyCode
|
|
493
|
+
const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
|
|
494
|
+
const insertAfter = orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
|
|
495
|
+
if (insertAfter && insertAfter.parentNode) {
|
|
496
|
+
insertAfter.parentNode.insertBefore(contractRef, insertAfter.nextSibling);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
// Add ProjectReference
|
|
500
|
+
if (businessReferences.projectReference && !root.getElementsByTagName('cac:ProjectReference')[0]) {
|
|
501
|
+
const projectRef = doc.createElement('cac:ProjectReference');
|
|
502
|
+
const projectId = doc.createElement('cbc:ID');
|
|
503
|
+
projectId.textContent = businessReferences.projectReference;
|
|
504
|
+
projectRef.appendChild(projectId);
|
|
505
|
+
// Insert after ContractDocumentReference or other refs
|
|
506
|
+
const contractRef = root.getElementsByTagName('cac:ContractDocumentReference')[0];
|
|
507
|
+
const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
|
|
508
|
+
const insertAfter = contractRef || orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
|
|
509
|
+
if (insertAfter && insertAfter.parentNode) {
|
|
510
|
+
insertAfter.parentNode.insertBefore(projectRef, insertAfter.nextSibling);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Enhances payment information from metadata in UBL document
|
|
516
|
+
* @param doc XML document
|
|
517
|
+
* @param root Root element
|
|
518
|
+
* @param paymentInfo Payment information from metadata
|
|
519
|
+
*/
|
|
520
|
+
enhancePaymentInformationUBL(doc, root, paymentInfo) {
|
|
521
|
+
if (!paymentInfo)
|
|
522
|
+
return;
|
|
523
|
+
let paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
|
|
524
|
+
// Create PaymentMeans if it doesn't exist
|
|
525
|
+
if (!paymentMeans) {
|
|
526
|
+
paymentMeans = doc.createElement('cac:PaymentMeans');
|
|
527
|
+
// Insert before TaxTotal
|
|
528
|
+
const taxTotal = root.getElementsByTagName('cac:TaxTotal')[0];
|
|
529
|
+
if (taxTotal && taxTotal.parentNode) {
|
|
530
|
+
taxTotal.parentNode.insertBefore(paymentMeans, taxTotal);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// Add PaymentMeansCode
|
|
534
|
+
if (paymentInfo.paymentMeansCode && !paymentMeans.getElementsByTagName('cbc:PaymentMeansCode')[0]) {
|
|
535
|
+
const meansCode = doc.createElement('cbc:PaymentMeansCode');
|
|
536
|
+
meansCode.textContent = paymentInfo.paymentMeansCode;
|
|
537
|
+
paymentMeans.appendChild(meansCode);
|
|
538
|
+
}
|
|
539
|
+
// Add PaymentID
|
|
540
|
+
if (paymentInfo.paymentID && !paymentMeans.getElementsByTagName('cbc:PaymentID')[0]) {
|
|
541
|
+
const paymentId = doc.createElement('cbc:PaymentID');
|
|
542
|
+
paymentId.textContent = paymentInfo.paymentID;
|
|
543
|
+
paymentMeans.appendChild(paymentId);
|
|
544
|
+
}
|
|
545
|
+
// Add PaymentDueDate
|
|
546
|
+
if (paymentInfo.paymentDueDate && !paymentMeans.getElementsByTagName('cbc:PaymentDueDate')[0]) {
|
|
547
|
+
const dueDate = doc.createElement('cbc:PaymentDueDate');
|
|
548
|
+
dueDate.textContent = paymentInfo.paymentDueDate;
|
|
549
|
+
paymentMeans.appendChild(dueDate);
|
|
550
|
+
}
|
|
551
|
+
// Add IBAN and BIC
|
|
552
|
+
if (paymentInfo.iban || paymentInfo.bic) {
|
|
553
|
+
let payeeAccount = paymentMeans.getElementsByTagName('cac:PayeeFinancialAccount')[0];
|
|
554
|
+
if (!payeeAccount) {
|
|
555
|
+
payeeAccount = doc.createElement('cac:PayeeFinancialAccount');
|
|
556
|
+
paymentMeans.appendChild(payeeAccount);
|
|
557
|
+
}
|
|
558
|
+
// Add IBAN
|
|
559
|
+
if (paymentInfo.iban && !payeeAccount.getElementsByTagName('cbc:ID')[0]) {
|
|
560
|
+
const iban = doc.createElement('cbc:ID');
|
|
561
|
+
iban.textContent = paymentInfo.iban;
|
|
562
|
+
payeeAccount.appendChild(iban);
|
|
563
|
+
}
|
|
564
|
+
// Add account name (must come after ID but before FinancialInstitutionBranch)
|
|
565
|
+
if (paymentInfo.accountName && !payeeAccount.getElementsByTagName('cbc:Name')[0]) {
|
|
566
|
+
const accountName = doc.createElement('cbc:Name');
|
|
567
|
+
accountName.textContent = paymentInfo.accountName;
|
|
568
|
+
// Insert after ID but before FinancialInstitutionBranch
|
|
569
|
+
const id = payeeAccount.getElementsByTagName('cbc:ID')[0];
|
|
570
|
+
const finInstBranch = payeeAccount.getElementsByTagName('cac:FinancialInstitutionBranch')[0];
|
|
571
|
+
if (finInstBranch) {
|
|
572
|
+
payeeAccount.insertBefore(accountName, finInstBranch);
|
|
573
|
+
}
|
|
574
|
+
else if (id && id.nextSibling) {
|
|
575
|
+
payeeAccount.insertBefore(accountName, id.nextSibling);
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
payeeAccount.appendChild(accountName);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
// Add BIC and bank name
|
|
582
|
+
if (paymentInfo.bic || paymentInfo.bankName) {
|
|
583
|
+
let finInstBranch = payeeAccount.getElementsByTagName('cac:FinancialInstitutionBranch')[0];
|
|
584
|
+
if (!finInstBranch) {
|
|
585
|
+
finInstBranch = doc.createElement('cac:FinancialInstitutionBranch');
|
|
586
|
+
payeeAccount.appendChild(finInstBranch);
|
|
587
|
+
}
|
|
588
|
+
// Add BIC as branch ID
|
|
589
|
+
if (paymentInfo.bic && !finInstBranch.getElementsByTagName('cbc:ID')[0]) {
|
|
590
|
+
const bicElement = doc.createElement('cbc:ID');
|
|
591
|
+
bicElement.textContent = paymentInfo.bic;
|
|
592
|
+
finInstBranch.appendChild(bicElement);
|
|
593
|
+
}
|
|
594
|
+
// Add bank name
|
|
595
|
+
if (paymentInfo.bankName && !finInstBranch.getElementsByTagName('cbc:Name')[0]) {
|
|
596
|
+
const bankNameElement = doc.createElement('cbc:Name');
|
|
597
|
+
bankNameElement.textContent = paymentInfo.bankName;
|
|
598
|
+
finInstBranch.appendChild(bankNameElement);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
// Add payment terms with discount if available
|
|
603
|
+
if (paymentInfo.paymentTermsNote && paymentInfo.paymentTermsNote.includes('early payment')) {
|
|
604
|
+
let paymentTerms = root.getElementsByTagName('cac:PaymentTerms')[0];
|
|
605
|
+
if (!paymentTerms) {
|
|
606
|
+
paymentTerms = doc.createElement('cac:PaymentTerms');
|
|
607
|
+
// Insert before PaymentMeans
|
|
608
|
+
const paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
|
|
609
|
+
if (paymentMeans && paymentMeans.parentNode) {
|
|
610
|
+
paymentMeans.parentNode.insertBefore(paymentTerms, paymentMeans);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
// Update or add note
|
|
614
|
+
let note = paymentTerms.getElementsByTagName('cbc:Note')[0];
|
|
615
|
+
if (!note) {
|
|
616
|
+
note = doc.createElement('cbc:Note');
|
|
617
|
+
paymentTerms.appendChild(note);
|
|
618
|
+
}
|
|
619
|
+
note.textContent = paymentInfo.paymentTermsNote;
|
|
620
|
+
// Add discount percent if available
|
|
621
|
+
if (paymentInfo.discountPercent && !paymentTerms.getElementsByTagName('cbc:SettlementDiscountPercent')[0]) {
|
|
622
|
+
const discountElement = doc.createElement('cbc:SettlementDiscountPercent');
|
|
623
|
+
discountElement.textContent = paymentInfo.discountPercent;
|
|
624
|
+
paymentTerms.appendChild(discountElement);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Adds date information from metadata to UBL document
|
|
630
|
+
* @param doc XML document
|
|
631
|
+
* @param root Root element
|
|
632
|
+
* @param dateInfo Date information from metadata
|
|
633
|
+
*/
|
|
634
|
+
addDateInformationUBL(doc, root, dateInfo) {
|
|
635
|
+
if (!dateInfo)
|
|
636
|
+
return;
|
|
637
|
+
// Add InvoicePeriod
|
|
638
|
+
if ((dateInfo.periodStart || dateInfo.periodEnd) && !root.getElementsByTagName('cac:InvoicePeriod')[0]) {
|
|
639
|
+
const invoicePeriod = doc.createElement('cac:InvoicePeriod');
|
|
640
|
+
if (dateInfo.periodStart) {
|
|
641
|
+
const startDate = doc.createElement('cbc:StartDate');
|
|
642
|
+
startDate.textContent = dateInfo.periodStart;
|
|
643
|
+
invoicePeriod.appendChild(startDate);
|
|
644
|
+
}
|
|
645
|
+
if (dateInfo.periodEnd) {
|
|
646
|
+
const endDate = doc.createElement('cbc:EndDate');
|
|
647
|
+
endDate.textContent = dateInfo.periodEnd;
|
|
648
|
+
invoicePeriod.appendChild(endDate);
|
|
649
|
+
}
|
|
650
|
+
// Insert after business references or DocumentCurrencyCode
|
|
651
|
+
const projectRef = root.getElementsByTagName('cac:ProjectReference')[0];
|
|
652
|
+
const contractRef = root.getElementsByTagName('cac:ContractDocumentReference')[0];
|
|
653
|
+
const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
|
|
654
|
+
const insertAfter = projectRef || contractRef || orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
|
|
655
|
+
if (insertAfter && insertAfter.parentNode) {
|
|
656
|
+
insertAfter.parentNode.insertBefore(invoicePeriod, insertAfter.nextSibling);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
// Add Delivery with ActualDeliveryDate
|
|
660
|
+
if (dateInfo.deliveryDate && !root.getElementsByTagName('cac:Delivery')[0]) {
|
|
661
|
+
const delivery = doc.createElement('cac:Delivery');
|
|
662
|
+
const deliveryDate = doc.createElement('cbc:ActualDeliveryDate');
|
|
663
|
+
deliveryDate.textContent = dateInfo.deliveryDate;
|
|
664
|
+
delivery.appendChild(deliveryDate);
|
|
665
|
+
// Insert before PaymentMeans
|
|
666
|
+
const paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
|
|
667
|
+
if (paymentMeans && paymentMeans.parentNode) {
|
|
668
|
+
paymentMeans.parentNode.insertBefore(delivery, paymentMeans);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Enhances party information with contact details from metadata
|
|
674
|
+
* @param doc XML document
|
|
675
|
+
* @param invoice Invoice data
|
|
676
|
+
*/
|
|
677
|
+
enhancePartyInformationUBL(doc, invoice) {
|
|
678
|
+
// Enhance supplier party
|
|
679
|
+
this.enhancePartyUBL(doc, 'cac:AccountingSupplierParty', invoice.from);
|
|
680
|
+
// Enhance customer party
|
|
681
|
+
this.enhancePartyUBL(doc, 'cac:AccountingCustomerParty', invoice.to);
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Enhances a party with GLN, additional identifiers, and contact info
|
|
685
|
+
* @param doc XML document
|
|
686
|
+
* @param partySelector Party selector
|
|
687
|
+
* @param partyData Party data
|
|
688
|
+
*/
|
|
689
|
+
enhancePartyUBL(doc, partySelector, partyData) {
|
|
690
|
+
if (!partyData)
|
|
691
|
+
return;
|
|
692
|
+
const partyContainer = doc.getElementsByTagName(partySelector)[0];
|
|
693
|
+
if (!partyContainer)
|
|
694
|
+
return;
|
|
695
|
+
const party = partyContainer.getElementsByTagName('cac:Party')[0];
|
|
696
|
+
if (!party)
|
|
697
|
+
return;
|
|
698
|
+
// Add GLN if available
|
|
699
|
+
if (partyData.gln && !party.getElementsByTagName('cbc:EndpointID')[0]) {
|
|
700
|
+
const endpointNode = doc.createElement('cbc:EndpointID');
|
|
701
|
+
endpointNode.setAttribute('schemeID', '0088'); // GLN scheme ID
|
|
702
|
+
endpointNode.textContent = partyData.gln;
|
|
703
|
+
// Insert as first child
|
|
704
|
+
if (party.firstChild) {
|
|
705
|
+
party.insertBefore(endpointNode, party.firstChild);
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
party.appendChild(endpointNode);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
// Add additional identifiers
|
|
712
|
+
if (partyData.additionalIdentifiers && Array.isArray(partyData.additionalIdentifiers)) {
|
|
713
|
+
for (const identifier of partyData.additionalIdentifiers) {
|
|
714
|
+
const partyId = doc.createElement('cac:PartyIdentification');
|
|
715
|
+
const id = doc.createElement('cbc:ID');
|
|
716
|
+
if (identifier.scheme) {
|
|
717
|
+
id.setAttribute('schemeID', identifier.scheme);
|
|
718
|
+
}
|
|
719
|
+
id.textContent = identifier.value;
|
|
720
|
+
partyId.appendChild(id);
|
|
721
|
+
// Insert after EndpointID or at beginning
|
|
722
|
+
const endpoint = party.getElementsByTagName('cbc:EndpointID')[0];
|
|
723
|
+
if (endpoint && endpoint.nextSibling) {
|
|
724
|
+
party.insertBefore(partyId, endpoint.nextSibling);
|
|
725
|
+
}
|
|
726
|
+
else if (party.firstChild) {
|
|
727
|
+
party.insertBefore(partyId, party.firstChild);
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
party.appendChild(partyId);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
// Add contact information from metadata if not already present
|
|
735
|
+
const contactInfo = partyData.metadata?.contactInformation;
|
|
736
|
+
if (contactInfo) {
|
|
737
|
+
this.addContactToPartyUBL(doc, partySelector, contactInfo);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Adds contact information to a party in UBL document
|
|
742
|
+
* @param doc XML document
|
|
743
|
+
* @param partySelector Party selector
|
|
744
|
+
* @param contactInfo Contact information from metadata
|
|
745
|
+
*/
|
|
746
|
+
addContactToPartyUBL(doc, partySelector, contactInfo) {
|
|
747
|
+
if (!contactInfo)
|
|
748
|
+
return;
|
|
749
|
+
const partyContainer = doc.getElementsByTagName(partySelector)[0];
|
|
750
|
+
if (!partyContainer)
|
|
751
|
+
return;
|
|
752
|
+
const party = partyContainer.getElementsByTagName('cac:Party')[0];
|
|
753
|
+
if (!party)
|
|
754
|
+
return;
|
|
755
|
+
// Check if Contact already exists
|
|
756
|
+
let contact = party.getElementsByTagName('cac:Contact')[0];
|
|
757
|
+
if (!contact && (contactInfo.name || contactInfo.phone || contactInfo.email)) {
|
|
758
|
+
contact = doc.createElement('cac:Contact');
|
|
759
|
+
// Insert after PartyName
|
|
760
|
+
const partyName = party.getElementsByTagName('cac:PartyName')[0];
|
|
761
|
+
if (partyName && partyName.parentNode) {
|
|
762
|
+
partyName.parentNode.insertBefore(contact, partyName.nextSibling);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
party.appendChild(contact);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
if (contact) {
|
|
769
|
+
// Add contact name
|
|
770
|
+
if (contactInfo.name && !contact.getElementsByTagName('cbc:Name')[0]) {
|
|
771
|
+
const name = doc.createElement('cbc:Name');
|
|
772
|
+
name.textContent = contactInfo.name;
|
|
773
|
+
contact.appendChild(name);
|
|
774
|
+
}
|
|
775
|
+
// Add telephone
|
|
776
|
+
if (contactInfo.phone && !contact.getElementsByTagName('cbc:Telephone')[0]) {
|
|
777
|
+
const phone = doc.createElement('cbc:Telephone');
|
|
778
|
+
phone.textContent = contactInfo.phone;
|
|
779
|
+
contact.appendChild(phone);
|
|
780
|
+
}
|
|
781
|
+
// Add email
|
|
782
|
+
if (contactInfo.email && !contact.getElementsByTagName('cbc:ElectronicMail')[0]) {
|
|
783
|
+
const email = doc.createElement('cbc:ElectronicMail');
|
|
784
|
+
email.textContent = contactInfo.email;
|
|
785
|
+
contact.appendChild(email);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Enhances line items with metadata in UBL document
|
|
791
|
+
* @param doc XML document
|
|
792
|
+
* @param invoice Invoice data
|
|
793
|
+
*/
|
|
794
|
+
enhanceLineItemsUBL(doc, invoice) {
|
|
795
|
+
const invoiceLines = doc.getElementsByTagName('cac:InvoiceLine');
|
|
796
|
+
for (let i = 0; i < invoiceLines.length && i < invoice.items.length; i++) {
|
|
797
|
+
const line = invoiceLines[i];
|
|
798
|
+
const item = invoice.items[i];
|
|
799
|
+
const itemMetadata = item.metadata;
|
|
800
|
+
if (!itemMetadata)
|
|
801
|
+
continue;
|
|
802
|
+
// Add OrderLineReference if available
|
|
803
|
+
if (itemMetadata.orderLineReference && !line.getElementsByTagName('cac:OrderLineReference')[0]) {
|
|
804
|
+
const orderLineRef = doc.createElement('cac:OrderLineReference');
|
|
805
|
+
const lineId = doc.createElement('cbc:LineID');
|
|
806
|
+
lineId.textContent = itemMetadata.orderLineReferenceId || '1';
|
|
807
|
+
orderLineRef.appendChild(lineId);
|
|
808
|
+
if (itemMetadata.orderLineReference) {
|
|
809
|
+
const orderRef = doc.createElement('cac:OrderReference');
|
|
810
|
+
const orderId = doc.createElement('cbc:ID');
|
|
811
|
+
orderId.textContent = itemMetadata.orderLineReference;
|
|
812
|
+
orderRef.appendChild(orderId);
|
|
813
|
+
orderLineRef.appendChild(orderRef);
|
|
814
|
+
}
|
|
815
|
+
// Insert after ID
|
|
816
|
+
const invoiceLineId = line.getElementsByTagName('cbc:ID')[0];
|
|
817
|
+
if (invoiceLineId && invoiceLineId.nextSibling) {
|
|
818
|
+
line.insertBefore(orderLineRef, invoiceLineId.nextSibling);
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
// Insert before InvoicedQuantity
|
|
822
|
+
const quantity = line.getElementsByTagName('cbc:InvoicedQuantity')[0];
|
|
823
|
+
if (quantity) {
|
|
824
|
+
line.insertBefore(orderLineRef, quantity);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
const itemElement = line.getElementsByTagName('cac:Item')[0];
|
|
829
|
+
if (!itemElement)
|
|
830
|
+
continue;
|
|
831
|
+
// Add item description
|
|
832
|
+
if (itemMetadata.description && !itemElement.getElementsByTagName('cbc:Description')[0]) {
|
|
833
|
+
const desc = doc.createElement('cbc:Description');
|
|
834
|
+
desc.textContent = itemMetadata.description;
|
|
835
|
+
// Insert before Name
|
|
836
|
+
const name = itemElement.getElementsByTagName('cbc:Name')[0];
|
|
837
|
+
if (name && name.parentNode) {
|
|
838
|
+
name.parentNode.insertBefore(desc, name);
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
itemElement.appendChild(desc);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
// Add SellersItemIdentification
|
|
845
|
+
if (item.articleNumber && !itemElement.getElementsByTagName('cac:SellersItemIdentification')[0]) {
|
|
846
|
+
const sellerId = doc.createElement('cac:SellersItemIdentification');
|
|
847
|
+
const id = doc.createElement('cbc:ID');
|
|
848
|
+
id.textContent = item.articleNumber;
|
|
849
|
+
sellerId.appendChild(id);
|
|
850
|
+
itemElement.appendChild(sellerId);
|
|
851
|
+
}
|
|
852
|
+
// Add BuyersItemIdentification
|
|
853
|
+
if (itemMetadata.buyerItemID && !itemElement.getElementsByTagName('cac:BuyersItemIdentification')[0]) {
|
|
854
|
+
const buyerId = doc.createElement('cac:BuyersItemIdentification');
|
|
855
|
+
const id = doc.createElement('cbc:ID');
|
|
856
|
+
id.textContent = itemMetadata.buyerItemID;
|
|
857
|
+
buyerId.appendChild(id);
|
|
858
|
+
itemElement.appendChild(buyerId);
|
|
859
|
+
}
|
|
860
|
+
// Add StandardItemIdentification
|
|
861
|
+
if (itemMetadata.standardItemID && !itemElement.getElementsByTagName('cac:StandardItemIdentification')[0]) {
|
|
862
|
+
const standardId = doc.createElement('cac:StandardItemIdentification');
|
|
863
|
+
const id = doc.createElement('cbc:ID');
|
|
864
|
+
id.textContent = itemMetadata.standardItemID;
|
|
865
|
+
standardId.appendChild(id);
|
|
866
|
+
itemElement.appendChild(standardId);
|
|
867
|
+
}
|
|
868
|
+
// Add CommodityClassification
|
|
869
|
+
if (itemMetadata.commodityClassification && !itemElement.getElementsByTagName('cac:CommodityClassification')[0]) {
|
|
870
|
+
const classification = doc.createElement('cac:CommodityClassification');
|
|
871
|
+
const code = doc.createElement('cbc:ItemClassificationCode');
|
|
872
|
+
code.textContent = itemMetadata.commodityClassification;
|
|
873
|
+
classification.appendChild(code);
|
|
874
|
+
itemElement.appendChild(classification);
|
|
875
|
+
}
|
|
876
|
+
// Add additional item properties
|
|
877
|
+
if (itemMetadata.additionalProperties) {
|
|
878
|
+
for (const [propName, propValue] of Object.entries(itemMetadata.additionalProperties)) {
|
|
879
|
+
const additionalProp = doc.createElement('cac:AdditionalItemProperty');
|
|
880
|
+
const nameElement = doc.createElement('cbc:Name');
|
|
881
|
+
nameElement.textContent = propName;
|
|
882
|
+
additionalProp.appendChild(nameElement);
|
|
883
|
+
const valueElement = doc.createElement('cbc:Value');
|
|
884
|
+
valueElement.textContent = propValue;
|
|
885
|
+
additionalProp.appendChild(valueElement);
|
|
886
|
+
itemElement.appendChild(additionalProp);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWJsLmVuY29kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9mb3JtYXRzL3VibC9nZW5lcmljL3VibC5lbmNvZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUvRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sVUFBVyxTQUFRLGNBQWM7SUFDNUM7Ozs7T0FJRztJQUNPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUF1QjtRQUN0RCxvQ0FBb0M7UUFDcEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbEUsTUFBTSxHQUFHLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFFMUUsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsVUFBaUMsRUFBRSxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFNUYsZ0NBQWdDO1FBQ2hDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFaEQsc0JBQXNCO1FBQ3RCLE9BQU8sSUFBSSxhQUFhLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNPLEtBQUssQ0FBQyxlQUFlLENBQUMsU0FBcUI7UUFDbkQsb0NBQW9DO1FBQ3BDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlELE1BQU0sR0FBRyxH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
|