@ekwo-ai/intra-consignment 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ekwo AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # `@ekwo-ai/intra-consignment`
2
+
3
+ The Belgian **intra-Community sales listing** — the XML Intervat takes for
4
+ form 723 — in TypeScript, with no dependencies.
5
+
6
+ Give it the rows of a recapitulative statement and it gives you the file, a
7
+ name for it, and the list of what could not be put in it.
8
+
9
+ ```ts
10
+ import { generateIntraConsignment } from '@ekwo-ai/intra-consignment';
11
+
12
+ const { file, filename, violations } = generateIntraConsignment(rows, {
13
+ declarant: { vatNumber: '0999999999', name: 'Demo SRL', countryCode: 'BE' },
14
+ period: { year: 2026, quarter: 3 },
15
+ });
16
+ ```
17
+
18
+ `StatementRow` is the row shape of the `ec_sales_list(company, from, to)`
19
+ function of [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os), declared here so
20
+ that nothing is imported from it. Any book-keeping system that can produce
21
+ those columns can use this package; it reads no database and knows no
22
+ accounting.
23
+
24
+ ## The specification this was written from
25
+
26
+ | What | Where |
27
+ |---|---|
28
+ | The schema, `NewICO-in_v0_9.xsd` | <https://finances.belgium.be/sites/default/files/downloads/NewICO-in_v0_9.zip> |
29
+ | Its common types | <https://finances.belgium.be/sites/default/files/downloads/IntervatInputCommon_v0_9-20240703.zip> |
30
+ | Its ISO types | <https://finances.belgium.be/sites/default/files/downloads/IntervatIsoTypes_v0_9-20240806.zip> |
31
+ | Technical documentation, Intervat 14.x | <https://finances.belgium.be/fr/E-services/Intervat/documentation-technique> |
32
+ | Directives for form 723, ref. 723.2, edition 2024 | <https://finances.belgium.be/sites/default/files/downloads/165-723-directives-releve-intracommunautaire-2024.pdf> |
33
+ | How the listing is filed | <https://finances.belgium.be/fr/E-services/Intervat/comment-utiliser-intervat/deposer-releve-intracommunautaire> |
34
+
35
+ The output of this package was checked against that schema with `xmllint`
36
+ before it was committed. The schema is not shipped here — it belongs to the
37
+ administration and it moves — so the test suite proves the shape of the
38
+ document and not its validity; re-running the validation after a change to this
39
+ package is a minute of work and worth it.
40
+
41
+ Two traps that cost an afternoon, written down so they cost nobody else one:
42
+
43
+ - **Take the dated archives of the common and ISO types.** The undated URLs
44
+ answer 200 and serve an older version, in which the declarant's number may
45
+ not begin with a 1 — which refuses every enterprise number issued since.
46
+ - **The children of `Declarant` are in the `InputCommon` namespace**, not in
47
+ the listing's own. `elementFormDefault` is `qualified` in both schemas, so
48
+ the validator refuses a `Declarant` whose children carry the listing's
49
+ namespace, and no published example makes that obvious.
50
+
51
+ ## The three codes
52
+
53
+ From the directives, § 2.3.1.4 b: category I is `L` — exempt supplies of goods
54
+ — category II is `T`, the supply in the Member State of arrival under a
55
+ triangular operation, and category III is `S`, services taxed where the
56
+ customer is. The enumeration in the schema is exactly `{L, S, T}`; the `G` that
57
+ circulates in third-party documentation is refused by the validator.
58
+
59
+ The directives also say the three categories are never merged: a customer
60
+ supplied both goods and services appears twice, with the same number and two
61
+ codes. That is what the rows already are, and this package does not group them.
62
+
63
+ ## What it refuses and what it reports
64
+
65
+ An exception, because it would make the whole file meaningless:
66
+
67
+ - a period that is neither one month nor one quarter;
68
+ - a declarant number the schema cannot hold — ten digits, the `BE` removed.
69
+
70
+ A violation, because one line is wrong and the rest of the file is not:
71
+
72
+ | `code` | Why |
73
+ |---|---|
74
+ | whatever the producer flagged | The row arrived with an `issue` on it: a customer with no VAT number recorded, or a number that is not in another Member State |
75
+ | `unknown_nature` | A nature other than goods, services or a triangular operation |
76
+ | `wrong_currency` | The listing is filed in euro and the line is not |
77
+ | `no_vat_number` | A client of the listing is identified by a number, and this line has none |
78
+ | `vat_country_is_the_declarant_country` | The schema's `MSCountryCodeExclBE`, said without naming a country |
79
+ | `vat_number_too_long` | More than twelve characters after the country prefix |
80
+ | `nil_balance` | The directives leave out a customer whose balance is 0,00 euro |
81
+
82
+ `AmountSum` is the total of the lines that were kept, so a file with violations
83
+ still balances against itself.
84
+
85
+ ## The file name
86
+
87
+ **The administration imposes none.** Intervat takes a bare `.xml`; only the ZIP
88
+ archive that carries attachments has a fixed extension, `.ic` for this listing.
89
+ The `VATINTRA` prefix that circulates comes from accounting software and
90
+ appears nowhere in the published documentation. `intraConsignmentFileName` is
91
+ therefore a name of ours — stable and readable — and a caller is free to pick
92
+ another.
93
+
94
+ ## What is out of scope, on purpose
95
+
96
+ - **Part 2 of the listing, call-off stock.** Since 1 January 2020 it is a
97
+ separate electronic filing with a schema of its own, `cos-in_v1_0_0.xsd` and
98
+ root `COSConsignment`. It reports movements of stock rather than supplies,
99
+ and nothing in the rows this package reads describes one.
100
+ - **Corrections of an earlier period.** The schema carries them as an ordinary
101
+ client line with a signed delta and a `CorrectingPeriod`; producing one means
102
+ knowing what was filed before, which is a question for the books and not for
103
+ a file writer.
104
+ - **Filing.** This package writes bytes. Uploading them, signing them and
105
+ reading the acknowledgement are Intervat's business.
106
+
107
+ MIT.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The Belgian intra-Community sales listing, as Intervat takes it.
3
+ *
4
+ * One XML document, `IntraConsignment`, described by the schema the SPF
5
+ * Finances publishes as `NewICO-in_v0_9.xsd`. Give it the rows of a
6
+ * recapitulative statement and it writes the file, a name for it, and the list
7
+ * of what could not be put in it.
8
+ *
9
+ * Sources are in the README, with the exact URL of every schema and of the
10
+ * directives that fix the three operation codes. This package depends on
11
+ * nothing, reads no database and knows no accounting.
12
+ */
13
+ import type { IntraConsignment, IntraConsignmentOptions, ListingPeriod, StatementRow } from './types.js';
14
+ export type { Declarant, IntraConsignment, IntraConsignmentOptions, ListingPeriod, StatementRow, Violation, } from './types.js';
15
+ /**
16
+ * The three codes of the listing, from the directives for form 723 (§ 2.3.1.4
17
+ * b): category I is `L`, category II `T`, category III `S`. There is no code
18
+ * for anything else, so a nature this map does not hold is a violation and not
19
+ * a guess.
20
+ */
21
+ export declare const OPERATION_CODES: Readonly<Record<string, string>>;
22
+ /** The listing is filed in euro. The form has no currency field to say so. */
23
+ export declare const CURRENCY = "EUR";
24
+ export declare class IntraConsignmentError extends Error {
25
+ name: string;
26
+ }
27
+ /**
28
+ * Two decimals with a point, which is what `-?[0-9]+\.[0-9]{2}` means.
29
+ *
30
+ * The web page of the administration writes its example with a comma, in
31
+ * French; the schema does not. A comma is refused by the validator.
32
+ */
33
+ export declare function formatAmount(value: string | number): string;
34
+ /**
35
+ * A name for the file.
36
+ *
37
+ * **The administration imposes none.** Intervat takes a bare `.xml`, and only
38
+ * the archive that carries attachments has a fixed extension (`.ic` for this
39
+ * listing). The `VATINTRA` prefix that circulates comes from accounting
40
+ * software and appears nowhere in the published documentation. So this is a
41
+ * name of ours, stable and readable, and a caller free to choose another.
42
+ */
43
+ export declare function intraConsignmentFileName(declarantVatNumber: string, period: ListingPeriod): string;
44
+ /**
45
+ * Writes the listing.
46
+ *
47
+ * Refuses, by exception, what would make the whole file meaningless: a period
48
+ * that is neither a month nor a quarter, or a declarant number the schema
49
+ * cannot hold. Everything that is wrong with one line comes back in
50
+ * `violations` and leaves the rest of the file valid, because a statement that
51
+ * refuses to exist over one unidentified customer helps nobody.
52
+ */
53
+ export declare function generateIntraConsignment(rows: StatementRow[], options: IntraConsignmentOptions): IntraConsignment;
54
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI3D,CAAC;AAEH,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAQ9B,qBAAa,qBAAsB,SAAQ,KAAK;IACrC,IAAI,SAA2B;CACzC;AAUD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAI3D;AAwJD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,aAAa,GACpB,MAAM,CASR;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,YAAY,EAAE,EACpB,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CAmElB"}
package/dist/index.js ADDED
@@ -0,0 +1,258 @@
1
+ /**
2
+ * The Belgian intra-Community sales listing, as Intervat takes it.
3
+ *
4
+ * One XML document, `IntraConsignment`, described by the schema the SPF
5
+ * Finances publishes as `NewICO-in_v0_9.xsd`. Give it the rows of a
6
+ * recapitulative statement and it writes the file, a name for it, and the list
7
+ * of what could not be put in it.
8
+ *
9
+ * Sources are in the README, with the exact URL of every schema and of the
10
+ * directives that fix the three operation codes. This package depends on
11
+ * nothing, reads no database and knows no accounting.
12
+ */
13
+ /**
14
+ * The three codes of the listing, from the directives for form 723 (§ 2.3.1.4
15
+ * b): category I is `L`, category II `T`, category III `S`. There is no code
16
+ * for anything else, so a nature this map does not hold is a violation and not
17
+ * a guess.
18
+ */
19
+ export const OPERATION_CODES = Object.freeze({
20
+ goods: 'L',
21
+ triangular: 'T',
22
+ services: 'S',
23
+ });
24
+ /** The listing is filed in euro. The form has no currency field to say so. */
25
+ export const CURRENCY = 'EUR';
26
+ const NS_LISTING = 'http://www.minfin.fgov.be/IntraConsignment';
27
+ const NS_COMMON = 'http://www.minfin.fgov.be/InputCommon';
28
+ /** The schema's own pattern for the declarant's enterprise number. */
29
+ const DECLARANT_NUMBER = /^[0-1][0-9][0-9]{8}$/;
30
+ export class IntraConsignmentError extends Error {
31
+ name = 'IntraConsignmentError';
32
+ }
33
+ function escapeXml(value) {
34
+ return value
35
+ .replace(/&/g, '&amp;')
36
+ .replace(/</g, '&lt;')
37
+ .replace(/>/g, '&gt;')
38
+ .replace(/"/g, '&quot;');
39
+ }
40
+ /**
41
+ * Two decimals with a point, which is what `-?[0-9]+\.[0-9]{2}` means.
42
+ *
43
+ * The web page of the administration writes its example with a comma, in
44
+ * French; the schema does not. A comma is refused by the validator.
45
+ */
46
+ export function formatAmount(value) {
47
+ const n = typeof value === 'number' ? value : Number(value);
48
+ if (!Number.isFinite(n))
49
+ throw new IntraConsignmentError(`invalid amount: ${String(value)}`);
50
+ return n.toFixed(2);
51
+ }
52
+ /** Letters and digits, upper case: what an administration compares. */
53
+ function normalise(value) {
54
+ return value.replace(/[^A-Za-z0-9]/g, '').toUpperCase();
55
+ }
56
+ function periodElement(period) {
57
+ const lines = [];
58
+ if (period.month !== undefined)
59
+ lines.push(` <ns2:Month>${period.month}</ns2:Month>`);
60
+ if (period.quarter !== undefined)
61
+ lines.push(` <ns2:Quarter>${period.quarter}</ns2:Quarter>`);
62
+ lines.push(` <ns2:Year>${period.year}</ns2:Year>`);
63
+ return lines.join('\n');
64
+ }
65
+ /**
66
+ * The declarant block. Its children live in the `InputCommon` namespace and
67
+ * not in the listing's own, because the schema that declares them is a
68
+ * different one — a detail the validator is strict about and no example makes
69
+ * obvious.
70
+ */
71
+ function declarantElement(options) {
72
+ const d = options.declarant;
73
+ const optional = [
74
+ ['Name', d.name],
75
+ ['Street', d.street],
76
+ ['PostCode', d.postCode],
77
+ ['City', d.city],
78
+ ['CountryCode', d.countryCode],
79
+ ['EmailAddress', d.emailAddress],
80
+ ['Phone', d.phone],
81
+ ];
82
+ const lines = [` <VATNumber>${escapeXml(d.vatNumber)}</VATNumber>`];
83
+ for (const [tag, value] of optional) {
84
+ if (value !== undefined && value !== '')
85
+ lines.push(` <${tag}>${escapeXml(value)}</${tag}>`);
86
+ }
87
+ return lines.join('\n');
88
+ }
89
+ /**
90
+ * Turns the rows into clients of the listing, and says what it could not use.
91
+ *
92
+ * The rules applied here are the schema's and the directives', in the order a
93
+ * reader of the form would apply them:
94
+ *
95
+ * - a line the producer already flagged is not filed, whatever else is true of
96
+ * it: an amount with no VAT number in front of it has nowhere to go;
97
+ * - the customer's number may not be the declarant's own country, which is
98
+ * what the schema says with `MSCountryCodeExclBE`;
99
+ * - the number, prefix excluded, is at most twelve characters;
100
+ * - a nil balance is left out, because the directives say a customer whose
101
+ * balance is 0,00 euro is not carried;
102
+ * - the three categories are never merged, so a customer who was supplied
103
+ * goods and services gets two lines with the same number, which is exactly
104
+ * what the rows already are.
105
+ */
106
+ function clientsOf(rows, options) {
107
+ const clients = [];
108
+ const violations = [];
109
+ const home = (options.declarant.countryCode ?? '').toUpperCase();
110
+ for (const row of rows) {
111
+ const number = row.vat_number === null ? '' : normalise(row.vat_number);
112
+ const country = row.vat_country === null ? '' : normalise(row.vat_country);
113
+ const named = row.contact_names?.join(', ');
114
+ const about = named === undefined || named === '' ? `${country}${number}` : named;
115
+ if (row.issue !== null && row.issue !== undefined && row.issue !== '') {
116
+ violations.push({
117
+ code: row.issue,
118
+ message: `${about}: this supply cannot be listed — ${row.issue.replace(/_/g, ' ')}.`,
119
+ ...(number === '' ? {} : { vatNumber: `${country}${number}` }),
120
+ });
121
+ continue;
122
+ }
123
+ const code = OPERATION_CODES[row.nature];
124
+ if (code === undefined) {
125
+ violations.push({
126
+ code: 'unknown_nature',
127
+ message: `${about}: the listing has a code for goods, services and triangular operations, and none for "${row.nature}".`,
128
+ });
129
+ continue;
130
+ }
131
+ if (row.currency_code.toUpperCase() !== CURRENCY) {
132
+ violations.push({
133
+ code: 'wrong_currency',
134
+ message: `${about}: the listing is filed in ${CURRENCY} and this line is in ${row.currency_code}.`,
135
+ });
136
+ continue;
137
+ }
138
+ if (country === '' || number === '') {
139
+ violations.push({
140
+ code: 'no_vat_number',
141
+ message: `${about}: a client of the listing is identified by a VAT number and this line has none.`,
142
+ });
143
+ continue;
144
+ }
145
+ if (country === home) {
146
+ violations.push({
147
+ code: 'vat_country_is_the_declarant_country',
148
+ message: `${about}: the listing carries supplies to other Member States, and ${country} is the declarant's own.`,
149
+ vatNumber: `${country}${number}`,
150
+ });
151
+ continue;
152
+ }
153
+ if (number.length > 12) {
154
+ violations.push({
155
+ code: 'vat_number_too_long',
156
+ message: `${about}: the schema holds twelve characters after the country prefix and this number has ${number.length}.`,
157
+ vatNumber: `${country}${number}`,
158
+ });
159
+ continue;
160
+ }
161
+ const amount = formatAmount(row.amount);
162
+ if (Number(amount) === 0) {
163
+ violations.push({
164
+ code: 'nil_balance',
165
+ message: `${about}: a client whose balance is 0,00 euro is not carried on the listing.`,
166
+ vatNumber: `${country}${number}`,
167
+ });
168
+ continue;
169
+ }
170
+ clients.push({ issuedBy: country, number, code, amount });
171
+ }
172
+ // The order the form prints: by customer, then by category, so the same
173
+ // number's two or three lines sit together.
174
+ clients.sort((a, b) => `${a.issuedBy}${a.number}`.localeCompare(`${b.issuedBy}${b.number}`) ||
175
+ a.code.localeCompare(b.code));
176
+ return { clients, violations };
177
+ }
178
+ /**
179
+ * A name for the file.
180
+ *
181
+ * **The administration imposes none.** Intervat takes a bare `.xml`, and only
182
+ * the archive that carries attachments has a fixed extension (`.ic` for this
183
+ * listing). The `VATINTRA` prefix that circulates comes from accounting
184
+ * software and appears nowhere in the published documentation. So this is a
185
+ * name of ours, stable and readable, and a caller free to choose another.
186
+ */
187
+ export function intraConsignmentFileName(declarantVatNumber, period) {
188
+ const number = normalise(declarantVatNumber);
189
+ const suffix = period.month !== undefined
190
+ ? `M${String(period.month).padStart(2, '0')}`
191
+ : period.quarter !== undefined
192
+ ? `Q${period.quarter}`
193
+ : 'Y';
194
+ return `IntraConsignment-${number}-${period.year}${suffix}.xml`;
195
+ }
196
+ /**
197
+ * Writes the listing.
198
+ *
199
+ * Refuses, by exception, what would make the whole file meaningless: a period
200
+ * that is neither a month nor a quarter, or a declarant number the schema
201
+ * cannot hold. Everything that is wrong with one line comes back in
202
+ * `violations` and leaves the rest of the file valid, because a statement that
203
+ * refuses to exist over one unidentified customer helps nobody.
204
+ */
205
+ export function generateIntraConsignment(rows, options) {
206
+ const { period } = options;
207
+ const named = [period.month !== undefined, period.quarter !== undefined].filter(Boolean).length;
208
+ if (named !== 1) {
209
+ throw new IntraConsignmentError('the period of a listing is one month or one quarter: name exactly one of them');
210
+ }
211
+ if (period.month !== undefined && (period.month < 1 || period.month > 12)) {
212
+ throw new IntraConsignmentError(`month out of range: ${period.month}`);
213
+ }
214
+ if (period.quarter !== undefined && (period.quarter < 1 || period.quarter > 4)) {
215
+ throw new IntraConsignmentError(`quarter out of range: ${period.quarter}`);
216
+ }
217
+ if (!Number.isInteger(period.year) || period.year < 2000) {
218
+ throw new IntraConsignmentError(`year out of range: ${period.year}`);
219
+ }
220
+ const declarantNumber = normalise(options.declarant.vatNumber).replace(/^BE/, '');
221
+ if (!DECLARANT_NUMBER.test(declarantNumber)) {
222
+ throw new IntraConsignmentError(`the declarant's number is ten digits without its country prefix: ${options.declarant.vatNumber}`);
223
+ }
224
+ const { clients, violations } = clientsOf(rows, options);
225
+ const total = clients.reduce((sum, client) => sum + Number(client.amount), 0);
226
+ const sequence = options.sequenceNumber ?? 1;
227
+ const parts = [];
228
+ parts.push('<?xml version="1.0" encoding="UTF-8"?>');
229
+ parts.push(`<ns2:IntraConsignment xmlns:ns2="${NS_LISTING}" xmlns="${NS_COMMON}" IntraListingsNbr="1">`);
230
+ const reference = options.declarantReference === undefined || options.declarantReference === ''
231
+ ? ''
232
+ : ` DeclarantReference="${escapeXml(options.declarantReference)}"`;
233
+ parts.push(` <ns2:IntraListing SequenceNumber="${sequence}" ClientsNbr="${clients.length}"${reference} AmountSum="${formatAmount(total)}">`);
234
+ parts.push(' <ns2:Declarant>');
235
+ parts.push(declarantElement({ ...options, declarant: { ...options.declarant, vatNumber: declarantNumber } }));
236
+ parts.push(' </ns2:Declarant>');
237
+ parts.push(' <ns2:Period>');
238
+ parts.push(periodElement(period));
239
+ parts.push(' </ns2:Period>');
240
+ for (const [index, client] of clients.entries()) {
241
+ parts.push(` <ns2:IntraClient SequenceNumber="${index + 1}">`);
242
+ parts.push(` <ns2:CompanyVATNumber issuedBy="${client.issuedBy}">${client.number}</ns2:CompanyVATNumber>`);
243
+ parts.push(` <ns2:Code>${client.code}</ns2:Code>`);
244
+ parts.push(` <ns2:Amount>${client.amount}</ns2:Amount>`);
245
+ parts.push(' </ns2:IntraClient>');
246
+ }
247
+ if (options.comment !== undefined && options.comment !== '') {
248
+ parts.push(` <ns2:Comment>${escapeXml(options.comment)}</ns2:Comment>`);
249
+ }
250
+ parts.push(' </ns2:IntraListing>');
251
+ parts.push('</ns2:IntraConsignment>');
252
+ return {
253
+ file: `${parts.join('\n')}\n`,
254
+ filename: intraConsignmentFileName(declarantNumber, period),
255
+ violations,
256
+ };
257
+ }
258
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The shapes this package reads and returns.
3
+ *
4
+ * {@link StatementRow} is the row shape of the `ec_sales_list(company, from,
5
+ * to)` function of [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os), declared
6
+ * here so that nothing is imported from it. Any book-keeping system that can
7
+ * produce those columns can use this package; it reads no database and knows
8
+ * no accounting.
9
+ */
10
+ /**
11
+ * One line of a recapitulative statement: a customer, what was supplied to
12
+ * them, and how much, over a period.
13
+ */
14
+ export interface StatementRow {
15
+ /** Country of the customer's VAT identification number, ISO 3166-1 alpha-2. */
16
+ vat_country: string | null;
17
+ /** The number itself, without its country prefix, letters and digits only. */
18
+ vat_number: string | null;
19
+ /**
20
+ * What was supplied: `goods`, `services`, `triangular`. A value this package
21
+ * does not know comes back as a violation rather than being guessed at.
22
+ */
23
+ nature: string;
24
+ /** Taxable amount, credit notes already deducted. A string keeps the cents. */
25
+ amount: string | number;
26
+ /** ISO 4217 code the amount is in. */
27
+ currency_code: string;
28
+ /** Why this line cannot be declared as it stands, or null when it can. */
29
+ issue?: string | null;
30
+ /** Names of the customers behind the line, for a message a human reads. */
31
+ contact_names?: string[] | null;
32
+ }
33
+ /** The party filing. Only the VAT number is required by the schema. */
34
+ export interface Declarant {
35
+ /**
36
+ * The Belgian enterprise number of the declarant, ten digits and no `BE`.
37
+ * The schema's own pattern is `[0-1][0-9][0-9]{8}`; anything else is
38
+ * reported rather than cleaned up.
39
+ */
40
+ vatNumber: string;
41
+ name?: string;
42
+ street?: string;
43
+ postCode?: string;
44
+ city?: string;
45
+ /** ISO 3166-1 alpha-2 of the declarant's address. */
46
+ countryCode?: string;
47
+ emailAddress?: string;
48
+ phone?: string;
49
+ }
50
+ /**
51
+ * The period the listing covers. Exactly one of `month` or `quarter`, because
52
+ * that is what the schema's `choice` allows and because a listing is filed on
53
+ * one cadence or the other.
54
+ */
55
+ export interface ListingPeriod {
56
+ year: number;
57
+ month?: number;
58
+ quarter?: number;
59
+ }
60
+ export interface IntraConsignmentOptions {
61
+ declarant: Declarant;
62
+ period: ListingPeriod;
63
+ /** Sequence number of this listing inside the consignment. Default 1. */
64
+ sequenceNumber?: number;
65
+ /** The declarant's own reference for this filing, at most 14 characters. */
66
+ declarantReference?: string;
67
+ /** Free text the administration displays with the filing. */
68
+ comment?: string;
69
+ }
70
+ /** Something that does not add up, said in the terms of this format. */
71
+ export interface Violation {
72
+ /** A stable token, for a caller that branches on it. */
73
+ code: string;
74
+ /** What is wrong, in a sentence. */
75
+ message: string;
76
+ /** The customer the line was about, where there is one. */
77
+ vatNumber?: string;
78
+ }
79
+ export interface IntraConsignment {
80
+ /** The XML, as text. */
81
+ file: string;
82
+ /** A name for it. See the README: the administration imposes none. */
83
+ filename: string;
84
+ /** Everything that could not be put in the file, and why. */
85
+ violations: Violation[];
86
+ }
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC;AAED,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB"}
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The shapes this package reads and returns.
3
+ *
4
+ * {@link StatementRow} is the row shape of the `ec_sales_list(company, from,
5
+ * to)` function of [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os), declared
6
+ * here so that nothing is imported from it. Any book-keeping system that can
7
+ * produce those columns can use this package; it reads no database and knows
8
+ * no accounting.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@ekwo-ai/intra-consignment",
3
+ "version": "0.4.0",
4
+ "description": "The Belgian intra-Community sales listing for Intervat (IntraConsignment XML, schema NewICO-in v0.9) in TypeScript, from plain statement rows. Zero dependencies.",
5
+ "keywords": [
6
+ "intervat",
7
+ "intraconsignment",
8
+ "intra-community",
9
+ "ec-sales-list",
10
+ "releve-intracommunautaire",
11
+ "vat",
12
+ "belgium",
13
+ "spf-finances",
14
+ "xml"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "Ekwo AI",
18
+ "homepage": "https://github.com/Ekwo-ai/ekwo-os/tree/main/packages/formats/intra-consignment#readme",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/Ekwo-ai/ekwo-os.git",
22
+ "directory": "packages/formats/intra-consignment"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Ekwo-ai/ekwo-os/issues"
26
+ },
27
+ "type": "module",
28
+ "sideEffects": false,
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md",
35
+ "LICENSE"
36
+ ],
37
+ "main": "./dist/index.js",
38
+ "types": "./dist/index.d.ts",
39
+ "exports": {
40
+ ".": {
41
+ "types": "./dist/index.d.ts",
42
+ "import": "./dist/index.js"
43
+ }
44
+ },
45
+ "scripts": {
46
+ "build": "tsc -p tsconfig.build.json",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "test": "vitest run"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^24.0.0",
52
+ "typescript": "^5.9.0",
53
+ "vitest": "^3.2.0"
54
+ }
55
+ }