mindee 3.3.1 → 3.5.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +4 -0
  4. data/bin/mindee.rb +39 -15
  5. data/docs/bank_statement_fr_v1.md +175 -0
  6. data/docs/carte_grise_v1.md +4 -4
  7. data/docs/code_samples/bank_statement_fr_v1_async.txt +19 -0
  8. data/docs/code_samples/default.txt +19 -19
  9. data/docs/code_samples/default_async.txt +25 -0
  10. data/docs/code_samples/eu_driver_license_v1.txt +19 -0
  11. data/docs/code_samples/international_id_v1_async.txt +19 -0
  12. data/docs/code_samples/international_id_v2_async.txt +19 -0
  13. data/docs/eu_driver_license_v1.md +223 -0
  14. data/docs/financial_document_v1.md +48 -40
  15. data/docs/generated_v1.md +90 -0
  16. data/docs/invoices_v4.md +13 -4
  17. data/docs/proof_of_address_v1.md +4 -4
  18. data/docs/us_driver_license_v1.md +2 -2
  19. data/lib/mindee/client.rb +5 -3
  20. data/lib/mindee/http/endpoint.rb +13 -12
  21. data/lib/mindee/input/sources.rb +28 -5
  22. data/lib/mindee/parsing/common/inference.rb +3 -1
  23. data/lib/mindee/parsing/generated/generated_list_field.rb +58 -0
  24. data/lib/mindee/parsing/generated/generated_object_field.rb +109 -0
  25. data/lib/mindee/parsing/generated.rb +4 -0
  26. data/lib/mindee/parsing/standard/string_field.rb +8 -0
  27. data/lib/mindee/parsing.rb +1 -0
  28. data/lib/mindee/product/barcode_reader/barcode_reader_v1.rb +3 -1
  29. data/lib/mindee/product/cropper/cropper_v1.rb +3 -1
  30. data/lib/mindee/product/eu/driver_license/driver_license_v1.rb +41 -0
  31. data/lib/mindee/product/eu/driver_license/driver_license_v1_document.rb +88 -0
  32. data/lib/mindee/product/eu/driver_license/driver_license_v1_page.rb +53 -0
  33. data/lib/mindee/product/eu/license_plate/license_plate_v1.rb +3 -1
  34. data/lib/mindee/product/financial_document/financial_document_v1.rb +3 -1
  35. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1.rb +3 -1
  36. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2.rb +3 -1
  37. data/lib/mindee/product/fr/bank_statement/bank_statement_v1.rb +41 -0
  38. data/lib/mindee/product/fr/bank_statement/bank_statement_v1_document.rb +130 -0
  39. data/lib/mindee/product/fr/bank_statement/bank_statement_v1_page.rb +34 -0
  40. data/lib/mindee/product/fr/bank_statement/bank_statement_v1_transaction.rb +64 -0
  41. data/lib/mindee/product/fr/carte_grise/carte_grise_v1.rb +3 -1
  42. data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1.rb +3 -1
  43. data/lib/mindee/product/fr/id_card/id_card_v1.rb +3 -1
  44. data/lib/mindee/product/fr/id_card/id_card_v2.rb +3 -1
  45. data/lib/mindee/product/generated/generated_v1.rb +38 -0
  46. data/lib/mindee/product/generated/generated_v1_document.rb +35 -0
  47. data/lib/mindee/product/generated/generated_v1_page.rb +51 -0
  48. data/lib/mindee/product/generated/generated_v1_prediction.rb +114 -0
  49. data/lib/mindee/product/international_id/international_id_v1.rb +39 -0
  50. data/lib/mindee/product/international_id/international_id_v1_document.rb +109 -0
  51. data/lib/mindee/product/international_id/international_id_v1_page.rb +32 -0
  52. data/lib/mindee/product/international_id/international_id_v2.rb +39 -0
  53. data/lib/mindee/product/international_id/international_id_v2_document.rb +119 -0
  54. data/lib/mindee/product/international_id/international_id_v2_page.rb +32 -0
  55. data/lib/mindee/product/invoice/invoice_v4.rb +3 -1
  56. data/lib/mindee/product/invoice/invoice_v4_document.rb +5 -0
  57. data/lib/mindee/product/multi_receipts_detector/multi_receipts_detector_v1.rb +3 -1
  58. data/lib/mindee/product/passport/passport_v1.rb +3 -1
  59. data/lib/mindee/product/proof_of_address/proof_of_address_v1.rb +3 -1
  60. data/lib/mindee/product/receipt/receipt_v5.rb +3 -1
  61. data/lib/mindee/product/us/bank_check/bank_check_v1.rb +3 -1
  62. data/lib/mindee/product/us/driver_license/driver_license_v1.rb +3 -1
  63. data/lib/mindee/product/us/w9/w9_v1.rb +3 -1
  64. data/lib/mindee/product.rb +5 -0
  65. data/lib/mindee/version.rb +1 -1
  66. data/lib/mindee.rb +4 -0
  67. metadata +30 -2
@@ -7,6 +7,7 @@ require_relative '../pdf'
7
7
 
8
8
  module Mindee
9
9
  module Input
10
+ # Document source handling.
10
11
  module Source
11
12
  # Mime types accepted by the server.
12
13
  ALLOWED_MIME_TYPES = [
@@ -107,8 +108,7 @@ module Mindee
107
108
  @io_stream = PdfProcessor.parse(@io_stream, options)
108
109
  end
109
110
 
110
- # Reads a document. Packs it into bytes if needed.
111
- # Note: only needs filename in case of some pdf files.
111
+ # Reads a document.
112
112
  # @param close [Boolean]
113
113
  # @return [Array<String, [String, aBinaryString ], [Hash, nil] >]
114
114
  def read_document(close: true)
@@ -116,9 +116,7 @@ module Mindee
116
116
  # Avoids needlessly re-packing some files
117
117
  data = @io_stream.read
118
118
  @io_stream.close if close
119
- return ['document', data, { filename: @filename }] if pdf?
120
-
121
- ['document', [data].pack('m')]
119
+ ['document', data, { filename: Mindee::Input::Source.convert_to_unicode_escape(@filename) }]
122
120
  end
123
121
  end
124
122
 
@@ -142,6 +140,16 @@ module Mindee
142
140
  io_stream.set_encoding Encoding::BINARY
143
141
  super(io_stream, filename, fix_pdf: fix_pdf)
144
142
  end
143
+
144
+ # Overload of the same function to prevent a base64 from being re-encoded.
145
+ # @param close [Boolean]
146
+ # @return [Array<String, [String, aBinaryString ], [Hash, nil] >]
147
+ def read_document(close: true)
148
+ @io_stream.seek(0)
149
+ data = @io_stream.read
150
+ @io_stream.close if close
151
+ ['document', [data].pack('m'), { filename: Source.convert_to_unicode_escape(@filename) }]
152
+ end
145
153
  end
146
154
 
147
155
  # Load a document from raw bytes.
@@ -178,6 +186,21 @@ module Mindee
178
186
  @url = url
179
187
  end
180
188
  end
189
+
190
+ # Replaces non-ASCII characters by their unicode escape sequence.
191
+ # Keeps other characters as is.
192
+ # @return A clean String.
193
+ def self.convert_to_unicode_escape(string)
194
+ unicode_escape_string = ''.dup
195
+ string.each_char do |char|
196
+ unicode_escape_string << if char.bytesize > 1
197
+ "\\u#{char.unpack1('U').to_s(16).rjust(4, '0')}"
198
+ else
199
+ char
200
+ end
201
+ end
202
+ unicode_escape_string
203
+ end
181
204
  end
182
205
  end
183
206
  end
@@ -34,8 +34,10 @@ module Mindee
34
34
  out_str << "\n:Rotation applied: #{is_rotation_applied}"
35
35
  out_str << "\n\nPrediction\n=========="
36
36
  out_str << "\n#{@prediction.to_s.size.positive? ? "#{@prediction}\n" : ''}"
37
- out_str << "\nPage Predictions\n================\n\n"
37
+ out_str << "\nPage Predictions\n================\n\n" unless @pages.empty?
38
38
  out_str << @pages.map(&:to_s).join("\n\n")
39
+ out_str.rstrip!
40
+ out_str
39
41
  end
40
42
  end
41
43
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generated_object_field'
4
+
5
+ module Mindee
6
+ module Parsing
7
+ module Generated
8
+ # A list of values or objects, used in generated APIs.
9
+ class GeneratedListField
10
+ include Mindee::Parsing::Standard
11
+ include Mindee::Parsing::Generated
12
+
13
+ # Id of the page (as given by the API).
14
+ # @return [Integer]
15
+ attr_accessor :page_id
16
+
17
+ # List of word values
18
+ # @return [Array<GeneratedObjectField, StringField>]
19
+ attr_accessor :values
20
+
21
+ # Id of the page the object was found on.
22
+ # List of word values.
23
+
24
+ def initialize(raw_prediction, page_id = nil)
25
+ @values = []
26
+
27
+ raw_prediction.each do |value|
28
+ page_id = value['page_id'] if value.key?('page_id') && !value['page_id'].nil?
29
+
30
+ if Generated.generated_object?(value)
31
+ @values.push(GeneratedObjectField.new(value, page_id))
32
+ else
33
+ value_str = value.dup
34
+ value_str['value'] = value_str['value'].to_s if value_str.key?('value') && !value_str['value'].nil?
35
+ @values.push(StringField.new(value_str, page_id))
36
+ end
37
+ end
38
+ end
39
+
40
+ # Return an Array of the contents of all values.
41
+ # @return [Array<String>]
42
+ def contents_list
43
+ @values.map(&:to_s)
44
+ end
45
+
46
+ # Return a string representation of all values.
47
+ def contents_string(separator = ' ')
48
+ @values.map(&:to_s).join(separator)
49
+ end
50
+
51
+ # String representation
52
+ def to_s
53
+ contents_string
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../common'
4
+
5
+ module Mindee
6
+ module Parsing
7
+ # Generated fields and functions.
8
+ module Generated
9
+ # A JSON-like object, with miscellaneous values.
10
+ class GeneratedObjectField
11
+ include Mindee::Parsing::Standard
12
+ attr_accessor :page_id, :confidence, :raw_value
13
+
14
+ # Id of the page the object was found on.
15
+ # Confidence with which the value was assessed.
16
+ # Raw unprocessed value, as it was sent by the server.
17
+
18
+ def initialize(raw_prediction, page_id = nil)
19
+ @all_values = {}
20
+ item_page_id = nil
21
+ raw_prediction.each do |name, value|
22
+ case name
23
+ when 'page_id'
24
+ item_page_id = value
25
+ when 'polygon', 'rectangle', 'quadrangle', 'bounding_box'
26
+ handle_position_field(name, value, item_page_id)
27
+ when 'confidence'
28
+ @confidence = value
29
+ when 'raw_value'
30
+ @raw_value = value
31
+ else
32
+ handle_default_field(name, value)
33
+ end
34
+ @page_id = page_id || item_page_id
35
+ end
36
+ end
37
+
38
+ # String representation that takes into account the level of indentation.
39
+ def str_level(level = 0)
40
+ indent = " #{' ' * level}"
41
+ out_str = ''
42
+ @all_values.each do |attr, value|
43
+ str_value = value.nil? ? '' : value.to_s
44
+ out_str += "\n#{indent}:#{attr}: #{str_value}".rstrip
45
+ end
46
+ "\n#{indent}#{out_str.strip}"
47
+ end
48
+
49
+ # Necessary overload of the method_missing method to allow for direct access to dynamic attributes without
50
+ # complicating usage too much
51
+ # Returns the corresponding attribute when asked.
52
+ #
53
+ # Otherwise, raises a NoMethodError.
54
+ #
55
+ # @param method_name [Symbol] The name of the method being called.
56
+ # @param _args [Array] Arguments passed to the method.
57
+ # @return [Object] The value associated with the method name in @all_values.
58
+ def method_missing(method_name, *_args)
59
+ super unless @all_values.key?(method_name.to_s)
60
+ @all_values[method_name.to_s]
61
+ end
62
+
63
+ # Necessary overload of the respond_to_missing? method to allow for direct access to dynamic attributes without
64
+ # complicating usage too much
65
+ # Returns true if the method name exists as a key in @all_values,
66
+ # indicating that the object can respond to the method.
67
+ # Otherwise, calls super to fallback to the default behavior.
68
+ #
69
+ # @param method_name [Symbol] The name of the method being checked.
70
+ # @param include_private [Boolean] Whether to include private methods in the check.
71
+ # @return [Boolean] True if the method can be responded to, false otherwise.
72
+ def respond_to_missing?(method_name, include_private = false)
73
+ @all_values.key?(method_name.to_s) || super
74
+ end
75
+
76
+ # String representation
77
+ def to_s
78
+ str_level
79
+ end
80
+
81
+ private
82
+
83
+ def handle_position_field(name, value, item_page_id)
84
+ @all_values[name.to_s] =
85
+ PositionField.new({ name.to_s => value }, value_key: name.to_s, page_id: item_page_id)
86
+ end
87
+
88
+ def handle_default_field(name, value)
89
+ @all_values[name] = value.nil? ? nil : value.to_s
90
+ end
91
+ end
92
+
93
+ def self.generated_object?(str_dict)
94
+ common_keys = [
95
+ 'value',
96
+ 'polygon',
97
+ 'rectangle',
98
+ 'page_id',
99
+ 'confidence',
100
+ 'quadrangle',
101
+ 'values',
102
+ 'raw_value',
103
+ ]
104
+ str_dict.each_key { |key| return true unless common_keys.include?(key) }
105
+ false
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generated/generated_object_field'
4
+ require_relative 'generated/generated_list_field'
@@ -10,6 +10,14 @@ module Mindee
10
10
  # Value as String
11
11
  # @return [String, nil]
12
12
  attr_reader :value
13
+ # Value as String
14
+ # @return [String, nil]
15
+ attr_reader :raw_value
16
+
17
+ def initialize(prediction, page_id = nil, reconstructed: false)
18
+ super
19
+ @raw_value = prediction['raw_value']
20
+ end
13
21
  end
14
22
  end
15
23
  end
@@ -3,3 +3,4 @@
3
3
  require_relative 'parsing/standard'
4
4
  require_relative 'parsing/custom'
5
5
  require_relative 'parsing/common'
6
+ require_relative 'parsing/generated'
@@ -19,7 +19,9 @@ module Mindee
19
19
  @prediction = BarcodeReaderV1Document.new(prediction['prediction'], nil)
20
20
  @pages = []
21
21
  prediction['pages'].each do |page|
22
- @pages.push(BarcodeReaderV1Page.new(page))
22
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
23
+ @pages.push(BarcodeReaderV1Page.new(page))
24
+ end
23
25
  end
24
26
  end
25
27
 
@@ -19,7 +19,9 @@ module Mindee
19
19
  @prediction = CropperV1Document.new
20
20
  @pages = []
21
21
  prediction['pages'].each do |page|
22
- @pages.push(CropperV1Page.new(page))
22
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
23
+ @pages.push(CropperV1Page.new(page))
24
+ end
23
25
  end
24
26
  end
25
27
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'driver_license_v1_document'
5
+ require_relative 'driver_license_v1_page'
6
+
7
+ module Mindee
8
+ module Product
9
+ module EU
10
+ # EU Driver License module.
11
+ module DriverLicense
12
+ # EU Driver License V1 prediction inference.
13
+ class DriverLicenseV1 < Mindee::Parsing::Common::Inference
14
+ @endpoint_name = 'eu_driver_license'
15
+ @endpoint_version = '1'
16
+
17
+ # @param prediction [Hash]
18
+ def initialize(prediction)
19
+ super
20
+ @prediction = DriverLicenseV1Document.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(DriverLicenseV1Page.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,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+
5
+ module Mindee
6
+ module Product
7
+ module EU
8
+ module DriverLicense
9
+ # EU Driver License V1 document prediction.
10
+ class DriverLicenseV1Document < Mindee::Parsing::Common::Prediction
11
+ include Mindee::Parsing::Standard
12
+ # EU driver license holders address
13
+ # @return [Mindee::Parsing::Standard::StringField]
14
+ attr_reader :address
15
+ # EU driver license holders categories
16
+ # @return [Mindee::Parsing::Standard::StringField]
17
+ attr_reader :category
18
+ # Country code extracted as a string.
19
+ # @return [Mindee::Parsing::Standard::StringField]
20
+ attr_reader :country_code
21
+ # The date of birth of the document holder
22
+ # @return [Mindee::Parsing::Standard::DateField]
23
+ attr_reader :date_of_birth
24
+ # ID number of the Document.
25
+ # @return [Mindee::Parsing::Standard::StringField]
26
+ attr_reader :document_id
27
+ # Date the document expires
28
+ # @return [Mindee::Parsing::Standard::DateField]
29
+ attr_reader :expiry_date
30
+ # First name(s) of the driver license holder
31
+ # @return [Mindee::Parsing::Standard::StringField]
32
+ attr_reader :first_name
33
+ # Authority that issued the document
34
+ # @return [Mindee::Parsing::Standard::StringField]
35
+ attr_reader :issue_authority
36
+ # Date the document was issued
37
+ # @return [Mindee::Parsing::Standard::DateField]
38
+ attr_reader :issue_date
39
+ # Last name of the driver license holder.
40
+ # @return [Mindee::Parsing::Standard::StringField]
41
+ attr_reader :last_name
42
+ # Machine-readable license number
43
+ # @return [Mindee::Parsing::Standard::StringField]
44
+ attr_reader :mrz
45
+ # Place where the driver license holder was born
46
+ # @return [Mindee::Parsing::Standard::StringField]
47
+ attr_reader :place_of_birth
48
+
49
+ # @param prediction [Hash]
50
+ # @param page_id [Integer, nil]
51
+ def initialize(prediction, page_id)
52
+ super()
53
+ @address = StringField.new(prediction['address'], page_id)
54
+ @category = StringField.new(prediction['category'], page_id)
55
+ @country_code = StringField.new(prediction['country_code'], page_id)
56
+ @date_of_birth = DateField.new(prediction['date_of_birth'], page_id)
57
+ @document_id = StringField.new(prediction['document_id'], page_id)
58
+ @expiry_date = DateField.new(prediction['expiry_date'], page_id)
59
+ @first_name = StringField.new(prediction['first_name'], page_id)
60
+ @issue_authority = StringField.new(prediction['issue_authority'], page_id)
61
+ @issue_date = DateField.new(prediction['issue_date'], page_id)
62
+ @last_name = StringField.new(prediction['last_name'], page_id)
63
+ @mrz = StringField.new(prediction['mrz'], page_id)
64
+ @place_of_birth = StringField.new(prediction['place_of_birth'], page_id)
65
+ end
66
+
67
+ # @return [String]
68
+ def to_s
69
+ out_str = String.new
70
+ out_str << "\n:Country Code: #{@country_code}".rstrip
71
+ out_str << "\n:Document ID: #{@document_id}".rstrip
72
+ out_str << "\n:Driver License Category: #{@category}".rstrip
73
+ out_str << "\n:Last Name: #{@last_name}".rstrip
74
+ out_str << "\n:First Name: #{@first_name}".rstrip
75
+ out_str << "\n:Date Of Birth: #{@date_of_birth}".rstrip
76
+ out_str << "\n:Place Of Birth: #{@place_of_birth}".rstrip
77
+ out_str << "\n:Expiry Date: #{@expiry_date}".rstrip
78
+ out_str << "\n:Issue Date: #{@issue_date}".rstrip
79
+ out_str << "\n:Issue Authority: #{@issue_authority}".rstrip
80
+ out_str << "\n:MRZ: #{@mrz}".rstrip
81
+ out_str << "\n:Address: #{@address}".rstrip
82
+ out_str[1..].to_s
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'driver_license_v1_document'
5
+
6
+ module Mindee
7
+ module Product
8
+ module EU
9
+ module DriverLicense
10
+ # EU Driver License V1 page.
11
+ class DriverLicenseV1Page < Mindee::Parsing::Common::Page
12
+ # @param prediction [Hash]
13
+ def initialize(prediction)
14
+ super(prediction)
15
+ @prediction = DriverLicenseV1PagePrediction.new(
16
+ prediction['prediction'],
17
+ prediction['id']
18
+ )
19
+ end
20
+ end
21
+
22
+ # EU Driver License V1 page prediction.
23
+ class DriverLicenseV1PagePrediction < DriverLicenseV1Document
24
+ include Mindee::Parsing::Standard
25
+
26
+ # Has a photo of the EU driver license holder
27
+ # @return [Mindee::Parsing::Standard::PositionField]
28
+ attr_reader :photo
29
+ # Has a signature of the EU driver license holder
30
+ # @return [Mindee::Parsing::Standard::PositionField]
31
+ attr_reader :signature
32
+
33
+ # @param prediction [Hash]
34
+ # @param page_id [Integer, nil]
35
+ def initialize(prediction, page_id)
36
+ @photo = PositionField.new(prediction['photo'], page_id)
37
+ @signature = PositionField.new(prediction['signature'], page_id)
38
+ super(prediction, page_id)
39
+ end
40
+
41
+ # @return [String]
42
+ def to_s
43
+ out_str = String.new
44
+ out_str << "\n:Photo: #{@photo}".rstrip
45
+ out_str << "\n:Signature: #{@signature}".rstrip
46
+ out_str << "\n#{super}"
47
+ out_str
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -20,7 +20,9 @@ module Mindee
20
20
  @prediction = LicensePlateV1Document.new(prediction['prediction'], nil)
21
21
  @pages = []
22
22
  prediction['pages'].each do |page|
23
- @pages.push(LicensePlateV1Page.new(page))
23
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
24
+ @pages.push(LicensePlateV1Page.new(page))
25
+ end
24
26
  end
25
27
  end
26
28
 
@@ -19,7 +19,9 @@ module Mindee
19
19
  @prediction = FinancialDocumentV1Document.new(prediction['prediction'], nil)
20
20
  @pages = []
21
21
  prediction['pages'].each do |page|
22
- @pages.push(FinancialDocumentV1Page.new(page))
22
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
23
+ @pages.push(FinancialDocumentV1Page.new(page))
24
+ end
23
25
  end
24
26
  end
25
27
 
@@ -20,7 +20,9 @@ module Mindee
20
20
  @prediction = BankAccountDetailsV1Document.new(prediction['prediction'], nil)
21
21
  @pages = []
22
22
  prediction['pages'].each do |page|
23
- @pages.push(BankAccountDetailsV1Page.new(page))
23
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
24
+ @pages.push(BankAccountDetailsV1Page.new(page))
25
+ end
24
26
  end
25
27
  end
26
28
 
@@ -20,7 +20,9 @@ module Mindee
20
20
  @prediction = BankAccountDetailsV2Document.new(prediction['prediction'], nil)
21
21
  @pages = []
22
22
  prediction['pages'].each do |page|
23
- @pages.push(BankAccountDetailsV2Page.new(page))
23
+ if page.key?('prediction') && !page['prediction'].nil? && !page['prediction'].empty?
24
+ @pages.push(BankAccountDetailsV2Page.new(page))
25
+ end
24
26
  end
25
27
  end
26
28
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../parsing'
4
+ require_relative 'bank_statement_v1_document'
5
+ require_relative 'bank_statement_v1_page'
6
+
7
+ module Mindee
8
+ module Product
9
+ module FR
10
+ # Bank Statement (FR) module.
11
+ module BankStatement
12
+ # Bank Statement (FR) V1 prediction inference.
13
+ class BankStatementV1 < Mindee::Parsing::Common::Inference
14
+ @endpoint_name = 'bank_statement_fr'
15
+ @endpoint_version = '1'
16
+
17
+ # @param prediction [Hash]
18
+ def initialize(prediction)
19
+ super
20
+ @prediction = BankStatementV1Document.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(BankStatementV1Page.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