crisphive 0.2.0 → 0.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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +98 -10
  3. data/lib/crisphive/api/business_skill_api.rb +348 -0
  4. data/lib/crisphive/api/customer_api.rb +7 -4
  5. data/lib/crisphive/api/job_request_business_api.rb +243 -27
  6. data/lib/crisphive/api/job_types_api.rb +208 -0
  7. data/lib/crisphive/api/permission_api.rb +79 -0
  8. data/lib/crisphive/api/service_area_api.rb +208 -0
  9. data/lib/crisphive/api/technician_api.rb +8 -8
  10. data/lib/crisphive/api/technician_time_off_api.rb +240 -0
  11. data/lib/crisphive/api/vehicle_api.rb +208 -0
  12. data/lib/crisphive/api/webhooks_api.rb +213 -0
  13. data/lib/crisphive/models/api_internal_techtimeoff_actions.rb +232 -0
  14. data/lib/crisphive/models/api_internal_techtimeoff_status.rb +42 -0
  15. data/lib/crisphive/models/assignable_group.rb +289 -0
  16. data/lib/crisphive/models/book_and_confirm_job_request200_response.rb +253 -0
  17. data/lib/crisphive/models/commit_absence_resolve200_response.rb +253 -0
  18. data/lib/crisphive/models/create_job_type200_response.rb +253 -0
  19. data/lib/crisphive/models/create_service_area200_response.rb +253 -0
  20. data/lib/crisphive/models/create_skill200_response.rb +253 -0
  21. data/lib/crisphive/models/create_skill_category200_response.rb +253 -0
  22. data/lib/crisphive/models/create_technician_time_off200_response.rb +253 -0
  23. data/lib/crisphive/models/create_vehicle200_response.rb +253 -0
  24. data/lib/crisphive/models/create_webhook_endpoint200_response.rb +253 -0
  25. data/lib/crisphive/models/customer.rb +11 -1
  26. data/lib/crisphive/models/customer_contact.rb +25 -5
  27. data/lib/crisphive/models/customer_create_request.rb +12 -2
  28. data/lib/crisphive/models/customer_list_item.rb +11 -1
  29. data/lib/crisphive/models/customer_quick_books_link.rb +235 -0
  30. data/lib/crisphive/models/customer_service_area_ref.rb +225 -0
  31. data/lib/crisphive/models/customer_technician_ref.rb +225 -0
  32. data/lib/crisphive/models/customer_update_request.rb +23 -20
  33. data/lib/crisphive/models/internal_jobrequest_http_address_req.rb +475 -0
  34. data/lib/crisphive/models/job_request.rb +11 -1
  35. data/lib/crisphive/models/job_request_absence_alternative.rb +356 -0
  36. data/lib/crisphive/models/job_request_absence_alternative_cost.rb +275 -0
  37. data/lib/crisphive/models/job_request_absence_assignment.rb +319 -0
  38. data/lib/crisphive/models/job_request_absence_commit_request.rb +296 -0
  39. data/lib/crisphive/models/job_request_absence_notification.rb +283 -0
  40. data/lib/crisphive/models/job_request_absence_plan.rb +322 -0
  41. data/lib/crisphive/models/job_request_absence_preview_request.rb +280 -0
  42. data/lib/crisphive/models/job_request_absence_resolved_job.rb +499 -0
  43. data/lib/crisphive/models/job_request_absence_solver.rb +289 -0
  44. data/lib/crisphive/models/job_request_absence_time_off.rb +281 -0
  45. data/lib/crisphive/models/job_request_absence_unresolved_job.rb +364 -0
  46. data/lib/crisphive/models/job_request_action_summary.rb +1 -1
  47. data/lib/crisphive/models/job_request_attention_summary.rb +2 -2
  48. data/lib/crisphive/models/job_request_blocker.rb +363 -0
  49. data/lib/crisphive/models/job_request_blocker_ref.rb +223 -0
  50. data/lib/crisphive/models/job_request_book_and_confirm_customer.rb +302 -0
  51. data/lib/crisphive/models/job_request_book_and_confirm_emergency.rb +315 -0
  52. data/lib/crisphive/models/job_request_book_and_confirm_emergency_result.rb +279 -0
  53. data/lib/crisphive/models/job_request_book_and_confirm_refusal.rb +280 -0
  54. data/lib/crisphive/models/job_request_book_and_confirm_request.rb +466 -0
  55. data/lib/crisphive/models/job_request_book_and_confirm_response.rb +295 -0
  56. data/lib/crisphive/models/job_request_confirm_request.rb +14 -4
  57. data/lib/crisphive/models/job_request_create_request.rb +1 -1
  58. data/lib/crisphive/models/job_request_emergency_candidate.rb +26 -4
  59. data/lib/crisphive/models/job_request_emergency_candidates.rb +1 -1
  60. data/lib/crisphive/models/job_request_emergency_candidates_request.rb +24 -11
  61. data/lib/crisphive/models/job_request_emergency_commit_request.rb +11 -1
  62. data/lib/crisphive/models/job_request_emergency_inline_job.rb +353 -0
  63. data/lib/crisphive/models/job_request_emergency_plan.rb +25 -3
  64. data/lib/crisphive/models/job_request_emergency_preview_request.rb +24 -11
  65. data/lib/crisphive/models/job_request_move_commit_req.rb +11 -1
  66. data/lib/crisphive/models/job_request_move_plan.rb +11 -1
  67. data/lib/crisphive/models/job_request_move_preview_req.rb +11 -1
  68. data/lib/crisphive/models/job_request_move_warning.rb +32 -8
  69. data/lib/crisphive/models/job_request_priority_update_result.rb +217 -0
  70. data/lib/crisphive/models/job_request_quote_request.rb +14 -11
  71. data/lib/crisphive/models/job_request_reassign_fallback.rb +287 -0
  72. data/lib/crisphive/models/job_request_skill_summary.rb +1 -1
  73. data/lib/crisphive/models/job_request_status_summary.rb +1 -1
  74. data/lib/crisphive/models/job_request_time_segments.rb +2 -2
  75. data/lib/crisphive/models/job_type.rb +42 -2
  76. data/lib/crisphive/models/job_type_create_request.rb +399 -0
  77. data/lib/crisphive/models/job_type_create_response.rb +215 -0
  78. data/lib/crisphive/models/job_type_update_request.rb +400 -0
  79. data/lib/crisphive/models/list_assignable_groups200_response.rb +255 -0
  80. data/lib/crisphive/models/list_technician_time_off200_response.rb +253 -0
  81. data/lib/crisphive/models/list_webhook_event_types200_response.rb +255 -0
  82. data/lib/crisphive/models/quote_job_request200_response.rb +253 -0
  83. data/lib/crisphive/models/service_area.rb +21 -1
  84. data/lib/crisphive/models/service_area_create_request.rb +455 -0
  85. data/lib/crisphive/models/service_area_create_response.rb +215 -0
  86. data/lib/crisphive/models/service_area_update_request.rb +451 -0
  87. data/lib/crisphive/models/skill_category_create_request.rb +270 -0
  88. data/lib/crisphive/models/skill_category_create_response.rb +215 -0
  89. data/lib/crisphive/models/skill_create_request.rb +270 -0
  90. data/lib/crisphive/models/skill_create_response.rb +215 -0
  91. data/lib/crisphive/models/skill_update_request.rb +281 -0
  92. data/lib/crisphive/models/technician.rb +64 -2
  93. data/lib/crisphive/models/technician_create_request.rb +14 -11
  94. data/lib/crisphive/models/technician_time_off.rb +334 -0
  95. data/lib/crisphive/models/technician_time_off_create_request.rb +285 -0
  96. data/lib/crisphive/models/technician_time_off_create_response.rb +215 -0
  97. data/lib/crisphive/models/technician_time_off_list.rb +246 -0
  98. data/lib/crisphive/models/technician_update_request.rb +2 -2
  99. data/lib/crisphive/models/vehicle_create_request.rb +420 -0
  100. data/lib/crisphive/models/vehicle_create_response.rb +215 -0
  101. data/lib/crisphive/models/vehicle_update_request.rb +440 -0
  102. data/lib/crisphive/models/webhook_create_request.rb +320 -0
  103. data/lib/crisphive/models/webhook_create_response.rb +391 -0
  104. data/lib/crisphive/models/webhook_verification.rb +235 -0
  105. data/lib/crisphive/version.rb +1 -1
  106. data/lib/crisphive.rb +66 -0
  107. metadata +68 -2
@@ -0,0 +1,295 @@
1
+ =begin
2
+ #Crisphive Developer API
3
+
4
+ #Public REST API for integrating Crisphive from your own backend. Authenticate every request with a secret API key as a Bearer token (`Authorization: Bearer chsk_live_…`). The key prefix selects the data environment: `chsk_live_…` → production (live), `chsk_test_…` → sandbox (isolated test). **Key scopes (restricted keys).** A key is either *full-access* (can call every endpoint below) or *restricted* to a set of permission codes chosen at creation — the same codes as the dashboard permission grid (e.g. `customers_view`, `job_create`, `team_manage`). A restricted key calling an endpoint outside its scope gets `403`. The full code list is the permission catalog (`GET /permission/modules` on the dashboard API). Create, scope, and revoke keys from the business dashboard. Every response is wrapped in the envelope `{ \"error_code\": 0, \"message\": \"Success\", \"data\": <payload> }`.
5
+
6
+ The version of the OpenAPI document: 1.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.11.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Crisphive
17
+ class JobRequestBookAndConfirmResponse
18
+ # Technician the engine assigned (or the one you forced). Present when confirmed.
19
+ attr_accessor :assigned_technician_id
20
+
21
+ # True when the job is confirmed at scheduled_at with a technician assigned. False means the job exists, quoted and waiting in the coordinator's queue, and `refusal` says why it could not be confirmed.
22
+ attr_accessor :confirmed
23
+
24
+ # The customer the job is booked for (matched or newly created).
25
+ attr_accessor :customer_id
26
+
27
+ # The customer's self-service link for this job.
28
+ attr_accessor :customer_url
29
+
30
+ # The P0 dispatch, echoed back. Present whenever the request carried `emergency`.
31
+ attr_accessor :emergency
32
+
33
+ # The job that was created. Present on every 200 — once booked, a job is never discarded.
34
+ attr_accessor :job_id
35
+
36
+ # Why the job is not confirmed. Present only when confirmed is false.
37
+ attr_accessor :refusal
38
+
39
+ # Confirmed start (UTC). Present when confirmed.
40
+ attr_accessor :scheduled_at
41
+
42
+ # Human-friendly job code to read back to a caller.
43
+ attr_accessor :short_code
44
+
45
+ # Attribute mapping from ruby-style variable name to JSON key.
46
+ def self.attribute_map
47
+ {
48
+ :'assigned_technician_id' => :'assigned_technician_id',
49
+ :'confirmed' => :'confirmed',
50
+ :'customer_id' => :'customer_id',
51
+ :'customer_url' => :'customer_url',
52
+ :'emergency' => :'emergency',
53
+ :'job_id' => :'job_id',
54
+ :'refusal' => :'refusal',
55
+ :'scheduled_at' => :'scheduled_at',
56
+ :'short_code' => :'short_code'
57
+ }
58
+ end
59
+
60
+ # Returns all the JSON keys this model knows about
61
+ def self.acceptable_attributes
62
+ attribute_map.values
63
+ end
64
+
65
+ # Attribute type mapping.
66
+ def self.openapi_types
67
+ {
68
+ :'assigned_technician_id' => :'String',
69
+ :'confirmed' => :'Boolean',
70
+ :'customer_id' => :'String',
71
+ :'customer_url' => :'String',
72
+ :'emergency' => :'JobRequestBookAndConfirmEmergencyResult',
73
+ :'job_id' => :'String',
74
+ :'refusal' => :'JobRequestBookAndConfirmRefusal',
75
+ :'scheduled_at' => :'Time',
76
+ :'short_code' => :'String'
77
+ }
78
+ end
79
+
80
+ # List of attributes with nullable: true
81
+ def self.openapi_nullable
82
+ Set.new([
83
+ ])
84
+ end
85
+
86
+ # Initializes the object
87
+ # @param [Hash] attributes Model attributes in the form of hash
88
+ def initialize(attributes = {})
89
+ if (!attributes.is_a?(Hash))
90
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Crisphive::JobRequestBookAndConfirmResponse` initialize method"
91
+ end
92
+
93
+ # check to see if the attribute exists and convert string to symbol for hash key
94
+ attributes = attributes.each_with_object({}) { |(k, v), h|
95
+ if (!self.class.attribute_map.key?(k.to_sym))
96
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Crisphive::JobRequestBookAndConfirmResponse`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
97
+ end
98
+ h[k.to_sym] = v
99
+ }
100
+
101
+ if attributes.key?(:'assigned_technician_id')
102
+ self.assigned_technician_id = attributes[:'assigned_technician_id']
103
+ end
104
+
105
+ if attributes.key?(:'confirmed')
106
+ self.confirmed = attributes[:'confirmed']
107
+ end
108
+
109
+ if attributes.key?(:'customer_id')
110
+ self.customer_id = attributes[:'customer_id']
111
+ end
112
+
113
+ if attributes.key?(:'customer_url')
114
+ self.customer_url = attributes[:'customer_url']
115
+ end
116
+
117
+ if attributes.key?(:'emergency')
118
+ self.emergency = attributes[:'emergency']
119
+ end
120
+
121
+ if attributes.key?(:'job_id')
122
+ self.job_id = attributes[:'job_id']
123
+ end
124
+
125
+ if attributes.key?(:'refusal')
126
+ self.refusal = attributes[:'refusal']
127
+ end
128
+
129
+ if attributes.key?(:'scheduled_at')
130
+ self.scheduled_at = attributes[:'scheduled_at']
131
+ end
132
+
133
+ if attributes.key?(:'short_code')
134
+ self.short_code = attributes[:'short_code']
135
+ end
136
+ end
137
+
138
+ # Show invalid properties with the reasons. Usually used together with valid?
139
+ # @return Array for valid properties with the reasons
140
+ def list_invalid_properties
141
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
142
+ invalid_properties = Array.new
143
+ invalid_properties
144
+ end
145
+
146
+ # Check to see if the all the properties in the model are valid
147
+ # @return true if the model is valid
148
+ def valid?
149
+ warn '[DEPRECATED] the `valid?` method is obsolete'
150
+ true
151
+ end
152
+
153
+ # Checks equality by comparing each attribute.
154
+ # @param [Object] Object to be compared
155
+ def ==(o)
156
+ return true if self.equal?(o)
157
+ self.class == o.class &&
158
+ assigned_technician_id == o.assigned_technician_id &&
159
+ confirmed == o.confirmed &&
160
+ customer_id == o.customer_id &&
161
+ customer_url == o.customer_url &&
162
+ emergency == o.emergency &&
163
+ job_id == o.job_id &&
164
+ refusal == o.refusal &&
165
+ scheduled_at == o.scheduled_at &&
166
+ short_code == o.short_code
167
+ end
168
+
169
+ # @see the `==` method
170
+ # @param [Object] Object to be compared
171
+ def eql?(o)
172
+ self == o
173
+ end
174
+
175
+ # Calculates hash code according to all attributes.
176
+ # @return [Integer] Hash code
177
+ def hash
178
+ [assigned_technician_id, confirmed, customer_id, customer_url, emergency, job_id, refusal, scheduled_at, short_code].hash
179
+ end
180
+
181
+ # Builds the object from hash
182
+ # @param [Hash] attributes Model attributes in the form of hash
183
+ # @return [Object] Returns the model itself
184
+ def self.build_from_hash(attributes)
185
+ return nil unless attributes.is_a?(Hash)
186
+ attributes = attributes.transform_keys(&:to_sym)
187
+ transformed_hash = {}
188
+ openapi_types.each_pair do |key, type|
189
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
190
+ transformed_hash["#{key}"] = nil
191
+ elsif type =~ /\AArray<(.*)>/i
192
+ # check to ensure the input is an array given that the attribute
193
+ # is documented as an array but the input is not
194
+ if attributes[attribute_map[key]].is_a?(Array)
195
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
196
+ end
197
+ elsif !attributes[attribute_map[key]].nil?
198
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
199
+ end
200
+ end
201
+ new(transformed_hash)
202
+ end
203
+
204
+ # Deserializes the data based on type
205
+ # @param string type Data type
206
+ # @param string value Value to be deserialized
207
+ # @return [Object] Deserialized data
208
+ def self._deserialize(type, value)
209
+ case type.to_sym
210
+ when :Time
211
+ Time.parse(value)
212
+ when :Date
213
+ Date.parse(value)
214
+ when :String
215
+ value.to_s
216
+ when :Integer
217
+ value.to_i
218
+ when :Float
219
+ value.to_f
220
+ when :Boolean
221
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
222
+ true
223
+ else
224
+ false
225
+ end
226
+ when :Object
227
+ # generic object (usually a Hash), return directly
228
+ value
229
+ when /\AArray<(?<inner_type>.+)>\z/
230
+ inner_type = Regexp.last_match[:inner_type]
231
+ value.map { |v| _deserialize(inner_type, v) }
232
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
233
+ k_type = Regexp.last_match[:k_type]
234
+ v_type = Regexp.last_match[:v_type]
235
+ {}.tap do |hash|
236
+ value.each do |k, v|
237
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
238
+ end
239
+ end
240
+ else # model
241
+ # models (e.g. Pet) or oneOf
242
+ klass = Crisphive.const_get(type)
243
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
244
+ end
245
+ end
246
+
247
+ # Returns the string representation of the object
248
+ # @return [String] String presentation of the object
249
+ def to_s
250
+ to_hash.to_s
251
+ end
252
+
253
+ # to_body is an alias to to_hash (backward compatibility)
254
+ # @return [Hash] Returns the object in the form of hash
255
+ def to_body
256
+ to_hash
257
+ end
258
+
259
+ # Returns the object in the form of hash
260
+ # @return [Hash] Returns the object in the form of hash
261
+ def to_hash
262
+ hash = {}
263
+ self.class.attribute_map.each_pair do |attr, param|
264
+ value = self.send(attr)
265
+ if value.nil?
266
+ is_nullable = self.class.openapi_nullable.include?(attr)
267
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
268
+ end
269
+
270
+ hash[param] = _to_hash(value)
271
+ end
272
+ hash
273
+ end
274
+
275
+ # Outputs non-array value in the form of hash
276
+ # For object, use to_hash. Otherwise, just return the value
277
+ # @param [Object] value Any valid value
278
+ # @return [Hash] Returns the value in the form of hash
279
+ def _to_hash(value)
280
+ if value.is_a?(Array)
281
+ value.compact.map { |v| _to_hash(v) }
282
+ elsif value.is_a?(Hash)
283
+ {}.tap do |hash|
284
+ value.each { |k, v| hash[k] = _to_hash(v) }
285
+ end
286
+ elsif value.respond_to? :to_hash
287
+ value.to_hash
288
+ else
289
+ value
290
+ end
291
+ end
292
+
293
+ end
294
+
295
+ end
@@ -15,21 +15,25 @@ require 'time'
15
15
 
16
16
  module Crisphive
17
17
  class JobRequestConfirmRequest
18
+ # AfterHoursOverride (BUSINESS confirm only): schedule this P0 outside the technician's working hours or approved time-off — you have phoned them and they agreed. Requires priority p0, a single-person job, and technician_id. Double-booking, service area, required skills and the lead-tier rule still reject. Deliberately NOT a binding-tag rule: gin evaluates tags before the handler, which would make the three AFTER_HOURS codes unreachable.
19
+ attr_accessor :after_hours_override
20
+
18
21
  # ArrivalWindowMinutes = width (phút) của arrival-window ô khách bấm ở slot-picker (chính là time_slot_step_minutes, mặc định 30). Persist để post-confirm detail render lại đúng window. Optional; bounds ([5, 240], khớp slot-picker step) validate ở usecase — single authority, một error code (JOB_REQUEST_INVALID_INPUT).
19
22
  attr_accessor :arrival_window_minutes
20
23
 
21
- # Chosen start time — business-local naive datetime, no offset (the business_time.datetime value from the time-segments picker). The server converts to UTC using the job's business timezone.
24
+ # Chosen start time — business-local wall clock (the business_time.datetime value from the time-segments picker), converted to UTC against the job's business timezone. Seconds may be omitted and a space may replace the T. An offset is accepted only when it agrees with the business timezone; a disagreeing one is refused with JOB_REQUEST_INVALID_INPUT naming what it means locally.
22
25
  attr_accessor :scheduled_at
23
26
 
24
27
  # Optimistic-lock fence: the status_version from your last read. Omitted/0 = fence on the row's current version (no race protection).
25
28
  attr_accessor :status_version
26
29
 
27
- # TechnicianID (BUSINESS confirm only — ignored on the customer surface): force-assign the job to this technician instead of the ranked auto-pick. Ranking is bypassed; feasibility (hours/time-off/geo/skills), the TierLead rule and the double-booking guard still apply — an infeasible forced tech rejects the confirm (P0 gets the displacement hint).
30
+ # TechnicianID (BUSINESS confirm only — ignored on the customer surface): force-assign the job to this technician instead of the ranked auto-pick. Ranking is bypassed; feasibility (hours/time-off/geo/skills), the TierLead rule and the double-booking guard still apply — an infeasible forced tech rejects the confirm (P0 gets the displacement hint). ⚠️ One exception: for a SINGLE-PERSON p0 job, a PERSONAL-CALENDAR overlap on this exact technician no longer rejects — naming them here is treated as having already phoned them, so the confirm succeeds and the override is recorded on the business's activity feed (this response has no warnings array to carry it). A multi-member crew still rejects on it.
28
31
  attr_accessor :technician_id
29
32
 
30
33
  # Attribute mapping from ruby-style variable name to JSON key.
31
34
  def self.attribute_map
32
35
  {
36
+ :'after_hours_override' => :'after_hours_override',
33
37
  :'arrival_window_minutes' => :'arrival_window_minutes',
34
38
  :'scheduled_at' => :'scheduled_at',
35
39
  :'status_version' => :'status_version',
@@ -45,8 +49,9 @@ module Crisphive
45
49
  # Attribute type mapping.
46
50
  def self.openapi_types
47
51
  {
52
+ :'after_hours_override' => :'Boolean',
48
53
  :'arrival_window_minutes' => :'Integer',
49
- :'scheduled_at' => :'String',
54
+ :'scheduled_at' => :'Time',
50
55
  :'status_version' => :'Integer',
51
56
  :'technician_id' => :'String'
52
57
  }
@@ -73,6 +78,10 @@ module Crisphive
73
78
  h[k.to_sym] = v
74
79
  }
75
80
 
81
+ if attributes.key?(:'after_hours_override')
82
+ self.after_hours_override = attributes[:'after_hours_override']
83
+ end
84
+
76
85
  if attributes.key?(:'arrival_window_minutes')
77
86
  self.arrival_window_minutes = attributes[:'arrival_window_minutes']
78
87
  end
@@ -110,6 +119,7 @@ module Crisphive
110
119
  def ==(o)
111
120
  return true if self.equal?(o)
112
121
  self.class == o.class &&
122
+ after_hours_override == o.after_hours_override &&
113
123
  arrival_window_minutes == o.arrival_window_minutes &&
114
124
  scheduled_at == o.scheduled_at &&
115
125
  status_version == o.status_version &&
@@ -125,7 +135,7 @@ module Crisphive
125
135
  # Calculates hash code according to all attributes.
126
136
  # @return [Integer] Hash code
127
137
  def hash
128
- [arrival_window_minutes, scheduled_at, status_version, technician_id].hash
138
+ [after_hours_override, arrival_window_minutes, scheduled_at, status_version, technician_id].hash
129
139
  end
130
140
 
131
141
  # Builds the object from hash
@@ -24,7 +24,7 @@ module Crisphive
24
24
  # Requested date(s) + period(s) the customer wants the job. At least one, up to 12.
25
25
  attr_accessor :job_dates
26
26
 
27
- # UUID of the job type to classify this job. Optional; null leaves the job unclassified.
27
+ # UUID of the job type to classify this job. Optional: omitted, the business's DEFAULT job type (`is_default`, the seeded \"General\") is used, so every new job has a type and can be quoted from its default duration.
28
28
  attr_accessor :job_type_id
29
29
 
30
30
  # Scheduling priority. Optional; omitted bookings receive the business's default_priority setting (assignment settings, default p2). p0=emergency (interrupt-driven insert), p1=top (displaced only by p0), p2=standard, p3=deferrable (first candidate for displacement).
@@ -18,6 +18,9 @@ module Crisphive
18
18
  # Minutes of work already booked on this technician that day (workload context).
19
19
  attr_accessor :booked_minutes
20
20
 
21
+ # True when this technician overlaps a PERSONAL-calendar window and is offered anyway, flagged and sorted last, for you to decide on. Render it as \"has a personal commitment then — phone them before choosing\", never as a recommendation. The event's hours are deliberately NOT disclosed: the platform stores no title and the times are a private commitment.
22
+ attr_accessor :calendar_busy
23
+
21
24
  # The displaced jobs, grouped per business-local day (same shape as the preview endpoint) — what the coordinator reviews before committing.
22
25
  attr_accessor :days
23
26
 
@@ -42,10 +45,14 @@ module Crisphive
42
45
  # ETA estimate in minutes from the tech's start location to the site — static origin (no live GPS), rank hint not a promise.
43
46
  attr_accessor :travel_minutes
44
47
 
48
+ # Per-technician warnings: TIME_OFF_OVERLAP when this technician is on approved leave at the requested time (only reachable with after_hours_override, which stops leave from rejecting), and CALENDAR_OVERLAP alongside calendar_busy above.
49
+ attr_accessor :warnings
50
+
45
51
  # Attribute mapping from ruby-style variable name to JSON key.
46
52
  def self.attribute_map
47
53
  {
48
54
  :'booked_minutes' => :'booked_minutes',
55
+ :'calendar_busy' => :'calendar_busy',
49
56
  :'days' => :'days',
50
57
  :'distance_km' => :'distance_km',
51
58
  :'full_name' => :'full_name',
@@ -53,7 +60,8 @@ module Crisphive
53
60
  :'technician_id' => :'technician_id',
54
61
  :'total_moves' => :'total_moves',
55
62
  :'total_score' => :'total_score',
56
- :'travel_minutes' => :'travel_minutes'
63
+ :'travel_minutes' => :'travel_minutes',
64
+ :'warnings' => :'warnings'
57
65
  }
58
66
  end
59
67
 
@@ -66,6 +74,7 @@ module Crisphive
66
74
  def self.openapi_types
67
75
  {
68
76
  :'booked_minutes' => :'Integer',
77
+ :'calendar_busy' => :'Boolean',
69
78
  :'days' => :'Array<JobRequestRescheduleDay>',
70
79
  :'distance_km' => :'Float',
71
80
  :'full_name' => :'String',
@@ -73,7 +82,8 @@ module Crisphive
73
82
  :'technician_id' => :'String',
74
83
  :'total_moves' => :'Integer',
75
84
  :'total_score' => :'Float',
76
- :'travel_minutes' => :'Float'
85
+ :'travel_minutes' => :'Float',
86
+ :'warnings' => :'Array<JobRequestMoveWarning>'
77
87
  }
78
88
  end
79
89
 
@@ -102,6 +112,10 @@ module Crisphive
102
112
  self.booked_minutes = attributes[:'booked_minutes']
103
113
  end
104
114
 
115
+ if attributes.key?(:'calendar_busy')
116
+ self.calendar_busy = attributes[:'calendar_busy']
117
+ end
118
+
105
119
  if attributes.key?(:'days')
106
120
  if (value = attributes[:'days']).is_a?(Array)
107
121
  self.days = value
@@ -135,6 +149,12 @@ module Crisphive
135
149
  if attributes.key?(:'travel_minutes')
136
150
  self.travel_minutes = attributes[:'travel_minutes']
137
151
  end
152
+
153
+ if attributes.key?(:'warnings')
154
+ if (value = attributes[:'warnings']).is_a?(Array)
155
+ self.warnings = value
156
+ end
157
+ end
138
158
  end
139
159
 
140
160
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -158,6 +178,7 @@ module Crisphive
158
178
  return true if self.equal?(o)
159
179
  self.class == o.class &&
160
180
  booked_minutes == o.booked_minutes &&
181
+ calendar_busy == o.calendar_busy &&
161
182
  days == o.days &&
162
183
  distance_km == o.distance_km &&
163
184
  full_name == o.full_name &&
@@ -165,7 +186,8 @@ module Crisphive
165
186
  technician_id == o.technician_id &&
166
187
  total_moves == o.total_moves &&
167
188
  total_score == o.total_score &&
168
- travel_minutes == o.travel_minutes
189
+ travel_minutes == o.travel_minutes &&
190
+ warnings == o.warnings
169
191
  end
170
192
 
171
193
  # @see the `==` method
@@ -177,7 +199,7 @@ module Crisphive
177
199
  # Calculates hash code according to all attributes.
178
200
  # @return [Integer] Hash code
179
201
  def hash
180
- [booked_minutes, days, distance_km, full_name, matched_skills, technician_id, total_moves, total_score, travel_minutes].hash
202
+ [booked_minutes, calendar_busy, days, distance_km, full_name, matched_skills, technician_id, total_moves, total_score, travel_minutes, warnings].hash
181
203
  end
182
204
 
183
205
  # Builds the object from hash
@@ -27,7 +27,7 @@ module Crisphive
27
27
  # Emergency visit window end (UTC) — start + the quoted visit duration.
28
28
  attr_accessor :emergency_end
29
29
 
30
- # ID of the P0 job being placed.
30
+ # ID of the P0 job being placed. Absent for a probe -- a `job` that does not exist yet.
31
31
  attr_accessor :emergency_job_id
32
32
 
33
33
  # Emergency visit window start (UTC).
@@ -15,16 +15,22 @@ require 'time'
15
15
 
16
16
  module Crisphive
17
17
  class JobRequestEmergencyCandidatesRequest
18
- # ID of the P0 job to place.
18
+ # Place this P0 outside working hours / approved time-off — you have phoned the technician and they agreed. Drops the non-working-day rejection; the response then carries an AFTER_HOURS warning. Double-booking, service area, required skills and the lead-tier rule still reject.
19
+ attr_accessor :after_hours_override
20
+
21
+ # UUID of the P0 job to place. Send this OR `job`, never both and never neither.
19
22
  attr_accessor :emergency_job_id
20
23
 
24
+ # A job that does not exist yet — the wizard's read-only preview before anything is written. Send this OR `emergency_job_id`.
25
+ attr_accessor :job
26
+
21
27
  # Max candidates to return (default 5, max 10).
22
28
  attr_accessor :limit
23
29
 
24
30
  # Cascade mode each candidate's displacement preview assumes: overtime = displaced jobs stay same-day; next_day = overflow rolls to the next working day.
25
31
  attr_accessor :mode
26
32
 
27
- # Desired start — business-local naive datetime, no offset. Must be in the future.
33
+ # Desired start — business-local wall clock. Seconds may be omitted and a space may replace the T; an offset is accepted only when it agrees with the business timezone (a disagreeing one is refused with JOB_REQUEST_INVALID_INPUT rather than guessed). Must be in the future.
28
34
  attr_accessor :start_at
29
35
 
30
36
  class EnumAttributeValidator
@@ -52,7 +58,9 @@ module Crisphive
52
58
  # Attribute mapping from ruby-style variable name to JSON key.
53
59
  def self.attribute_map
54
60
  {
61
+ :'after_hours_override' => :'after_hours_override',
55
62
  :'emergency_job_id' => :'emergency_job_id',
63
+ :'job' => :'job',
56
64
  :'limit' => :'limit',
57
65
  :'mode' => :'mode',
58
66
  :'start_at' => :'start_at'
@@ -67,10 +75,12 @@ module Crisphive
67
75
  # Attribute type mapping.
68
76
  def self.openapi_types
69
77
  {
78
+ :'after_hours_override' => :'Boolean',
70
79
  :'emergency_job_id' => :'String',
80
+ :'job' => :'JobRequestEmergencyInlineJob',
71
81
  :'limit' => :'Integer',
72
82
  :'mode' => :'String',
73
- :'start_at' => :'String'
83
+ :'start_at' => :'Time'
74
84
  }
75
85
  end
76
86
 
@@ -95,10 +105,16 @@ module Crisphive
95
105
  h[k.to_sym] = v
96
106
  }
97
107
 
108
+ if attributes.key?(:'after_hours_override')
109
+ self.after_hours_override = attributes[:'after_hours_override']
110
+ end
111
+
98
112
  if attributes.key?(:'emergency_job_id')
99
113
  self.emergency_job_id = attributes[:'emergency_job_id']
100
- else
101
- self.emergency_job_id = nil
114
+ end
115
+
116
+ if attributes.key?(:'job')
117
+ self.job = attributes[:'job']
102
118
  end
103
119
 
104
120
  if attributes.key?(:'limit')
@@ -123,10 +139,6 @@ module Crisphive
123
139
  def list_invalid_properties
124
140
  warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
125
141
  invalid_properties = Array.new
126
- if @emergency_job_id.nil?
127
- invalid_properties.push('invalid value for "emergency_job_id", emergency_job_id cannot be nil.')
128
- end
129
-
130
142
  if !@limit.nil? && @limit > 10
131
143
  invalid_properties.push('invalid value for "limit", must be smaller than or equal to 10.')
132
144
  end
@@ -150,7 +162,6 @@ module Crisphive
150
162
  # @return true if the model is valid
151
163
  def valid?
152
164
  warn '[DEPRECATED] the `valid?` method is obsolete'
153
- return false if @emergency_job_id.nil?
154
165
  return false if !@limit.nil? && @limit > 10
155
166
  return false if !@limit.nil? && @limit < 1
156
167
  return false if @mode.nil?
@@ -193,7 +204,9 @@ module Crisphive
193
204
  def ==(o)
194
205
  return true if self.equal?(o)
195
206
  self.class == o.class &&
207
+ after_hours_override == o.after_hours_override &&
196
208
  emergency_job_id == o.emergency_job_id &&
209
+ job == o.job &&
197
210
  limit == o.limit &&
198
211
  mode == o.mode &&
199
212
  start_at == o.start_at
@@ -208,7 +221,7 @@ module Crisphive
208
221
  # Calculates hash code according to all attributes.
209
222
  # @return [Integer] Hash code
210
223
  def hash
211
- [emergency_job_id, limit, mode, start_at].hash
224
+ [after_hours_override, emergency_job_id, job, limit, mode, start_at].hash
212
225
  end
213
226
 
214
227
  # Builds the object from hash
@@ -15,6 +15,9 @@ require 'time'
15
15
 
16
16
  module Crisphive
17
17
  class JobRequestEmergencyCommitRequest
18
+ # Place this P0 outside working hours / approved time-off — you have phoned the technician and they agreed. Drops the non-working-day rejection; the response then carries an AFTER_HOURS warning. Double-booking, service area, required skills and the lead-tier rule still reject.
19
+ attr_accessor :after_hours_override
20
+
18
21
  # Fate of displaced jobs: reschedule (default) or reassign — must match the preview.
19
22
  attr_accessor :displacement_mode
20
23
 
@@ -61,6 +64,7 @@ module Crisphive
61
64
  # Attribute mapping from ruby-style variable name to JSON key.
62
65
  def self.attribute_map
63
66
  {
67
+ :'after_hours_override' => :'after_hours_override',
64
68
  :'displacement_mode' => :'displacement_mode',
65
69
  :'emergency_expected_version' => :'emergency_expected_version',
66
70
  :'emergency_job_id' => :'emergency_job_id',
@@ -79,6 +83,7 @@ module Crisphive
79
83
  # Attribute type mapping.
80
84
  def self.openapi_types
81
85
  {
86
+ :'after_hours_override' => :'Boolean',
82
87
  :'displacement_mode' => :'String',
83
88
  :'emergency_expected_version' => :'Integer',
84
89
  :'emergency_job_id' => :'String',
@@ -110,6 +115,10 @@ module Crisphive
110
115
  h[k.to_sym] = v
111
116
  }
112
117
 
118
+ if attributes.key?(:'after_hours_override')
119
+ self.after_hours_override = attributes[:'after_hours_override']
120
+ end
121
+
113
122
  if attributes.key?(:'displacement_mode')
114
123
  self.displacement_mode = attributes[:'displacement_mode']
115
124
  end
@@ -213,6 +222,7 @@ module Crisphive
213
222
  def ==(o)
214
223
  return true if self.equal?(o)
215
224
  self.class == o.class &&
225
+ after_hours_override == o.after_hours_override &&
216
226
  displacement_mode == o.displacement_mode &&
217
227
  emergency_expected_version == o.emergency_expected_version &&
218
228
  emergency_job_id == o.emergency_job_id &&
@@ -231,7 +241,7 @@ module Crisphive
231
241
  # Calculates hash code according to all attributes.
232
242
  # @return [Integer] Hash code
233
243
  def hash
234
- [displacement_mode, emergency_expected_version, emergency_job_id, expected_move_ids, mode, start_at, technician_id].hash
244
+ [after_hours_override, displacement_mode, emergency_expected_version, emergency_job_id, expected_move_ids, mode, start_at, technician_id].hash
235
245
  end
236
246
 
237
247
  # Builds the object from hash