mindee 3.2.0 → 3.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v3.3.0 - 2022-12-01
4
+ ### Changes
5
+ * :sparkles: Add Invoice V4 with line items
6
+ * :sparkles: An env variable can be used to change the Mindee base API url
7
+
3
8
  ## v3.2.0 - 2022-11-14
4
9
  ### Changes
5
10
  * :sparkles: Add support for shipping container API V1
package/README.md CHANGED
@@ -66,11 +66,11 @@ const apiResponse = mindeeClient
66
66
 
67
67
  ### Handling the Return
68
68
  ```js
69
- // Print a brief summary of the parsed data
69
+ // Handle the response Promise
70
70
  apiResponse.then((resp) => {
71
71
 
72
- // The document property can be undefined:
73
- // * TypeScript will throw an error without this guard clause
72
+ // The `document` property can be undefined:
73
+ // * TypeScript will not compile without this guard clause
74
74
  // (or consider using the '?' notation)
75
75
  // * JavaScript will be very happy to produce subtle bugs
76
76
  // without this guard clause
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindee",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Mindee Client Library for Node.js",
5
5
  "main": "src/index.js",
6
6
  "bin": "bin/mindee.js",
@@ -3,6 +3,7 @@ import { InputSource } from "../inputs";
3
3
  import { IncomingMessage } from "http";
4
4
  export declare const STANDARD_API_OWNER = "mindee";
5
5
  export declare const API_KEY_ENVVAR_NAME = "MINDEE_API_KEY";
6
+ export declare const API_BASE_URL_ENVVAR_NAME = "MINDEE_BASE_URL";
6
7
  export interface predictResponse {
7
8
  messageObj: IncomingMessage;
8
9
  data: {
@@ -25,6 +26,7 @@ export declare class Endpoint {
25
26
  */
26
27
  predictReqPost(input: InputSource, includeWords?: boolean, cropper?: boolean): Promise<predictResponse>;
27
28
  protected apiKeyFromEnv(): string;
29
+ protected baseUrlFromEnv(): string;
28
30
  }
29
31
  export declare class StandardEndpoint extends Endpoint {
30
32
  constructor(endpointName: string, version: string, apiKey: string);
@@ -26,24 +26,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.CustomEndpoint = exports.StandardEndpoint = exports.Endpoint = exports.API_KEY_ENVVAR_NAME = exports.STANDARD_API_OWNER = void 0;
29
+ exports.CustomEndpoint = exports.StandardEndpoint = exports.Endpoint = exports.API_BASE_URL_ENVVAR_NAME = exports.API_KEY_ENVVAR_NAME = exports.STANDARD_API_OWNER = void 0;
30
30
  const https = __importStar(require("https"));
31
31
  const os = __importStar(require("os"));
32
32
  const package_json_1 = require("../../package.json");
33
33
  const url_1 = require("url");
34
34
  const form_data_1 = __importDefault(require("form-data"));
35
35
  const logger_1 = require("../logger");
36
- const MINDEE_API_URL = "https://api.mindee.net/v1";
36
+ const DEFAULT_MINDEE_API_URL = "https://api.mindee.net/v1";
37
37
  const USER_AGENT = `mindee-api-nodejs@v${package_json_1.version} nodejs-${process.version} ${os.type().toLowerCase()}`;
38
38
  exports.STANDARD_API_OWNER = "mindee";
39
39
  exports.API_KEY_ENVVAR_NAME = "MINDEE_API_KEY";
40
+ exports.API_BASE_URL_ENVVAR_NAME = "MINDEE_BASE_URL";
40
41
  class Endpoint {
41
42
  constructor(owner, urlName, version, apiKey) {
42
43
  this.owner = owner;
43
44
  this.urlName = urlName;
44
45
  this.version = version;
45
46
  this.apiKey = apiKey || this.apiKeyFromEnv();
46
- this.urlRoot = `${MINDEE_API_URL}/products/${owner}/${urlName}/v${version}`;
47
+ this.urlRoot = `${this.baseUrlFromEnv()}/products/${owner}/${urlName}/v${version}`;
47
48
  this.baseHeaders = {
48
49
  "User-Agent": USER_AGENT,
49
50
  Authorization: `Token ${this.apiKey}`,
@@ -112,6 +113,14 @@ class Endpoint {
112
113
  }
113
114
  return "";
114
115
  }
116
+ baseUrlFromEnv() {
117
+ const envVarValue = process.env[exports.API_BASE_URL_ENVVAR_NAME];
118
+ if (envVarValue) {
119
+ logger_1.logger.debug(`Set the API base URL to ${envVarValue}`);
120
+ return envVarValue;
121
+ }
122
+ return DEFAULT_MINDEE_API_URL;
123
+ }
115
124
  }
116
125
  exports.Endpoint = Endpoint;
117
126
  class StandardEndpoint extends Endpoint {
package/src/cli.js CHANGED
@@ -22,8 +22,8 @@ const CLI_COMMAND_CONFIG = new Map([
22
22
  [
23
23
  "invoice",
24
24
  {
25
- description: "Invoice V3",
26
- docClass: documents_1.InvoiceV3,
25
+ description: "Invoice V4",
26
+ docClass: documents_1.InvoiceV4,
27
27
  fullText: true,
28
28
  },
29
29
  ],
package/src/client.d.ts CHANGED
@@ -14,7 +14,7 @@ export interface PredictOptions {
14
14
  */
15
15
  endpointName?: string;
16
16
  /**
17
- * For custom endpoints, your organization's username on the API Builder.
17
+ * For custom endpoints, your account or organization's username on the API Builder.
18
18
  * This is normally not required unless you have a custom endpoint which has the
19
19
  * same name as standard (off the shelf) endpoint.
20
20
  *
package/src/client.js CHANGED
@@ -83,6 +83,9 @@ class Client {
83
83
  this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.InvoiceV3.name], new documentConfig_1.DocumentConfig(documents_1.InvoiceV3, [
84
84
  new api_1.StandardEndpoint("invoices", "3", this.apiKey),
85
85
  ]));
86
+ this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.InvoiceV4.name], new documentConfig_1.DocumentConfig(documents_1.InvoiceV4, [
87
+ new api_1.StandardEndpoint("invoices", "4", this.apiKey),
88
+ ]));
86
89
  this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.ReceiptV3.name], new documentConfig_1.DocumentConfig(documents_1.ReceiptV3, [
87
90
  new api_1.StandardEndpoint("expense_receipts", "3", this.apiKey),
88
91
  ]));
@@ -1,4 +1,5 @@
1
1
  export { InvoiceV3 } from "./invoice/invoiceV3";
2
+ export { InvoiceV4 } from "./invoice/invoiceV4";
2
3
  export { ReceiptV3 } from "./receipt/receiptV3";
3
4
  export { ReceiptV4 } from "./receipt/receiptV4";
4
5
  export { PassportV1 } from "./passport/passportV1";
@@ -23,9 +23,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.eu = exports.us = exports.fr = exports.Document = exports.ShippingContainerV1 = exports.CropperV1 = exports.CustomV1 = exports.FinancialDocumentV1 = exports.PassportV1 = exports.ReceiptV4 = exports.ReceiptV3 = exports.InvoiceV3 = void 0;
26
+ exports.eu = exports.us = exports.fr = exports.Document = exports.ShippingContainerV1 = exports.CropperV1 = exports.CustomV1 = exports.FinancialDocumentV1 = exports.PassportV1 = exports.ReceiptV4 = exports.ReceiptV3 = exports.InvoiceV4 = exports.InvoiceV3 = void 0;
27
27
  var invoiceV3_1 = require("./invoice/invoiceV3");
28
28
  Object.defineProperty(exports, "InvoiceV3", { enumerable: true, get: function () { return invoiceV3_1.InvoiceV3; } });
29
+ var invoiceV4_1 = require("./invoice/invoiceV4");
30
+ Object.defineProperty(exports, "InvoiceV4", { enumerable: true, get: function () { return invoiceV4_1.InvoiceV4; } });
29
31
  var receiptV3_1 = require("./receipt/receiptV3");
30
32
  Object.defineProperty(exports, "ReceiptV3", { enumerable: true, get: function () { return receiptV3_1.ReceiptV3; } });
31
33
  var receiptV4_1 = require("./receipt/receiptV4");
@@ -0,0 +1,5 @@
1
+ import { InvoiceV3 } from "./invoiceV3";
2
+ import { InvoiceV4 } from "./invoiceV4";
3
+ export declare function taxesMatchTotalIncl(document: InvoiceV4 | InvoiceV3): boolean;
4
+ export declare function taxesMatchTotalExcl(document: InvoiceV4 | InvoiceV3): boolean;
5
+ export declare function taxesAndTotalExclMatchTotalIncl(document: InvoiceV4 | InvoiceV3): boolean;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.taxesAndTotalExclMatchTotalIncl = exports.taxesMatchTotalExcl = exports.taxesMatchTotalIncl = void 0;
4
+ function taxesMatchTotalIncl(document) {
5
+ // Check taxes and total include exist
6
+ if (document.taxes.length === 0 || document.totalAmount.value === undefined)
7
+ return false;
8
+ // Reconstruct totalIncl from taxes
9
+ let totalVat = 0;
10
+ let reconstructedTotal = 0;
11
+ document.taxes.forEach((tax) => {
12
+ if (tax.value === undefined || !tax.rate)
13
+ return false;
14
+ totalVat += tax.value;
15
+ reconstructedTotal += tax.value + (100 * tax.value) / tax.rate;
16
+ });
17
+ // Sanity check
18
+ if (totalVat <= 0)
19
+ return false;
20
+ // Crate epsilon
21
+ const eps = 1 / (100 * totalVat);
22
+ if (document.totalAmount.value * (1 - eps) - 0.02 <= reconstructedTotal &&
23
+ reconstructedTotal <= document.totalAmount.value * (1 + eps) + 0.02) {
24
+ document.taxes.forEach((tax) => {
25
+ tax.confidence = 1.0;
26
+ });
27
+ document.totalTax.confidence = 1.0;
28
+ document.totalAmount.confidence = 1.0;
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ exports.taxesMatchTotalIncl = taxesMatchTotalIncl;
34
+ function taxesMatchTotalExcl(document) {
35
+ // Check taxes and total amount exist
36
+ if (document.taxes.length === 0 || document.totalNet.value === undefined) {
37
+ return false;
38
+ }
39
+ // Reconstruct total_incl from taxes
40
+ let totalVat = 0;
41
+ let reconstructedTotal = 0;
42
+ document.taxes.forEach((tax) => {
43
+ if (tax.value === undefined || !tax.rate) {
44
+ return false;
45
+ }
46
+ totalVat += tax.value;
47
+ reconstructedTotal += (100 * tax.value) / tax.rate;
48
+ });
49
+ // Sanity check
50
+ if (totalVat <= 0)
51
+ return false;
52
+ // Crate epsilon
53
+ const eps = 1 / (100 * totalVat);
54
+ if (document.totalNet.value * (1 - eps) - 0.02 <= reconstructedTotal &&
55
+ reconstructedTotal <= document.totalNet.value * (1 + eps) + 0.02) {
56
+ document.taxes.forEach((tax) => {
57
+ tax.confidence = 1.0;
58
+ });
59
+ document.totalTax.confidence = 1.0;
60
+ document.totalNet.confidence = 1.0;
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+ exports.taxesMatchTotalExcl = taxesMatchTotalExcl;
66
+ function taxesAndTotalExclMatchTotalIncl(document) {
67
+ if (document.totalNet.value === undefined ||
68
+ document.taxes.length === 0 ||
69
+ document.totalAmount.value === undefined)
70
+ return false;
71
+ let totalVat = 0;
72
+ document.taxes.forEach((tax) => (totalVat += tax.value || 0));
73
+ const reconstructedTotal = totalVat + document.totalNet.value;
74
+ if (totalVat <= 0)
75
+ return false;
76
+ if (document.totalAmount.value - 0.01 <= reconstructedTotal &&
77
+ reconstructedTotal <= document.totalAmount.value + 0.01) {
78
+ document.taxes.forEach((tax) => {
79
+ tax.confidence = 1.0;
80
+ });
81
+ document.totalTax.confidence = 1.0;
82
+ document.totalAmount.confidence = 1.0;
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ exports.taxesAndTotalExclMatchTotalIncl = taxesAndTotalExclMatchTotalIncl;
@@ -0,0 +1,29 @@
1
+ import { stringDict } from "../../fields";
2
+ import { Polygon } from "../../geometry";
3
+ export declare class InvoiceLineItem {
4
+ /** The product code referring to the item. */
5
+ productCode: string;
6
+ /** The item description. */
7
+ description: string;
8
+ /** The item quantity */
9
+ quantity: number | null;
10
+ /** The item unit price. */
11
+ unitPrice: number | null;
12
+ /** The item total amount. */
13
+ totalAmount: number | null;
14
+ /** The item tax rate in percentage. */
15
+ taxRate: number | null;
16
+ /** The item tax amount. */
17
+ taxAmount: number | null;
18
+ /** Confidence score */
19
+ confidence: number;
20
+ /** The document page on which the information was found. */
21
+ pageId: number;
22
+ /**
23
+ * Contains the relative vertices coordinates (points) of a polygon containing
24
+ * the field in the document.
25
+ */
26
+ polygon: Polygon;
27
+ constructor({ prediction }: stringDict);
28
+ toString(): string;
29
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvoiceLineItem = void 0;
4
+ const amount_1 = require("../../fields/amount");
5
+ class InvoiceLineItem {
6
+ constructor({ prediction }) {
7
+ /** Confidence score */
8
+ this.confidence = 0.0;
9
+ /**
10
+ * Contains the relative vertices coordinates (points) of a polygon containing
11
+ * the field in the document.
12
+ */
13
+ this.polygon = [];
14
+ this.productCode = prediction.product_code;
15
+ this.description = prediction.description;
16
+ this.quantity = +parseFloat(prediction.quantity).toFixed(3);
17
+ if (isNaN(this.quantity)) {
18
+ this.quantity = null;
19
+ }
20
+ this.unitPrice = +parseFloat(prediction.unit_price).toFixed(3);
21
+ if (isNaN(this.unitPrice)) {
22
+ this.unitPrice = null;
23
+ }
24
+ this.totalAmount = +parseFloat(prediction.total_amount).toFixed(3);
25
+ if (isNaN(this.totalAmount)) {
26
+ this.totalAmount = null;
27
+ }
28
+ this.taxRate = +parseFloat(prediction.tax_rate).toFixed(3);
29
+ if (isNaN(this.taxRate)) {
30
+ this.taxRate = null;
31
+ }
32
+ this.taxAmount = +parseFloat(prediction.tax_amount).toFixed(3);
33
+ if (isNaN(this.taxAmount)) {
34
+ this.taxAmount = null;
35
+ }
36
+ this.pageId = prediction.page_id;
37
+ this.confidence = prediction.confidence ? prediction.confidence : 0.0;
38
+ if (prediction.polygon) {
39
+ this.polygon = prediction.polygon;
40
+ }
41
+ }
42
+ toString() {
43
+ const productCode = this.productCode ?? "";
44
+ const quantity = this.quantity !== null ? (0, amount_1.floatToString)(this.quantity) : "";
45
+ const unitPrice = this.unitPrice !== null ? (0, amount_1.floatToString)(this.unitPrice) : "";
46
+ const totalAmount = this.totalAmount !== null ? (0, amount_1.floatToString)(this.totalAmount) : "";
47
+ let tax = this.taxAmount !== null ? (0, amount_1.floatToString)(this.taxAmount) : "";
48
+ tax += this.taxRate !== null ? ` (${this.taxRate} %)` : "";
49
+ let description = this.description ?? "";
50
+ if (description.length > 32) {
51
+ description = this.description.substring(0, 32) + "...";
52
+ }
53
+ return (productCode.padEnd(14) +
54
+ " | " +
55
+ quantity.padEnd(6) +
56
+ " | " +
57
+ unitPrice.padEnd(7) +
58
+ " | " +
59
+ totalAmount.padEnd(8) +
60
+ " | " +
61
+ tax.padEnd(14) +
62
+ " | " +
63
+ description);
64
+ }
65
+ }
66
+ exports.InvoiceLineItem = InvoiceLineItem;
@@ -6,8 +6,8 @@ export declare class InvoiceV3 extends Document {
6
6
  locale: Locale;
7
7
  /** The nature of the invoice. */
8
8
  documentType: BaseField;
9
- /** The total amount with tax included. */
10
- totalIncl: Amount;
9
+ /** The total amount with tax included. Same as totalIncl. */
10
+ totalAmount: Amount;
11
11
  /** The creation date of the invoice. */
12
12
  date: DateField;
13
13
  /** The due date of the invoice. */
@@ -16,8 +16,8 @@ export declare class InvoiceV3 extends Document {
16
16
  time: Field;
17
17
  /** The total tax. */
18
18
  totalTax: Amount;
19
- /** The total amount without the tax value. */
20
- totalExcl: Amount;
19
+ /** The total amount without the tax value. Same as totalExcl. */
20
+ totalNet: Amount;
21
21
  /** The supplier name. */
22
22
  supplier: Field;
23
23
  /** The supplier address. */
@@ -36,12 +36,14 @@ export declare class InvoiceV3 extends Document {
36
36
  paymentDetails: PaymentDetails[];
37
37
  /** The company registration information for the customer. */
38
38
  customerCompanyRegistration: CompanyRegistration[];
39
+ /** The total amount without the tax value. */
40
+ get totalExcl(): Amount;
41
+ /** The total amount without the tax value. */
42
+ set totalExcl(value: Amount);
43
+ /** The total amount with tax included. */
44
+ get totalIncl(): Amount;
45
+ /** The total amount with tax included. */
46
+ set totalIncl(value: Amount);
39
47
  constructor({ prediction, orientation, extras, inputSource, fullText, pageId, }: DocumentConstructorProps);
40
48
  toString(): string;
41
- private taxesMatchTotalIncl;
42
- /**
43
- *
44
- */
45
- private taxesMatchTotalExcl;
46
- private taxesAndTotalExclMatchTotalIncl;
47
49
  }
@@ -4,11 +4,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var _InvoiceV3_instances, _InvoiceV3_initFromApiPrediction, _InvoiceV3_checklist, _InvoiceV3_reconstruct, _InvoiceV3_reconstructTotalTax, _InvoiceV3_reconstructTotalTaxFromTotals, _InvoiceV3_reconstructTotalExcl, _InvoiceV3_reconstructTotalIncl;
7
+ var _InvoiceV3_instances, _InvoiceV3_initFromApiPrediction, _InvoiceV3_checklist, _InvoiceV3_reconstruct;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.InvoiceV3 = void 0;
10
10
  const document_1 = require("../document");
11
11
  const fields_1 = require("../../fields");
12
+ const checks_1 = require("./checks");
13
+ const reconstruction_1 = require("./reconstruction");
12
14
  class InvoiceV3 extends document_1.Document {
13
15
  constructor({ prediction, orientation = undefined, extras = undefined, inputSource = undefined, fullText = undefined, pageId = undefined, }) {
14
16
  super({
@@ -31,6 +33,22 @@ class InvoiceV3 extends document_1.Document {
31
33
  __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_checklist).call(this);
32
34
  __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_reconstruct).call(this);
33
35
  }
36
+ /** The total amount without the tax value. */
37
+ get totalExcl() {
38
+ return this.totalNet;
39
+ }
40
+ /** The total amount without the tax value. */
41
+ set totalExcl(value) {
42
+ this.totalNet = value;
43
+ }
44
+ /** The total amount with tax included. */
45
+ get totalIncl() {
46
+ return this.totalAmount;
47
+ }
48
+ /** The total amount with tax included. */
49
+ set totalIncl(value) {
50
+ this.totalAmount = value;
51
+ }
34
52
  toString() {
35
53
  const taxes = this.taxes.map((item) => item.toString()).join("\n ");
36
54
  const paymentDetails = this.paymentDetails
@@ -42,7 +60,7 @@ class InvoiceV3 extends document_1.Document {
42
60
  const companyRegistration = this.companyRegistration
43
61
  .map((item) => item.toString())
44
62
  .join("; ");
45
- const outStr = `-----Invoice data-----
63
+ const outStr = `----- Invoice V3 -----
46
64
  Filename: ${this.filename}
47
65
  Invoice number: ${this.invoiceNumber}
48
66
  Total amount including taxes: ${this.totalIncl}
@@ -63,90 +81,6 @@ Locale: ${this.locale}
63
81
  `;
64
82
  return InvoiceV3.cleanOutString(outStr);
65
83
  }
66
- taxesMatchTotalIncl() {
67
- // Check taxes and total include exist
68
- if (this.taxes.length === 0 || this.totalIncl.value === undefined)
69
- return false;
70
- // Reconstruct totalIncl from taxes
71
- let totalVat = 0;
72
- let reconstructedTotal = 0;
73
- this.taxes.forEach((tax) => {
74
- if (tax.value === undefined || !tax.rate)
75
- return false;
76
- totalVat += tax.value;
77
- reconstructedTotal += tax.value + (100 * tax.value) / tax.rate;
78
- });
79
- // Sanity check
80
- if (totalVat <= 0)
81
- return false;
82
- // Crate epsilon
83
- const eps = 1 / (100 * totalVat);
84
- if (this.totalIncl.value * (1 - eps) - 0.02 <= reconstructedTotal &&
85
- reconstructedTotal <= this.totalIncl.value * (1 + eps) + 0.02) {
86
- this.taxes.forEach((tax) => {
87
- tax.confidence = 1.0;
88
- });
89
- this.totalTax.confidence = 1.0;
90
- this.totalIncl.confidence = 1.0;
91
- return true;
92
- }
93
- return false;
94
- }
95
- /**
96
- *
97
- */
98
- taxesMatchTotalExcl() {
99
- // Check taxes and total amount exist
100
- if (this.taxes.length === 0 || this.totalExcl.value === undefined) {
101
- return false;
102
- }
103
- // Reconstruct total_incl from taxes
104
- let totalVat = 0;
105
- let reconstructedTotal = 0;
106
- this.taxes.forEach((tax) => {
107
- if (tax.value === undefined || !tax.rate) {
108
- return false;
109
- }
110
- totalVat += tax.value;
111
- reconstructedTotal += (100 * tax.value) / tax.rate;
112
- });
113
- // Sanity check
114
- if (totalVat <= 0)
115
- return false;
116
- // Crate epsilon
117
- const eps = 1 / (100 * totalVat);
118
- if (this.totalExcl.value * (1 - eps) - 0.02 <= reconstructedTotal &&
119
- reconstructedTotal <= this.totalExcl.value * (1 + eps) + 0.02) {
120
- this.taxes.forEach((tax) => {
121
- tax.confidence = 1.0;
122
- });
123
- this.totalTax.confidence = 1.0;
124
- this.totalExcl.confidence = 1.0;
125
- return true;
126
- }
127
- return false;
128
- }
129
- taxesAndTotalExclMatchTotalIncl() {
130
- if (this.totalExcl.value === undefined ||
131
- this.taxes.length === 0 ||
132
- this.totalIncl.value === undefined)
133
- return false;
134
- let totalVat = 0;
135
- this.taxes.forEach((tax) => (totalVat += tax.value || 0));
136
- const reconstructedTotal = totalVat + this.totalExcl.value;
137
- if (totalVat <= 0)
138
- return false;
139
- if (this.totalIncl.value - 0.01 <= reconstructedTotal &&
140
- reconstructedTotal <= this.totalIncl.value + 0.01) {
141
- this.taxes.forEach((tax) => {
142
- tax.confidence = 1.0;
143
- });
144
- this.totalTax.confidence = 1.0;
145
- this.totalIncl.confidence = 1.0;
146
- return true;
147
- }
148
- return false;
149
- }
150
84
  }
151
85
  exports.InvoiceV3 = InvoiceV3;
152
86
  _InvoiceV3_instances = new WeakSet(), _InvoiceV3_initFromApiPrediction = function _InvoiceV3_initFromApiPrediction(apiPrediction, pageId) {
@@ -163,12 +97,13 @@ _InvoiceV3_instances = new WeakSet(), _InvoiceV3_initFromApiPrediction = functio
163
97
  valueKey: "value",
164
98
  pageId: pageId,
165
99
  });
100
+ this.totalAmount = this.totalIncl;
166
101
  this.totalTax = new fields_1.Amount({
167
102
  prediction: { value: undefined, confidence: 0.0 },
168
103
  valueKey: "value",
169
104
  pageId: pageId,
170
105
  });
171
- this.totalExcl = new fields_1.Amount({
106
+ this.totalNet = new fields_1.Amount({
172
107
  prediction: apiPrediction.total_excl,
173
108
  valueKey: "value",
174
109
  pageId: pageId,
@@ -224,78 +159,13 @@ _InvoiceV3_instances = new WeakSet(), _InvoiceV3_initFromApiPrediction = functio
224
159
  })));
225
160
  }, _InvoiceV3_checklist = function _InvoiceV3_checklist() {
226
161
  this.checklist = {
227
- taxesMatchTotalIncl: this.taxesMatchTotalIncl(),
228
- taxesMatchTotalExcl: this.taxesMatchTotalExcl(),
229
- taxesAndTotalExclMatchTotalIncl: this.taxesAndTotalExclMatchTotalIncl(),
162
+ taxesMatchTotalIncl: (0, checks_1.taxesMatchTotalIncl)(this),
163
+ taxesMatchTotalExcl: (0, checks_1.taxesMatchTotalExcl)(this),
164
+ taxesAndTotalExclMatchTotalIncl: (0, checks_1.taxesAndTotalExclMatchTotalIncl)(this),
230
165
  };
231
166
  }, _InvoiceV3_reconstruct = function _InvoiceV3_reconstruct() {
232
- __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_reconstructTotalTax).call(this);
233
- __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_reconstructTotalExcl).call(this);
234
- __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_reconstructTotalIncl).call(this);
235
- __classPrivateFieldGet(this, _InvoiceV3_instances, "m", _InvoiceV3_reconstructTotalTaxFromTotals).call(this);
236
- }, _InvoiceV3_reconstructTotalTax = function _InvoiceV3_reconstructTotalTax() {
237
- if (this.taxes.length > 0) {
238
- const totalTax = {
239
- value: this.taxes.reduce((acc, tax) => {
240
- return tax.value !== undefined ? acc + tax.value : acc;
241
- }, 0),
242
- confidence: fields_1.Field.arrayConfidence(this.taxes),
243
- };
244
- if (totalTax.value > 0)
245
- this.totalTax = new fields_1.Amount({
246
- prediction: totalTax,
247
- valueKey: "value",
248
- reconstructed: true,
249
- });
250
- }
251
- }, _InvoiceV3_reconstructTotalTaxFromTotals = function _InvoiceV3_reconstructTotalTaxFromTotals() {
252
- if (this.totalTax.value !== undefined ||
253
- this.totalExcl.value === undefined ||
254
- this.totalIncl.value === undefined) {
255
- return;
256
- }
257
- const totalTax = {
258
- value: this.totalIncl.value - this.totalExcl.value,
259
- confidence: this.totalIncl.confidence * this.totalExcl.confidence,
260
- };
261
- if (totalTax.value >= 0) {
262
- this.totalTax = new fields_1.Amount({
263
- prediction: totalTax,
264
- valueKey: "value",
265
- reconstructed: true,
266
- });
267
- }
268
- }, _InvoiceV3_reconstructTotalExcl = function _InvoiceV3_reconstructTotalExcl() {
269
- if (this.totalIncl.value === undefined ||
270
- this.taxes.length === 0 ||
271
- this.totalExcl.value !== undefined) {
272
- return;
273
- }
274
- const totalExcl = {
275
- value: this.totalIncl.value - fields_1.Field.arraySum(this.taxes),
276
- confidence: fields_1.Field.arrayConfidence(this.taxes) *
277
- this.totalIncl.confidence,
278
- };
279
- this.totalExcl = new fields_1.Amount({
280
- prediction: totalExcl,
281
- valueKey: "value",
282
- reconstructed: true,
283
- });
284
- }, _InvoiceV3_reconstructTotalIncl = function _InvoiceV3_reconstructTotalIncl() {
285
- if (!(this.totalExcl.value === undefined ||
286
- this.taxes.length === 0 ||
287
- this.totalIncl.value !== undefined)) {
288
- const totalIncl = {
289
- value: this.totalExcl.value +
290
- this.taxes.reduce((acc, tax) => {
291
- return tax.value ? acc + tax.value : acc;
292
- }, 0.0),
293
- confidence: fields_1.Field.arrayConfidence(this.taxes) * this.totalExcl.confidence,
294
- };
295
- this.totalIncl = new fields_1.Amount({
296
- prediction: totalIncl,
297
- valueKey: "value",
298
- reconstructed: true,
299
- });
300
- }
167
+ (0, reconstruction_1.reconstructTotalTax)(this);
168
+ (0, reconstruction_1.reconstructTotalExcl)(this);
169
+ (0, reconstruction_1.reconstructTotalIncl)(this);
170
+ (0, reconstruction_1.reconstructTotalTaxFromTotals)(this);
301
171
  };
@@ -0,0 +1,44 @@
1
+ import { Document, DocumentConstructorProps } from "../document";
2
+ import { TaxField, PaymentDetails, Locale, Amount, Field, DateField, CompanyRegistration, BaseField } from "../../fields";
3
+ import { InvoiceLineItem } from "./invoiceLineItem";
4
+ export declare class InvoiceV4 extends Document {
5
+ #private;
6
+ /** Locale information. */
7
+ locale: Locale;
8
+ /** The nature of the invoice. */
9
+ documentType: BaseField;
10
+ /** The total amount with tax included. */
11
+ totalAmount: Amount;
12
+ /** The creation date of the invoice. */
13
+ date: DateField;
14
+ /** The due date of the invoice. */
15
+ dueDate: DateField;
16
+ /** The created time of the invoice */
17
+ time: Field;
18
+ /** The total tax. */
19
+ totalTax: Amount;
20
+ /** The total amount without the tax value. */
21
+ totalNet: Amount;
22
+ /** The supplier name. */
23
+ supplierName: Field;
24
+ /** The supplier address. */
25
+ supplierAddress: Field;
26
+ /** The payment information. */
27
+ supplierPaymentDetails: PaymentDetails[];
28
+ /** The supplier company regitration information. */
29
+ supplierCompanyRegistrations: CompanyRegistration[];
30
+ /** The invoice number. */
31
+ invoiceNumber: Field;
32
+ /** The name of the customer. */
33
+ customerName: Field;
34
+ /** The address of the customer. */
35
+ customerAddress: Field;
36
+ /** The company registration information for the customer. */
37
+ customerCompanyRegistrations: CompanyRegistration[];
38
+ /** The list of the taxes. */
39
+ taxes: TaxField[];
40
+ /** Line items details. */
41
+ lineItems: InvoiceLineItem[];
42
+ constructor({ prediction, orientation, extras, inputSource, fullText, pageId, }: DocumentConstructorProps);
43
+ toString(): string;
44
+ }
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _InvoiceV4_instances, _InvoiceV4_initFromApiPrediction, _InvoiceV4_checklist, _InvoiceV4_reconstruct;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.InvoiceV4 = void 0;
10
+ const document_1 = require("../document");
11
+ const fields_1 = require("../../fields");
12
+ const invoiceLineItem_1 = require("./invoiceLineItem");
13
+ const checks_1 = require("./checks");
14
+ const reconstruction_1 = require("./reconstruction");
15
+ class InvoiceV4 extends document_1.Document {
16
+ constructor({ prediction, orientation = undefined, extras = undefined, inputSource = undefined, fullText = undefined, pageId = undefined, }) {
17
+ super({
18
+ inputSource: inputSource,
19
+ pageId: pageId,
20
+ orientation: orientation,
21
+ fullText: fullText,
22
+ extras: extras,
23
+ });
24
+ _InvoiceV4_instances.add(this);
25
+ /** The payment information. */
26
+ this.supplierPaymentDetails = [];
27
+ /** The supplier company regitration information. */
28
+ this.supplierCompanyRegistrations = [];
29
+ /** The company registration information for the customer. */
30
+ this.customerCompanyRegistrations = [];
31
+ /** The list of the taxes. */
32
+ this.taxes = [];
33
+ /** Line items details. */
34
+ this.lineItems = [];
35
+ __classPrivateFieldGet(this, _InvoiceV4_instances, "m", _InvoiceV4_initFromApiPrediction).call(this, prediction, pageId);
36
+ __classPrivateFieldGet(this, _InvoiceV4_instances, "m", _InvoiceV4_checklist).call(this);
37
+ __classPrivateFieldGet(this, _InvoiceV4_instances, "m", _InvoiceV4_reconstruct).call(this);
38
+ }
39
+ toString() {
40
+ const taxes = this.taxes.map((item) => item.toString()).join("\n ");
41
+ const paymentDetails = this.supplierPaymentDetails
42
+ .map((item) => item.toString())
43
+ .join("\n ");
44
+ const customerCompanyRegistration = this.customerCompanyRegistrations
45
+ .map((item) => item.toString())
46
+ .join("; ");
47
+ const companyRegistration = this.supplierCompanyRegistrations
48
+ .map((item) => item.toString())
49
+ .join("; ");
50
+ let lineItems = "\n";
51
+ if (this.lineItems.length > 0) {
52
+ lineItems =
53
+ "\n Code | QTY | Price | Amount | Tax (Rate) | Description\n ";
54
+ lineItems += this.lineItems.map((item) => item.toString()).join("\n ");
55
+ }
56
+ const outStr = `----- Invoice V4 -----
57
+ Filename: ${this.filename}
58
+ Locale: ${this.locale}
59
+ Invoice number: ${this.invoiceNumber}
60
+ Invoice date: ${this.date}
61
+ Invoice due date: ${this.dueDate}
62
+ Supplier name: ${this.supplierName}
63
+ Supplier address: ${this.supplierAddress}
64
+ Supplier company registrations: ${companyRegistration}
65
+ Supplier payment details: ${paymentDetails}
66
+ Customer name: ${this.customerName}
67
+ Customer company registrations: ${customerCompanyRegistration}
68
+ Customer address: ${this.customerAddress}
69
+ Line Items: ${lineItems}
70
+ Taxes: ${taxes}
71
+ Total taxes: ${this.totalTax}
72
+ Total amount excluding taxes: ${this.totalNet}
73
+ Total amount including taxes: ${this.totalAmount}
74
+ ----------------------
75
+ `;
76
+ return InvoiceV4.cleanOutString(outStr);
77
+ }
78
+ }
79
+ exports.InvoiceV4 = InvoiceV4;
80
+ _InvoiceV4_instances = new WeakSet(), _InvoiceV4_initFromApiPrediction = function _InvoiceV4_initFromApiPrediction(apiPrediction, pageId) {
81
+ this.locale = new fields_1.Locale({
82
+ prediction: apiPrediction.locale,
83
+ valueKey: "language",
84
+ });
85
+ this.documentType = new fields_1.BaseField({
86
+ prediction: apiPrediction.document_type,
87
+ valueKey: "value",
88
+ });
89
+ this.totalAmount = new fields_1.Amount({
90
+ prediction: apiPrediction.total_amount,
91
+ valueKey: "value",
92
+ pageId: pageId,
93
+ });
94
+ this.totalTax = new fields_1.Amount({
95
+ prediction: { value: undefined, confidence: 0.0 },
96
+ valueKey: "value",
97
+ pageId: pageId,
98
+ });
99
+ this.totalNet = new fields_1.Amount({
100
+ prediction: apiPrediction.total_net,
101
+ valueKey: "value",
102
+ pageId: pageId,
103
+ });
104
+ this.date = new fields_1.DateField({
105
+ prediction: apiPrediction.date,
106
+ pageId,
107
+ });
108
+ apiPrediction.taxes.map((prediction) => this.taxes.push(new fields_1.TaxField({
109
+ prediction: prediction,
110
+ pageId: pageId,
111
+ valueKey: "value",
112
+ rateKey: "rate",
113
+ codeKey: "code",
114
+ })));
115
+ this.supplierCompanyRegistrations =
116
+ apiPrediction.supplier_company_registrations.map(function (prediction) {
117
+ return new fields_1.CompanyRegistration({
118
+ prediction: prediction,
119
+ pageId: pageId,
120
+ });
121
+ });
122
+ this.dueDate = new fields_1.DateField({
123
+ prediction: apiPrediction.due_date,
124
+ pageId: pageId,
125
+ });
126
+ this.invoiceNumber = new fields_1.Field({
127
+ prediction: apiPrediction.invoice_number,
128
+ pageId: pageId,
129
+ });
130
+ this.supplierName = new fields_1.Field({
131
+ prediction: apiPrediction.supplier_name,
132
+ pageId: pageId,
133
+ });
134
+ this.supplierAddress = new fields_1.Field({
135
+ prediction: apiPrediction.supplier_address,
136
+ pageId: pageId,
137
+ });
138
+ this.customerName = new fields_1.Field({
139
+ prediction: apiPrediction.customer_name,
140
+ pageId: pageId,
141
+ });
142
+ this.customerAddress = new fields_1.Field({
143
+ prediction: apiPrediction.customer_address,
144
+ pageId: pageId,
145
+ });
146
+ apiPrediction.customer_company_registrations.map((prediction) => this.customerCompanyRegistrations.push(new fields_1.CompanyRegistration({
147
+ prediction: prediction,
148
+ pageId: pageId,
149
+ })));
150
+ apiPrediction.supplier_payment_details.map((prediction) => this.supplierPaymentDetails.push(new fields_1.PaymentDetails({
151
+ prediction: prediction,
152
+ pageId: pageId,
153
+ })));
154
+ apiPrediction.line_items.map((prediction) => this.lineItems.push(new invoiceLineItem_1.InvoiceLineItem({
155
+ prediction: prediction,
156
+ })));
157
+ }, _InvoiceV4_checklist = function _InvoiceV4_checklist() {
158
+ this.checklist = {
159
+ taxesMatchTotalIncl: (0, checks_1.taxesMatchTotalIncl)(this),
160
+ taxesMatchTotalExcl: (0, checks_1.taxesMatchTotalExcl)(this),
161
+ taxesAndTotalExclMatchTotalIncl: (0, checks_1.taxesAndTotalExclMatchTotalIncl)(this),
162
+ };
163
+ }, _InvoiceV4_reconstruct = function _InvoiceV4_reconstruct() {
164
+ (0, reconstruction_1.reconstructTotalTax)(this);
165
+ (0, reconstruction_1.reconstructTotalExcl)(this);
166
+ (0, reconstruction_1.reconstructTotalIncl)(this);
167
+ (0, reconstruction_1.reconstructTotalTaxFromTotals)(this);
168
+ };
@@ -0,0 +1,6 @@
1
+ import { InvoiceV3 } from "./invoiceV3";
2
+ import { InvoiceV4 } from "./invoiceV4";
3
+ export declare function reconstructTotalTax(document: InvoiceV3 | InvoiceV4): void;
4
+ export declare function reconstructTotalTaxFromTotals(document: InvoiceV3 | InvoiceV4): void;
5
+ export declare function reconstructTotalExcl(document: InvoiceV3 | InvoiceV4): void;
6
+ export declare function reconstructTotalIncl(document: InvoiceV3 | InvoiceV4): void;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reconstructTotalIncl = exports.reconstructTotalExcl = exports.reconstructTotalTaxFromTotals = exports.reconstructTotalTax = void 0;
4
+ const fields_1 = require("../../fields");
5
+ function reconstructTotalTax(document) {
6
+ if (document.taxes.length > 0) {
7
+ const totalTax = {
8
+ value: document.taxes.reduce((acc, tax) => {
9
+ return tax.value !== undefined ? acc + tax.value : acc;
10
+ }, 0),
11
+ confidence: fields_1.Field.arrayConfidence(document.taxes),
12
+ };
13
+ if (totalTax.value > 0)
14
+ document.totalTax = new fields_1.Amount({
15
+ prediction: totalTax,
16
+ valueKey: "value",
17
+ reconstructed: true,
18
+ });
19
+ }
20
+ }
21
+ exports.reconstructTotalTax = reconstructTotalTax;
22
+ function reconstructTotalTaxFromTotals(document) {
23
+ if (document.totalTax.value !== undefined ||
24
+ document.totalNet.value === undefined ||
25
+ document.totalAmount.value === undefined) {
26
+ return;
27
+ }
28
+ const totalTax = {
29
+ value: document.totalAmount.value - document.totalNet.value,
30
+ confidence: document.totalAmount.confidence * document.totalNet.confidence,
31
+ };
32
+ if (totalTax.value >= 0) {
33
+ document.totalTax = new fields_1.Amount({
34
+ prediction: totalTax,
35
+ valueKey: "value",
36
+ reconstructed: true,
37
+ });
38
+ }
39
+ }
40
+ exports.reconstructTotalTaxFromTotals = reconstructTotalTaxFromTotals;
41
+ function reconstructTotalExcl(document) {
42
+ if (document.totalAmount.value === undefined ||
43
+ document.taxes.length === 0 ||
44
+ document.totalNet.value !== undefined) {
45
+ return;
46
+ }
47
+ const totalExcl = {
48
+ value: document.totalAmount.value - fields_1.Field.arraySum(document.taxes),
49
+ confidence: fields_1.Field.arrayConfidence(document.taxes) *
50
+ document.totalAmount.confidence,
51
+ };
52
+ document.totalNet = new fields_1.Amount({
53
+ prediction: totalExcl,
54
+ valueKey: "value",
55
+ reconstructed: true,
56
+ });
57
+ }
58
+ exports.reconstructTotalExcl = reconstructTotalExcl;
59
+ function reconstructTotalIncl(document) {
60
+ if (!(document.totalNet.value === undefined ||
61
+ document.taxes.length === 0 ||
62
+ document.totalAmount.value !== undefined)) {
63
+ const totalIncl = {
64
+ value: document.totalNet.value +
65
+ document.taxes.reduce((acc, tax) => {
66
+ return tax.value ? acc + tax.value : acc;
67
+ }, 0.0),
68
+ confidence: fields_1.Field.arrayConfidence(document.taxes) * document.totalNet.confidence,
69
+ };
70
+ document.totalAmount = new fields_1.Amount({
71
+ prediction: totalIncl,
72
+ valueKey: "value",
73
+ reconstructed: true,
74
+ });
75
+ }
76
+ }
77
+ exports.reconstructTotalIncl = reconstructTotalIncl;
package/src/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { CustomV1, FinancialDocumentV1, InvoiceV3, PassportV1, ReceiptV3, ReceiptV4, CropperV1, ShippingContainerV1, fr, us, eu, } from "./documents";
1
+ export { CustomV1, FinancialDocumentV1, InvoiceV3, InvoiceV4, PassportV1, ReceiptV3, ReceiptV4, CropperV1, ShippingContainerV1, fr, us, eu, } from "./documents";
2
2
  export { Client } from "./client";
3
3
  export { PageOptionsOperation } from "./inputs";
package/src/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PageOptionsOperation = exports.Client = exports.eu = exports.us = exports.fr = exports.ShippingContainerV1 = exports.CropperV1 = exports.ReceiptV4 = exports.ReceiptV3 = exports.PassportV1 = exports.InvoiceV3 = exports.FinancialDocumentV1 = exports.CustomV1 = void 0;
3
+ exports.PageOptionsOperation = exports.Client = exports.eu = exports.us = exports.fr = exports.ShippingContainerV1 = exports.CropperV1 = exports.ReceiptV4 = exports.ReceiptV3 = exports.PassportV1 = exports.InvoiceV4 = exports.InvoiceV3 = exports.FinancialDocumentV1 = exports.CustomV1 = void 0;
4
4
  var documents_1 = require("./documents");
5
5
  Object.defineProperty(exports, "CustomV1", { enumerable: true, get: function () { return documents_1.CustomV1; } });
6
6
  Object.defineProperty(exports, "FinancialDocumentV1", { enumerable: true, get: function () { return documents_1.FinancialDocumentV1; } });
7
7
  Object.defineProperty(exports, "InvoiceV3", { enumerable: true, get: function () { return documents_1.InvoiceV3; } });
8
+ Object.defineProperty(exports, "InvoiceV4", { enumerable: true, get: function () { return documents_1.InvoiceV4; } });
8
9
  Object.defineProperty(exports, "PassportV1", { enumerable: true, get: function () { return documents_1.PassportV1; } });
9
10
  Object.defineProperty(exports, "ReceiptV3", { enumerable: true, get: function () { return documents_1.ReceiptV3; } });
10
11
  Object.defineProperty(exports, "ReceiptV4", { enumerable: true, get: function () { return documents_1.ReceiptV4; } });