trustid_sdk 0.2.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 (90) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +80 -0
  3. data/lib/trustid_sdk/client.rb +21 -0
  4. data/lib/trustid_sdk/concerns/attribute_resolution.rb +19 -0
  5. data/lib/trustid_sdk/concerns/has_nested_models.rb +179 -0
  6. data/lib/trustid_sdk/config.rb +45 -0
  7. data/lib/trustid_sdk/errors.rb +23 -0
  8. data/lib/trustid_sdk/models/access_lock.rb +28 -0
  9. data/lib/trustid_sdk/models/advanced_query_arguments.rb +78 -0
  10. data/lib/trustid_sdk/models/application_flexible_field.rb +34 -0
  11. data/lib/trustid_sdk/models/application_flexible_field_attribute.rb +75 -0
  12. data/lib/trustid_sdk/models/application_flexible_field_list.rb +79 -0
  13. data/lib/trustid_sdk/models/application_flexible_field_value.rb +79 -0
  14. data/lib/trustid_sdk/models/base_model.rb +53 -0
  15. data/lib/trustid_sdk/models/branch.rb +34 -0
  16. data/lib/trustid_sdk/models/callback_info.rb +33 -0
  17. data/lib/trustid_sdk/models/callback_state.rb +46 -0
  18. data/lib/trustid_sdk/models/chargeable_status.rb +31 -0
  19. data/lib/trustid_sdk/models/configuration.rb +78 -0
  20. data/lib/trustid_sdk/models/container.rb +254 -0
  21. data/lib/trustid_sdk/models/custom_field.rb +29 -0
  22. data/lib/trustid_sdk/models/dbs_check_initiation.rb +14 -0
  23. data/lib/trustid_sdk/models/dbs_form.rb +108 -0
  24. data/lib/trustid_sdk/models/digital_identification_scheme.rb +43 -0
  25. data/lib/trustid_sdk/models/document.rb +646 -0
  26. data/lib/trustid_sdk/models/document_configuration.rb +21 -0
  27. data/lib/trustid_sdk/models/document_container_field.rb +31 -0
  28. data/lib/trustid_sdk/models/document_container_validation.rb +45 -0
  29. data/lib/trustid_sdk/models/document_container_validation_outcome.rb +58 -0
  30. data/lib/trustid_sdk/models/document_feature_feedback.rb +24 -0
  31. data/lib/trustid_sdk/models/document_feedback.rb +35 -0
  32. data/lib/trustid_sdk/models/document_field.rb +48 -0
  33. data/lib/trustid_sdk/models/document_field_data_type.rb +22 -0
  34. data/lib/trustid_sdk/models/document_field_source.rb +34 -0
  35. data/lib/trustid_sdk/models/document_sorting_column.rb +27 -0
  36. data/lib/trustid_sdk/models/document_source.rb +29 -0
  37. data/lib/trustid_sdk/models/document_status.rb +34 -0
  38. data/lib/trustid_sdk/models/document_storage_type.rb +32 -0
  39. data/lib/trustid_sdk/models/document_type.rb +46 -0
  40. data/lib/trustid_sdk/models/document_type_charge_status.rb +37 -0
  41. data/lib/trustid_sdk/models/document_validation.rb +45 -0
  42. data/lib/trustid_sdk/models/document_validation_result.rb +60 -0
  43. data/lib/trustid_sdk/models/established_document_data.rb +20 -0
  44. data/lib/trustid_sdk/models/external_service_data.rb +29 -0
  45. data/lib/trustid_sdk/models/filter_date_option.rb +36 -0
  46. data/lib/trustid_sdk/models/flexible_field_data_type.rb +39 -0
  47. data/lib/trustid_sdk/models/flexible_field_search_specification.rb +50 -0
  48. data/lib/trustid_sdk/models/flexible_field_specification_search_operator.rb +30 -0
  49. data/lib/trustid_sdk/models/gender.rb +31 -0
  50. data/lib/trustid_sdk/models/guest_link_response.rb +38 -0
  51. data/lib/trustid_sdk/models/image.rb +101 -0
  52. data/lib/trustid_sdk/models/image_orientation.rb +52 -0
  53. data/lib/trustid_sdk/models/image_type.rb +89 -0
  54. data/lib/trustid_sdk/models/kdb_country.rb +37 -0
  55. data/lib/trustid_sdk/models/kdb_document_number.rb +37 -0
  56. data/lib/trustid_sdk/models/kdb_document_sub_type.rb +28 -0
  57. data/lib/trustid_sdk/models/kdb_feature_type.rb +45 -0
  58. data/lib/trustid_sdk/models/liveness_result_type.rb +55 -0
  59. data/lib/trustid_sdk/models/mrz_query_option.rb +35 -0
  60. data/lib/trustid_sdk/models/ocr_coordinates.rb +19 -0
  61. data/lib/trustid_sdk/models/ocr_field.rb +78 -0
  62. data/lib/trustid_sdk/models/ocr_field_data.rb +28 -0
  63. data/lib/trustid_sdk/models/organisation.rb +19 -0
  64. data/lib/trustid_sdk/models/overall_status.rb +39 -0
  65. data/lib/trustid_sdk/models/pdf.rb +17 -0
  66. data/lib/trustid_sdk/models/referral_history_record.rb +68 -0
  67. data/lib/trustid_sdk/models/referral_type.rb +27 -0
  68. data/lib/trustid_sdk/models/remaining_credits.rb +16 -0
  69. data/lib/trustid_sdk/models/report.rb +17 -0
  70. data/lib/trustid_sdk/models/review_application_state.rb +33 -0
  71. data/lib/trustid_sdk/models/sorting_direction.rb +28 -0
  72. data/lib/trustid_sdk/models/user.rb +41 -0
  73. data/lib/trustid_sdk/models/user_archive_visibility.rb +28 -0
  74. data/lib/trustid_sdk/models/user_reference.rb +16 -0
  75. data/lib/trustid_sdk/models/webhook_callback.rb +129 -0
  76. data/lib/trustid_sdk/models/webhook_data.rb +272 -0
  77. data/lib/trustid_sdk/models/webhook_response.rb +89 -0
  78. data/lib/trustid_sdk/models/workflow_storage_item.rb +52 -0
  79. data/lib/trustid_sdk/models/workflow_type.rb +31 -0
  80. data/lib/trustid_sdk/request.rb +116 -0
  81. data/lib/trustid_sdk/services/authentication.rb +23 -0
  82. data/lib/trustid_sdk/services/containers.rb +20 -0
  83. data/lib/trustid_sdk/services/documents.rb +23 -0
  84. data/lib/trustid_sdk/services/guest_links.rb +19 -0
  85. data/lib/trustid_sdk/services/images.rb +21 -0
  86. data/lib/trustid_sdk/services/reports.rb +79 -0
  87. data/lib/trustid_sdk/services/webhook_parser.rb +220 -0
  88. data/lib/trustid_sdk/version.rb +5 -0
  89. data/lib/trustid_sdk.rb +23 -0
  90. metadata +186 -0
@@ -0,0 +1,646 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'image'
4
+ require_relative 'document_type'
5
+ require_relative 'document_status'
6
+ require_relative 'document_field'
7
+ require_relative 'document_validation'
8
+ require_relative 'document_validation_result'
9
+ require_relative 'external_service_data'
10
+ require_relative 'document_feedback'
11
+ require_relative 'document_configuration'
12
+ require_relative 'kdb_country'
13
+ require_relative 'kdb_document_sub_type'
14
+
15
+ module TrustID
16
+ # Document
17
+ #
18
+ # Represents a document and its metadata in the TrustID system (TrustID API).
19
+ #
20
+ # Fields:
21
+ # aspect_ratio - Float: Aspect ratio of the document image.
22
+ # audited - Boolean: Whether the document has been audited.
23
+ # audited_by_user - String: User who audited the document.
24
+ # auditor_message - String: Message from the auditor.
25
+ # auditor_status - Integer: Auditor status (see DocumentStatus).
26
+ # blacklisted - Boolean: Whether the document is blacklisted.
27
+ # blacklisted_at - DateTime: When the document was blacklisted.
28
+ # branch_name - String: Name of the branch.
29
+ # compatibility_document_sub_type_code - String: Compatibility document sub-type code.
30
+ # compatibility_document_type_code - String: Compatibility document type code.
31
+ # compatibility_issuing_country_code - String: Compatibility issuing country code.
32
+ # compatibility_nationality_code - String: Compatibility nationality code.
33
+ # contactless_chip_read_state - Integer: Contactless chip read state.
34
+ # container_id - String: ID of the container this document belongs to.
35
+ # continued_manually - Boolean: Whether the document was continued manually.
36
+ # created_at - DateTime: When the document was created.
37
+ # custom_field_dictionary - Array<{ key: String, value: CustomField }>: Custom fields.
38
+ # custom_field_keys - Array<String>: Keys for custom fields.
39
+ # detected_orientation - Integer: Detected image orientation (see ImageOrientation).
40
+ # document_completed - Boolean: Whether the document is completed.
41
+ # document_configuration - DocumentConfiguration: Document configuration.
42
+ # document_fields - Array<DocumentField>: Document fields.
43
+ # document_id - String: Document ID.
44
+ # document_name - String: Name of the document.
45
+ # document_results_summary - Array<DocumentFeedback>: Results summary.
46
+ # document_sub_type - Integer: Document sub-type (see KDBDocumentSubType).
47
+ # document_type - Integer: Document type (see DocumentType).
48
+ # document_validations - Array<DocumentValidation>: Document validations.
49
+ # document_version - String: Version of the document.
50
+ # driving_licence_category - String: Driving licence category.
51
+ # editable - Boolean: Whether the document is editable.
52
+ # expiry_notification - Boolean: Expiry notification flag.
53
+ # external_services - Array<ExternalServiceData>: External services data.
54
+ # external_services_queried - Boolean: Whether external services were queried.
55
+ # feedback_face - Integer: Feedback face.
56
+ # feedback_features - Array<DocumentFeatureFeedback>: Feedback features.
57
+ # feedback_has_mrz - Boolean: Whether feedback has MRZ.
58
+ # feedback_person_matches - Integer: Number of person matches in feedback.
59
+ # feedback_rfid_image_matches - Boolean or nil: Whether RFID image matches.
60
+ # feedback_uv - Integer: Feedback UV.
61
+ # feedback_uv_pattern - Integer: Feedback UV pattern.
62
+ # font - String: Font.
63
+ # font_alignment - Integer: Font alignment.
64
+ # font_height - Integer: Font height.
65
+ # forwarded - Boolean: Forwarded flag.
66
+ # general_document_properties - Array<DocumentFeedback>: General document properties.
67
+ # has_error - Boolean: Whether the document has an error.
68
+ # high_risk_country - Boolean: High risk country flag.
69
+ # images - Array<Image>: Associated images.
70
+ # issuing_authority - String: Issuing authority.
71
+ # issuing_country - Integer: Issuing country (see KDBCountry).
72
+ # kdb - Boolean: KDB flag.
73
+ # locked - Boolean: Locked flag.
74
+ # mandatory_document_fields_flag - Integer: Mandatory document fields flag.
75
+ # mrz_corrected - Boolean: Whether MRZ was corrected.
76
+ # mrz_correction_provided - Boolean: Whether MRZ correction was provided.
77
+ # max_age_failed - Integer or nil: Max age failed value.
78
+ # min_age_failed - Integer or nil: Min age failed value.
79
+ # missing_fields_properties - Array<DocumentFeedback>: Missing fields properties.
80
+ # mrz - String: MRZ string.
81
+ # mrz_character_count - Integer: MRZ character count.
82
+ # mrz_image_type - Integer: MRZ image type (see ImageType).
83
+ # mrz_line_count - Integer: MRZ line count.
84
+ # mrz_same_length - Boolean: Whether MRZ lines are the same length.
85
+ # mrz_validation_properties - Array<DocumentFeedback>: MRZ validation properties.
86
+ # nationality - Integer: Nationality (see KDBCountry).
87
+ # no_initial_face_image - Boolean: No initial face image flag.
88
+ # notes - String: Notes.
89
+ # ocr_data_applied - Boolean: Whether OCR data was applied.
90
+ # ocr_field_data - Array<OcrFieldData>: OCR field data.
91
+ # ocr_type - Integer: OCR type.
92
+ # operator_message - String: Operator message.
93
+ # operator_status - Integer: Operator status (see DocumentStatus).
94
+ # optional_document_fields_flag - Integer: Optional document fields flag.
95
+ # original_mrz - String: Original MRZ string.
96
+ # partially_recognised - Boolean: Partially recognised flag.
97
+ # reading_attempts_count - Integer: Reading attempts count.
98
+ # rfid_failed - Boolean: RFID failed flag.
99
+ # rfid_mrz - String: RFID MRZ string.
100
+ # rule_denied - Boolean: Rule denied flag.
101
+ # scan_counter - Integer: Scan counter.
102
+ # scanned_at - DateTime: When the document was scanned.
103
+ # scanner_type - String: Scanner type.
104
+ # seen_before_document_container_id - String: Seen before document container ID.
105
+ # seen_before_document_id - String: Seen before document ID.
106
+ # successfully_read - Boolean: Successfully read flag.
107
+ # supporting_document_name - String: Supporting document name.
108
+ # system_id - String: System ID.
109
+ # unrecognised - Boolean: Unrecognised flag.
110
+ # updated_at - DateTime: When the document was last updated.
111
+ # valid_from - Date: Valid from date.
112
+ # valid_length - Boolean: Valid length flag.
113
+ # vpe_device_id - String: VPE device ID.
114
+ # vpe_name - String: VPE name.
115
+ # wizard_completed - Boolean: Wizard completed flag.
116
+ # workflow_flags - Integer: Workflow flags.
117
+ #
118
+ # The model resolves nested/related models for images and custom fields, and provides full access to all
119
+ # TrustID document metadata.
120
+ #
121
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/Document.html
122
+ class Document < BaseModel # rubocop:disable Metrics/ClassLength
123
+ include ActiveModel::Model
124
+ include ActiveModel::Attributes
125
+
126
+ # Attributes (from TrustID API):
127
+ # - aspect_ratio: Float
128
+ # - audited: Boolean
129
+ # - audited_by_user: String
130
+ # - auditor_message: String
131
+ # - auditor_status: Integer (see DocumentStatus)
132
+ # - blacklisted: Boolean
133
+ # - blacklisted_at: String (ISO8601 datetime)
134
+ # - branch_name: String
135
+ # - compatibility_document_sub_type_code: String
136
+ # - compatibility_document_type_code: String
137
+ # - compatibility_issuing_country_code: String
138
+ # - compatibility_nationality_code: String
139
+ # - contactless_chip_read_state: Integer
140
+ # - container_id: String
141
+ # - continued_manually: Boolean
142
+ # - created_at: String (ISO8601 datetime)
143
+ # - custom_field_dictionary: Array of { key: String, value: CustomField }
144
+ # - custom_field_keys: Array of String
145
+ # - detected_orientation: Integer (see ImageOrientation)
146
+ # - document_completed: Boolean
147
+ # - document_configuration: DocumentConfiguration
148
+ # - document_fields: Array of DocumentField
149
+ # - document_id: String
150
+ # - document_name: String
151
+ # - document_results_summary: Array of DocumentFeedback
152
+ # - document_sub_type: Integer (see KDBDocumentSubType)
153
+ # - document_type: Integer (see DocumentType)
154
+ # - document_validations: Array of DocumentValidation
155
+ # - document_version: String
156
+ # - driving_licence_category: String
157
+ # - editable: Boolean
158
+ # - expiry_notification: Boolean
159
+ # - external_services: Array of ExternalServiceData
160
+ # - external_services_queried: Boolean
161
+ # - feedback_face: Integer
162
+ # - feedback_features: Array of DocumentFeatureFeedback
163
+ # - feedback_has_mrz: Boolean
164
+ # - feedback_person_matches: Integer
165
+ # - feedback_rfid_image_matches: Boolean or nil
166
+ # - feedback_uv: Integer
167
+ # - feedback_uv_pattern: Integer
168
+ # - font: String
169
+ # - font_alignment: Integer
170
+ # - font_height: Integer
171
+ # - forwarded: Boolean
172
+ # - general_document_properties: Array of DocumentFeedback
173
+ # - has_error: Boolean
174
+ # - high_risk_country: Boolean
175
+ # - images: Array of Image
176
+ # - issuing_authority: String
177
+ # - issuing_country: Integer (see KDBCountry)
178
+ # - kdb: Boolean
179
+ # - locked: Boolean
180
+ # - mandatory_document_fields_flag: Integer
181
+ # - mrz_corrected: Boolean
182
+ # - mrz_correction_provided: Boolean
183
+ # - max_age_failed: Integer or nil
184
+ # - min_age_failed: Integer or nil
185
+ # - missing_fields_properties: Array of DocumentFeedback
186
+ # - mrz: String
187
+ # - mrz_character_count: Integer
188
+ # - mrz_image_type: Integer (see ImageType)
189
+ # - mrz_line_count: Integer
190
+ # - mrz_same_length: Boolean
191
+ # - mrz_validation_properties: Array of DocumentFeedback
192
+ # - nationality: Integer (see KDBCountry)
193
+ # - no_initial_face_image: Boolean
194
+ # - notes: String
195
+ # - ocr_data_applied: Boolean
196
+ # - ocr_field_data: Array of OcrFieldData
197
+ # - ocr_type: Integer
198
+ # - operator_message: String
199
+ # - operator_status: Integer (see DocumentStatus)
200
+ # - optional_document_fields_flag: Integer
201
+ # - original_mrz: String
202
+ # - partially_recognised: Boolean
203
+ # - reading_attempts_count: Integer
204
+ # - rfid_failed: Boolean
205
+ # - rfid_mrz: String
206
+ # - rule_denied: Boolean
207
+ # - scan_counter: Integer
208
+ # - scanned_at: String (ISO8601 datetime)
209
+ # - scanner_type: String
210
+ # - seen_before_document_container_id: String
211
+ # - seen_before_document_id: String
212
+ # - successfully_read: Boolean
213
+ # - supporting_document_name: String
214
+ # - system_id: String
215
+ # - unrecognised: Boolean
216
+ # - updated_at: String (ISO8601 datetime)
217
+ # - valid_from: String (ISO8601 date)
218
+ # - valid_length: Boolean
219
+ # - vpe_device_id: String
220
+ # - vpe_name: String
221
+ # - wizard_completed: Boolean
222
+ # - workflow_flags: Integer
223
+ #
224
+
225
+ attribute :aspect_ratio, :float
226
+ attribute :audited, :boolean
227
+ attribute :audited_by_user, :string
228
+ attribute :auditor_message, :string
229
+ attribute :auditor_status, :integer
230
+ attribute :blacklisted, :boolean
231
+ attribute :blacklisted_at, :datetime
232
+ attribute :branch_name, :string
233
+ attribute :compatibility_document_sub_type_code, :string
234
+ attribute :compatibility_document_type_code, :string
235
+ attribute :compatibility_issuing_country_code, :string
236
+ attribute :compatibility_nationality_code, :string
237
+ attribute :contactless_chip_read_state, :integer
238
+ attribute :container_id, :string
239
+ attribute :continued_manually, :boolean
240
+ attribute :created_at, :datetime
241
+ attribute :custom_field_dictionary
242
+ attribute :custom_field_keys
243
+ attribute :detected_orientation, :integer
244
+ attribute :document_completed, :boolean
245
+ attribute :document_configuration
246
+ attribute :document_fields
247
+ attribute :document_id, :string
248
+ # NOTE: 'id' is a Container-level attribute, not a Document attribute.
249
+ # It may appear in some API responses but is ignored here.
250
+ attribute :id, :string
251
+ attribute :document_name, :string
252
+ attribute :document_results_summary
253
+ attribute :document_sub_type
254
+ attribute :document_type, :integer
255
+ attribute :document_validations
256
+ attribute :document_version, :string
257
+ attribute :driving_licence_category, :string
258
+ attribute :editable, :boolean
259
+ attribute :expiry_notification, :boolean
260
+ attribute :external_services
261
+ attribute :external_services_queried, :boolean
262
+ attribute :feedback_face, :integer
263
+ attribute :feedback_features
264
+ attribute :feedback_has_mrz, :boolean
265
+ attribute :feedback_person_matches, :integer
266
+ attribute :feedback_rfid_image_matches
267
+ attribute :feedback_uv, :integer
268
+ attribute :feedback_uv_pattern, :integer
269
+ attribute :font, :string
270
+ attribute :font_alignment, :integer
271
+ attribute :font_height, :integer
272
+ attribute :forwarded, :boolean
273
+ attribute :general_document_properties
274
+ attribute :has_error, :boolean
275
+ attribute :high_risk_country, :boolean
276
+ attribute :issuing_authority, :string
277
+ attribute :issuing_country
278
+ attribute :kdb, :boolean
279
+ attribute :locked, :boolean
280
+ attribute :mandatory_document_fields_flag, :integer
281
+ attribute :mrz_corrected, :boolean
282
+ attribute :mrz_correction_provided, :boolean
283
+ attribute :max_age_failed, :integer
284
+ attribute :min_age_failed, :integer
285
+ attribute :missing_fields_properties
286
+ attribute :mrz, :string
287
+ attribute :mrz_character_count, :integer
288
+ attribute :mrz_image_type, :integer
289
+ attribute :mrz_line_count, :integer
290
+ attribute :mrz_same_length, :boolean
291
+ attribute :mrz_validation_properties
292
+ attribute :nationality, :integer
293
+ attribute :no_initial_face_image, :boolean
294
+ attribute :notes, :string
295
+ attribute :ocr_data_applied, :boolean
296
+ attribute :ocr_field_data
297
+ attribute :ocr_type, :integer
298
+ attribute :operator_message, :string
299
+ attribute :operator_status, :integer
300
+ attribute :optional_document_fields_flag, :integer
301
+ attribute :original_mrz, :string
302
+ attribute :partially_recognised, :boolean
303
+ attribute :reading_attempts_count, :integer
304
+ attribute :rfid_failed, :boolean
305
+ attribute :rfid_mrz, :string
306
+ attribute :rule_denied, :boolean
307
+ attribute :scan_counter, :integer
308
+ attribute :scanned_at, :datetime
309
+ attribute :scanner_type, :string
310
+ attribute :seen_before_document_container_id, :string
311
+ attribute :seen_before_document_id, :string
312
+ attribute :successfully_read, :boolean
313
+ attribute :supporting_document_name, :string
314
+ attribute :system_id, :string
315
+ attribute :unrecognised, :boolean
316
+ attribute :updated_at, :datetime
317
+ attribute :valid_from, :date
318
+ attribute :valid_length, :boolean
319
+ attribute :vpe_device_id, :string
320
+ attribute :vpe_name, :string
321
+ attribute :wizard_completed, :boolean
322
+ attribute :workflow_flags, :integer
323
+ attribute :is_biometric, :boolean
324
+ attribute :images, array: true
325
+
326
+ # Store the images separately since it's a complex nested structure
327
+ attr_reader :images, :document_fields, :document_validations, :external_services, :document_configuration,
328
+ :general_document_properties, :document_results_summary, :mrz_validation_properties,
329
+ :missing_fields_properties
330
+
331
+ # Initialize method to properly handle nested structures
332
+ def initialize(attrs = {})
333
+ # Normalize input hash - convert all keys to strings for consistent lookup
334
+ attrs = attrs.transform_keys(&:to_s) if attrs.is_a?(Hash)
335
+
336
+ # Initialize the model with all attributes (including nested ones)
337
+ super
338
+
339
+ # Convert nested structures from hashes to model instances after initialization
340
+ convert_nested_models
341
+ end
342
+
343
+ # Convert nested model data from hashes to proper model instances
344
+ def convert_nested_models
345
+ convert_array_attribute(:images, @images)
346
+ convert_array_attribute(:document_fields, document_fields)
347
+ convert_array_attribute(:document_validations, document_validations)
348
+ convert_array_attribute(:external_services, external_services)
349
+ convert_array_attribute(:document_results_summary, document_results_summary)
350
+ convert_array_attribute(:general_document_properties, general_document_properties)
351
+ convert_array_attribute(:mrz_validation_properties, mrz_validation_properties)
352
+ convert_array_attribute(:missing_fields_properties, missing_fields_properties)
353
+ convert_hash_attribute(:nationality, nationality)
354
+ convert_hash_attribute(:issuing_country, issuing_country)
355
+ convert_hash_attribute(:document_sub_type, document_sub_type)
356
+ convert_hash_attribute(:document_configuration, document_configuration)
357
+ end
358
+
359
+ # Convert an array attribute if it contains hashes
360
+ def convert_array_attribute(attr_name, value)
361
+ return unless value.is_a?(Array) && value.first.is_a?(Hash)
362
+
363
+ send("#{attr_name}=", value)
364
+ end
365
+
366
+ # Convert a hash attribute to a model instance
367
+ def convert_hash_attribute(attr_name, value)
368
+ return unless value.is_a?(Hash)
369
+
370
+ send("#{attr_name}=", value)
371
+ end
372
+
373
+ # Set the images array with proper type conversion
374
+ def images=(images_data)
375
+ return unless images_data
376
+
377
+ @images = images_data.map do |image_data|
378
+ image_data.is_a?(TrustID::Image) ? image_data : TrustID::Image.from_hash(image_data)
379
+ end
380
+ end
381
+
382
+ # Set document_fields with proper type conversion
383
+ def document_fields=(fields_data)
384
+ return unless fields_data
385
+
386
+ # Handle both array of hashes and already converted models
387
+ @document_fields = Array(fields_data).map do |field_data|
388
+ if field_data.is_a?(Hash)
389
+ TrustID::DocumentField.from_hash(field_data)
390
+ else
391
+ field_data
392
+ end
393
+ end
394
+ end
395
+
396
+ # Set document_validations with proper type conversion
397
+ def document_validations=(validations_data)
398
+ return unless validations_data
399
+
400
+ # Handle both array of hashes and already converted models
401
+ @document_validations = Array(validations_data).map do |validation_data|
402
+ if validation_data.is_a?(Hash)
403
+ TrustID::DocumentValidation.from_hash(validation_data)
404
+ else
405
+ validation_data
406
+ end
407
+ end
408
+ end
409
+
410
+ # Set external_services with proper type conversion
411
+ def external_services=(services_data)
412
+ return unless services_data
413
+
414
+ # Handle both array of hashes and already converted models
415
+ @external_services = Array(services_data).map do |service_data|
416
+ if service_data.is_a?(Hash)
417
+ TrustID::ExternalServiceData.from_hash(service_data)
418
+ else
419
+ service_data
420
+ end
421
+ end
422
+ end
423
+
424
+ # Set document_results_summary with proper type conversion
425
+ def document_results_summary=(summary_data)
426
+ return unless summary_data
427
+
428
+ @document_results_summary = summary_data.map do |item_data|
429
+ item_data.is_a?(TrustID::DocumentFeedback) ? item_data : TrustID::DocumentFeedback.from_hash(item_data)
430
+ end
431
+ end
432
+
433
+ # Set general_document_properties with proper type conversion
434
+ def general_document_properties=(properties_data)
435
+ return unless properties_data
436
+
437
+ @general_document_properties = properties_data.map do |item_data|
438
+ item_data.is_a?(TrustID::DocumentFeedback) ? item_data : TrustID::DocumentFeedback.from_hash(item_data)
439
+ end
440
+ end
441
+
442
+ # Set mrz_validation_properties with proper type conversion
443
+ def mrz_validation_properties=(properties_data)
444
+ return unless properties_data
445
+
446
+ @mrz_validation_properties = properties_data.map do |item_data|
447
+ item_data.is_a?(TrustID::DocumentFeedback) ? item_data : TrustID::DocumentFeedback.from_hash(item_data)
448
+ end
449
+ end
450
+
451
+ # Set missing_fields_properties with proper type conversion
452
+ def missing_fields_properties=(properties_data)
453
+ return unless properties_data
454
+
455
+ @missing_fields_properties = properties_data.map do |item_data|
456
+ item_data.is_a?(TrustID::DocumentFeedback) ? item_data : TrustID::DocumentFeedback.from_hash(item_data)
457
+ end
458
+ end
459
+
460
+ # Set nationality as KDBCountry object
461
+ def nationality=(country_data)
462
+ return unless country_data
463
+
464
+ @nationality = country_data.is_a?(TrustID::KDBCountry) ? country_data : TrustID::KDBCountry.from_hash(country_data)
465
+ end
466
+
467
+ # Set issuing_country as KDBCountry object
468
+ def issuing_country=(country_data)
469
+ return unless country_data
470
+
471
+ @issuing_country = country_data.is_a?(TrustID::KDBCountry) ? country_data : TrustID::KDBCountry.from_hash(country_data)
472
+ end
473
+
474
+ # Set document_sub_type as KDBDocumentSubType object
475
+ def document_sub_type=(sub_type_data)
476
+ return unless sub_type_data
477
+
478
+ @document_sub_type = sub_type_data.is_a?(TrustID::KDBDocumentSubType) ? sub_type_data : TrustID::KDBDocumentSubType.from_hash(sub_type_data)
479
+ end
480
+
481
+ # Set document_version (keeping as string for now, but could be an object)
482
+ attr_writer :document_version
483
+
484
+ # Set document_configuration with proper type conversion
485
+ def document_configuration=(config_data)
486
+ return unless config_data
487
+
488
+ @document_configuration = config_data.is_a?(TrustID::DocumentConfiguration) ? config_data : TrustID::DocumentConfiguration.from_hash(config_data)
489
+ end
490
+
491
+ DocumentType::NAMES.each do |code, name|
492
+ define_method("document_type_#{name.underscore}?") do
493
+ document_type == code
494
+ end
495
+ end
496
+
497
+ def document_type_name
498
+ DocumentType.name_for(document_type)
499
+ end
500
+
501
+ DocumentStatus::NAMES.each do |code, name|
502
+ define_method("auditor_status_#{name.underscore}?") do
503
+ auditor_status == code
504
+ end
505
+ end
506
+
507
+ def auditor_status_name
508
+ DocumentStatus.name_for(auditor_status)
509
+ end
510
+
511
+ # Convenience methods for easier access to document data
512
+
513
+ # Find a document field by name (case-insensitive)
514
+ #
515
+ # @param field_name [String] The name of the field to find (e.g., "VI Firstname", "VIZ Surname")
516
+ # @return [DocumentField, nil] The document field if found, nil otherwise
517
+ def field_by_name(field_name)
518
+ return nil unless document_fields.is_a?(Array)
519
+
520
+ document_fields.find { |f| f.name&.downcase == field_name.to_s.downcase }
521
+ end
522
+
523
+ # Get the value of a document field by name
524
+ #
525
+ # @param field_name [String] The name of the field
526
+ # @return [String, DateTime, nil] The field value (string or date), or nil if not found
527
+ def field_value(field_name)
528
+ field = field_by_name(field_name)
529
+ return nil unless field
530
+
531
+ field.field_value_string || field.field_value_date
532
+ end
533
+
534
+ # Find a document validation by name (case-insensitive)
535
+ #
536
+ # @param validation_name [String] The name of the validation to find
537
+ # @return [DocumentValidation, nil] The document validation if found, nil otherwise
538
+ def validation_by_name(validation_name)
539
+ return nil unless document_validations.is_a?(Array)
540
+
541
+ document_validations.find { |v| v.name&.downcase == validation_name.to_s.downcase }
542
+ end
543
+
544
+ # Get all passed validations
545
+ #
546
+ # @return [Array<DocumentValidation>] Array of passed validations
547
+ def passed_validations
548
+ return [] unless document_validations.is_a?(Array)
549
+
550
+ document_validations.select { |v| v.result == DocumentValidationResult::PASSED }
551
+ end
552
+
553
+ # Get all failed validations (excluding passed and unknown)
554
+ #
555
+ # @return [Array<DocumentValidation>] Array of failed validations
556
+ def failed_validations
557
+ return [] unless document_validations.is_a?(Array)
558
+
559
+ document_validations.reject do |v|
560
+ [DocumentValidationResult::PASSED, DocumentValidationResult::UNKNOWN].include?(v.result)
561
+ end
562
+ end
563
+
564
+ # Check if all validations passed
565
+ #
566
+ # @return [Boolean] True if all validations passed, false otherwise
567
+ def all_validations_passed?
568
+ return true unless document_validations.is_a?(Array)
569
+
570
+ document_validations.all? do |v|
571
+ [DocumentValidationResult::PASSED, DocumentValidationResult::UNKNOWN].include?(v.result)
572
+ end
573
+ end
574
+
575
+ # Find an external service by name (case-insensitive)
576
+ #
577
+ # @param service_name [String] The name of the external service
578
+ # @return [ExternalServiceData, nil] The external service if found, nil otherwise
579
+ def external_service_by_name(service_name)
580
+ return nil unless external_services.is_a?(Array)
581
+
582
+ external_services.find { |s| s.name&.downcase == service_name.to_s.downcase }
583
+ end
584
+
585
+ # Get a summary result by name from document_results_summary
586
+ #
587
+ # @param summary_name [String] The name of the summary result
588
+ # @return [DocumentFeedback, nil] The summary result if found, nil otherwise
589
+ def summary_result_by_name(summary_name)
590
+ return nil unless document_results_summary.is_a?(Array)
591
+
592
+ document_results_summary.find { |s| s.name&.downcase == summary_name.to_s.downcase }
593
+ end
594
+
595
+ # Check if a summary result passed
596
+ #
597
+ # @param summary_name [String] The name of the summary result
598
+ # @return [Boolean, nil] True if passed, false if failed, nil if not found or unknown
599
+ def summary_result_passed?(summary_name)
600
+ result = summary_result_by_name(summary_name)
601
+ result&.value == true
602
+ end
603
+
604
+ # Get nationality name (from KDBCountry object if available)
605
+ #
606
+ # @return [String, nil] The nationality name, or nil if not available
607
+ def nationality_name
608
+ nationality.is_a?(TrustID::KDBCountry) ? nationality.name : nil
609
+ end
610
+
611
+ # Get issuing country name (from KDBCountry object if available)
612
+ #
613
+ # @return [String, nil] The issuing country name, or nil if not available
614
+ def issuing_country_name
615
+ issuing_country.is_a?(TrustID::KDBCountry) ? issuing_country.name : nil
616
+ end
617
+
618
+ # Get the main face image (ImageType 1)
619
+ #
620
+ # @return [Image, nil] The face image if found, nil otherwise
621
+ def face_image
622
+ return nil unless images.is_a?(Array)
623
+
624
+ images.find { |img| img.image_type == 1 }
625
+ end
626
+
627
+ # Get the MRZ image (ImageType 2)
628
+ #
629
+ # @return [Image, nil] The MRZ image if found, nil otherwise
630
+ def mrz_image
631
+ return nil unless images.is_a?(Array)
632
+
633
+ images.find { |img| img.image_type == 2 }
634
+ end
635
+
636
+ # Get all images of a specific type
637
+ #
638
+ # @param image_type [Integer] The image type to filter by
639
+ # @return [Array<Image>] Array of images of the specified type
640
+ def images_by_type(image_type)
641
+ return [] unless images.is_a?(Array)
642
+
643
+ images.select { |img| img.image_type == image_type }
644
+ end
645
+ end
646
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TrustID
4
+ # DocumentConfiguration
5
+ #
6
+ # Represents document processing/validation configuration from the TrustID API.
7
+ #
8
+ # Fields:
9
+ # disable_expired_eu_documents_failure - Boolean: If true, the system generates warnings rather than
10
+ # failures for expired EU documents.
11
+ # (API key: DisableExpiredEUDocumentsFailure; PascalCase key is converted to snake_case by BaseModel.)
12
+ # disable_expired_non_eu_documents_failure - Boolean: If true, the system generates warnings rather than
13
+ # failures for expired non-EU documents.
14
+ # (API key: DisableExpiredNonEuDocumentsFailure; PascalCase key is converted to snake_case by BaseModel.)
15
+ #
16
+ # @see https://developer.trustid.co.uk/documentation/ref/raw_ref/model/DocumentConfiguration.html
17
+ class DocumentConfiguration < BaseModel
18
+ attribute :disable_expired_eu_documents_failure, :boolean
19
+ attribute :disable_expired_non_eu_documents_failure, :boolean
20
+ end
21
+ end