@ekwo-ai/document-reading 0.0.0-stage → 0.19.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/dist/model.js ADDED
@@ -0,0 +1,434 @@
1
+ /**
2
+ * The model path: a photograph or a plain PDF, read by a vision model.
3
+ *
4
+ * This package calls no model. It publishes what a caller sends to one — the
5
+ * JSON schema the answer is held to (`readingSchema()`) and the words that go
6
+ * with it (`readingPrompt()`) — and checks what comes back (`readingOf()`)
7
+ * into the `ReceivedInvoice` the exact readers return, so that whatever turns
8
+ * an invoice into a purchase does it once for a Factur-X file and for a
9
+ * photograph of a till receipt. The call, its key, its timeout and what it
10
+ * costs stay with the product that makes it.
11
+ *
12
+ * The model copies; it never computes. Every figure is the text the page
13
+ * prints, every code one the page prints or that names, in a published list,
14
+ * a word the page prints. A field the page does not print is left empty, and
15
+ * `readingOf()` keeps it empty: `null` where `ReceivedInvoice` allows it,
16
+ * `''` where EN 16931 requires a value, named then in `missing`. Nothing is
17
+ * defaulted — not the currency, not the date, not a quantity of one.
18
+ *
19
+ * A caller may ask for more than an invoice: an energy layer asks for the
20
+ * meter, the bands and the contract type. It hands an `extension` — its own
21
+ * properties, in JSON schema — and gets them back, untouched, beside the
22
+ * invoice. The same call reads both.
23
+ */
24
+ import { checkReceived, isValidIban, toUnitCode, } from '@ekwo-ai/factur-x';
25
+ /** Changed with every change of the schema or of the words below; a product writes it in the log of every reading. */
26
+ export const READING_VERSION = '2026-10-22';
27
+ export const CONFIDENCES = ['high', 'medium', 'low'];
28
+ /**
29
+ * The fields of the document the model rates its confidence in, one by one.
30
+ * A line rates itself (`lines[n]`).
31
+ */
32
+ export const CONFIDENCE_FIELDS = [
33
+ 'document',
34
+ 'number',
35
+ 'issue_date',
36
+ 'due_date',
37
+ 'currency',
38
+ 'seller',
39
+ 'seller_vat_id',
40
+ 'seller_legal_id',
41
+ 'buyer',
42
+ 'invoicing_period',
43
+ 'taxes',
44
+ 'totals',
45
+ 'payment',
46
+ ];
47
+ /**
48
+ * The categories of VAT EN 16931 names (UNTDID 5305, the subset of BT-118):
49
+ * standard, zero, exempt, reverse charge, intra-Community, export, outside the
50
+ * scope, and the two of the Canary Islands, Ceuta and Melilla.
51
+ */
52
+ export const VAT_CATEGORIES = ['S', 'Z', 'E', 'AE', 'K', 'G', 'O', 'L', 'M'];
53
+ // ---------------------------------------------------------------------------
54
+ // The schema
55
+ // ---------------------------------------------------------------------------
56
+ const TEXT = (description) => ({ type: 'string', description });
57
+ const DECIMAL = (description) => TEXT(`${description} Digits, a dot for the decimals, a leading minus where printed; no grouping, no currency sign. Empty if not printed.`);
58
+ const DAY = (description) => TEXT(`${description} YYYY-MM-DD, or empty if not printed.`);
59
+ function object(properties, description) {
60
+ return {
61
+ type: 'object',
62
+ ...(description === undefined ? {} : { description }),
63
+ additionalProperties: false,
64
+ required: Object.keys(properties),
65
+ properties,
66
+ };
67
+ }
68
+ const CONFIDENCE = { type: 'string', enum: CONFIDENCES };
69
+ const PERIOD = (what) => object({ start: DAY(`First day of ${what}.`), end: DAY(`Last day of ${what}.`) }, `${what[0]?.toUpperCase()}${what.slice(1)}, as printed; both empty when none is printed.`);
70
+ const ADDRESS = object({
71
+ lines: { type: 'array', items: { type: 'string' }, description: 'The street lines, as printed, in order.' },
72
+ city: TEXT('As printed, or empty.'),
73
+ postal_code: TEXT('As printed, or empty.'),
74
+ country: TEXT('ISO 3166-1 alpha-2 code of the country printed in the address, or empty.'),
75
+ }, 'The postal address, as printed.');
76
+ const PARTY = (who) => object({
77
+ name: TEXT(`The legal name of ${who}, as printed.`),
78
+ trade_name: TEXT(`The name ${who} trades under, where printed beside the legal name; otherwise empty.`),
79
+ vat_id: TEXT(`The VAT identifier of ${who}, as printed, its country prefix included; empty if none is printed.`),
80
+ legal_id: TEXT(`The company registration number of ${who}, as printed; empty if none is printed.`),
81
+ tax_registration_id: TEXT(`A tax registration number of ${who} other than the VAT identifier, as printed; otherwise empty.`),
82
+ address: ADDRESS,
83
+ }, `${who[0]?.toUpperCase()}${who.slice(1)}.`);
84
+ const LINE = object({
85
+ name: TEXT('What the line bills, as printed.'),
86
+ description: TEXT('A further description printed on the line, or empty.'),
87
+ quantity: DECIMAL('The quantity, as printed.'),
88
+ unit: TEXT('The unit of the quantity, as printed (kWh, h, pcs…), or empty.'),
89
+ unit_code: TEXT('The UN/ECE Recommendation 20 code of that unit (KWH, HUR, C62…) where the printed unit names exactly one; otherwise empty.'),
90
+ net_price: DECIMAL('The price of one unit before VAT, as printed.'),
91
+ net_amount: DECIMAL('The amount of the line before VAT, as printed.'),
92
+ vat_category: TEXT('The VAT category of the line, an UNTDID 5305 code (S, Z, E, AE, K, G, O, L, M), where the page prints it or prints the words that name it; otherwise empty.'),
93
+ vat_rate: DECIMAL('The VAT rate of the line in percent, as printed.'),
94
+ period: PERIOD('the period this line bills'),
95
+ confidence: { ...CONFIDENCE, description: 'How sure you are of what you copied on this line.' },
96
+ });
97
+ const TAX = object({
98
+ category: TEXT('The VAT category of the group, an UNTDID 5305 code, where printed or named; otherwise empty.'),
99
+ rate: DECIMAL('The rate in percent.'),
100
+ base: DECIMAL('The amount the tax is computed on, at that rate.'),
101
+ tax: DECIMAL('The tax at that rate.'),
102
+ amount_including_tax: DECIMAL('The amount including tax at that rate, where the page prints it.'),
103
+ exemption_reason: TEXT('The reason printed for a rate of zero or an exemption, or empty.'),
104
+ });
105
+ /**
106
+ * The JSON schema of the answer, as a structured output takes it: every
107
+ * object closed, every property required and answered — with an empty text,
108
+ * an empty list — where the page does not print it.
109
+ */
110
+ export function readingSchema(extension) {
111
+ const properties = {
112
+ document: {
113
+ type: 'string',
114
+ enum: ['invoice', 'credit_note', 'receipt', 'other'],
115
+ description: 'invoice: a supplier asks to be paid. credit_note: it gives money back. receipt: what was bought and already paid, a till receipt. other: anything else.',
116
+ },
117
+ number: TEXT('The number of the invoice, credit note or receipt, as printed; empty if none is printed.'),
118
+ issue_date: DAY('The date the document was issued.'),
119
+ due_date: DAY('The date payment is due, where printed.'),
120
+ tax_point_date: DAY('The date the tax falls due, where printed apart from the issue date.'),
121
+ currency: TEXT('The ISO 4217 code of the currency the amounts are in, where the page prints the code, the symbol or the name of one currency only; empty otherwise. Never the currency of a country the page is from.'),
122
+ seller: PARTY('the supplier who issued the document'),
123
+ buyer: PARTY('the customer the document is addressed to'),
124
+ buyer_reference: TEXT('A reference of the customer printed for its own use (customer number, account number), or empty.'),
125
+ order_reference: TEXT('The purchase order the document refers to, as printed, or empty.'),
126
+ contract_reference: TEXT('The contract the document refers to, as printed, or empty.'),
127
+ preceding_invoice: TEXT('On a credit note, the number of the invoice it corrects, as printed; otherwise empty.'),
128
+ invoicing_period: PERIOD('the period the whole document bills'),
129
+ payment: object({
130
+ iban: TEXT('The account to pay to, as printed, spaces removed, or empty.'),
131
+ bic: TEXT('The BIC of that account, as printed, or empty.'),
132
+ reference: TEXT('The reference to quote when paying, as printed, or empty.'),
133
+ terms: TEXT('The terms of payment, as printed, or empty.'),
134
+ }, 'How the supplier asks to be paid.'),
135
+ lines: {
136
+ type: 'array',
137
+ description: 'One entry per line the page prints, in order; empty when it prints none.',
138
+ items: LINE,
139
+ },
140
+ taxes: {
141
+ type: 'array',
142
+ description: 'One entry per VAT rate the page prints in its tax summary, in order; empty when it prints none.',
143
+ items: TAX,
144
+ },
145
+ totals: object({
146
+ line_total: DECIMAL('The sum of the lines, where printed.'),
147
+ tax_exclusive: DECIMAL('The total without VAT.'),
148
+ tax_total: DECIMAL('The total VAT.'),
149
+ tax_inclusive: DECIMAL('The total with VAT.'),
150
+ prepaid: DECIMAL('What was already paid, where printed.'),
151
+ payable: DECIMAL('The amount still to pay.'),
152
+ }, 'The totals the page prints.'),
153
+ confidence: object(Object.fromEntries(CONFIDENCE_FIELDS.map((field) => [field, CONFIDENCE])), 'How sure you are of what you copied into each field: high, medium, low.'),
154
+ };
155
+ if (extension !== undefined) {
156
+ properties['extension'] = {
157
+ type: 'object',
158
+ additionalProperties: false,
159
+ required: extension.required ?? Object.keys(extension.properties),
160
+ properties: extension.properties,
161
+ };
162
+ }
163
+ return object(properties);
164
+ }
165
+ /** The words that go with the schema. Nothing in them names a country, a currency or a language. */
166
+ export const READING_PROMPT = `You read one purchase document for a company's books: an invoice, a credit note or a receipt, as a photograph or a PDF. Answer with what is printed on it, in the JSON format required.
167
+
168
+ Copy, never compute. Every amount, quantity, price and rate is the one printed, with a dot as the decimal separator, no grouping and no currency sign. Never add, multiply, convert or round a figure, and never fill a total from its parts: a total that is not printed stays empty.
169
+
170
+ Leave empty rather than guess. A field the page does not print is an empty text or an empty list. The currency is the one the page prints by code, symbol or name; when it prints none, or a symbol several currencies share, leave it empty. A code (a country, a unit, a VAT category) is given only where the page prints it or prints words that name exactly one.
171
+
172
+ Dates are YYYY-MM-DD. Give one entry in lines per line printed, with its own period where it prints one, and one entry in taxes per rate of the tax summary. For each field of confidence, say how sure you are of what you copied there.
173
+
174
+ If the page is not a purchase document, answer document "other" and leave every other field empty.`;
175
+ /** The words, with the caller's own instructions for its extension after them. */
176
+ export function readingPrompt(extension) {
177
+ const more = extension?.instructions?.trim();
178
+ return more === undefined || more.length === 0
179
+ ? READING_PROMPT
180
+ : `${READING_PROMPT}\n\nThe field extension is asked for by the caller:\n${more}`;
181
+ }
182
+ const MAX_LINES = 500;
183
+ const MAX_TAXES = 20;
184
+ const bag = (value) => (value !== null && typeof value === 'object' && !Array.isArray(value) ? value : {});
185
+ const list = (value, max) => (Array.isArray(value) ? value.slice(0, max).map(bag) : []);
186
+ /** The checker of one answer: what it rejects is remembered by path. */
187
+ class Checker {
188
+ rejected = [];
189
+ text(value, max = 300) {
190
+ if (typeof value !== 'string')
191
+ return null;
192
+ const kept = value.replace(/\s+/g, ' ').trim().slice(0, max);
193
+ return kept.length === 0 ? null : kept;
194
+ }
195
+ /** A decimal as printed: blanks removed, a lone comma read as the decimal separator; anything else rejected. */
196
+ decimal(value, path) {
197
+ const raw = this.text(value, 40);
198
+ if (raw === null)
199
+ return null;
200
+ const compact = raw.replace(/[\s  ]/g, '').replace(/^(-?\d+),(\d+)$/, '$1.$2');
201
+ if (/^-?\d{1,15}(\.\d{1,8})?$/.test(compact))
202
+ return compact;
203
+ this.rejected.push(path);
204
+ return null;
205
+ }
206
+ day(value, path) {
207
+ const raw = this.text(value, 40);
208
+ if (raw === null)
209
+ return null;
210
+ if (/^\d{4}-\d{2}-\d{2}$/.test(raw) && new Date(`${raw}T00:00:00Z`).toISOString().startsWith(raw))
211
+ return raw;
212
+ this.rejected.push(path);
213
+ return null;
214
+ }
215
+ code(value, path, shape) {
216
+ const raw = this.text(value, 40);
217
+ if (raw === null)
218
+ return null;
219
+ const upper = raw.toUpperCase();
220
+ if (shape.test(upper))
221
+ return upper;
222
+ this.rejected.push(path);
223
+ return null;
224
+ }
225
+ category(value, path) {
226
+ const code = this.code(value, path, /^[A-Z]{1,2}$/);
227
+ if (code === null || VAT_CATEGORIES.includes(code))
228
+ return code;
229
+ this.rejected.push(path);
230
+ return null;
231
+ }
232
+ period(value, path) {
233
+ const read = bag(value);
234
+ const start = this.day(read['start'], `${path}.start`);
235
+ const end = this.day(read['end'], `${path}.end`);
236
+ return start === null && end === null ? null : { start, end };
237
+ }
238
+ }
239
+ function addressOf(check, value, path) {
240
+ const read = bag(value);
241
+ const lines = (Array.isArray(read['lines']) ? read['lines'] : [])
242
+ .slice(0, 5)
243
+ .map((line) => check.text(line))
244
+ .filter((line) => line !== null);
245
+ const address = {
246
+ lines,
247
+ city: check.text(read['city'], 100),
248
+ postalCode: check.text(read['postal_code'], 20),
249
+ region: null,
250
+ country: check.code(read['country'], `${path}.country`, /^[A-Z]{2}$/),
251
+ };
252
+ return lines.length === 0 && address.city === null && address.postalCode === null && address.country === null ? null : address;
253
+ }
254
+ function partyOf(check, value, path) {
255
+ const read = bag(value);
256
+ const legal = check.text(read['legal_id'], 60);
257
+ return {
258
+ name: check.text(read['name'], 200),
259
+ tradeName: check.text(read['trade_name'], 200),
260
+ identifiers: [],
261
+ legalId: legal === null ? null : { value: legal, scheme: null },
262
+ vatId: check.text(read['vat_id'], 40)?.replace(/[\s.]/g, '') ?? null,
263
+ taxRegistrationId: check.text(read['tax_registration_id'], 60),
264
+ legalForm: null,
265
+ electronicAddress: null,
266
+ address: addressOf(check, read['address'], `${path}.address`),
267
+ contact: null,
268
+ };
269
+ }
270
+ function confidenceOf(value) {
271
+ return typeof value === 'string' && CONFIDENCES.includes(value) ? value : null;
272
+ }
273
+ /**
274
+ * The model's answer, parsed from its JSON, checked into a `ReceivedInvoice`.
275
+ *
276
+ * Anything not of the shape the schema asks for is left empty and named in
277
+ * `rejected`; anything EN 16931 requires and the answer leaves empty is `''`
278
+ * and named in `missing`. Nothing is computed, defaulted or corrected.
279
+ * `undefined` where the answer is not an object, or says the page is not a
280
+ * purchase document.
281
+ */
282
+ export function readingOf(answer) {
283
+ if (answer === null || typeof answer !== 'object' || Array.isArray(answer))
284
+ return undefined;
285
+ const read = answer;
286
+ const document = read['document'];
287
+ if (document !== 'invoice' && document !== 'credit_note' && document !== 'receipt')
288
+ return undefined;
289
+ const check = new Checker();
290
+ const missing = [];
291
+ const required = (value, path) => {
292
+ if (value !== null)
293
+ return value;
294
+ missing.push(path);
295
+ return '';
296
+ };
297
+ const lines = list(read['lines'], MAX_LINES).map((line, index) => {
298
+ const path = `lines[${index}]`;
299
+ const printedUnit = check.text(line['unit'], 20);
300
+ const unitCode = check.code(line['unit_code'], `${path}.unit_code`, /^[A-Z0-9]{2,3}$/) ??
301
+ (printedUnit === null ? null : knownUnit(printedUnit));
302
+ return {
303
+ id: String(index + 1),
304
+ note: null,
305
+ quantity: check.decimal(line['quantity'], `${path}.quantity`),
306
+ unitCode,
307
+ netAmount: required(check.decimal(line['net_amount'], `${path}.net_amount`), `${path}.net_amount`),
308
+ orderLineReference: null,
309
+ period: check.period(line['period'], `${path}.period`),
310
+ allowances: [],
311
+ netPrice: check.decimal(line['net_price'], `${path}.net_price`),
312
+ priceDiscount: null,
313
+ grossPrice: null,
314
+ priceBaseQuantity: null,
315
+ priceBaseUnitCode: null,
316
+ vatCategory: check.category(line['vat_category'], `${path}.vat_category`),
317
+ vatRate: check.decimal(line['vat_rate'], `${path}.vat_rate`),
318
+ name: check.text(line['name']),
319
+ description: check.text(line['description'], 1000),
320
+ sellerItemId: null,
321
+ buyerItemId: null,
322
+ standardItemId: null,
323
+ };
324
+ });
325
+ const printedTaxes = list(read['taxes'], MAX_TAXES);
326
+ const taxes = printedTaxes.map((tax, index) => {
327
+ const path = `taxes[${index}]`;
328
+ return {
329
+ category: check.category(tax['category'], `${path}.category`),
330
+ rate: check.decimal(tax['rate'], `${path}.rate`),
331
+ base: required(check.decimal(tax['base'], `${path}.base`), `${path}.base`),
332
+ tax: required(check.decimal(tax['tax'], `${path}.tax`), `${path}.tax`),
333
+ exemptionReasonCode: null,
334
+ exemptionReason: check.text(tax['exemption_reason']),
335
+ };
336
+ });
337
+ const taxInclusiveByGroup = printedTaxes.map((tax, index) => check.decimal(tax['amount_including_tax'], `taxes[${index}].amount_including_tax`));
338
+ const totals = bag(read['totals']);
339
+ const payment = bag(read['payment']);
340
+ const iban = check.text(payment['iban'], 40)?.replace(/\s/g, '').toUpperCase() ?? null;
341
+ const bic = check.code(payment['bic'], 'payment.bic', /^[A-Z0-9]{8}([A-Z0-9]{3})?$/);
342
+ const paymentReference = check.text(payment['reference'], 140);
343
+ const paymentMeans = iban === null && bic === null && paymentReference === null
344
+ ? []
345
+ : [
346
+ {
347
+ code: null,
348
+ text: null,
349
+ reference: paymentReference,
350
+ account: iban === null ? null : isValidIban(iban) ? { kind: 'iban', value: iban } : { kind: 'other', value: iban },
351
+ accountName: null,
352
+ bic,
353
+ cardNumber: null,
354
+ mandateReference: null,
355
+ debitedAccount: null,
356
+ },
357
+ ];
358
+ const preceding = check.text(read['preceding_invoice'], 60);
359
+ const invoice = {
360
+ syntax: 'model',
361
+ customizationId: null,
362
+ profileId: null,
363
+ kind: document === 'credit_note' ? 'credit_note' : 'invoice',
364
+ typeCode: null,
365
+ number: required(check.text(read['number'], 60), 'number'),
366
+ issueDate: required(check.day(read['issue_date'], 'issue_date'), 'issue_date'),
367
+ dueDate: check.day(read['due_date'], 'due_date'),
368
+ taxPointDate: check.day(read['tax_point_date'], 'tax_point_date'),
369
+ currency: required(check.code(read['currency'], 'currency', /^[A-Z]{3}$/), 'currency'),
370
+ taxCurrency: null,
371
+ buyerReference: check.text(read['buyer_reference'], 100),
372
+ orderReference: check.text(read['order_reference'], 100),
373
+ salesOrderReference: null,
374
+ contractReference: check.text(read['contract_reference'], 100),
375
+ projectReference: null,
376
+ accountingCost: null,
377
+ precedingInvoices: preceding === null ? [] : [{ number: preceding, issueDate: null }],
378
+ notes: [],
379
+ seller: partyOf(check, read['seller'], 'seller'),
380
+ buyer: partyOf(check, read['buyer'], 'buyer'),
381
+ deliveryDate: null,
382
+ deliveryAddress: null,
383
+ invoicingPeriod: check.period(read['invoicing_period'], 'invoicing_period'),
384
+ paymentTerms: check.text(payment['terms'], 500),
385
+ paymentMeans,
386
+ allowances: [],
387
+ taxes,
388
+ totals: {
389
+ lineTotal: check.decimal(totals['line_total'], 'totals.line_total'),
390
+ allowanceTotal: null,
391
+ chargeTotal: null,
392
+ taxExclusive: required(check.decimal(totals['tax_exclusive'], 'totals.tax_exclusive'), 'totals.tax_exclusive'),
393
+ taxTotal: check.decimal(totals['tax_total'], 'totals.tax_total'),
394
+ taxTotalInTaxCurrency: null,
395
+ taxInclusive: required(check.decimal(totals['tax_inclusive'], 'totals.tax_inclusive'), 'totals.tax_inclusive'),
396
+ prepaid: check.decimal(totals['prepaid'], 'totals.prepaid'),
397
+ rounding: null,
398
+ payable: required(check.decimal(totals['payable'], 'totals.payable'), 'totals.payable'),
399
+ },
400
+ lines,
401
+ attachments: [],
402
+ };
403
+ if (invoice.seller.name === null && invoice.seller.tradeName === null)
404
+ missing.push('seller.name');
405
+ const figures = ['totals.tax_exclusive', 'totals.tax_inclusive', 'totals.payable', 'lines[', 'taxes['];
406
+ const complete = !missing.some((path) => figures.some((figure) => path.startsWith(figure)));
407
+ const said = bag(read['confidence']);
408
+ const confidence = Object.fromEntries(CONFIDENCE_FIELDS.map((field) => [field, confidenceOf(said[field])]));
409
+ list(read['lines'], MAX_LINES).forEach((line, index) => {
410
+ confidence[`lines[${index}]`] = confidenceOf(line['confidence']);
411
+ });
412
+ const extension = read['extension'];
413
+ return {
414
+ document,
415
+ invoice,
416
+ violations: complete ? checkReceived(invoice) : [],
417
+ missing,
418
+ rejected: check.rejected,
419
+ confidence,
420
+ taxInclusiveByGroup,
421
+ extension: extension !== null && typeof extension === 'object' ? extension : null,
422
+ };
423
+ }
424
+ /**
425
+ * The UN/ECE code of a printed unit, where the list of words of
426
+ * `@ekwo-ai/factur-x` knows it; null where it does not, rather than the
427
+ * `C62` that list falls back to — and so null for a printed "unit" too,
428
+ * which the model is asked to code itself.
429
+ */
430
+ function knownUnit(printed) {
431
+ const code = toUnitCode(printed);
432
+ return code === 'C62' ? null : code;
433
+ }
434
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * The purchase a received invoice becomes, before anybody's books are read.
3
+ *
4
+ * Whichever way the invoice was read — a Factur-X file, a UBL message, a
5
+ * photograph read by a model — it is one `ReceivedInvoice`, and this file
6
+ * turns it into the draft of a purchase document in the columns of Ekwo OS
7
+ * (`documents`, `document_lines`): the fields a caller passes to
8
+ * `create_document` once it has chosen, in its own books, the supplier, the
9
+ * account and the tax. Those three choices need the books and the country
10
+ * pack, so they are not made here; the draft carries what they are made
11
+ * from — the supplier as the invoice names it, and each line's VAT category
12
+ * and rate.
13
+ *
14
+ * What the core has a column for goes in that column: the unit code of a
15
+ * line, the supplier's invoice number, the references, the due date, the
16
+ * tax point. What it has none for and EN 16931 carries on a line — the period
17
+ * a line bills (BG-26) — goes in the line's `attributes`, which hold "what an
18
+ * electronic invoice format asks of this line that no other column says".
19
+ * The period of the whole invoice (BG-14) has no column on a document: each
20
+ * line that states no period of its own takes it, which is what EN 16931
21
+ * means by it, and the draft returns it as well for whoever keeps it beside
22
+ * the document.
23
+ *
24
+ * Nothing is defaulted: no currency, no date, no name. Where the invoice is
25
+ * silent the draft is silent, and the caller asks, or fills in its own.
26
+ */
27
+ import type { DecimalText, ReceivedInvoice } from '@ekwo-ai/factur-x';
28
+ /** A period as EN 16931 carries it: either end may be unknown. */
29
+ export interface Period {
30
+ start: string | null;
31
+ end: string | null;
32
+ }
33
+ /**
34
+ * The names under which a line's `attributes` carry what no column of
35
+ * `document_lines` holds. The period is BT-134 and BT-135; the three
36
+ * `invoiced_*` keep the invoice's own quantity, unit and price where the
37
+ * line had to be written as one unit at its amount (see `PurchaseDraftLine`).
38
+ */
39
+ export declare const LINE_ATTRIBUTES: {
40
+ readonly periodStart: "period_start";
41
+ readonly periodEnd: "period_end";
42
+ readonly invoicedQuantity: "invoiced_quantity";
43
+ readonly invoicedUnitCode: "invoiced_unit_code";
44
+ readonly invoicedNetPrice: "invoiced_net_price";
45
+ };
46
+ /** One line of the draft, in the fields of `document_lines` (`LineArgs` of `@ekwo-ai/core`). */
47
+ export interface PurchaseDraftLine {
48
+ /** BT-153, else BT-154, else BT-127; null where the invoice names nothing, for the caller to name. */
49
+ name: string | null;
50
+ /** BT-154, where it is beside a name. */
51
+ description: string | null;
52
+ /**
53
+ * The invoice's quantity, unit code and net price where they make the
54
+ * line's amount at the decimals of its currency, as `document_lines`
55
+ * computes `amount_untaxed`; otherwise one unit (`C62`) at the line's
56
+ * amount, the invoice's own figures kept in `attributes`.
57
+ */
58
+ quantity: DecimalText;
59
+ unit_code: string;
60
+ unit_price: DecimalText;
61
+ /** BT-151 and BT-152, from which the caller chooses the tax of its own pack. */
62
+ vat_category: string | null;
63
+ vat_rate: DecimalText | null;
64
+ /** What `document_lines.attributes` keeps that no column holds; see `LINE_ATTRIBUTES`. */
65
+ attributes: Record<string, string>;
66
+ }
67
+ /** The draft of a purchase document, in the fields of `documents`. */
68
+ export interface PurchaseDraft {
69
+ doc_type: 'purchase_invoice' | 'purchase_credit_note';
70
+ /** BT-2; null where it was not read. */
71
+ document_date: string | null;
72
+ /** BT-9. */
73
+ due_date: string | null;
74
+ /** BT-7. */
75
+ tax_point_date: string | null;
76
+ /** BT-1: the supplier's own number. */
77
+ supplier_reference: string | null;
78
+ /** BT-5, as the invoice says it; null where it was not read, never the company's. */
79
+ currency_code: string | null;
80
+ buyer_reference: string | null;
81
+ order_reference: string | null;
82
+ contract_reference: string | null;
83
+ project_reference: string | null;
84
+ delivery_date: string | null;
85
+ payment_terms: string | null;
86
+ payment_reference: string | null;
87
+ /** BT-84 where it is an IBAN. */
88
+ payee_iban: string | null;
89
+ /** BG-14. No column of `documents` holds it: it is on each line without a period of its own, and here. */
90
+ invoicing_period: Period | null;
91
+ /** The supplier as the invoice names it, for the caller to find among its contacts or to add. */
92
+ supplier: {
93
+ name: string | null;
94
+ trade_name: string | null;
95
+ vat_id: string | null;
96
+ legal_id: string | null;
97
+ country: string | null;
98
+ };
99
+ /** BT-112 and BT-115, as the invoice says them. */
100
+ total: DecimalText | null;
101
+ payable: DecimalText | null;
102
+ /** One per line of the invoice, then one per allowance or charge of the whole document. */
103
+ lines: PurchaseDraftLine[];
104
+ }
105
+ /** The decimals a currency is written with, as the platform's `Intl` knows it; null for a code it does not know. */
106
+ export declare function currencyDigits(currency: string): number | null;
107
+ /**
108
+ * Whether `quantity × price`, rounded half up on its absolute value at
109
+ * `digits` decimals — the rounding of `document_lines.amount_untaxed` — is
110
+ * `amount`.
111
+ */
112
+ export declare function makesAmount(quantity: string, price: string, amount: string, digits: number): boolean;
113
+ /**
114
+ * The draft of the purchase a received invoice becomes.
115
+ *
116
+ * One line per line of the invoice, its amount net of the line's own
117
+ * allowances; then one line per allowance (negative) or charge of the whole
118
+ * document. A credit note is a purchase credit note, its figures positive as
119
+ * the invoice writes them. Where the currency was not read, amounts are
120
+ * compared at the decimals the invoice wrote them with.
121
+ */
122
+ export declare function purchaseDraftOf(invoice: ReceivedInvoice): PurchaseDraft;
123
+ //# sourceMappingURL=purchase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purchase.d.ts","sourceRoot":"","sources":["../src/purchase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAA2B,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAE7G,kEAAkE;AAClE,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;;CAMlB,CAAC;AAEX,gGAAgG;AAChG,MAAM,WAAW,iBAAiB;IAChC,sGAAsG;IACtG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,WAAW,CAAC;IACxB,gFAAgF;IAChF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,0FAA0F;IAC1F,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,kBAAkB,GAAG,sBAAsB,CAAC;IACtD,wCAAwC;IACxC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY;IACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uCAAuC;IACvC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qFAAqF;IACrF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iCAAiC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0GAA0G;IAC1G,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iGAAiG;IACjG,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;IACF,mDAAmD;IACnD,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,2FAA2F;IAC3F,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAKD,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9D;AAWD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAmBpG;AAiDD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa,CAyCvE"}