@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.
Files changed (171) hide show
  1. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  2. package/dist_ts/00_commitinfo_data.js +9 -0
  3. package/dist_ts/classes.decoder.d.ts +40 -0
  4. package/dist_ts/classes.decoder.js +320 -0
  5. package/dist_ts/classes.encoder.d.ts +51 -0
  6. package/dist_ts/classes.encoder.js +293 -0
  7. package/dist_ts/classes.xinvoice.d.ts +136 -0
  8. package/dist_ts/classes.xinvoice.js +352 -0
  9. package/dist_ts/einvoice.d.ts +217 -0
  10. package/dist_ts/einvoice.js +505 -0
  11. package/dist_ts/errors.d.ts +121 -0
  12. package/dist_ts/errors.js +241 -0
  13. package/dist_ts/formats/base/base.decoder.d.ts +32 -0
  14. package/dist_ts/formats/base/base.decoder.js +52 -0
  15. package/dist_ts/formats/base/base.encoder.d.ts +13 -0
  16. package/dist_ts/formats/base/base.encoder.js +7 -0
  17. package/dist_ts/formats/base/base.validator.d.ts +44 -0
  18. package/dist_ts/formats/base/base.validator.js +39 -0
  19. package/dist_ts/formats/base.decoder.d.ts +19 -0
  20. package/dist_ts/formats/base.decoder.js +130 -0
  21. package/dist_ts/formats/base.validator.d.ts +44 -0
  22. package/dist_ts/formats/base.validator.js +39 -0
  23. package/dist_ts/formats/cii/cii.decoder.d.ts +61 -0
  24. package/dist_ts/formats/cii/cii.decoder.js +111 -0
  25. package/dist_ts/formats/cii/cii.encoder.d.ts +43 -0
  26. package/dist_ts/formats/cii/cii.encoder.js +48 -0
  27. package/dist_ts/formats/cii/cii.types.d.ts +31 -0
  28. package/dist_ts/formats/cii/cii.types.js +40 -0
  29. package/dist_ts/formats/cii/cii.validator.d.ts +56 -0
  30. package/dist_ts/formats/cii/cii.validator.js +146 -0
  31. package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +43 -0
  32. package/dist_ts/formats/cii/facturx/facturx.decoder.js +207 -0
  33. package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +82 -0
  34. package/dist_ts/formats/cii/facturx/facturx.encoder.js +400 -0
  35. package/dist_ts/formats/cii/facturx/facturx.types.d.ts +10 -0
  36. package/dist_ts/formats/cii/facturx/facturx.types.js +15 -0
  37. package/dist_ts/formats/cii/facturx/facturx.validator.d.ts +32 -0
  38. package/dist_ts/formats/cii/facturx/facturx.validator.js +138 -0
  39. package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +43 -0
  40. package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +218 -0
  41. package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +97 -0
  42. package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +550 -0
  43. package/dist_ts/formats/cii/zugferd/zugferd.types.d.ts +10 -0
  44. package/dist_ts/formats/cii/zugferd/zugferd.types.js +15 -0
  45. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +49 -0
  46. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +229 -0
  47. package/dist_ts/formats/cii/zugferd/zugferd.validator.d.ts +16 -0
  48. package/dist_ts/formats/cii/zugferd/zugferd.validator.js +29 -0
  49. package/dist_ts/formats/decoder.factory.d.ts +15 -0
  50. package/dist_ts/formats/decoder.factory.js +46 -0
  51. package/dist_ts/formats/factories/decoder.factory.d.ts +13 -0
  52. package/dist_ts/formats/factories/decoder.factory.js +56 -0
  53. package/dist_ts/formats/factories/encoder.factory.d.ts +14 -0
  54. package/dist_ts/formats/factories/encoder.factory.js +40 -0
  55. package/dist_ts/formats/factories/validator.factory.d.ts +12 -0
  56. package/dist_ts/formats/factories/validator.factory.js +110 -0
  57. package/dist_ts/formats/factorx.decoder.d.ts +18 -0
  58. package/dist_ts/formats/factorx.decoder.js +178 -0
  59. package/dist_ts/formats/factorx.encoder.d.ts +51 -0
  60. package/dist_ts/formats/factorx.encoder.js +293 -0
  61. package/dist_ts/formats/facturx.decoder.d.ts +18 -0
  62. package/dist_ts/formats/facturx.decoder.js +210 -0
  63. package/dist_ts/formats/facturx.encoder.d.ts +51 -0
  64. package/dist_ts/formats/facturx.encoder.js +293 -0
  65. package/dist_ts/formats/facturx.validator.d.ts +67 -0
  66. package/dist_ts/formats/facturx.validator.js +266 -0
  67. package/dist_ts/formats/pdf/extractors/associated.extractor.d.ts +14 -0
  68. package/dist_ts/formats/pdf/extractors/associated.extractor.js +68 -0
  69. package/dist_ts/formats/pdf/extractors/base.extractor.d.ts +92 -0
  70. package/dist_ts/formats/pdf/extractors/base.extractor.js +319 -0
  71. package/dist_ts/formats/pdf/extractors/index.d.ts +4 -0
  72. package/dist_ts/formats/pdf/extractors/index.js +5 -0
  73. package/dist_ts/formats/pdf/extractors/standard.extractor.d.ts +13 -0
  74. package/dist_ts/formats/pdf/extractors/standard.extractor.js +74 -0
  75. package/dist_ts/formats/pdf/extractors/text.extractor.d.ts +45 -0
  76. package/dist_ts/formats/pdf/extractors/text.extractor.js +151 -0
  77. package/dist_ts/formats/pdf/pdf.embedder.d.ts +69 -0
  78. package/dist_ts/formats/pdf/pdf.embedder.js +183 -0
  79. package/dist_ts/formats/pdf/pdf.extractor.d.ts +49 -0
  80. package/dist_ts/formats/pdf/pdf.extractor.js +98 -0
  81. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +40 -0
  82. package/dist_ts/formats/pdf/robust-pdf.extractor.js +324 -0
  83. package/dist_ts/formats/ubl/en16931.ubl.validator.d.ts +18 -0
  84. package/dist_ts/formats/ubl/en16931.ubl.validator.js +169 -0
  85. package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +151 -0
  86. package/dist_ts/formats/ubl/generic/ubl.encoder.js +892 -0
  87. package/dist_ts/formats/ubl/ubl.decoder.d.ts +61 -0
  88. package/dist_ts/formats/ubl/ubl.decoder.js +95 -0
  89. package/dist_ts/formats/ubl/ubl.encoder.d.ts +38 -0
  90. package/dist_ts/formats/ubl/ubl.encoder.js +46 -0
  91. package/dist_ts/formats/ubl/ubl.types.d.ts +16 -0
  92. package/dist_ts/formats/ubl/ubl.types.js +21 -0
  93. package/dist_ts/formats/ubl/ubl.validator.d.ts +50 -0
  94. package/dist_ts/formats/ubl/ubl.validator.js +112 -0
  95. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +34 -0
  96. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +424 -0
  97. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +75 -0
  98. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +555 -0
  99. package/dist_ts/formats/ubl/xrechnung.validator.d.ts +15 -0
  100. package/dist_ts/formats/ubl/xrechnung.validator.js +107 -0
  101. package/dist_ts/formats/ubl.validator.d.ts +82 -0
  102. package/dist_ts/formats/ubl.validator.js +306 -0
  103. package/dist_ts/formats/utils/format.detector.d.ts +62 -0
  104. package/dist_ts/formats/utils/format.detector.js +249 -0
  105. package/dist_ts/formats/validation/en16931.validator.d.ts +23 -0
  106. package/dist_ts/formats/validation/en16931.validator.js +119 -0
  107. package/dist_ts/formats/validator.factory.d.ts +18 -0
  108. package/dist_ts/formats/validator.factory.js +78 -0
  109. package/dist_ts/formats/xinvoice.decoder.d.ts +28 -0
  110. package/dist_ts/formats/xinvoice.decoder.js +332 -0
  111. package/dist_ts/formats/xinvoice.encoder.d.ts +19 -0
  112. package/dist_ts/formats/xinvoice.encoder.js +282 -0
  113. package/dist_ts/index.d.ts +51 -0
  114. package/dist_ts/index.js +90 -0
  115. package/dist_ts/interfaces/common.d.ts +79 -0
  116. package/dist_ts/interfaces/common.js +24 -0
  117. package/dist_ts/interfaces.d.ts +87 -0
  118. package/dist_ts/interfaces.js +23 -0
  119. package/dist_ts/plugins.d.ts +14 -0
  120. package/dist_ts/plugins.js +31 -0
  121. package/npmextra.json +35 -0
  122. package/package.json +71 -0
  123. package/readme.hints.md +1107 -0
  124. package/readme.howtofixtests.md +38 -0
  125. package/readme.literature.md +1 -0
  126. package/readme.md +998 -0
  127. package/readme.plan.md +481 -0
  128. package/ts/00_commitinfo_data.ts +8 -0
  129. package/ts/einvoice.ts +603 -0
  130. package/ts/errors.ts +341 -0
  131. package/ts/formats/base/base.decoder.ts +68 -0
  132. package/ts/formats/base/base.encoder.ts +14 -0
  133. package/ts/formats/base/base.validator.ts +64 -0
  134. package/ts/formats/cii/cii.decoder.ts +139 -0
  135. package/ts/formats/cii/cii.encoder.ts +64 -0
  136. package/ts/formats/cii/cii.types.ts +44 -0
  137. package/ts/formats/cii/cii.validator.ts +171 -0
  138. package/ts/formats/cii/facturx/facturx.decoder.ts +243 -0
  139. package/ts/formats/cii/facturx/facturx.encoder.ts +483 -0
  140. package/ts/formats/cii/facturx/facturx.types.ts +18 -0
  141. package/ts/formats/cii/facturx/facturx.validator.ts +180 -0
  142. package/ts/formats/cii/zugferd/zugferd.decoder.ts +256 -0
  143. package/ts/formats/cii/zugferd/zugferd.encoder.ts +661 -0
  144. package/ts/formats/cii/zugferd/zugferd.types.ts +18 -0
  145. package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +267 -0
  146. package/ts/formats/cii/zugferd/zugferd.validator.ts +31 -0
  147. package/ts/formats/factories/decoder.factory.ts +62 -0
  148. package/ts/formats/factories/encoder.factory.ts +47 -0
  149. package/ts/formats/factories/validator.factory.ts +134 -0
  150. package/ts/formats/pdf/extractors/associated.extractor.ts +78 -0
  151. package/ts/formats/pdf/extractors/base.extractor.ts +355 -0
  152. package/ts/formats/pdf/extractors/index.ts +4 -0
  153. package/ts/formats/pdf/extractors/standard.extractor.ts +86 -0
  154. package/ts/formats/pdf/extractors/text.extractor.ts +162 -0
  155. package/ts/formats/pdf/pdf.embedder.ts +242 -0
  156. package/ts/formats/pdf/pdf.extractor.ts +141 -0
  157. package/ts/formats/ubl/en16931.ubl.validator.ts +216 -0
  158. package/ts/formats/ubl/generic/ubl.encoder.ts +1041 -0
  159. package/ts/formats/ubl/ubl.decoder.ts +121 -0
  160. package/ts/formats/ubl/ubl.encoder.ts +63 -0
  161. package/ts/formats/ubl/ubl.types.ts +22 -0
  162. package/ts/formats/ubl/ubl.validator.ts +133 -0
  163. package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +471 -0
  164. package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +619 -0
  165. package/ts/formats/ubl/xrechnung.validator.ts +185 -0
  166. package/ts/formats/utils/format.detector.ts +306 -0
  167. package/ts/formats/validation/en16931.validator.ts +135 -0
  168. package/ts/index.ts +164 -0
  169. package/ts/interfaces/common.ts +90 -0
  170. package/ts/interfaces.ts +98 -0
  171. 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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