mindee 1.0.2 → 1.0.7

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 (43) hide show
  1. package/CHANGELOG.md +36 -5
  2. package/README.md +11 -8
  3. package/examples/documents/invoices/credit_note.pdf +899 -1
  4. package/examples/financialDocument.js +2 -2
  5. package/examples/invoice.js +21 -4
  6. package/examples/receipt.js +3 -3
  7. package/lib/api/financialDocument.js +12 -8
  8. package/lib/api/invoice.js +28 -9
  9. package/lib/api/receipt.js +13 -9
  10. package/lib/api/request.js +1 -5
  11. package/lib/documents/document.js +4 -2
  12. package/lib/documents/fields/amount.js +1 -1
  13. package/lib/documents/fields/date.js +1 -1
  14. package/lib/documents/fields/locale.js +1 -1
  15. package/lib/documents/fields/orientation.js +1 -1
  16. package/lib/documents/fields/paymentDetails.js +1 -1
  17. package/lib/documents/fields/tax.js +1 -1
  18. package/lib/inputs.js +52 -4
  19. package/mindee/api/financialDocument.js +40 -0
  20. package/mindee/api/index.js +5 -0
  21. package/mindee/api/invoice.js +48 -0
  22. package/mindee/api/object.js +82 -0
  23. package/mindee/api/receipt.js +34 -0
  24. package/mindee/api/request.js +63 -0
  25. package/mindee/api/response.js +62 -0
  26. package/mindee/documents/document.js +65 -0
  27. package/mindee/documents/fields/amount.js +25 -0
  28. package/mindee/documents/fields/date.js +29 -0
  29. package/mindee/documents/fields/field.js +89 -0
  30. package/mindee/documents/fields/index.js +7 -0
  31. package/mindee/documents/fields/locale.js +30 -0
  32. package/mindee/documents/fields/orientation.js +24 -0
  33. package/mindee/documents/fields/paymentDetails.js +52 -0
  34. package/mindee/documents/fields/tax.js +47 -0
  35. package/mindee/documents/financialDocument.js +204 -0
  36. package/mindee/documents/index.js +5 -0
  37. package/mindee/documents/invoice.js +395 -0
  38. package/mindee/documents/receipt.js +272 -0
  39. package/mindee/errors/handler.js +16 -0
  40. package/mindee/index.js +35 -0
  41. package/mindee/inputs.js +155 -0
  42. package/mindee/logger.js +33 -0
  43. package/package.json +12 -7
@@ -0,0 +1,204 @@
1
+ const Document = require("./document");
2
+ const Invoice = require("./invoice");
3
+ const Receipt = require("./receipt");
4
+ const Field = require("./fields").field;
5
+ const Date = require("./fields").date;
6
+ const Amount = require("./fields").amount;
7
+ const Locale = require("./fields").locale;
8
+ const Orientation = require("./fields").orientation;
9
+ const Tax = require("./fields").tax;
10
+
11
+ class FinancialDocument extends Document {
12
+ /**
13
+ * @param {Object} apiPrediction - Json parsed prediction from HTTP response
14
+ * @param {Input} input - Input object
15
+ * @param {Integer} pageNumber - Page number for multi pages pdf input
16
+ * @param {Object} locale - locale value for creating FinancialDocument object from scratch
17
+ * @param {Object} totalIncl - total tax included value for creating FinancialDocument object from scratch
18
+ * @param {Object} totalExcl - total tax excluded value for creating FinancialDocument object from scratch
19
+ * @param {Object} Date - date value for creating FinancialDocument object from scratch
20
+ * @param {Object} InvoiceNumber - Invoice number value for creating FinancialDocument object from scratch
21
+ * @param {Object} taxes - taxes value for creating FinancialDocument object from scratch
22
+ * @param {Object} merchantName - merchant name value for creating FinancialDocument object from scratch
23
+ * @param {Object} paymentDetails - payment details value for creating FinancialDocument object from scratch
24
+ * @param {Object} companyNumber - company number value for creating FinancialDocument object from scratch
25
+ * @param {Object} vatNumber - vat number value for creating FinancialDocument object from scratch
26
+ * @param {Object} orientation - orientation value for creating FinancialDocument object from scratch
27
+ * @param {Object} totalTax - total tax value for creating FinancialDocument object from scratch
28
+ * @param {Object} time - time value for creating FinancialDocument object from scratch
29
+ * @param {Object} pageNumber - pageNumber for multi pages pdf input
30
+ */
31
+ constructor({
32
+ apiPrediction = undefined,
33
+ inputFile = undefined,
34
+ locale = undefined,
35
+ totalIncl = undefined,
36
+ totalExcl = undefined,
37
+ date = undefined,
38
+ invoiceNumber = undefined,
39
+ dueDate = undefined,
40
+ taxes = undefined,
41
+ merchantName = undefined,
42
+ paymentDetails = undefined,
43
+ companyNumber = undefined,
44
+ vatNumber = undefined,
45
+ orientation = undefined,
46
+ totalTax = undefined,
47
+ time = undefined,
48
+ pageNumber = 0,
49
+ }) {
50
+ super(inputFile);
51
+ if (apiPrediction === undefined) {
52
+ this.#initFromScratch({
53
+ locale,
54
+ totalIncl,
55
+ totalExcl,
56
+ date,
57
+ invoiceNumber,
58
+ dueDate,
59
+ taxes,
60
+ merchantName,
61
+ paymentDetails,
62
+ companyNumber,
63
+ vatNumber,
64
+ orientation,
65
+ pageNumber,
66
+ totalTax,
67
+ time,
68
+ });
69
+ } else {
70
+ this.#initFromApiPrediction(apiPrediction, inputFile, pageNumber);
71
+ }
72
+ this.#checklist();
73
+ }
74
+
75
+ #initFromScratch({
76
+ locale,
77
+ totalIncl,
78
+ totalExcl,
79
+ totalTax,
80
+ date,
81
+ invoiceNumber,
82
+ dueDate,
83
+ taxes,
84
+ paymentDetails,
85
+ companyNumber,
86
+ vatNumber,
87
+ orientation,
88
+ pageNumber,
89
+ merchantName,
90
+ time,
91
+ }) {
92
+ const constructPrediction = function (item) {
93
+ return { prediction: { value: item }, valueKey: "value", pageNumber };
94
+ };
95
+ this.locale = new Locale(constructPrediction(locale));
96
+ this.totalIncl = new Amount(constructPrediction(totalIncl));
97
+ this.totalExcl = new Amount(constructPrediction(totalExcl));
98
+ this.totalTax = new Amount(constructPrediction(totalTax));
99
+ this.date = new Date(constructPrediction(date));
100
+ this.dueDate = new Date(constructPrediction(dueDate));
101
+ this.merchantName = new Field(constructPrediction(merchantName));
102
+ this.time = new Field(constructPrediction(time));
103
+ this.orientation = new Orientation(constructPrediction(orientation));
104
+ this.invoiceNumber = new Field(constructPrediction(invoiceNumber));
105
+ this.paymentDetails = new Field(constructPrediction(paymentDetails));
106
+ this.companyNumber = new Field(constructPrediction(companyNumber));
107
+ this.vatNumber = new Field(constructPrediction(vatNumber));
108
+ if (taxes !== undefined) {
109
+ this.taxes = [];
110
+ for (const t of taxes) {
111
+ this.taxes.push(
112
+ new Tax({
113
+ prediction: { value: t[0], rate: t[1] },
114
+ pageNumber,
115
+ valueKey: "value",
116
+ rateKey: "rate",
117
+ })
118
+ );
119
+ }
120
+ }
121
+ }
122
+
123
+ #initFromApiPrediction(apiPrediction, inputFile, pageNumber) {
124
+ if (Object.keys(apiPrediction).includes("invoice_number")) {
125
+ const invoice = new Invoice({ apiPrediction, inputFile, pageNumber });
126
+ Object.assign(this, invoice);
127
+ this.time = new Field({
128
+ prediction: { value: undefined, probability: 0.0 },
129
+ });
130
+ this.merchantName = new Field({
131
+ prediction: { value: undefined, probability: 0.0 },
132
+ });
133
+ } else {
134
+ const receipt = new Receipt({ apiPrediction, inputFile, pageNumber });
135
+ Object.assign(this, receipt);
136
+ this.invoiceDate = new Field({
137
+ prediction: { value: undefined, probability: 0.0 },
138
+ });
139
+ this.invoiceNumber = new Field({
140
+ prediction: { value: undefined, probability: 0.0 },
141
+ });
142
+ this.dueDate = new Field({
143
+ prediction: { value: undefined, probability: 0.0 },
144
+ });
145
+ this.paymentDetails = new Field({
146
+ prediction: { value: undefined, probability: 0.0 },
147
+ });
148
+ this.companyNumber = new Field({
149
+ prediction: { value: undefined, probability: 0.0 },
150
+ });
151
+ }
152
+ }
153
+
154
+ toString() {
155
+ return `
156
+ -----Financial document-----
157
+ Filename: ${this.filename}
158
+ Total amount: ${this.totalIncl.value}
159
+ Date: ${this.date.value}
160
+ Merchant name: ${this.merchantName.value}
161
+ Total taxes: ${this.totalTax.value}
162
+ `;
163
+ }
164
+
165
+ #checklist() {
166
+ this.checklist = {
167
+ taxesMatchTotalIncl: this.#taxesMatchTotalIncl(),
168
+ };
169
+ }
170
+
171
+ #taxesMatchTotalIncl() {
172
+ // Check taxes and total include exist
173
+ if (this.taxes.length === 0 || this.totalIncl.value === undefined)
174
+ return false;
175
+
176
+ // Reconstruct totalIncl from taxes
177
+ let totalVat = 0;
178
+ let reconstructedTotal = 0;
179
+ this.taxes.forEach((tax) => {
180
+ if (tax.value === undefined || !tax.rate) return false;
181
+ totalVat += tax.value;
182
+ reconstructedTotal += tax.value + (100 * tax.value) / tax.rate;
183
+ });
184
+
185
+ // Sanity check
186
+ if (totalVat <= 0) return false;
187
+
188
+ // Crate epsilon
189
+ const eps = 1 / (100 * totalVat);
190
+
191
+ if (
192
+ this.totalIncl.value * (1 - eps) - 0.02 <= reconstructedTotal &&
193
+ reconstructedTotal <= this.totalIncl.value * (1 + eps) + 0.02
194
+ ) {
195
+ this.taxes = this.taxes.map((tax) => ({ ...tax, probability: 1.0 }));
196
+ this.totalTax.probability = 1.0;
197
+ this.totalIncl.probability = 1.0;
198
+ return true;
199
+ }
200
+ return false;
201
+ }
202
+ }
203
+
204
+ module.exports = FinancialDocument;
@@ -0,0 +1,5 @@
1
+ exports.fields = require("./fields");
2
+ exports.document = require("./document");
3
+ exports.receipt = require("./receipt");
4
+ exports.invoice = require("./invoice");
5
+ exports.financialDocument = require("./financialDocument");
@@ -0,0 +1,395 @@
1
+ const Document = require("./document");
2
+ const Field = require("./fields").field;
3
+ const Date = require("./fields").date;
4
+ const Amount = require("./fields").amount;
5
+ const Locale = require("./fields").locale;
6
+ const Orientation = require("./fields").orientation;
7
+ const PaymentDetails = require("./fields").paymentDetails;
8
+ const Tax = require("./fields").tax;
9
+
10
+ class Invoice extends Document {
11
+ /**
12
+ * @param {Object} apiPrediction - Json parsed prediction from HTTP response
13
+ * @param {Input} input - Input object
14
+ * @param {Integer} pageNumber - Page number for multi pages pdf input
15
+ * @param {Object} locale - locale value for creating Invoice object from scratch
16
+ * @param {Object} totalIncl - total tax included value for creating Invoice object from scratch
17
+ * @param {Object} totalExcl - total tax excluded value for creating Invoice object from scratch
18
+ * @param {Object} invoiceDate - invoice date value for creating Invoice object from scratch
19
+ * @param {Object} invoiceNumber - invoice number value for creating Invoice object from scratch
20
+ * @param {Object} taxes - taxes value for creating Invoice object from scratch
21
+ * @param {Object} supplier - supplier value for creating Invoice object from scratch
22
+ * @param {Object} paymentDetails - payment details value for creating Invoice object from scratch
23
+ * @param {Object} companyNumber - company number value for creating Invoice object from scratch
24
+ * @param {Object} vatNumber - vat number value for creating Invoice object from scratch
25
+ * @param {Object} orientation - orientation value for creating Invoice object from scratch
26
+ * @param {Object} totalTax - total tax value for creating Invoice object from scratch
27
+ * @param {Object} pageNumber - pageNumber for multi pages pdf input
28
+ */
29
+ constructor({
30
+ apiPrediction = undefined,
31
+ inputFile = undefined,
32
+ locale = undefined,
33
+ totalIncl = undefined,
34
+ totalExcl = undefined,
35
+ invoiceDate = undefined,
36
+ invoiceNumber = undefined,
37
+ dueDate = undefined,
38
+ taxes = undefined,
39
+ supplier = undefined,
40
+ paymentDetails = undefined,
41
+ companyNumber = undefined,
42
+ vatNumber = undefined,
43
+ orientation = undefined,
44
+ totalTax = undefined,
45
+ pageNumber = 0,
46
+ }) {
47
+ super(inputFile);
48
+ if (apiPrediction === undefined) {
49
+ this.#initFromScratch({
50
+ locale,
51
+ totalIncl,
52
+ totalExcl,
53
+ invoiceDate,
54
+ invoiceNumber,
55
+ dueDate,
56
+ taxes,
57
+ supplier,
58
+ paymentDetails,
59
+ companyNumber,
60
+ vatNumber,
61
+ orientation,
62
+ pageNumber,
63
+ totalTax,
64
+ });
65
+ } else {
66
+ this.#initFromApiPrediction(apiPrediction, pageNumber);
67
+ }
68
+ this.#checklist();
69
+ this.#reconstruct();
70
+ }
71
+
72
+ #initFromScratch({
73
+ locale,
74
+ totalIncl,
75
+ totalExcl,
76
+ totalTax,
77
+ invoiceDate,
78
+ invoiceNumber,
79
+ dueDate,
80
+ taxes,
81
+ supplier,
82
+ paymentDetails,
83
+ companyNumber,
84
+ vatNumber,
85
+ orientation,
86
+ pageNumber,
87
+ }) {
88
+ const constructPrediction = function (item) {
89
+ return { prediction: { value: item }, valueKey: "value", pageNumber };
90
+ };
91
+ this.locale = new Locale(constructPrediction(locale));
92
+ this.totalIncl = new Amount(constructPrediction(totalIncl));
93
+ this.totalExcl = new Amount(constructPrediction(totalExcl));
94
+ this.totalTax = new Amount(constructPrediction(totalTax));
95
+ this.date = new Date(constructPrediction(invoiceDate));
96
+ this.invoiceDate = new Date(constructPrediction(invoiceDate));
97
+ this.dueDate = new Date(constructPrediction(dueDate));
98
+ this.supplier = new Field(constructPrediction(supplier));
99
+ this.orientation = new Orientation(constructPrediction(orientation));
100
+ this.invoiceNumber = new Field(constructPrediction(invoiceNumber));
101
+ this.paymentDetails = new Field(constructPrediction(paymentDetails));
102
+ this.companyNumber = new Field(constructPrediction(companyNumber));
103
+ this.vatNumber = new Field(constructPrediction(vatNumber));
104
+ if (taxes !== undefined) {
105
+ this.taxes = [];
106
+ for (const t of taxes) {
107
+ this.taxes.push(
108
+ new Tax({
109
+ prediction: { value: t[0], rate: t[1] },
110
+ pageNumber,
111
+ valueKey: "value",
112
+ rateKey: "rate",
113
+ })
114
+ );
115
+ }
116
+ }
117
+ }
118
+
119
+ #initFromApiPrediction(apiPrediction, pageNumber) {
120
+ this.words = [];
121
+ this.locale = new Locale({ prediction: apiPrediction.locale, pageNumber });
122
+ this.totalIncl = new Amount({
123
+ prediction: apiPrediction.total_incl,
124
+ valueKey: "value",
125
+ pageNumber,
126
+ });
127
+ this.totalTax = new Amount({
128
+ prediction: { value: undefined, probability: 0.0 },
129
+ valueKey: "value",
130
+ pageNumber,
131
+ });
132
+ this.totalExcl = new Amount({
133
+ prediction: apiPrediction.total_excl,
134
+ valueKey: "value",
135
+ pageNumber,
136
+ });
137
+ this.date = new Date({
138
+ prediction: apiPrediction.date,
139
+ valueKey: "value",
140
+ pageNumber,
141
+ });
142
+ this.invoiceDate = new Date({
143
+ prediction: apiPrediction.date,
144
+ valueKey: "value",
145
+ pageNumber,
146
+ });
147
+ this.taxes = apiPrediction.taxes.map(function (taxPrediction) {
148
+ return new Tax({
149
+ prediction: taxPrediction,
150
+ pageNumber,
151
+ valueKey: "value",
152
+ rateKey: "rate",
153
+ codeKey: "code",
154
+ });
155
+ });
156
+ this.orientation = new Orientation({
157
+ prediction: apiPrediction.orientation,
158
+ pageNumber,
159
+ });
160
+ this.companyNumber = apiPrediction.company_registration.map(function (
161
+ companyNumber
162
+ ) {
163
+ return new Field({
164
+ prediction: companyNumber,
165
+ pageNumber,
166
+ extraFields: ["type"],
167
+ });
168
+ });
169
+ this.dueDate = new Date({
170
+ prediction: apiPrediction.due_date,
171
+ valueKey: "value",
172
+ pageNumber,
173
+ });
174
+ this.invoiceNumber = new Field({
175
+ prediction: apiPrediction.invoice_number,
176
+ pageNumber,
177
+ });
178
+ this.supplier = new Field({
179
+ prediction: apiPrediction.supplier,
180
+ pageNumber,
181
+ });
182
+ this.paymentDetails = apiPrediction.payment_details.map(function (
183
+ paymentDetail
184
+ ) {
185
+ return new PaymentDetails({ prediction: paymentDetail, pageNumber });
186
+ });
187
+
188
+ if ("mvision" in apiPrediction) this.words = apiPrediction.mvision;
189
+ }
190
+
191
+ toString() {
192
+ return `
193
+ -----Invoice data-----
194
+ Filename: ${this.filename}
195
+ Invoice number: ${this.invoiceNumber.value}
196
+ Total amount including taxes: ${this.totalIncl.value}
197
+ Total amount excluding taxes: ${this.totalExcl.value}
198
+ Invoice Date: ${this.invoiceDate.value}
199
+ Supplier name: ${this.supplier.value}
200
+ Taxes: ${this.taxes.map((tax) => tax.toString()).join(" - ")}
201
+ Total taxes: ${this.totalTax.value}
202
+ `;
203
+ }
204
+
205
+ #checklist() {
206
+ this.checklist = {
207
+ taxesMatchTotalIncl: this.#taxesMatchTotalIncl(),
208
+ taxesMatchTotalExcl: this.#taxesMatchTotalExcl(),
209
+ taxesPlusTotalExclMatchTotalIncl: this.#taxesPlusTotalExclMatchTotalIncl(),
210
+ };
211
+ }
212
+
213
+ #reconstruct() {
214
+ this.#reconstructTotalTax();
215
+ this.#reconstructTotalExcl();
216
+ this.#reconstructTotalIncl();
217
+ this.#reconstructTotalTaxFromTotals();
218
+ }
219
+
220
+ #taxesMatchTotalIncl() {
221
+ // Check taxes and total include exist
222
+ if (this.taxes.length === 0 || this.totalIncl.value === undefined)
223
+ return false;
224
+
225
+ // Reconstruct totalIncl from taxes
226
+ let totalVat = 0;
227
+ let reconstructedTotal = 0;
228
+ this.taxes.forEach((tax) => {
229
+ if (tax.value === undefined || !tax.rate) return false;
230
+ totalVat += tax.value;
231
+ reconstructedTotal += tax.value + (100 * tax.value) / tax.rate;
232
+ });
233
+
234
+ // Sanity check
235
+ if (totalVat <= 0) return false;
236
+
237
+ // Crate epsilon
238
+ const eps = 1 / (100 * totalVat);
239
+
240
+ if (
241
+ this.totalIncl.value * (1 - eps) - 0.02 <= reconstructedTotal &&
242
+ reconstructedTotal <= this.totalIncl.value * (1 + eps) + 0.02
243
+ ) {
244
+ this.taxes = this.taxes.map((tax) => ({ ...tax, probability: 1.0 }));
245
+ this.totalTax.probability = 1.0;
246
+ this.totalIncl.probability = 1.0;
247
+ return true;
248
+ }
249
+ return false;
250
+ }
251
+
252
+ /**
253
+ *
254
+ */
255
+ #taxesMatchTotalExcl() {
256
+ // Check taxes and total amount exist
257
+ if (this.taxes.length === 0 || this.totalExcl.value == null) return false;
258
+
259
+ // Reconstruct total_incl from taxes
260
+ let totalVat = 0;
261
+ let reconstructedTotal = 0;
262
+ this.taxes.forEach((tax) => {
263
+ if (tax.value == null || !tax.rate) return false;
264
+ totalVat += tax.value;
265
+ reconstructedTotal += (100 * tax.value) / tax.rate;
266
+ });
267
+
268
+ // Sanity check
269
+ if (totalVat <= 0) return false;
270
+
271
+ // Crate epsilon
272
+ const eps = 1 / (100 * totalVat);
273
+
274
+ if (
275
+ this.totalExcl.value * (1 - eps) - 0.02 <= reconstructedTotal &&
276
+ reconstructedTotal <= this.totalExcl.value * (1 + eps) + 0.02
277
+ ) {
278
+ this.taxes = this.taxes.map((tax) => ({ ...tax, probability: 1.0 }));
279
+ this.totalTax.probability = 1.0;
280
+ this.totalExcl.probability = 1.0;
281
+ return true;
282
+ }
283
+ return false;
284
+ }
285
+
286
+ #taxesPlusTotalExclMatchTotalIncl() {
287
+ if (
288
+ this.totalExcl.value === undefined ||
289
+ this.taxes.length == 0 ||
290
+ this.totalIncl === undefined
291
+ )
292
+ return false;
293
+ let totalVat = 0;
294
+ this.taxes.forEach((tax) => (totalVat += tax.value));
295
+ const reconstructedTotal = totalVat + this.totalExcl.value;
296
+
297
+ if (totalVat <= 0) return false;
298
+
299
+ if (
300
+ this.totalIncl.value - 0.01 <= reconstructedTotal &&
301
+ reconstructedTotal <= this.totalIncl.value + 0.01
302
+ ) {
303
+ this.taxes = this.taxes.map((tax) => ({ ...tax, probability: 1.0 }));
304
+ this.totalTax.probability = 1.0;
305
+ this.totalIncl.probability = 1.0;
306
+ return true;
307
+ }
308
+ return false;
309
+ }
310
+
311
+ #reconstructTotalTax() {
312
+ if (this.taxes.length > 0) {
313
+ const totalTax = {
314
+ value: this.taxes.reduce((acc, tax) => {
315
+ return tax.value !== undefined ? acc + tax.value : acc;
316
+ }, 0),
317
+ probability: Field.arrayProbability(this.taxes),
318
+ };
319
+ if (totalTax.value > 0)
320
+ this.totalTax = new Amount({
321
+ prediction: totalTax,
322
+ valueKey: "value",
323
+ reconstructed: true,
324
+ });
325
+ }
326
+ }
327
+
328
+ #reconstructTotalTaxFromTotals() {
329
+ if (
330
+ this.totalTax.value === undefined &&
331
+ this.totalIncl.value > 0 &&
332
+ this.totalExcl.value > 0 &&
333
+ this.totalExcl.value <= this.totalIncl.value
334
+ ) {
335
+ const totalTax = {
336
+ value: this.totalIncl.value - this.totalExcl.value,
337
+ probability: this.totalIncl.probability * this.totalExcl.probability,
338
+ };
339
+ if (totalTax.value > 0)
340
+ this.totalTax = new Amount({
341
+ prediction: totalTax,
342
+ valueKey: "value",
343
+ reconstructed: true,
344
+ });
345
+ }
346
+ }
347
+
348
+ #reconstructTotalExcl() {
349
+ if (
350
+ this.taxes.length &&
351
+ this.totalIncl.value != null &&
352
+ this.totalExcl.value === undefined
353
+ ) {
354
+ const totalExcl = {
355
+ value:
356
+ this.totalIncl.value -
357
+ this.taxes.reduce((acc, tax) => {
358
+ return tax.value !== undefined ? acc + tax.value : acc;
359
+ }, 0),
360
+ probability:
361
+ Field.arrayProbability(this.taxes) * this.totalIncl.probability,
362
+ };
363
+ this.totalExcl = new Amount({
364
+ prediction: totalExcl,
365
+ valueKey: "value",
366
+ reconstructed: true,
367
+ });
368
+ }
369
+ }
370
+
371
+ #reconstructTotalIncl() {
372
+ if (
373
+ this.taxes.length &&
374
+ this.totalExcl.value != null &&
375
+ this.totalIncl.value === undefined
376
+ ) {
377
+ const totalIncl = {
378
+ value:
379
+ this.totalExcl.value +
380
+ this.taxes.reduce((acc, tax) => {
381
+ return tax.value ? acc + tax.value : acc;
382
+ }, 0.0),
383
+ probability:
384
+ Field.arrayProbability(this.taxes) * this.totalExcl.probability,
385
+ };
386
+ this.totalIncl = new Amount({
387
+ prediction: totalIncl,
388
+ valueKey: "value",
389
+ reconstructed: true,
390
+ });
391
+ }
392
+ }
393
+ }
394
+
395
+ module.exports = Invoice;