@ekwo-ai/peppol-ubl 0.4.0

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.
@@ -0,0 +1,232 @@
1
+ /**
2
+ * The shapes this package reads and returns.
3
+ *
4
+ * The three row types are the columns of `document_header`,
5
+ * `document_line_items` and `document_tax_summary` in
6
+ * [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os), declared here so that nothing
7
+ * is imported from it: a posted document, its lines and its VAT breakdown as
8
+ * the books hold them. Any invoicing system that can produce the same three
9
+ * things can use this package; it reads no database and knows no accounting.
10
+ *
11
+ * Only the columns this format has a place for are declared, and a row that
12
+ * carries more is accepted as it is. One field is marked *not in the view
13
+ * today*: the net price of a line keyed with its tax in it, which the books
14
+ * have not decided how to round. Nothing is ever filled in for a field that
15
+ * is absent.
16
+ */
17
+ /** A `numeric` as it is read from the database. A string keeps every digit. */
18
+ export type Numeric = string | number;
19
+ /** ISO-8601 calendar date, `YYYY-MM-DD`. */
20
+ export type IsoDate = string;
21
+ /** One row of `document_header`: everything printed above the lines. */
22
+ export interface DocumentHeaderRow {
23
+ /**
24
+ * `sale_invoice` or `sale_credit_note`. Anything else is refused outright: a
25
+ * purchase is somebody else's invoice and a quote is not an invoice at all.
26
+ */
27
+ doc_type: string;
28
+ /** BT-1. A document without a number was never issued, and is refused. */
29
+ number: string | null;
30
+ /** BT-2. */
31
+ document_date: IsoDate;
32
+ /** BT-9. */
33
+ due_date?: IsoDate | null;
34
+ /** BT-72. */
35
+ delivery_date?: IsoDate | null;
36
+ /** BT-7. */
37
+ tax_point_date?: IsoDate | null;
38
+ /** BT-5. There is no default: a document without a currency is refused. */
39
+ currency_code: string;
40
+ /** BT-109. Also written as BT-106: this model has no document-level allowance or charge. */
41
+ amount_untaxed: Numeric;
42
+ /** BT-110. */
43
+ amount_tax: Numeric;
44
+ /** BT-112. */
45
+ amount_total: Numeric;
46
+ /** BT-113. Left out of the file when it is zero or absent. */
47
+ amount_paid?: Numeric | null;
48
+ /** BT-115. Where it is absent, the total less what was paid — which is its definition (BR-CO-16). */
49
+ amount_residual?: Numeric | null;
50
+ /** BT-20. */
51
+ payment_terms?: string | null;
52
+ /** BT-81, UNTDID 4461. Without it no payment instruction is written, IBAN or not. */
53
+ payment_means_code?: string | null;
54
+ /** BT-83. */
55
+ payment_reference?: string | null;
56
+ /** BT-84. */
57
+ payee_iban?: string | null;
58
+ /** BT-86. */
59
+ payee_bic?: string | null;
60
+ /** BT-10. */
61
+ buyer_reference?: string | null;
62
+ /** BT-13. */
63
+ order_reference?: string | null;
64
+ /** BT-12. */
65
+ contract_reference?: string | null;
66
+ /** BT-11. */
67
+ project_reference?: string | null;
68
+ /** BT-22. */
69
+ note?: string | null;
70
+ /** BT-28 where a legal name is given beside it, BT-27 otherwise. */
71
+ seller_name: string | null;
72
+ /** BT-27. */
73
+ seller_legal_name?: string | null;
74
+ /** BT-33. */
75
+ seller_legal_form?: string | null;
76
+ /** BT-31, with its country prefix. */
77
+ seller_vat_number?: string | null;
78
+ /** BT-30. */
79
+ seller_registration_number?: string | null;
80
+ seller_address_line1?: string | null;
81
+ seller_address_line2?: string | null;
82
+ seller_postal_code?: string | null;
83
+ seller_city?: string | null;
84
+ /** BT-40, ISO 3166-1 alpha-2. */
85
+ seller_country?: string | null;
86
+ seller_region?: string | null;
87
+ /** BT-43. */
88
+ seller_email?: string | null;
89
+ /** BT-42. */
90
+ seller_phone?: string | null;
91
+ /** BT-44. */
92
+ buyer_name: string | null;
93
+ /** BT-48. */
94
+ buyer_vat_number?: string | null;
95
+ /** BT-47. */
96
+ buyer_registration_number?: string | null;
97
+ buyer_address_line1?: string | null;
98
+ buyer_address_line2?: string | null;
99
+ buyer_postal_code?: string | null;
100
+ buyer_city?: string | null;
101
+ /** BT-55. */
102
+ buyer_country?: string | null;
103
+ buyer_region?: string | null;
104
+ /** BT-58. */
105
+ buyer_email?: string | null;
106
+ /**
107
+ * BT-34 and BT-49, the electronic addresses: a scheme of the EAS list and a
108
+ * value, as the seller and the buyer are registered. `options.sellerEndpoint`
109
+ * and `options.buyerEndpoint` take precedence where they are given.
110
+ */
111
+ seller_peppol_scheme?: string | null;
112
+ seller_peppol_identifier?: string | null;
113
+ buyer_peppol_scheme?: string | null;
114
+ buyer_peppol_identifier?: string | null;
115
+ /** BG-15, the deliver-to address. */
116
+ delivery_address_line1?: string | null;
117
+ delivery_postal_code?: string | null;
118
+ delivery_city?: string | null;
119
+ /** BT-80. */
120
+ delivery_country?: string | null;
121
+ }
122
+ /** One row of `document_line_items`. */
123
+ export interface DocumentLineRow {
124
+ /** `product` lines are invoice lines. Anything else — a section, a note — is layout and is skipped. */
125
+ line_type?: string | null;
126
+ /** BT-126. Where it is absent the line is numbered by its position. */
127
+ sequence?: number | string | null;
128
+ /** BT-153. */
129
+ item_name: string | null;
130
+ /** BT-154. */
131
+ item_description?: string | null;
132
+ /** BT-155. */
133
+ seller_item_identifier?: string | null;
134
+ /** BT-129. */
135
+ quantity: Numeric | null;
136
+ /** BT-130, UN/ECE Recommendation 20. */
137
+ unit_code?: string | null;
138
+ /** The price as it was keyed: before the discount, and with the tax in it where `unit_price_includes_tax`. */
139
+ unit_price?: Numeric | null;
140
+ discount_percent?: Numeric | null;
141
+ unit_price_includes_tax?: boolean | null;
142
+ /**
143
+ * BT-146, for a line whose price was keyed with the tax in it. Not in the
144
+ * view today, and not worked out here: the net price of such a line is its
145
+ * base divided by its quantity, which is a rounding decision and therefore
146
+ * the books' to make.
147
+ */
148
+ net_unit_price?: Numeric | null;
149
+ /** BT-131. */
150
+ amount_untaxed: Numeric;
151
+ /** BT-151, as the line was posted. A line that does not say is a line without a category (BR-CO-04). */
152
+ vat_category?: string | null;
153
+ /** BT-152, as the line was posted. */
154
+ vat_rate?: Numeric | null;
155
+ /** BT-121 of the tax on this line, carried up to the breakdown it belongs to. */
156
+ tax_exemption_code?: string | null;
157
+ }
158
+ /** One row of `document_tax_summary`: one tax of the document, rounded once on its group. */
159
+ export interface DocumentTaxRow {
160
+ /** BT-118. */
161
+ vat_category: string | null;
162
+ /** BT-119. */
163
+ tax_rate?: Numeric | null;
164
+ /** BT-116. */
165
+ base_amount: Numeric;
166
+ /** BT-117: what the buyer is charged, which is nothing where the tax is self-assessed. */
167
+ tax_charged: Numeric;
168
+ /** BT-121. Where it is absent the code of the lines of the group is used. */
169
+ exemption_code?: string | null;
170
+ /** BT-120: why the group charges nothing, in a sentence a customer can read. */
171
+ exemption_reason?: string | null;
172
+ }
173
+ /** An electronic address (BT-34, BT-49): where the network delivers. */
174
+ export interface ElectronicAddress {
175
+ /** The EAS scheme, e.g. `0088` for a GLN. There is no default. */
176
+ scheme: string;
177
+ id: string;
178
+ }
179
+ export interface PeppolUblOptions {
180
+ /**
181
+ * BT-34 and BT-49, for a caller whose header does not carry them, or to
182
+ * send under another address than the one on file. Both are mandatory on the
183
+ * network and neither is derived from anything: which identifier a
184
+ * participant is registered under is a fact of the registration, not of its
185
+ * VAT number.
186
+ */
187
+ sellerEndpoint?: ElectronicAddress;
188
+ buyerEndpoint?: ElectronicAddress;
189
+ /**
190
+ * BT-30-1 and BT-47-1: the ISO 6523 scheme a registration number is written
191
+ * in, e.g. `0208` for a Belgian enterprise number. Left out, the number
192
+ * travels without one, which the standard allows. It is not read from the
193
+ * books: what Ekwo OS calls `party_scheme` is the scheme a party is
194
+ * *addressed* by, which is an electronic address scheme and, in more than one
195
+ * country, not a scheme a registration number can be written in at all.
196
+ */
197
+ sellerRegistrationScheme?: string;
198
+ buyerRegistrationScheme?: string;
199
+ /** BG-3: the invoice a credit note credits, or a corrected invoice corrects. */
200
+ precedingInvoice?: {
201
+ number: string;
202
+ issueDate?: IsoDate;
203
+ };
204
+ }
205
+ /** A posted sales document, as three reads of the books. */
206
+ export interface PeppolUblInput {
207
+ header: DocumentHeaderRow;
208
+ lines: readonly DocumentLineRow[];
209
+ taxes: readonly DocumentTaxRow[];
210
+ }
211
+ /** A rule of the format this document breaks. */
212
+ export interface Violation {
213
+ /**
214
+ * The identifier the rule is published under — `BR-CO-15`,
215
+ * `PEPPOL-EN16931-R003` — which is what a validator on the network will
216
+ * report, and the only name worth branching on.
217
+ */
218
+ code: string;
219
+ /** What is wrong, in a sentence. */
220
+ message: string;
221
+ /** The line the trouble is on, by its identifier (BT-126), where there is one. */
222
+ line?: string;
223
+ }
224
+ export interface PeppolUbl {
225
+ /** The XML, as text. */
226
+ file: string;
227
+ /** A name for it. The network imposes none. */
228
+ filename: string;
229
+ /** Every published rule the file breaks. Empty is the only state to send in. */
230
+ violations: Violation[];
231
+ }
232
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The shapes this package reads and returns.
3
+ *
4
+ * The three row types are the columns of `document_header`,
5
+ * `document_line_items` and `document_tax_summary` in
6
+ * [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os), declared here so that nothing
7
+ * is imported from it: a posted document, its lines and its VAT breakdown as
8
+ * the books hold them. Any invoicing system that can produce the same three
9
+ * things can use this package; it reads no database and knows no accounting.
10
+ *
11
+ * Only the columns this format has a place for are declared, and a row that
12
+ * carries more is accepted as it is. One field is marked *not in the view
13
+ * today*: the net price of a line keyed with its tax in it, which the books
14
+ * have not decided how to round. Nothing is ever filled in for a field that
15
+ * is absent.
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
package/dist/ubl.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The model, printed as UBL 2.1.
3
+ *
4
+ * The order of the elements is the order of the OASIS schema, which is a
5
+ * sequence and refuses anything else — and it is not the same order in an
6
+ * invoice and in a credit note, which is why the two are written apart rather
7
+ * than from one template with the word replaced. `test/schema.test.ts`
8
+ * validates both against the published schema.
9
+ *
10
+ * Nothing is written empty. An element with nothing in it is a rule broken
11
+ * (PEPPOL-EN16931-R008), so an absent value is an absent element.
12
+ */
13
+ import type { DocumentModel } from './model.js';
14
+ /** BT-24: what the file claims to conform to. */
15
+ export declare const CUSTOMIZATION_ID = "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0";
16
+ /** BT-23: the one business process Peppol BIS Billing 3.0 defines. */
17
+ export declare const PROFILE_ID = "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0";
18
+ export declare function escapeXml(value: string): string;
19
+ export declare function writeUbl(model: DocumentModel): string;
20
+ //# sourceMappingURL=ubl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ubl.d.ts","sourceRoot":"","sources":["../src/ubl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,YAAY,CAAC;AAEtF,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,+EAA+E,CAAC;AAC7G,sEAAsE;AACtE,eAAO,MAAM,UAAU,gDAAgD,CAAC;AASxE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AA8GD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CA6GrD"}
package/dist/ubl.js ADDED
@@ -0,0 +1,233 @@
1
+ /**
2
+ * The model, printed as UBL 2.1.
3
+ *
4
+ * The order of the elements is the order of the OASIS schema, which is a
5
+ * sequence and refuses anything else — and it is not the same order in an
6
+ * invoice and in a credit note, which is why the two are written apart rather
7
+ * than from one template with the word replaced. `test/schema.test.ts`
8
+ * validates both against the published schema.
9
+ *
10
+ * Nothing is written empty. An element with nothing in it is a rule broken
11
+ * (PEPPOL-EN16931-R008), so an absent value is an absent element.
12
+ */
13
+ import { formatDecimal, isZero } from './decimal.js';
14
+ /** BT-24: what the file claims to conform to. */
15
+ export const CUSTOMIZATION_ID = 'urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0';
16
+ /** BT-23: the one business process Peppol BIS Billing 3.0 defines. */
17
+ export const PROFILE_ID = 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0';
18
+ const NAMESPACES = {
19
+ Invoice: 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2',
20
+ CreditNote: 'urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2',
21
+ cac: 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2',
22
+ cbc: 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2',
23
+ };
24
+ export function escapeXml(value) {
25
+ return value
26
+ .replace(/&/g, '&')
27
+ .replace(/</g, '&lt;')
28
+ .replace(/>/g, '&gt;')
29
+ .replace(/"/g, '&quot;');
30
+ }
31
+ /** `<name attrs>text</name>`, or nothing where there is no text. */
32
+ function leaf(name, value, attributes = {}) {
33
+ if (value === null || value === '')
34
+ return null;
35
+ const attrs = Object.entries(attributes)
36
+ .filter((entry) => entry[1] !== null && entry[1] !== '')
37
+ .map(([key, text]) => ` ${key}="${escapeXml(text)}"`)
38
+ .join('');
39
+ return `<${name}${attrs}>${escapeXml(value)}</${name}>`;
40
+ }
41
+ /** `<name>children</name>`, indented, or nothing where there are no children. */
42
+ function group(name, children) {
43
+ const present = children.filter((child) => child !== null);
44
+ if (present.length === 0)
45
+ return null;
46
+ const body = present.map((child) => child.replace(/^/gm, ' ')).join('\n');
47
+ return `<${name}>\n${body}\n</${name}>`;
48
+ }
49
+ /**
50
+ * An amount, with its currency. Two decimals at least, because that is how the
51
+ * standard writes an amount; more where more were given, because a digit is not
52
+ * dropped here — the rule it breaks is reported instead (BR-DEC-*).
53
+ */
54
+ function money(name, value, currency) {
55
+ return value === null ? null : leaf(name, formatDecimal(value, 2), { currencyID: currency });
56
+ }
57
+ const vatScheme = group('cac:TaxScheme', [leaf('cbc:ID', 'VAT')]);
58
+ function party(model) {
59
+ const a = model.address;
60
+ return group('cac:Party', [
61
+ model.endpoint ? leaf('cbc:EndpointID', model.endpoint.id, { schemeID: model.endpoint.scheme }) : null,
62
+ group('cac:PartyName', [leaf('cbc:Name', model.tradeName)]),
63
+ a &&
64
+ group('cac:PostalAddress', [
65
+ leaf('cbc:StreetName', a.line1),
66
+ leaf('cbc:AdditionalStreetName', a.line2),
67
+ leaf('cbc:CityName', a.city),
68
+ leaf('cbc:PostalZone', a.postalCode),
69
+ leaf('cbc:CountrySubentity', a.region),
70
+ group('cac:Country', [leaf('cbc:IdentificationCode', a.country)]),
71
+ ]),
72
+ model.vatId === null ? null : group('cac:PartyTaxScheme', [leaf('cbc:CompanyID', model.vatId), vatScheme]),
73
+ group('cac:PartyLegalEntity', [
74
+ leaf('cbc:RegistrationName', model.registrationName),
75
+ leaf('cbc:CompanyID', model.legalId, { schemeID: model.legalIdScheme }),
76
+ leaf('cbc:CompanyLegalForm', model.legalForm),
77
+ ]),
78
+ model.contact &&
79
+ group('cac:Contact', [leaf('cbc:Telephone', model.contact.phone), leaf('cbc:ElectronicMail', model.contact.email)]),
80
+ ]);
81
+ }
82
+ /** The rate of a category, where the category has one: outside the scope of VAT there is none (BR-O-05). */
83
+ function percent(category, rate) {
84
+ if (rate === null)
85
+ return null;
86
+ if (category === 'O' && isZero(rate))
87
+ return null;
88
+ return leaf('cbc:Percent', formatDecimal(rate));
89
+ }
90
+ function subtotal(model, currency) {
91
+ return group('cac:TaxSubtotal', [
92
+ money('cbc:TaxableAmount', model.base, currency),
93
+ money('cbc:TaxAmount', model.tax, currency),
94
+ group('cac:TaxCategory', [
95
+ leaf('cbc:ID', model.category),
96
+ percent(model.category, model.rate),
97
+ leaf('cbc:TaxExemptionReasonCode', model.reasonCode),
98
+ leaf('cbc:TaxExemptionReason', model.reason),
99
+ vatScheme,
100
+ ]),
101
+ ]);
102
+ }
103
+ function line(model, kind, currency) {
104
+ const quantity = kind === 'Invoice' ? 'cbc:InvoicedQuantity' : 'cbc:CreditedQuantity';
105
+ return group(kind === 'Invoice' ? 'cac:InvoiceLine' : 'cac:CreditNoteLine', [
106
+ leaf('cbc:ID', model.id),
107
+ model.quantity === null ? null : leaf(quantity, formatDecimal(model.quantity), { unitCode: model.unitCode }),
108
+ money('cbc:LineExtensionAmount', model.netAmount, currency),
109
+ group('cac:Item', [
110
+ leaf('cbc:Description', model.description),
111
+ leaf('cbc:Name', model.name),
112
+ group('cac:SellersItemIdentification', [leaf('cbc:ID', model.sellerItemId)]),
113
+ group('cac:ClassifiedTaxCategory', [
114
+ leaf('cbc:ID', model.category),
115
+ percent(model.category, model.rate),
116
+ model.category === null ? null : vatScheme,
117
+ ]),
118
+ ]),
119
+ model.netPrice === null
120
+ ? null
121
+ : group('cac:Price', [
122
+ leaf('cbc:PriceAmount', formatDecimal(model.netPrice), { currencyID: currency }),
123
+ model.grossPrice !== null && model.priceDiscount !== null
124
+ ? group('cac:AllowanceCharge', [
125
+ leaf('cbc:ChargeIndicator', 'false'),
126
+ leaf('cbc:Amount', formatDecimal(model.priceDiscount), { currencyID: currency }),
127
+ leaf('cbc:BaseAmount', formatDecimal(model.grossPrice), { currencyID: currency }),
128
+ ])
129
+ : null,
130
+ ]),
131
+ ]);
132
+ }
133
+ export function writeUbl(model) {
134
+ const { kind, currency } = model;
135
+ const invoice = kind === 'Invoice';
136
+ const delivery = model.delivery &&
137
+ group('cac:Delivery', [
138
+ leaf('cbc:ActualDeliveryDate', model.delivery.date),
139
+ model.delivery.address &&
140
+ group('cac:DeliveryLocation', [
141
+ group('cac:Address', [
142
+ leaf('cbc:StreetName', model.delivery.address.line1),
143
+ leaf('cbc:CityName', model.delivery.address.city),
144
+ leaf('cbc:PostalZone', model.delivery.address.postalCode),
145
+ group('cac:Country', [leaf('cbc:IdentificationCode', model.delivery.address.country)]),
146
+ ]),
147
+ ]),
148
+ ]);
149
+ const payment = model.payment &&
150
+ group('cac:PaymentMeans', [
151
+ leaf('cbc:PaymentMeansCode', model.payment.meansCode),
152
+ // A credit note has no due date of its own in UBL 2.1; BT-9 lives here.
153
+ invoice ? null : leaf('cbc:PaymentDueDate', model.dueDate),
154
+ leaf('cbc:PaymentID', model.payment.reference),
155
+ model.payment.iban === null
156
+ ? null
157
+ : group('cac:PayeeFinancialAccount', [
158
+ leaf('cbc:ID', model.payment.iban),
159
+ group('cac:FinancialInstitutionBranch', [leaf('cbc:ID', model.payment.bic)]),
160
+ ]),
161
+ ]);
162
+ const billingReference = model.preceding &&
163
+ group('cac:BillingReference', [
164
+ group('cac:InvoiceDocumentReference', [
165
+ leaf('cbc:ID', model.preceding.number),
166
+ leaf('cbc:IssueDate', model.preceding.issueDate),
167
+ ]),
168
+ ]);
169
+ // BT-11 has an element of its own in an invoice. A credit note has none in
170
+ // UBL 2.1, and carries it as an additional document of type 50.
171
+ const project = invoice
172
+ ? group('cac:ProjectReference', [leaf('cbc:ID', model.projectReference)])
173
+ : model.projectReference === null
174
+ ? null
175
+ : group('cac:AdditionalDocumentReference', [
176
+ leaf('cbc:ID', model.projectReference),
177
+ leaf('cbc:DocumentTypeCode', '50'),
178
+ ]);
179
+ const head = invoice
180
+ ? [
181
+ leaf('cbc:CustomizationID', CUSTOMIZATION_ID),
182
+ leaf('cbc:ProfileID', PROFILE_ID),
183
+ leaf('cbc:ID', model.number),
184
+ leaf('cbc:IssueDate', model.issueDate),
185
+ leaf('cbc:DueDate', model.dueDate),
186
+ leaf('cbc:InvoiceTypeCode', model.typeCode),
187
+ leaf('cbc:Note', model.note),
188
+ leaf('cbc:TaxPointDate', model.taxPointDate),
189
+ leaf('cbc:DocumentCurrencyCode', currency),
190
+ leaf('cbc:BuyerReference', model.buyerReference),
191
+ ]
192
+ : [
193
+ leaf('cbc:CustomizationID', CUSTOMIZATION_ID),
194
+ leaf('cbc:ProfileID', PROFILE_ID),
195
+ leaf('cbc:ID', model.number),
196
+ leaf('cbc:IssueDate', model.issueDate),
197
+ leaf('cbc:TaxPointDate', model.taxPointDate),
198
+ leaf('cbc:CreditNoteTypeCode', model.typeCode),
199
+ leaf('cbc:Note', model.note),
200
+ leaf('cbc:DocumentCurrencyCode', currency),
201
+ leaf('cbc:BuyerReference', model.buyerReference),
202
+ ];
203
+ const body = group(kind, [
204
+ ...head,
205
+ group('cac:OrderReference', [leaf('cbc:ID', model.orderReference)]),
206
+ billingReference,
207
+ group('cac:ContractDocumentReference', [leaf('cbc:ID', model.contractReference)]),
208
+ // In both schemas the additional documents come before the project.
209
+ project,
210
+ group('cac:AccountingSupplierParty', [party(model.seller)]),
211
+ group('cac:AccountingCustomerParty', [party(model.buyer)]),
212
+ delivery,
213
+ payment,
214
+ group('cac:PaymentTerms', [leaf('cbc:Note', model.paymentTerms)]),
215
+ // The total VAT is the books' figure and is written with or without a
216
+ // breakdown under it; a document without one is reported, not tidied.
217
+ group('cac:TaxTotal', [
218
+ money('cbc:TaxAmount', model.taxTotal, currency),
219
+ ...model.subtotals.map((each) => subtotal(each, currency)),
220
+ ]),
221
+ group('cac:LegalMonetaryTotal', [
222
+ money('cbc:LineExtensionAmount', model.lineTotal, currency),
223
+ money('cbc:TaxExclusiveAmount', model.taxExclusive, currency),
224
+ money('cbc:TaxInclusiveAmount', model.taxInclusive, currency),
225
+ money('cbc:PrepaidAmount', model.prepaid, currency),
226
+ money('cbc:PayableAmount', model.payable, currency),
227
+ ]),
228
+ ...model.lines.map((each) => line(each, kind, currency)),
229
+ ]);
230
+ const root = `<${kind} xmlns="${NAMESPACES[kind]}" xmlns:cac="${NAMESPACES.cac}" xmlns:cbc="${NAMESPACES.cbc}">`;
231
+ return `<?xml version="1.0" encoding="UTF-8"?>\n${body.replace(`<${kind}>`, root)}\n`;
232
+ }
233
+ //# sourceMappingURL=ubl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ubl.js","sourceRoot":"","sources":["../src/ubl.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@ekwo-ai/peppol-ubl",
3
+ "version": "0.4.0",
4
+ "description": "Peppol BIS Billing 3.0 invoices and credit notes (UBL 2.1, EN 16931) in TypeScript, from a posted document, with every published rule the file breaks named by its identifier. Zero dependencies.",
5
+ "keywords": [
6
+ "peppol",
7
+ "peppol-bis",
8
+ "bis-billing-3",
9
+ "ubl",
10
+ "ubl-2.1",
11
+ "en16931",
12
+ "e-invoicing",
13
+ "einvoice",
14
+ "invoice",
15
+ "credit-note",
16
+ "xml"
17
+ ],
18
+ "license": "MIT",
19
+ "author": "Ekwo AI",
20
+ "homepage": "https://github.com/Ekwo-ai/ekwo-os/tree/main/packages/formats/peppol-ubl#readme",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/Ekwo-ai/ekwo-os.git",
24
+ "directory": "packages/formats/peppol-ubl"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/Ekwo-ai/ekwo-os/issues"
28
+ },
29
+ "type": "module",
30
+ "sideEffects": false,
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE",
38
+ "CHANGELOG.md"
39
+ ],
40
+ "main": "./dist/index.js",
41
+ "types": "./dist/index.d.ts",
42
+ "exports": {
43
+ ".": {
44
+ "types": "./dist/index.d.ts",
45
+ "import": "./dist/index.js"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.build.json",
50
+ "typecheck": "tsc -p tsconfig.json --noEmit",
51
+ "test": "vitest run",
52
+ "codelists": "node scripts/build-codelists.mjs",
53
+ "codelists:check": "node scripts/build-codelists.mjs --check"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^24.0.0",
57
+ "typescript": "^5.9.0",
58
+ "vitest": "^3.2.0",
59
+ "xmllint-wasm": "^5.3.0"
60
+ }
61
+ }