mindee 3.8.0 → 3.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d657be2dabdd3f93c49ead9299fa47fdad4d1afbc0115224668ffc43489b923e
4
- data.tar.gz: 3f36429f4d0302573f0619818f0eb1f26177fbf839f9fbb47ed6b8d5a2abd067
3
+ metadata.gz: bdc0f8cc57ce32684b3da523ce0a6666a251ff90d7a6d894a7b4601231bed3e4
4
+ data.tar.gz: e249e12de6c86cc4a7683392504d5cd914afb941a99b5b00bff3f90fd0f4ae36
5
5
  SHA512:
6
- metadata.gz: 4457a03fac7ad60960fe271d4672b17615be5e2bedc34d4b679a17ded4a52afa01cdf1d70f01efae77ff34c6f9e5ebb107098c2e33bc2055d9a7275194a95c4e
7
- data.tar.gz: b2671d071bbef4afc2764f9d56a7d8e60022b403ab77b845b0e74b0f33a3ed47a8b9968308baa3595b9db220516d675250d2c20231c9403a0c3f0e74e96fc5a9
6
+ metadata.gz: 713cf8cb6259b54637865f6799db1f5da7d7f27c436960316f84e2d404fe743d343d2d307feb2023c0fcab580421e5e0004bc70d34735d5800f0530d135c70ea
7
+ data.tar.gz: 535dc099fe76a27b3af26bb5cb726756e1b158056027782b607820e2648b92dbc32e65cf453d356c33355c5b94a3df9ffbbd86fabfc18fd5f439b48efa68816c
data/.rubocop.yml CHANGED
@@ -32,7 +32,7 @@ Metrics/BlockLength:
32
32
  - '**/*.gemspec'
33
33
 
34
34
  Metrics/MethodLength:
35
- Max: 45
35
+ Max: 50
36
36
 
37
37
  Metrics/ClassLength:
38
38
  Max: 200
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Mindee Ruby API Library Changelog
2
2
 
3
+ ## v3.10.0 - 2024-05-31
4
+ ### Changes
5
+ * :sparkles: add support for us mail v2 (#98)
6
+ * :sparkles: add support for boolean fields
7
+ * :sparkles: add support for webhooks (#97)
8
+ ### Fixes
9
+ * :recycle: tweak display for LocaleField
10
+
11
+
12
+ ## v3.9.0 - 2024-05-16
13
+ ### Changes
14
+ * :sparkles: update financial document to v1.7 & receipts to v5.2
15
+
16
+
3
17
  ## v3.8.0 - 2024-05-02
4
18
  ### Changes
5
19
  * :recycle: update products to newer syntax
@@ -0,0 +1,19 @@
1
+ require 'mindee'
2
+
3
+ # Init a new client
4
+ mindee_client = Mindee::Client.new(api_key: 'my-api-key')
5
+
6
+ # Load a file from disk
7
+ input_source = mindee_client.source_from_path('/path/to/the/file.ext')
8
+
9
+ # Parse the file
10
+ result = mindee_client.enqueue_and_parse(
11
+ input_source,
12
+ Mindee::Product::US::UsMail::UsMailV2
13
+ )
14
+
15
+ # Print a full summary of the parsed data in RST format
16
+ puts result.document
17
+
18
+ # Print the document-level parsed data
19
+ # puts result.document.inference.prediction
@@ -221,6 +221,13 @@ end
221
221
  puts result.document.inference.prediction.locale.value
222
222
  ```
223
223
 
224
+ ## Receipt Number
225
+ **receipt_number** ([StringField](#string-field)): The receipt number or identifier.
226
+
227
+ ```rb
228
+ puts result.document.inference.prediction.receipt_number.value
229
+ ```
230
+
224
231
  ## Purchase Subcategory
225
232
  **subcategory** ([ClassificationField](#classification-field)): The purchase subcategory among predefined classes for transport and food.
226
233
 
@@ -276,6 +276,13 @@ puts result.document.inference.prediction.customer_name.value
276
276
  puts result.document.inference.prediction.date.value
277
277
  ```
278
278
 
279
+ ## Document Number
280
+ **document_number** ([StringField](#string-field)): The document number or identifier.
281
+
282
+ ```rb
283
+ puts result.document.inference.prediction.document_number.value
284
+ ```
285
+
279
286
  ## Document Type
280
287
  **document_type** ([ClassificationField](#classification-field)): One of: 'INVOICE', 'CREDIT NOTE', 'CREDIT CARD RECEIPT', 'EXPENSE RECEIPT'.
281
288
 
@@ -291,7 +298,7 @@ puts result.document.inference.prediction.due_date.value
291
298
  ```
292
299
 
293
300
  ## Invoice Number
294
- **invoice_number** ([StringField](#string-field)): The invoice number or identifier.
301
+ **invoice_number** ([StringField](#string-field)): The invoice number or identifier only if document is an invoice.
295
302
 
296
303
  ```rb
297
304
  puts result.document.inference.prediction.invoice_number.value
@@ -313,6 +320,13 @@ end
313
320
  puts result.document.inference.prediction.locale.value
314
321
  ```
315
322
 
323
+ ## Receipt Number
324
+ **receipt_number** ([StringField](#string-field)): The receipt number or identifier only if document is a receipt.
325
+
326
+ ```rb
327
+ puts result.document.inference.prediction.receipt_number.value
328
+ ```
329
+
316
330
  ## Reference Numbers
317
331
  **reference_numbers** (Array<[StringField](#string-field)>): List of Reference numbers, including PO number.
318
332
 
@@ -0,0 +1,135 @@
1
+ ---
2
+ title: US US Mail OCR Ruby
3
+ ---
4
+ The Ruby OCR SDK supports the [US Mail API](https://platform.mindee.com/mindee/us_mail).
5
+
6
+ Using the [sample below](https://github.com/mindee/client-lib-test-data/blob/main/products/us_mail/default_sample.jpg), we are going to illustrate how to extract the data that we want using the OCR SDK.
7
+ ![US Mail sample](https://github.com/mindee/client-lib-test-data/blob/main/products/us_mail/default_sample.jpg?raw=true)
8
+
9
+ # Quick-Start
10
+ ```rb
11
+ require 'mindee'
12
+
13
+ # Init a new client
14
+ mindee_client = Mindee::Client.new(api_key: 'my-api-key')
15
+
16
+ # Load a file from disk
17
+ input_source = mindee_client.source_from_path('/path/to/the/file.ext')
18
+
19
+ # Parse the file
20
+ result = mindee_client.enqueue_and_parse(
21
+ input_source,
22
+ Mindee::Product::US::UsMail::UsMailV2
23
+ )
24
+
25
+ # Print a full summary of the parsed data in RST format
26
+ puts result.document
27
+
28
+ # Print the document-level parsed data
29
+ # puts result.document.inference.prediction
30
+ ```
31
+
32
+ **Output (RST):**
33
+ ```rst
34
+ :Sender Name: zed
35
+ :Sender Address:
36
+ :City: Dallas
37
+ :Complete Address: 54321 Elm Street, Dallas, Texas ...
38
+ :Postal Code: 54321
39
+ :State: TX
40
+ :Street: 54321 Elm Street
41
+ :Recipient Names: Jane Doe
42
+ :Recipient Addresses:
43
+ +-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+
44
+ | City | Complete Address | Is Address Change | Postal Code | Private Mailbox Number | State | Street |
45
+ +=================+=====================================+===================+=============+========================+=======+===========================+
46
+ | Detroit | 1234 Market Street PMB 4321, Det... | | 12345 | 4321 | MI | 1234 Market Street |
47
+ +-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+
48
+ ```
49
+
50
+ # Field Types
51
+ ## Standard Fields
52
+ These fields are generic and used in several products.
53
+
54
+ ### Basic Field
55
+ Each prediction object contains a set of fields that inherit from the generic `Field` class.
56
+ A typical `Field` object will have the following attributes:
57
+
58
+ * **value** (`String`, `Float`, `Integer`, `Boolean`): corresponds to the field value. Can be `nil` if no value was extracted.
59
+ * **confidence** (Float, nil): the confidence score of the field prediction.
60
+ * **bounding_box** (`Mindee::Geometry::Quadrilateral`, `nil`): contains exactly 4 relative vertices (points) coordinates of a right rectangle containing the field in the document.
61
+ * **polygon** (`Mindee::Geometry::Polygon`, `nil`): contains the relative vertices coordinates (`Point`) of a polygon containing the field in the image.
62
+ * **page_id** (`Integer`, `nil`): the ID of the page, is `nil` when at document-level.
63
+ * **reconstructed** (`Boolean`): indicates whether an object was reconstructed (not extracted as the API gave it).
64
+
65
+
66
+ Aside from the previous attributes, all basic fields have access to a `to_s` method that can be used to print their value as a string.
67
+
68
+ ### String Field
69
+ The text field `StringField` only has one constraint: it's **value** is a `String` (or `nil`).
70
+
71
+ ## Specific Fields
72
+ Fields which are specific to this product; they are not used in any other product.
73
+
74
+ ### Recipient Addresses Field
75
+ The addresses of the recipients.
76
+
77
+ A `UsMailV2RecipientAddress` implements the following attributes:
78
+
79
+ * `city` (String): The city of the recipient's address.
80
+ * `complete` (String): The complete address of the recipient.
81
+ * `is_address_change` (Boolean): Indicates if the recipient's address is a change of address.
82
+ * `postal_code` (String): The postal code of the recipient's address.
83
+ * `private_mailbox_number` (String): The private mailbox number of the recipient's address.
84
+ * `state` (String): Second part of the ISO 3166-2 code, consisting of two letters indicating the US State.
85
+ * `street` (String): The street of the recipient's address.
86
+ Fields which are specific to this product; they are not used in any other product.
87
+
88
+ ### Sender Address Field
89
+ The address of the sender.
90
+
91
+ A `UsMailV2SenderAddress` implements the following attributes:
92
+
93
+ * `city` (String): The city of the sender's address.
94
+ * `complete` (String): The complete address of the sender.
95
+ * `postal_code` (String): The postal code of the sender's address.
96
+ * `state` (String): Second part of the ISO 3166-2 code, consisting of two letters indicating the US State.
97
+ * `street` (String): The street of the sender's address.
98
+
99
+ # Attributes
100
+ The following fields are extracted for US Mail V2:
101
+
102
+ ## Recipient Addresses
103
+ **recipient_addresses** (Array<[UsMailV2RecipientAddress](#recipient-addresses-field)>): The addresses of the recipients.
104
+
105
+ ```rb
106
+ for recipient_addresses_elem in result.document.inference.prediction.recipient_addresses do
107
+ puts recipient_addresses_elem.value
108
+ end
109
+ ```
110
+
111
+ ## Recipient Names
112
+ **recipient_names** (Array<[StringField](#string-field)>): The names of the recipients.
113
+
114
+ ```rb
115
+ for recipient_names_elem in result.document.inference.prediction.recipient_names do
116
+ puts recipient_names_elem.value
117
+ end
118
+ ```
119
+
120
+ ## Sender Address
121
+ **sender_address** ([UsMailV2SenderAddress](#sender-address-field)): The address of the sender.
122
+
123
+ ```rb
124
+ puts result.document.inference.prediction.sender_address.value
125
+ ```
126
+
127
+ ## Sender Name
128
+ **sender_name** ([StringField](#string-field)): The name of the sender.
129
+
130
+ ```rb
131
+ puts result.document.inference.prediction.sender_name.value
132
+ ```
133
+
134
+ # Questions?
135
+ [Join our Slack](https://join.slack.com/t/mindee-community/shared_invite/zt-2d0ds7dtz-DPAF81ZqTy20chsYpQBW5g)
data/lib/mindee/client.rb CHANGED
@@ -182,6 +182,17 @@ module Mindee
182
182
 
183
183
  # rubocop:enable Metrics/ParameterLists
184
184
 
185
+ # Load a prediction.
186
+ #
187
+ # @param product_class [Mindee::Product] class of the product
188
+ # @param local_response [Mindee::Input::LocalResponse]
189
+ # @return [Mindee::Parsing::Common::ApiResponse]
190
+ def load_prediction(product_class, local_response)
191
+ Mindee::Parsing::Common::ApiResponse.new(product_class, local_response.as_hash, local_response.as_hash.to_json)
192
+ rescue KeyError
193
+ raise 'No prediction found in local response.'
194
+ end
195
+
185
196
  # Load a document from an absolute path, as a string.
186
197
  # @param input_path [String] Path of file to open
187
198
  # @param fix_pdf [Boolean] Attempts to fix broken pdf if true
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'openssl'
5
+ require 'stringio'
6
+ require 'pathname'
7
+ require 'tempfile'
8
+
9
+ module Mindee
10
+ module Input
11
+ # Response loaded locally.
12
+ class LocalResponse
13
+ attr_reader :file
14
+
15
+ # @param input_file [File, Tempfile, IO, StringIO, String, Pathname] The input file, which can be a StringIO.
16
+ def initialize(input_file)
17
+ case input_file
18
+ when IO, StringIO, File, Tempfile
19
+ str_stripped = input_file.read.gsub(%r{[\r\n]}, '')
20
+ @file = StringIO.new(str_stripped)
21
+ @file.rewind
22
+ when Pathname, String
23
+ @file = if Pathname(input_file).exist?
24
+ StringIO.new(File.read(input_file, encoding: 'utf-8').gsub(%r{[\r\n]}, ''))
25
+ else
26
+ StringIO.new(input_file.gsub(%r{[\r\n]}, ''))
27
+ end
28
+ @file.rewind
29
+ else
30
+ raise "Incompatible type for input '#{input_file.class}'."
31
+ end
32
+ end
33
+
34
+ # Returns the file as a hash.
35
+ # @return [Hash]
36
+ def as_hash
37
+ @file.rewind
38
+ file_str = @file.read
39
+ JSON.parse(file_str, object_class: Hash)
40
+ rescue JSON::ParserError
41
+ raise "File is not a valid dict. #{file_str}"
42
+ end
43
+
44
+ # Processes the secret key
45
+ # @param secret_key [String] the secret key as plain text.
46
+ # @return [String]
47
+ def self.process_secret_key(secret_key)
48
+ secret_key.is_a?(String) ? secret_key.encode('utf-8') : secret_key
49
+ end
50
+
51
+ # @param [String] secret_key [String] Secret key, either a string or a byte/byte array.
52
+ # @return [String]
53
+ def get_hmac_signature(secret_key)
54
+ algorithm = OpenSSL::Digest.new('sha256')
55
+ begin
56
+ @file.rewind
57
+ mac = OpenSSL::HMAC.hexdigest(algorithm, self.class.process_secret_key(secret_key), @file.read)
58
+ rescue StandardError
59
+ raise 'Could not get HMAC signature from payload.'
60
+ end
61
+ mac
62
+ end
63
+
64
+ # @param secret_key [String] Secret key, either a string or a byte/byte array.
65
+ # @param signature [String]
66
+ # @return [Boolean]
67
+ def valid_hmac_signature?(secret_key, signature)
68
+ signature == get_hmac_signature(secret_key)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -166,11 +166,11 @@ module Mindee
166
166
 
167
167
  # Load a document from a file handle.
168
168
  class FileInputSource < LocalInputSource
169
- # @param file_handle [String]
169
+ # @param input_file [File]
170
170
  # @param filename [String]
171
171
  # @param fix_pdf [Boolean]
172
- def initialize(file_handle, filename, fix_pdf: false)
173
- io_stream = file_handle
172
+ def initialize(input_file, filename, fix_pdf: false)
173
+ io_stream = input_file
174
174
  super(io_stream, filename, fix_pdf: fix_pdf)
175
175
  end
176
176
  end
@@ -108,9 +108,10 @@ module Mindee
108
108
  # @param raw_http [String]
109
109
  def initialize(product_class, http_response, raw_http)
110
110
  @raw_http = raw_http.to_s
111
- if http_response.key?('api_request')
112
- @api_request = Mindee::Parsing::Common::ApiRequest.new(http_response['api_request'])
113
- end
111
+ raise 'Invalid response format.' unless http_response.key?('api_request')
112
+
113
+ @api_request = Mindee::Parsing::Common::ApiRequest.new(http_response['api_request'])
114
+
114
115
  if http_response.key?('document') &&
115
116
  (!http_response.key?('job') ||
116
117
  http_response['job']['status'] == 'completed') &&
@@ -89,10 +89,12 @@ module Mindee
89
89
  # Feature field object wrapper for specialized methods.
90
90
  class FeatureField < AbstractField
91
91
  # Format strings for display by shortening long strings and assigning empty ones.
92
- # @param in_str [String, nil]
92
+ # @param in_str [String, Boolean, nil]
93
93
  # @param max_col_size [int, nil]
94
94
  # @return [String]
95
95
  def format_for_display(in_str, max_col_size = nil)
96
+ return 'True' if in_str == true
97
+ return 'False' if in_str == false
96
98
  return '' if in_str.nil?
97
99
  return in_str if max_col_size.nil?
98
100
 
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_field'
4
+
5
+ module Mindee
6
+ module Parsing
7
+ module Standard
8
+ # Represents basic text information.
9
+ class BooleanField < Field
10
+ # Value as Boolean
11
+ # @return [Boolean, nil]
12
+ attr_reader :value
13
+
14
+ def initialize(prediction, page_id = nil, reconstructed: false)
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -23,10 +23,10 @@ module Mindee
23
23
 
24
24
  # @param prediction [Hash]
25
25
  def initialize(prediction, _page_id = nil)
26
- value_key = if prediction.include? 'value'
27
- 'value'
28
- else
26
+ value_key = if !prediction.include?('value') || prediction['value'].nil?
29
27
  'language'
28
+ else
29
+ 'value'
30
30
  end
31
31
  @confidence = prediction['confidence']
32
32
  @value = prediction[value_key]
@@ -38,7 +38,7 @@ module Mindee
38
38
  # @return [String]
39
39
  def to_s
40
40
  out_str = String.new
41
- out_str << "#{@value}; " if @value
41
+ out_str << "#{@value}; " unless @value.nil?
42
42
  out_str << "#{@language}; " if @language
43
43
  out_str << "#{@country}; " if @country
44
44
  out_str << "#{@currency}; " if @currency
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'standard/amount_field'
4
4
  require_relative 'standard/base_field'
5
+ require_relative 'standard/boolean_field'
5
6
  require_relative 'standard/classification_field'
6
7
  require_relative 'standard/company_registration_field'
7
8
  require_relative 'standard/date_field'
@@ -6,7 +6,7 @@ require_relative 'financial_document_v1_line_item'
6
6
  module Mindee
7
7
  module Product
8
8
  module FinancialDocument
9
- # Financial Document API version 1.6 document data.
9
+ # Financial Document API version 1.7 document data.
10
10
  class FinancialDocumentV1Document < Mindee::Parsing::Common::Prediction
11
11
  include Mindee::Parsing::Standard
12
12
  # The customer's address used for billing.
@@ -30,13 +30,16 @@ module Mindee
30
30
  # The date the purchase was made.
31
31
  # @return [Mindee::Parsing::Standard::DateField]
32
32
  attr_reader :date
33
+ # The document number or identifier.
34
+ # @return [Mindee::Parsing::Standard::StringField]
35
+ attr_reader :document_number
33
36
  # One of: 'INVOICE', 'CREDIT NOTE', 'CREDIT CARD RECEIPT', 'EXPENSE RECEIPT'.
34
37
  # @return [Mindee::Parsing::Standard::ClassificationField]
35
38
  attr_reader :document_type
36
39
  # The date on which the payment is due.
37
40
  # @return [Mindee::Parsing::Standard::DateField]
38
41
  attr_reader :due_date
39
- # The invoice number or identifier.
42
+ # The invoice number or identifier only if document is an invoice.
40
43
  # @return [Mindee::Parsing::Standard::StringField]
41
44
  attr_reader :invoice_number
42
45
  # List of line item details.
@@ -45,6 +48,9 @@ module Mindee
45
48
  # The locale detected on the document.
46
49
  # @return [Mindee::Parsing::Standard::LocaleField]
47
50
  attr_reader :locale
51
+ # The receipt number or identifier only if document is a receipt.
52
+ # @return [Mindee::Parsing::Standard::StringField]
53
+ attr_reader :receipt_number
48
54
  # List of Reference numbers, including PO number.
49
55
  # @return [Array<Mindee::Parsing::Standard::StringField>]
50
56
  attr_reader :reference_numbers
@@ -108,6 +114,7 @@ module Mindee
108
114
  @customer_id = StringField.new(prediction['customer_id'], page_id)
109
115
  @customer_name = StringField.new(prediction['customer_name'], page_id)
110
116
  @date = DateField.new(prediction['date'], page_id)
117
+ @document_number = StringField.new(prediction['document_number'], page_id)
111
118
  @document_type = ClassificationField.new(prediction['document_type'], page_id)
112
119
  @due_date = DateField.new(prediction['due_date'], page_id)
113
120
  @invoice_number = StringField.new(prediction['invoice_number'], page_id)
@@ -116,6 +123,7 @@ module Mindee
116
123
  @line_items.push(FinancialDocumentV1LineItem.new(item, page_id))
117
124
  end
118
125
  @locale = LocaleField.new(prediction['locale'], page_id)
126
+ @receipt_number = StringField.new(prediction['receipt_number'], page_id)
119
127
  @reference_numbers = []
120
128
  prediction['reference_numbers'].each do |item|
121
129
  @reference_numbers.push(StringField.new(item, page_id))
@@ -153,6 +161,8 @@ module Mindee
153
161
  out_str = String.new
154
162
  out_str << "\n:Locale: #{@locale}".rstrip
155
163
  out_str << "\n:Invoice Number: #{@invoice_number}".rstrip
164
+ out_str << "\n:Receipt Number: #{@receipt_number}".rstrip
165
+ out_str << "\n:Document Number: #{@document_number}".rstrip
156
166
  out_str << "\n:Reference Numbers: #{reference_numbers}".rstrip
157
167
  out_str << "\n:Purchase Date: #{@date}".rstrip
158
168
  out_str << "\n:Due Date: #{@due_date}".rstrip
@@ -6,7 +6,7 @@ require_relative 'financial_document_v1_document'
6
6
  module Mindee
7
7
  module Product
8
8
  module FinancialDocument
9
- # Financial Document API version 1.6 page data.
9
+ # Financial Document API version 1.7 page data.
10
10
  class FinancialDocumentV1Page < Mindee::Parsing::Common::Page
11
11
  # @param prediction [Hash]
12
12
  def initialize(prediction)
@@ -6,7 +6,7 @@ require_relative 'receipt_v5_line_item'
6
6
  module Mindee
7
7
  module Product
8
8
  module Receipt
9
- # Receipt API version 5.1 document data.
9
+ # Receipt API version 5.2 document data.
10
10
  class ReceiptV5Document < Mindee::Parsing::Common::Prediction
11
11
  include Mindee::Parsing::Standard
12
12
  # The purchase category among predefined classes.
@@ -24,6 +24,9 @@ module Mindee
24
24
  # The locale detected on the document.
25
25
  # @return [Mindee::Parsing::Standard::LocaleField]
26
26
  attr_reader :locale
27
+ # The receipt number or identifier.
28
+ # @return [Mindee::Parsing::Standard::StringField]
29
+ attr_reader :receipt_number
27
30
  # The purchase subcategory among predefined classes for transport and food.
28
31
  # @return [Mindee::Parsing::Standard::ClassificationField]
29
32
  attr_reader :subcategory
@@ -70,6 +73,7 @@ module Mindee
70
73
  @line_items.push(ReceiptV5LineItem.new(item, page_id))
71
74
  end
72
75
  @locale = LocaleField.new(prediction['locale'], page_id)
76
+ @receipt_number = StringField.new(prediction['receipt_number'], page_id)
73
77
  @subcategory = ClassificationField.new(prediction['subcategory'], page_id)
74
78
  @supplier_address = StringField.new(prediction['supplier_address'], page_id)
75
79
  @supplier_company_registrations = []
@@ -106,6 +110,7 @@ module Mindee
106
110
  out_str << "\n:Supplier Company Registrations: #{supplier_company_registrations}".rstrip
107
111
  out_str << "\n:Supplier Address: #{@supplier_address}".rstrip
108
112
  out_str << "\n:Supplier Phone Number: #{@supplier_phone_number}".rstrip
113
+ out_str << "\n:Receipt Number: #{@receipt_number}".rstrip
109
114
  out_str << "\n:Line Items:"
110
115
  out_str << line_items
111
116
  out_str[1..].to_s
@@ -6,7 +6,7 @@ require_relative 'receipt_v5_document'
6
6
  module Mindee
7
7
  module Product
8
8
  module Receipt
9
- # Receipt API version 5.1 page data.
9
+ # Receipt API version 5.2 page data.
10
10
  class ReceiptV5Page < Mindee::Parsing::Common::Page
11
11
  # @param prediction [Hash]
12
12
  def initialize(prediction)
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'us_mail_v2_document'
5
+ require_relative 'us_mail_v2_page'
6
+
7
+ module Mindee
8
+ module Product
9
+ module US
10
+ # US Mail module.
11
+ module UsMail
12
+ # US Mail API version 2 inference prediction.
13
+ class UsMailV2 < Mindee::Parsing::Common::Inference
14
+ @endpoint_name = 'us_mail'
15
+ @endpoint_version = '2'
16
+
17
+ # @param prediction [Hash]
18
+ def initialize(prediction)
19
+ super
20
+ @prediction = UsMailV2Document.new(prediction['prediction'], nil)
21
+ @pages = []
22
+ prediction['pages'].each do |page|
23
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
24
+ @pages.push(UsMailV2Page.new(page))
25
+ end
26
+ end
27
+ end
28
+
29
+ class << self
30
+ # Name of the endpoint for this product.
31
+ # @return [String]
32
+ attr_reader :endpoint_name
33
+ # Version for this product.
34
+ # @return [String]
35
+ attr_reader :endpoint_version
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'us_mail_v2_sender_address'
5
+ require_relative 'us_mail_v2_recipient_address'
6
+
7
+ module Mindee
8
+ module Product
9
+ module US
10
+ module UsMail
11
+ # US Mail API version 2.0 document data.
12
+ class UsMailV2Document < Mindee::Parsing::Common::Prediction
13
+ include Mindee::Parsing::Standard
14
+ # The addresses of the recipients.
15
+ # @return [Array<Mindee::Product::US::UsMail::UsMailV2RecipientAddress>]
16
+ attr_reader :recipient_addresses
17
+ # The names of the recipients.
18
+ # @return [Array<Mindee::Parsing::Standard::StringField>]
19
+ attr_reader :recipient_names
20
+ # The address of the sender.
21
+ # @return [Mindee::Product::US::UsMail::UsMailV2SenderAddress]
22
+ attr_reader :sender_address
23
+ # The name of the sender.
24
+ # @return [Mindee::Parsing::Standard::StringField]
25
+ attr_reader :sender_name
26
+
27
+ # @param prediction [Hash]
28
+ # @param page_id [Integer, nil]
29
+ def initialize(prediction, page_id)
30
+ super()
31
+ @recipient_addresses = []
32
+ prediction['recipient_addresses'].each do |item|
33
+ @recipient_addresses.push(UsMailV2RecipientAddress.new(item, page_id))
34
+ end
35
+ @recipient_names = []
36
+ prediction['recipient_names'].each do |item|
37
+ @recipient_names.push(StringField.new(item, page_id))
38
+ end
39
+ @sender_address = UsMailV2SenderAddress.new(prediction['sender_address'], page_id)
40
+ @sender_name = StringField.new(prediction['sender_name'], page_id)
41
+ end
42
+
43
+ # @return [String]
44
+ def to_s
45
+ sender_address = @sender_address.to_s
46
+ recipient_names = @recipient_names.join("\n #{' ' * 17}")
47
+ recipient_addresses = recipient_addresses_to_s
48
+ out_str = String.new
49
+ out_str << "\n:Sender Name: #{@sender_name}".rstrip
50
+ out_str << "\n:Sender Address:"
51
+ out_str << sender_address
52
+ out_str << "\n:Recipient Names: #{recipient_names}".rstrip
53
+ out_str << "\n:Recipient Addresses:"
54
+ out_str << recipient_addresses
55
+ out_str[1..].to_s
56
+ end
57
+
58
+ private
59
+
60
+ # @param char [String]
61
+ # @return [String]
62
+ def recipient_addresses_separator(char)
63
+ out_str = String.new
64
+ out_str << ' '
65
+ out_str << "+#{char * 17}"
66
+ out_str << "+#{char * 37}"
67
+ out_str << "+#{char * 19}"
68
+ out_str << "+#{char * 13}"
69
+ out_str << "+#{char * 24}"
70
+ out_str << "+#{char * 7}"
71
+ out_str << "+#{char * 27}"
72
+ out_str << '+'
73
+ out_str
74
+ end
75
+
76
+ # @return [String]
77
+ def recipient_addresses_to_s
78
+ return '' if @recipient_addresses.empty?
79
+
80
+ line_items = @recipient_addresses.map(&:to_table_line).join("\n#{recipient_addresses_separator('-')}\n ")
81
+ out_str = String.new
82
+ out_str << "\n#{recipient_addresses_separator('-')}"
83
+ out_str << "\n |"
84
+ out_str << ' City |'
85
+ out_str << ' Complete Address |'
86
+ out_str << ' Is Address Change |'
87
+ out_str << ' Postal Code |'
88
+ out_str << ' Private Mailbox Number |'
89
+ out_str << ' State |'
90
+ out_str << ' Street |'
91
+ out_str << "\n#{recipient_addresses_separator('=')}"
92
+ out_str << "\n #{line_items}"
93
+ out_str << "\n#{recipient_addresses_separator('-')}"
94
+ out_str
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'us_mail_v2_document'
5
+
6
+ module Mindee
7
+ module Product
8
+ module US
9
+ module UsMail
10
+ # US Mail API version 2.0 page data.
11
+ class UsMailV2Page < Mindee::Parsing::Common::Page
12
+ # @param prediction [Hash]
13
+ def initialize(prediction)
14
+ super(prediction)
15
+ @prediction = UsMailV2PagePrediction.new(
16
+ prediction['prediction'],
17
+ prediction['id']
18
+ )
19
+ end
20
+ end
21
+
22
+ # US Mail V2 page prediction.
23
+ class UsMailV2PagePrediction < UsMailV2Document
24
+ # @return [String]
25
+ def to_s
26
+ out_str = String.new
27
+ out_str << "\n#{super}"
28
+ out_str
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+
5
+ module Mindee
6
+ module Product
7
+ module US
8
+ module UsMail
9
+ # The addresses of the recipients.
10
+ class UsMailV2RecipientAddress < Mindee::Parsing::Standard::FeatureField
11
+ include Mindee::Parsing::Standard
12
+ # The city of the recipient's address.
13
+ # @return [String]
14
+ attr_reader :city
15
+ # The complete address of the recipient.
16
+ # @return [String]
17
+ attr_reader :complete
18
+ # Indicates if the recipient's address is a change of address.
19
+ # @return [Boolean]
20
+ attr_reader :is_address_change
21
+ # The postal code of the recipient's address.
22
+ # @return [String]
23
+ attr_reader :postal_code
24
+ # The private mailbox number of the recipient's address.
25
+ # @return [String]
26
+ attr_reader :private_mailbox_number
27
+ # Second part of the ISO 3166-2 code, consisting of two letters indicating the US State.
28
+ # @return [String]
29
+ attr_reader :state
30
+ # The street of the recipient's address.
31
+ # @return [String]
32
+ attr_reader :street
33
+
34
+ # @param prediction [Hash]
35
+ # @param page_id [Integer, nil]
36
+ def initialize(prediction, page_id)
37
+ super(prediction, page_id)
38
+ @city = prediction['city']
39
+ @complete = prediction['complete']
40
+ @is_address_change = prediction['is_address_change']
41
+ @postal_code = prediction['postal_code']
42
+ @private_mailbox_number = prediction['private_mailbox_number']
43
+ @state = prediction['state']
44
+ @street = prediction['street']
45
+ @page_id = page_id
46
+ end
47
+
48
+ # @return [Hash]
49
+ def printable_values
50
+ printable = {}
51
+ printable[:city] = format_for_display(@city, 15)
52
+ printable[:complete] = format_for_display(@complete, 35)
53
+ printable[:is_address_change] = format_for_display(@is_address_change, nil)
54
+ printable[:postal_code] = format_for_display(@postal_code, nil)
55
+ printable[:private_mailbox_number] = format_for_display(@private_mailbox_number, nil)
56
+ printable[:state] = format_for_display(@state, nil)
57
+ printable[:street] = format_for_display(@street, 25)
58
+ printable
59
+ end
60
+
61
+ # @return [String]
62
+ def to_table_line
63
+ printable = printable_values
64
+ out_str = String.new
65
+ out_str << format('| %- 16s', printable[:city])
66
+ out_str << format('| %- 36s', printable[:complete])
67
+ out_str << format('| %- 18s', printable[:is_address_change])
68
+ out_str << format('| %- 12s', printable[:postal_code])
69
+ out_str << format('| %- 23s', printable[:private_mailbox_number])
70
+ out_str << format('| %- 6s', printable[:state])
71
+ out_str << format('| %- 26s', printable[:street])
72
+ out_str << '|'
73
+ end
74
+
75
+ # @return [String]
76
+ def to_s
77
+ printable = printable_values
78
+ out_str = String.new
79
+ out_str << "\n :City: #{printable[:city]}"
80
+ out_str << "\n :Complete Address: #{printable[:complete]}"
81
+ out_str << "\n :Is Address Change: #{printable[:is_address_change]}"
82
+ out_str << "\n :Postal Code: #{printable[:postal_code]}"
83
+ out_str << "\n :Private Mailbox Number: #{printable[:private_mailbox_number]}"
84
+ out_str << "\n :State: #{printable[:state]}"
85
+ out_str << "\n :Street: #{printable[:street]}"
86
+ out_str
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+
5
+ module Mindee
6
+ module Product
7
+ module US
8
+ module UsMail
9
+ # The address of the sender.
10
+ class UsMailV2SenderAddress < Mindee::Parsing::Standard::FeatureField
11
+ include Mindee::Parsing::Standard
12
+ # The city of the sender's address.
13
+ # @return [String]
14
+ attr_reader :city
15
+ # The complete address of the sender.
16
+ # @return [String]
17
+ attr_reader :complete
18
+ # The postal code of the sender's address.
19
+ # @return [String]
20
+ attr_reader :postal_code
21
+ # Second part of the ISO 3166-2 code, consisting of two letters indicating the US State.
22
+ # @return [String]
23
+ attr_reader :state
24
+ # The street of the sender's address.
25
+ # @return [String]
26
+ attr_reader :street
27
+
28
+ # @param prediction [Hash]
29
+ # @param page_id [Integer, nil]
30
+ def initialize(prediction, page_id)
31
+ super(prediction, page_id)
32
+ @city = prediction['city']
33
+ @complete = prediction['complete']
34
+ @postal_code = prediction['postal_code']
35
+ @state = prediction['state']
36
+ @street = prediction['street']
37
+ @page_id = page_id
38
+ end
39
+
40
+ # @return [Hash]
41
+ def printable_values
42
+ printable = {}
43
+ printable[:city] = format_for_display(@city, 15)
44
+ printable[:complete] = format_for_display(@complete, 35)
45
+ printable[:postal_code] = format_for_display(@postal_code, nil)
46
+ printable[:state] = format_for_display(@state, nil)
47
+ printable[:street] = format_for_display(@street, 25)
48
+ printable
49
+ end
50
+
51
+ # @return [String]
52
+ def to_table_line
53
+ printable = printable_values
54
+ out_str = String.new
55
+ out_str << format('| %- 16s', printable[:city])
56
+ out_str << format('| %- 36s', printable[:complete])
57
+ out_str << format('| %- 12s', printable[:postal_code])
58
+ out_str << format('| %- 6s', printable[:state])
59
+ out_str << format('| %- 26s', printable[:street])
60
+ out_str << '|'
61
+ end
62
+
63
+ # @return [String]
64
+ def to_s
65
+ printable = printable_values
66
+ out_str = String.new
67
+ out_str << "\n :City: #{printable[:city]}"
68
+ out_str << "\n :Complete Address: #{printable[:complete]}"
69
+ out_str << "\n :Postal Code: #{printable[:postal_code]}"
70
+ out_str << "\n :State: #{printable[:state]}"
71
+ out_str << "\n :Street: #{printable[:street]}"
72
+ out_str
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -26,4 +26,5 @@ require_relative 'product/international_id/international_id_v2'
26
26
  require_relative 'product/resume/resume_v1'
27
27
  require_relative 'product/us/bank_check/bank_check_v1'
28
28
  require_relative 'product/us/driver_license/driver_license_v1'
29
+ require_relative 'product/us/us_mail/us_mail_v2'
29
30
  require_relative 'product/us/w9/w9_v1'
@@ -3,7 +3,7 @@
3
3
  # Mindee
4
4
  module Mindee
5
5
  # Current version.
6
- VERSION = '3.8.0'
6
+ VERSION = '3.10.0'
7
7
 
8
8
  # Finds and return the current platform.
9
9
  # @return [String]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mindee
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.0
4
+ version: 3.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mindee, SA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-02 00:00:00.000000000 Z
11
+ date: 2024-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: marcel
@@ -150,6 +150,7 @@ files:
150
150
  - docs/code_samples/proof_of_address_v1.txt
151
151
  - docs/code_samples/resume_v1_async.txt
152
152
  - docs/code_samples/us_driver_license_v1.txt
153
+ - docs/code_samples/us_mail_v2_async.txt
153
154
  - docs/code_samples/us_w9_v1.txt
154
155
  - docs/cropper_v1.md
155
156
  - docs/custom_v1.md
@@ -168,6 +169,7 @@ files:
168
169
  - docs/proof_of_address_v1.md
169
170
  - docs/resume_v1.md
170
171
  - docs/us_driver_license_v1.md
172
+ - docs/us_mail_v2.md
171
173
  - docs/us_w9_v1.md
172
174
  - lib/mindee.rb
173
175
  - lib/mindee/client.rb
@@ -183,6 +185,7 @@ files:
183
185
  - lib/mindee/http/error.rb
184
186
  - lib/mindee/http/response_validation.rb
185
187
  - lib/mindee/input.rb
188
+ - lib/mindee/input/local_response.rb
186
189
  - lib/mindee/input/sources.rb
187
190
  - lib/mindee/parsing.rb
188
191
  - lib/mindee/parsing/common.rb
@@ -205,6 +208,7 @@ files:
205
208
  - lib/mindee/parsing/standard.rb
206
209
  - lib/mindee/parsing/standard/amount_field.rb
207
210
  - lib/mindee/parsing/standard/base_field.rb
211
+ - lib/mindee/parsing/standard/boolean_field.rb
208
212
  - lib/mindee/parsing/standard/classification_field.rb
209
213
  - lib/mindee/parsing/standard/company_registration_field.rb
210
214
  - lib/mindee/parsing/standard/date_field.rb
@@ -307,6 +311,11 @@ files:
307
311
  - lib/mindee/product/us/driver_license/driver_license_v1.rb
308
312
  - lib/mindee/product/us/driver_license/driver_license_v1_document.rb
309
313
  - lib/mindee/product/us/driver_license/driver_license_v1_page.rb
314
+ - lib/mindee/product/us/us_mail/us_mail_v2.rb
315
+ - lib/mindee/product/us/us_mail/us_mail_v2_document.rb
316
+ - lib/mindee/product/us/us_mail/us_mail_v2_page.rb
317
+ - lib/mindee/product/us/us_mail/us_mail_v2_recipient_address.rb
318
+ - lib/mindee/product/us/us_mail/us_mail_v2_sender_address.rb
310
319
  - lib/mindee/product/us/w9/w9_v1.rb
311
320
  - lib/mindee/product/us/w9/w9_v1_document.rb
312
321
  - lib/mindee/product/us/w9/w9_v1_page.rb