mindee 3.1.1 → 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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +26 -0
- data/README.md +57 -7
- data/bin/mindee.rb +160 -83
- data/docs/bank_account_details_v2.md +137 -0
- data/docs/bank_check_v1.md +179 -0
- data/docs/barcode_reader_v1.md +104 -0
- data/docs/carte_grise_v1.md +454 -0
- data/docs/carte_vitale_v1.md +123 -0
- data/docs/code_samples/barcode_reader_v1.txt +19 -0
- data/docs/code_samples/carte_grise_v1.txt +19 -0
- data/docs/code_samples/cropper_v1.txt +16 -0
- data/docs/code_samples/idcard_fr_v2.txt +19 -0
- data/docs/code_samples/invoice_splitter_v1_async.txt +6 -54
- data/docs/code_samples/multi_receipts_detector_v1.txt +19 -0
- data/docs/code_samples/us_w9_v1.txt +16 -0
- data/docs/cropper_v1.md +97 -0
- data/docs/custom_v1.md +109 -0
- data/docs/expense_receipts_v5.md +306 -0
- data/docs/financial_document_v1.md +384 -0
- data/docs/{ruby-getting-started.md → getting_started.md} +22 -6
- data/docs/idcard_fr_v2.md +253 -0
- data/docs/invoice_splitter_v1.md +85 -0
- data/docs/invoices_v4.md +338 -0
- data/docs/license_plates_v1.md +91 -0
- data/docs/multi_receipts_detector_v1.md +105 -0
- data/docs/passport_v1.md +186 -0
- data/docs/proof_of_address_v1.md +207 -0
- data/docs/us_driver_license_v1.md +268 -0
- data/docs/us_w9_v1.md +207 -0
- data/lib/mindee/client.rb +95 -16
- data/lib/mindee/geometry/quadrilateral.rb +5 -0
- data/lib/mindee/http/.rubocop.yml +8 -0
- data/lib/mindee/http/endpoint.rb +19 -7
- data/lib/mindee/http/error.rb +104 -0
- data/lib/mindee/http.rb +1 -0
- data/lib/mindee/input/sources.rb +83 -14
- data/lib/mindee/parsing/common/api_response.rb +12 -1
- data/lib/mindee/parsing/common/document.rb +4 -1
- data/lib/mindee/parsing/common/inference.rb +2 -2
- data/lib/mindee/parsing/common/ocr/ocr.rb +1 -0
- data/lib/mindee/parsing/common.rb +0 -1
- data/lib/mindee/parsing/custom/list_field.rb +7 -5
- data/lib/mindee/parsing/standard/base_field.rb +1 -1
- data/lib/mindee/parsing/standard/company_registration_field.rb +1 -1
- data/lib/mindee/parsing/standard/locale_field.rb +1 -1
- data/lib/mindee/parsing/standard/payment_details_field.rb +1 -1
- data/lib/mindee/parsing/standard/position_field.rb +10 -3
- data/lib/mindee/parsing/standard/{text_field.rb → string_field.rb} +1 -1
- data/lib/mindee/parsing/standard.rb +1 -1
- data/lib/mindee/pdf/pdf_processing.rb +2 -1
- data/lib/mindee/product/barcode_reader/barcode_reader_v1.rb +37 -0
- data/lib/mindee/product/barcode_reader/barcode_reader_v1_document.rb +44 -0
- data/lib/mindee/product/barcode_reader/barcode_reader_v1_page.rb +32 -0
- data/lib/mindee/product/cropper/cropper_v1.rb +37 -0
- data/lib/mindee/product/cropper/cropper_v1_document.rb +13 -0
- data/lib/mindee/product/cropper/cropper_v1_page.rb +49 -0
- data/lib/mindee/product/custom/custom_v1.rb +1 -0
- data/lib/mindee/product/eu/license_plate/license_plate_v1.rb +1 -0
- data/lib/mindee/product/eu/license_plate/license_plate_v1_document.rb +2 -2
- data/lib/mindee/product/financial_document/financial_document_v1.rb +1 -0
- data/lib/mindee/product/financial_document/financial_document_v1_document.rb +26 -26
- data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1.rb +1 -0
- data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1_document.rb +6 -6
- data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2.rb +1 -0
- data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2_document.rb +6 -6
- data/lib/mindee/product/fr/carte_grise/carte_grise_v1.rb +39 -0
- data/lib/mindee/product/fr/carte_grise/carte_grise_v1_document.rb +235 -0
- data/lib/mindee/product/fr/carte_grise/carte_grise_v1_page.rb +34 -0
- data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1.rb +1 -0
- data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1_document.rb +6 -6
- data/lib/mindee/product/fr/id_card/id_card_v1.rb +1 -0
- data/lib/mindee/product/fr/id_card/id_card_v1_document.rb +16 -16
- data/lib/mindee/product/fr/id_card/id_card_v2.rb +39 -0
- data/lib/mindee/product/fr/id_card/id_card_v2_document.rb +107 -0
- data/lib/mindee/product/fr/id_card/id_card_v2_page.rb +53 -0
- data/lib/mindee/product/invoice/invoice_v4.rb +2 -2
- data/lib/mindee/product/invoice/invoice_v4_document.rb +115 -155
- data/lib/mindee/product/invoice/invoice_v4_line_item.rb +54 -30
- data/lib/mindee/product/invoice_splitter/invoice_splitter_v1.rb +1 -0
- data/lib/mindee/product/invoice_splitter/invoice_splitter_v1_document.rb +5 -3
- data/lib/mindee/product/multi_receipts_detector/multi_receipts_detector_v1.rb +37 -0
- data/lib/mindee/product/multi_receipts_detector/multi_receipts_detector_v1_document.rb +35 -0
- data/lib/mindee/product/multi_receipts_detector/multi_receipts_detector_v1_page.rb +32 -0
- data/lib/mindee/product/passport/passport_v1.rb +1 -0
- data/lib/mindee/product/passport/passport_v1_document.rb +16 -16
- data/lib/mindee/product/proof_of_address/proof_of_address_v1.rb +1 -0
- data/lib/mindee/product/proof_of_address/proof_of_address_v1_document.rb +14 -14
- data/lib/mindee/product/receipt/receipt_v4_document.rb +6 -6
- data/lib/mindee/product/receipt/receipt_v5.rb +1 -0
- data/lib/mindee/product/receipt/receipt_v5_document.rb +12 -12
- data/lib/mindee/product/us/bank_check/bank_check_v1.rb +1 -0
- data/lib/mindee/product/us/bank_check/bank_check_v1_document.rb +8 -8
- data/lib/mindee/product/us/driver_license/driver_license_v1.rb +1 -0
- data/lib/mindee/product/us/driver_license/driver_license_v1_document.rb +28 -28
- data/lib/mindee/product/us/w9/w9_v1.rb +39 -0
- data/lib/mindee/product/us/w9/w9_v1_document.rb +15 -0
- data/lib/mindee/product/us/w9/w9_v1_page.rb +102 -0
- data/lib/mindee/product.rb +6 -0
- data/lib/mindee/version.rb +5 -1
- data/lib/mindee.rb +45 -1
- metadata +48 -9
- data/docs/ruby-api-builder.md +0 -123
- data/docs/ruby-invoice-ocr.md +0 -271
- data/docs/ruby-passport-ocr.md +0 -165
- data/docs/ruby-receipt-ocr.md +0 -196
- data/lib/mindee/parsing/common/error.rb +0 -24
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../parsing'
|
|
4
|
+
require_relative 'id_card_v2_document'
|
|
5
|
+
require_relative 'id_card_v2_page'
|
|
6
|
+
|
|
7
|
+
module Mindee
|
|
8
|
+
module Product
|
|
9
|
+
module FR
|
|
10
|
+
# Carte Nationale d'Identité module.
|
|
11
|
+
module IdCard
|
|
12
|
+
# Carte Nationale d'Identité V2 prediction inference.
|
|
13
|
+
class IdCardV2 < Mindee::Parsing::Common::Inference
|
|
14
|
+
@endpoint_name = 'idcard_fr'
|
|
15
|
+
@endpoint_version = '2'
|
|
16
|
+
|
|
17
|
+
# @param prediction [Hash]
|
|
18
|
+
def initialize(prediction)
|
|
19
|
+
super
|
|
20
|
+
@prediction = IdCardV2Document.new(prediction['prediction'], nil)
|
|
21
|
+
@pages = []
|
|
22
|
+
prediction['pages'].each do |page|
|
|
23
|
+
@pages.push(IdCardV2Page.new(page))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
# Name of the endpoint for this product.
|
|
29
|
+
# @return [String]
|
|
30
|
+
attr_reader :endpoint_name
|
|
31
|
+
# Version for this product.
|
|
32
|
+
# @return [String]
|
|
33
|
+
attr_reader :endpoint_version
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../parsing'
|
|
4
|
+
|
|
5
|
+
module Mindee
|
|
6
|
+
module Product
|
|
7
|
+
module FR
|
|
8
|
+
module IdCard
|
|
9
|
+
# Carte Nationale d'Identité V2 document prediction.
|
|
10
|
+
class IdCardV2Document < Mindee::Parsing::Common::Prediction
|
|
11
|
+
include Mindee::Parsing::Standard
|
|
12
|
+
# The alternate name of the card holder.
|
|
13
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
14
|
+
attr_reader :alternate_name
|
|
15
|
+
# The name of the issuing authority.
|
|
16
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
17
|
+
attr_reader :authority
|
|
18
|
+
# The date of birth of the card holder.
|
|
19
|
+
# @return [Mindee::Parsing::Standard::DateField]
|
|
20
|
+
attr_reader :birth_date
|
|
21
|
+
# The place of birth of the card holder.
|
|
22
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
23
|
+
attr_reader :birth_place
|
|
24
|
+
# The card access number (CAN).
|
|
25
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
26
|
+
attr_reader :card_access_number
|
|
27
|
+
# The document number.
|
|
28
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
29
|
+
attr_reader :document_number
|
|
30
|
+
# The expiry date of the identification card.
|
|
31
|
+
# @return [Mindee::Parsing::Standard::DateField]
|
|
32
|
+
attr_reader :expiry_date
|
|
33
|
+
# The gender of the card holder.
|
|
34
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
35
|
+
attr_reader :gender
|
|
36
|
+
# The given name(s) of the card holder.
|
|
37
|
+
# @return [Array<Mindee::Parsing::Standard::StringField>]
|
|
38
|
+
attr_reader :given_names
|
|
39
|
+
# The date of issue of the identification card.
|
|
40
|
+
# @return [Mindee::Parsing::Standard::DateField]
|
|
41
|
+
attr_reader :issue_date
|
|
42
|
+
# The Machine Readable Zone, first line.
|
|
43
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
44
|
+
attr_reader :mrz1
|
|
45
|
+
# The Machine Readable Zone, second line.
|
|
46
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
47
|
+
attr_reader :mrz2
|
|
48
|
+
# The Machine Readable Zone, third line.
|
|
49
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
50
|
+
attr_reader :mrz3
|
|
51
|
+
# The nationality of the card holder.
|
|
52
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
53
|
+
attr_reader :nationality
|
|
54
|
+
# The surname of the card holder.
|
|
55
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
56
|
+
attr_reader :surname
|
|
57
|
+
|
|
58
|
+
# @param prediction [Hash]
|
|
59
|
+
# @param page_id [Integer, nil]
|
|
60
|
+
def initialize(prediction, page_id)
|
|
61
|
+
super()
|
|
62
|
+
@alternate_name = StringField.new(prediction['alternate_name'], page_id)
|
|
63
|
+
@authority = StringField.new(prediction['authority'], page_id)
|
|
64
|
+
@birth_date = DateField.new(prediction['birth_date'], page_id)
|
|
65
|
+
@birth_place = StringField.new(prediction['birth_place'], page_id)
|
|
66
|
+
@card_access_number = StringField.new(prediction['card_access_number'], page_id)
|
|
67
|
+
@document_number = StringField.new(prediction['document_number'], page_id)
|
|
68
|
+
@expiry_date = DateField.new(prediction['expiry_date'], page_id)
|
|
69
|
+
@gender = StringField.new(prediction['gender'], page_id)
|
|
70
|
+
@given_names = []
|
|
71
|
+
prediction['given_names'].each do |item|
|
|
72
|
+
@given_names.push(StringField.new(item, page_id))
|
|
73
|
+
end
|
|
74
|
+
@issue_date = DateField.new(prediction['issue_date'], page_id)
|
|
75
|
+
@mrz1 = StringField.new(prediction['mrz1'], page_id)
|
|
76
|
+
@mrz2 = StringField.new(prediction['mrz2'], page_id)
|
|
77
|
+
@mrz3 = StringField.new(prediction['mrz3'], page_id)
|
|
78
|
+
@nationality = StringField.new(prediction['nationality'], page_id)
|
|
79
|
+
@surname = StringField.new(prediction['surname'], page_id)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [String]
|
|
83
|
+
def to_s
|
|
84
|
+
given_names = @given_names.join("\n #{' ' * 15}")
|
|
85
|
+
out_str = String.new
|
|
86
|
+
out_str << "\n:Nationality: #{@nationality}".rstrip
|
|
87
|
+
out_str << "\n:Card Access Number: #{@card_access_number}".rstrip
|
|
88
|
+
out_str << "\n:Document Number: #{@document_number}".rstrip
|
|
89
|
+
out_str << "\n:Given Name(s): #{given_names}".rstrip
|
|
90
|
+
out_str << "\n:Surname: #{@surname}".rstrip
|
|
91
|
+
out_str << "\n:Alternate Name: #{@alternate_name}".rstrip
|
|
92
|
+
out_str << "\n:Date of Birth: #{@birth_date}".rstrip
|
|
93
|
+
out_str << "\n:Place of Birth: #{@birth_place}".rstrip
|
|
94
|
+
out_str << "\n:Gender: #{@gender}".rstrip
|
|
95
|
+
out_str << "\n:Expiry Date: #{@expiry_date}".rstrip
|
|
96
|
+
out_str << "\n:Mrz Line 1: #{@mrz1}".rstrip
|
|
97
|
+
out_str << "\n:Mrz Line 2: #{@mrz2}".rstrip
|
|
98
|
+
out_str << "\n:Mrz Line 3: #{@mrz3}".rstrip
|
|
99
|
+
out_str << "\n:Date of Issue: #{@issue_date}".rstrip
|
|
100
|
+
out_str << "\n:Issuing Authority: #{@authority}".rstrip
|
|
101
|
+
out_str[1..].to_s
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../parsing'
|
|
4
|
+
require_relative 'id_card_v2_document'
|
|
5
|
+
|
|
6
|
+
module Mindee
|
|
7
|
+
module Product
|
|
8
|
+
module FR
|
|
9
|
+
module IdCard
|
|
10
|
+
# Carte Nationale d'Identité V2 page.
|
|
11
|
+
class IdCardV2Page < Mindee::Parsing::Common::Page
|
|
12
|
+
# @param prediction [Hash]
|
|
13
|
+
def initialize(prediction)
|
|
14
|
+
super(prediction)
|
|
15
|
+
@prediction = IdCardV2PagePrediction.new(
|
|
16
|
+
prediction['prediction'],
|
|
17
|
+
prediction['id']
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Carte Nationale d'Identité V2 page prediction.
|
|
23
|
+
class IdCardV2PagePrediction < IdCardV2Document
|
|
24
|
+
include Mindee::Parsing::Standard
|
|
25
|
+
|
|
26
|
+
# The sides of the document which are visible.
|
|
27
|
+
# @return [Mindee::Parsing::Standard::ClassificationField]
|
|
28
|
+
attr_reader :document_side
|
|
29
|
+
# The document type or format.
|
|
30
|
+
# @return [Mindee::Parsing::Standard::ClassificationField]
|
|
31
|
+
attr_reader :document_type
|
|
32
|
+
|
|
33
|
+
# @param prediction [Hash]
|
|
34
|
+
# @param page_id [Integer, nil]
|
|
35
|
+
def initialize(prediction, page_id)
|
|
36
|
+
@document_side = ClassificationField.new(prediction['document_side'], page_id)
|
|
37
|
+
@document_type = ClassificationField.new(prediction['document_type'], 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:Document Type: #{@document_type}".rstrip
|
|
45
|
+
out_str << "\n:Document Sides: #{@document_side}".rstrip
|
|
46
|
+
out_str << "\n#{super}"
|
|
47
|
+
out_str
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -6,10 +6,10 @@ require_relative 'invoice_v4_page'
|
|
|
6
6
|
|
|
7
7
|
module Mindee
|
|
8
8
|
module Product
|
|
9
|
+
# Invoice module.
|
|
9
10
|
module Invoice
|
|
10
|
-
# Invoice
|
|
11
|
+
# Invoice V4 prediction inference.
|
|
11
12
|
class InvoiceV4 < Mindee::Parsing::Common::Inference
|
|
12
|
-
include Mindee::Parsing::Common
|
|
13
13
|
@endpoint_name = 'invoices'
|
|
14
14
|
@endpoint_version = '4'
|
|
15
15
|
|
|
@@ -9,202 +9,162 @@ module Mindee
|
|
|
9
9
|
# Invoice V4 document prediction.
|
|
10
10
|
class InvoiceV4Document < Mindee::Parsing::Common::Prediction
|
|
11
11
|
include Mindee::Parsing::Standard
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
#
|
|
12
|
+
# The address of the customer.
|
|
13
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
14
|
+
attr_reader :customer_address
|
|
15
|
+
# List of company registrations associated to the customer.
|
|
16
|
+
# @return [Array<Mindee::Parsing::Standard::CompanyRegistrationField>]
|
|
17
|
+
attr_reader :customer_company_registrations
|
|
18
|
+
# The name of the customer or client.
|
|
19
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
20
|
+
attr_reader :customer_name
|
|
21
|
+
# The date the purchase was made.
|
|
22
|
+
# @return [Mindee::Parsing::Standard::DateField]
|
|
23
|
+
attr_reader :date
|
|
24
|
+
# One of: 'INVOICE', 'CREDIT NOTE'.
|
|
17
25
|
# @return [Mindee::Parsing::Standard::ClassificationField]
|
|
18
26
|
attr_reader :document_type
|
|
19
|
-
# The
|
|
20
|
-
# @return [Mindee::Parsing::Standard::AmountField]
|
|
21
|
-
attr_reader :total_amount
|
|
22
|
-
# The total amount without the tax value.
|
|
23
|
-
# @return [Mindee::Parsing::Standard::AmountField]
|
|
24
|
-
attr_reader :total_net
|
|
25
|
-
# The total tax.
|
|
26
|
-
# @return [Mindee::Parsing::Standard::AmountField]
|
|
27
|
-
attr_reader :total_tax
|
|
28
|
-
# The creation date of the invoice.
|
|
27
|
+
# The date on which the payment is due.
|
|
29
28
|
# @return [Mindee::Parsing::Standard::DateField]
|
|
30
|
-
attr_reader :
|
|
31
|
-
# The invoice number.
|
|
32
|
-
# @return [Mindee::Parsing::Standard::
|
|
29
|
+
attr_reader :due_date
|
|
30
|
+
# The invoice number or identifier.
|
|
31
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
33
32
|
attr_reader :invoice_number
|
|
34
|
-
# List of
|
|
35
|
-
# @return [Mindee::
|
|
33
|
+
# List of line item details.
|
|
34
|
+
# @return [Array<Mindee::Product::Invoice::InvoiceV4LineItem>]
|
|
35
|
+
attr_reader :line_items
|
|
36
|
+
# The locale detected on the document.
|
|
37
|
+
# @return [Mindee::Parsing::Standard::LocaleField]
|
|
38
|
+
attr_reader :locale
|
|
39
|
+
# List of Reference numbers, including PO number.
|
|
40
|
+
# @return [Array<Mindee::Parsing::Standard::StringField>]
|
|
36
41
|
attr_reader :reference_numbers
|
|
37
|
-
# The
|
|
38
|
-
# @return [Mindee::Parsing::Standard::
|
|
39
|
-
attr_reader :due_date
|
|
40
|
-
# The list of taxes.
|
|
41
|
-
# @return [Mindee::Parsing::Standard::Taxes]
|
|
42
|
-
attr_reader :taxes
|
|
43
|
-
# The name of the customer.
|
|
44
|
-
# @return [Mindee::Parsing::Standard::TextField]
|
|
45
|
-
attr_reader :customer_name
|
|
46
|
-
# The address of the customer.
|
|
47
|
-
# @return [Mindee::Parsing::Standard::TextField]
|
|
48
|
-
attr_reader :customer_address
|
|
49
|
-
# The company registration information for the customer.
|
|
50
|
-
# @return [Array<Mindee::Parsing::Standard::CompanyRegistration>]
|
|
51
|
-
attr_reader :customer_company_registrations
|
|
52
|
-
# The supplier's name.
|
|
53
|
-
# @return [Mindee::Parsing::Standard::TextField]
|
|
54
|
-
attr_reader :supplier_name
|
|
55
|
-
# The supplier's address.
|
|
56
|
-
# @return [Mindee::Parsing::Standard::TextField]
|
|
42
|
+
# The address of the supplier or merchant.
|
|
43
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
57
44
|
attr_reader :supplier_address
|
|
58
|
-
#
|
|
59
|
-
# @return [Array<Mindee::Parsing::Standard::
|
|
60
|
-
attr_reader :supplier_payment_details
|
|
61
|
-
# The supplier's company registration information.
|
|
62
|
-
# @return [Array<Mindee::Parsing::Standard::CompanyRegistration>]
|
|
45
|
+
# List of company registrations associated to the supplier.
|
|
46
|
+
# @return [Array<Mindee::Parsing::Standard::CompanyRegistrationField>]
|
|
63
47
|
attr_reader :supplier_company_registrations
|
|
64
|
-
#
|
|
65
|
-
# @return [
|
|
66
|
-
attr_reader :
|
|
48
|
+
# The name of the supplier or merchant.
|
|
49
|
+
# @return [Mindee::Parsing::Standard::StringField]
|
|
50
|
+
attr_reader :supplier_name
|
|
51
|
+
# List of payment details associated to the supplier.
|
|
52
|
+
# @return [Array<Mindee::Parsing::Standard::PaymentDetailsField>]
|
|
53
|
+
attr_reader :supplier_payment_details
|
|
54
|
+
# List of tax line details.
|
|
55
|
+
# @return [Mindee::Parsing::Standard::Taxes]
|
|
56
|
+
attr_reader :taxes
|
|
57
|
+
# The total amount paid: includes taxes, tips, fees, and other charges.
|
|
58
|
+
# @return [Mindee::Parsing::Standard::AmountField]
|
|
59
|
+
attr_reader :total_amount
|
|
60
|
+
# The net amount paid: does not include taxes, fees, and discounts.
|
|
61
|
+
# @return [Mindee::Parsing::Standard::AmountField]
|
|
62
|
+
attr_reader :total_net
|
|
67
63
|
|
|
68
64
|
# @param prediction [Hash]
|
|
69
65
|
# @param page_id [Integer, nil]
|
|
70
66
|
def initialize(prediction, page_id)
|
|
71
67
|
super()
|
|
72
|
-
@
|
|
73
|
-
@
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@customer_name =
|
|
68
|
+
@customer_address = StringField.new(prediction['customer_address'], page_id)
|
|
69
|
+
@customer_company_registrations = []
|
|
70
|
+
prediction['customer_company_registrations'].each do |item|
|
|
71
|
+
@customer_company_registrations.push(CompanyRegistrationField.new(item, page_id))
|
|
72
|
+
end
|
|
73
|
+
@customer_name = StringField.new(prediction['customer_name'], page_id)
|
|
78
74
|
@date = DateField.new(prediction['date'], page_id)
|
|
75
|
+
@document_type = ClassificationField.new(prediction['document_type'], page_id)
|
|
79
76
|
@due_date = DateField.new(prediction['due_date'], page_id)
|
|
80
|
-
@invoice_number =
|
|
81
|
-
@
|
|
82
|
-
|
|
77
|
+
@invoice_number = StringField.new(prediction['invoice_number'], page_id)
|
|
78
|
+
@line_items = []
|
|
79
|
+
prediction['line_items'].each do |item|
|
|
80
|
+
@line_items.push(InvoiceV4LineItem.new(item, page_id))
|
|
81
|
+
end
|
|
82
|
+
@locale = LocaleField.new(prediction['locale'], page_id)
|
|
83
83
|
@reference_numbers = []
|
|
84
84
|
prediction['reference_numbers'].each do |item|
|
|
85
|
-
@reference_numbers.push(
|
|
86
|
-
end
|
|
87
|
-
@customer_company_registrations = []
|
|
88
|
-
prediction['customer_company_registrations'].each do |item|
|
|
89
|
-
@customer_company_registrations.push(CompanyRegistration.new(item, page_id))
|
|
90
|
-
end
|
|
91
|
-
@taxes = Taxes.new(prediction['taxes'], page_id)
|
|
92
|
-
@supplier_payment_details = []
|
|
93
|
-
prediction['supplier_payment_details'].each do |item|
|
|
94
|
-
@supplier_payment_details.push(PaymentDetails.new(item, page_id))
|
|
85
|
+
@reference_numbers.push(StringField.new(item, page_id))
|
|
95
86
|
end
|
|
87
|
+
@supplier_address = StringField.new(prediction['supplier_address'], page_id)
|
|
96
88
|
@supplier_company_registrations = []
|
|
97
89
|
prediction['supplier_company_registrations'].each do |item|
|
|
98
|
-
@supplier_company_registrations.push(
|
|
90
|
+
@supplier_company_registrations.push(CompanyRegistrationField.new(item, page_id))
|
|
99
91
|
end
|
|
100
|
-
@
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
prediction['line_items'].each do |item|
|
|
105
|
-
@line_items.push(InvoiceV4LineItem.new(item, page_id))
|
|
92
|
+
@supplier_name = StringField.new(prediction['supplier_name'], page_id)
|
|
93
|
+
@supplier_payment_details = []
|
|
94
|
+
prediction['supplier_payment_details'].each do |item|
|
|
95
|
+
@supplier_payment_details.push(PaymentDetailsField.new(item, page_id))
|
|
106
96
|
end
|
|
107
|
-
|
|
97
|
+
@taxes = Taxes.new(prediction['taxes'], page_id)
|
|
98
|
+
@total_amount = AmountField.new(prediction['total_amount'], page_id)
|
|
99
|
+
@total_net = AmountField.new(prediction['total_net'], page_id)
|
|
108
100
|
end
|
|
109
101
|
|
|
110
102
|
# @return [String]
|
|
111
103
|
def to_s
|
|
112
|
-
|
|
113
|
-
supplier_payment_details = @supplier_payment_details.
|
|
114
|
-
supplier_company_registrations = @supplier_company_registrations.
|
|
115
|
-
|
|
104
|
+
reference_numbers = @reference_numbers.join("\n #{' ' * 19}")
|
|
105
|
+
supplier_payment_details = @supplier_payment_details.join("\n #{' ' * 26}")
|
|
106
|
+
supplier_company_registrations = @supplier_company_registrations.join("\n #{' ' * 32}")
|
|
107
|
+
customer_company_registrations = @customer_company_registrations.join("\n #{' ' * 32}")
|
|
108
|
+
line_items = line_items_to_s
|
|
116
109
|
out_str = String.new
|
|
117
110
|
out_str << "\n:Locale: #{@locale}".rstrip
|
|
118
|
-
out_str << "\n:
|
|
119
|
-
out_str << "\n:
|
|
120
|
-
out_str << "\n:
|
|
121
|
-
out_str << "\n:
|
|
122
|
-
out_str << "\n:
|
|
123
|
-
out_str << "\n:
|
|
124
|
-
out_str << "\n:Supplier address: #{@supplier_address}".rstrip
|
|
125
|
-
out_str << "\n:Supplier company registrations: #{supplier_company_registrations}".rstrip
|
|
126
|
-
out_str << "\n:Supplier payment details: #{supplier_payment_details}".rstrip
|
|
127
|
-
out_str << "\n:Customer name: #{@customer_name}".rstrip
|
|
128
|
-
out_str << "\n:Customer address: #{@customer_address}".rstrip
|
|
129
|
-
out_str << "\n:Customer company registrations: #{customer_company_registrations}".rstrip
|
|
111
|
+
out_str << "\n:Invoice Number: #{@invoice_number}".rstrip
|
|
112
|
+
out_str << "\n:Reference Numbers: #{reference_numbers}".rstrip
|
|
113
|
+
out_str << "\n:Purchase Date: #{@date}".rstrip
|
|
114
|
+
out_str << "\n:Due Date: #{@due_date}".rstrip
|
|
115
|
+
out_str << "\n:Total Net: #{@total_net}".rstrip
|
|
116
|
+
out_str << "\n:Total Amount: #{@total_amount}".rstrip
|
|
130
117
|
out_str << "\n:Taxes:#{@taxes}".rstrip
|
|
131
|
-
out_str << "\n:
|
|
132
|
-
out_str << "\n:
|
|
133
|
-
out_str << "\n:
|
|
118
|
+
out_str << "\n:Supplier Payment Details: #{supplier_payment_details}".rstrip
|
|
119
|
+
out_str << "\n:Supplier Name: #{@supplier_name}".rstrip
|
|
120
|
+
out_str << "\n:Supplier Company Registrations: #{supplier_company_registrations}".rstrip
|
|
121
|
+
out_str << "\n:Supplier Address: #{@supplier_address}".rstrip
|
|
122
|
+
out_str << "\n:Customer Name: #{@customer_name}".rstrip
|
|
123
|
+
out_str << "\n:Customer Company Registrations: #{customer_company_registrations}".rstrip
|
|
124
|
+
out_str << "\n:Customer Address: #{@customer_address}".rstrip
|
|
125
|
+
out_str << "\n:Document Type: #{@document_type}".rstrip
|
|
134
126
|
out_str << "\n:Line Items:"
|
|
135
|
-
out_str <<
|
|
127
|
+
out_str << line_items
|
|
136
128
|
out_str[1..].to_s
|
|
137
129
|
end
|
|
138
130
|
|
|
139
131
|
private
|
|
140
132
|
|
|
141
|
-
|
|
142
|
-
|
|
133
|
+
# @param char [String]
|
|
134
|
+
# @return [String]
|
|
135
|
+
def line_items_separator(char)
|
|
136
|
+
out_str = String.new
|
|
137
|
+
out_str << ' '
|
|
138
|
+
out_str << "+#{char * 38}"
|
|
139
|
+
out_str << "+#{char * 14}"
|
|
140
|
+
out_str << "+#{char * 10}"
|
|
141
|
+
out_str << "+#{char * 12}"
|
|
142
|
+
out_str << "+#{char * 14}"
|
|
143
|
+
out_str << "+#{char * 14}"
|
|
144
|
+
out_str << "+#{char * 12}"
|
|
145
|
+
out_str << '+'
|
|
146
|
+
out_str
|
|
143
147
|
end
|
|
144
148
|
|
|
149
|
+
# @return [String]
|
|
145
150
|
def line_items_to_s
|
|
146
151
|
return '' if @line_items.empty?
|
|
147
152
|
|
|
148
|
-
line_items = @line_items.map(&:
|
|
153
|
+
line_items = @line_items.map(&:to_table_line).join("\n#{line_items_separator('-')}\n ")
|
|
149
154
|
out_str = String.new
|
|
150
|
-
out_str << "\n#{
|
|
151
|
-
out_str << "\n |
|
|
152
|
-
out_str <<
|
|
155
|
+
out_str << "\n#{line_items_separator('-')}"
|
|
156
|
+
out_str << "\n |"
|
|
157
|
+
out_str << ' Description |'
|
|
158
|
+
out_str << ' Product code |'
|
|
159
|
+
out_str << ' Quantity |'
|
|
160
|
+
out_str << ' Tax Amount |'
|
|
161
|
+
out_str << ' Tax Rate (%) |'
|
|
162
|
+
out_str << ' Total Amount |'
|
|
163
|
+
out_str << ' Unit Price |'
|
|
164
|
+
out_str << "\n#{line_items_separator('=')}"
|
|
153
165
|
out_str << "\n #{line_items}"
|
|
154
|
-
out_str << "\n#{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def reconstruct(page_id)
|
|
158
|
-
construct_total_tax_from_taxes(page_id)
|
|
159
|
-
return unless page_id.nil?
|
|
160
|
-
|
|
161
|
-
construct_total_excl_from_tcc_and_taxes(page_id)
|
|
162
|
-
construct_total_incl_from_taxes_plus_excl(page_id)
|
|
163
|
-
construct_total_tax_from_totals(page_id)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def construct_total_excl_from_tcc_and_taxes(page_id)
|
|
167
|
-
return if @total_amount.value.nil? || taxes.empty? || !@total_net.value.nil?
|
|
168
|
-
|
|
169
|
-
total_excl = {
|
|
170
|
-
'value' => @total_amount.value - @taxes.map(&:value).sum,
|
|
171
|
-
'confidence' => TextField.array_confidence(@taxes) * @total_amount.confidence,
|
|
172
|
-
}
|
|
173
|
-
@total_net = AmountField.new(total_excl, page_id, reconstructed: true)
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def construct_total_incl_from_taxes_plus_excl(page_id)
|
|
177
|
-
return if @total_net.value.nil? || @taxes.empty? || !@total_amount.value.nil?
|
|
178
|
-
|
|
179
|
-
total_incl = {
|
|
180
|
-
'value' => @taxes.map(&:value).sum + @total_net.value,
|
|
181
|
-
'confidence' => TextField.array_confidence(@taxes) * @total_net.confidence,
|
|
182
|
-
}
|
|
183
|
-
@total_amount = AmountField.new(total_incl, page_id, reconstructed: true)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def construct_total_tax_from_taxes(page_id)
|
|
187
|
-
return if @taxes.empty?
|
|
188
|
-
|
|
189
|
-
total_tax = {
|
|
190
|
-
'value' => @taxes.map(&:value).sum,
|
|
191
|
-
'confidence' => TextField.array_confidence(@taxes),
|
|
192
|
-
}
|
|
193
|
-
return unless total_tax['value'].positive?
|
|
194
|
-
|
|
195
|
-
@total_tax = AmountField.new(total_tax, page_id, reconstructed: true)
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def construct_total_tax_from_totals(page_id)
|
|
199
|
-
return if !@total_tax.value.nil? || @total_amount.value.nil? || @total_net.value.nil?
|
|
200
|
-
|
|
201
|
-
total_tax = {
|
|
202
|
-
'value' => @total_amount.value - @total_net.value,
|
|
203
|
-
'confidence' => TextField.array_confidence(@taxes),
|
|
204
|
-
}
|
|
205
|
-
return unless total_tax['value'] >= 0
|
|
206
|
-
|
|
207
|
-
@total_tax = AmountField.new(total_tax, page_id, reconstructed: true)
|
|
166
|
+
out_str << "\n#{line_items_separator('-')}"
|
|
167
|
+
out_str
|
|
208
168
|
end
|
|
209
169
|
end
|
|
210
170
|
end
|
|
@@ -5,61 +5,85 @@ require_relative '../../parsing'
|
|
|
5
5
|
module Mindee
|
|
6
6
|
module Product
|
|
7
7
|
module Invoice
|
|
8
|
-
#
|
|
9
|
-
class InvoiceV4LineItem
|
|
10
|
-
include Mindee::Parsing::Common
|
|
8
|
+
# List of line item details.
|
|
9
|
+
class InvoiceV4LineItem < Mindee::Parsing::Standard::FeatureField
|
|
11
10
|
include Mindee::Parsing::Standard
|
|
12
|
-
#
|
|
13
|
-
attr_reader :product_code
|
|
11
|
+
# The item description.
|
|
14
12
|
# @return [String]
|
|
15
13
|
attr_reader :description
|
|
14
|
+
# The product code referring to the item.
|
|
15
|
+
# @return [String]
|
|
16
|
+
attr_reader :product_code
|
|
17
|
+
# The item quantity
|
|
16
18
|
# @return [Float]
|
|
17
19
|
attr_reader :quantity
|
|
20
|
+
# The item tax amount.
|
|
18
21
|
# @return [Float]
|
|
19
|
-
attr_reader :
|
|
22
|
+
attr_reader :tax_amount
|
|
23
|
+
# The item tax rate in percentage.
|
|
20
24
|
# @return [Float]
|
|
21
|
-
attr_reader :total_amount
|
|
22
|
-
# @return [Float] The item tax rate percentage.
|
|
23
25
|
attr_reader :tax_rate
|
|
26
|
+
# The item total amount.
|
|
24
27
|
# @return [Float]
|
|
25
|
-
attr_reader :
|
|
28
|
+
attr_reader :total_amount
|
|
29
|
+
# The item unit price.
|
|
26
30
|
# @return [Float]
|
|
27
|
-
attr_reader :
|
|
28
|
-
# @return [Integer]
|
|
29
|
-
attr_reader :page_id
|
|
30
|
-
# @return [Mindee::Geometry::Quadrilateral]
|
|
31
|
-
attr_reader :bounding_box
|
|
32
|
-
# @return [Array<Mindee::Geometry::Polygon>]
|
|
33
|
-
attr_reader :polygon
|
|
31
|
+
attr_reader :unit_price
|
|
34
32
|
|
|
35
33
|
# @param prediction [Hash]
|
|
36
34
|
# @param page_id [Integer, nil]
|
|
37
35
|
def initialize(prediction, page_id)
|
|
36
|
+
super(prediction, page_id)
|
|
37
|
+
@description = prediction['description']
|
|
38
38
|
@product_code = prediction['product_code']
|
|
39
39
|
@quantity = prediction['quantity']
|
|
40
|
-
@unit_price = prediction['unit_price']
|
|
41
|
-
@total_amount = prediction['total_amount']
|
|
42
40
|
@tax_amount = prediction['tax_amount']
|
|
43
41
|
@tax_rate = prediction['tax_rate']
|
|
44
|
-
@
|
|
42
|
+
@total_amount = prediction['total_amount']
|
|
43
|
+
@unit_price = prediction['unit_price']
|
|
45
44
|
@page_id = page_id
|
|
46
45
|
end
|
|
47
46
|
|
|
47
|
+
# @return [Hash]
|
|
48
|
+
def printable_values
|
|
49
|
+
printable = {}
|
|
50
|
+
printable[:description] = format_for_display(@description, 36)
|
|
51
|
+
printable[:product_code] = format_for_display(@product_code, nil)
|
|
52
|
+
printable[:quantity] = @quantity.nil? ? '' : Field.float_to_string(@quantity)
|
|
53
|
+
printable[:tax_amount] = @tax_amount.nil? ? '' : Field.float_to_string(@tax_amount)
|
|
54
|
+
printable[:tax_rate] = @tax_rate.nil? ? '' : Field.float_to_string(@tax_rate)
|
|
55
|
+
printable[:total_amount] = @total_amount.nil? ? '' : Field.float_to_string(@total_amount)
|
|
56
|
+
printable[:unit_price] = @unit_price.nil? ? '' : Field.float_to_string(@unit_price)
|
|
57
|
+
printable
|
|
58
|
+
end
|
|
59
|
+
|
|
48
60
|
# @return [String]
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
tax << " (#{Field.float_to_string(@tax_rate)}%)" unless @tax_rate.nil?
|
|
52
|
-
description = @description.nil? ? '' : @description
|
|
53
|
-
description = "#{description[0..32]}..." if description.size > 35
|
|
61
|
+
def to_table_line
|
|
62
|
+
printable = printable_values
|
|
54
63
|
out_str = String.new
|
|
55
|
-
out_str << format('| %-
|
|
56
|
-
out_str <<
|
|
57
|
-
out_str <<
|
|
58
|
-
out_str <<
|
|
59
|
-
out_str <<
|
|
60
|
-
out_str <<
|
|
64
|
+
out_str << format('| %- 37s', printable[:description])
|
|
65
|
+
out_str << format('| %- 13s', printable[:product_code])
|
|
66
|
+
out_str << format('| %- 9s', printable[:quantity])
|
|
67
|
+
out_str << format('| %- 11s', printable[:tax_amount])
|
|
68
|
+
out_str << format('| %- 13s', printable[:tax_rate])
|
|
69
|
+
out_str << format('| %- 13s', printable[:total_amount])
|
|
70
|
+
out_str << format('| %- 11s', printable[:unit_price])
|
|
61
71
|
out_str << '|'
|
|
62
72
|
end
|
|
73
|
+
|
|
74
|
+
# @return [String]
|
|
75
|
+
def to_s
|
|
76
|
+
printable = printable_values
|
|
77
|
+
out_str = String.new
|
|
78
|
+
out_str << "\n :Description: #{printable[:description]}"
|
|
79
|
+
out_str << "\n :Product code: #{printable[:product_code]}"
|
|
80
|
+
out_str << "\n :Quantity: #{printable[:quantity]}"
|
|
81
|
+
out_str << "\n :Tax Amount: #{printable[:tax_amount]}"
|
|
82
|
+
out_str << "\n :Tax Rate (%): #{printable[:tax_rate]}"
|
|
83
|
+
out_str << "\n :Total Amount: #{printable[:total_amount]}"
|
|
84
|
+
out_str << "\n :Unit Price: #{printable[:unit_price]}"
|
|
85
|
+
out_str
|
|
86
|
+
end
|
|
63
87
|
end
|
|
64
88
|
end
|
|
65
89
|
end
|