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.
- checksums.yaml +4 -4
- data/README.md +98 -10
- data/lib/crisphive/api/business_skill_api.rb +348 -0
- data/lib/crisphive/api/customer_api.rb +7 -4
- data/lib/crisphive/api/job_request_business_api.rb +243 -27
- data/lib/crisphive/api/job_types_api.rb +208 -0
- data/lib/crisphive/api/permission_api.rb +79 -0
- data/lib/crisphive/api/service_area_api.rb +208 -0
- data/lib/crisphive/api/technician_api.rb +8 -8
- data/lib/crisphive/api/technician_time_off_api.rb +240 -0
- data/lib/crisphive/api/vehicle_api.rb +208 -0
- data/lib/crisphive/api/webhooks_api.rb +213 -0
- data/lib/crisphive/models/api_internal_techtimeoff_actions.rb +232 -0
- data/lib/crisphive/models/api_internal_techtimeoff_status.rb +42 -0
- data/lib/crisphive/models/assignable_group.rb +289 -0
- data/lib/crisphive/models/book_and_confirm_job_request200_response.rb +253 -0
- data/lib/crisphive/models/commit_absence_resolve200_response.rb +253 -0
- data/lib/crisphive/models/create_job_type200_response.rb +253 -0
- data/lib/crisphive/models/create_service_area200_response.rb +253 -0
- data/lib/crisphive/models/create_skill200_response.rb +253 -0
- data/lib/crisphive/models/create_skill_category200_response.rb +253 -0
- data/lib/crisphive/models/create_technician_time_off200_response.rb +253 -0
- data/lib/crisphive/models/create_vehicle200_response.rb +253 -0
- data/lib/crisphive/models/create_webhook_endpoint200_response.rb +253 -0
- data/lib/crisphive/models/customer.rb +11 -1
- data/lib/crisphive/models/customer_contact.rb +25 -5
- data/lib/crisphive/models/customer_create_request.rb +12 -2
- data/lib/crisphive/models/customer_list_item.rb +11 -1
- data/lib/crisphive/models/customer_quick_books_link.rb +235 -0
- data/lib/crisphive/models/customer_service_area_ref.rb +225 -0
- data/lib/crisphive/models/customer_technician_ref.rb +225 -0
- data/lib/crisphive/models/customer_update_request.rb +23 -20
- data/lib/crisphive/models/internal_jobrequest_http_address_req.rb +475 -0
- data/lib/crisphive/models/job_request.rb +11 -1
- data/lib/crisphive/models/job_request_absence_alternative.rb +356 -0
- data/lib/crisphive/models/job_request_absence_alternative_cost.rb +275 -0
- data/lib/crisphive/models/job_request_absence_assignment.rb +319 -0
- data/lib/crisphive/models/job_request_absence_commit_request.rb +296 -0
- data/lib/crisphive/models/job_request_absence_notification.rb +283 -0
- data/lib/crisphive/models/job_request_absence_plan.rb +322 -0
- data/lib/crisphive/models/job_request_absence_preview_request.rb +280 -0
- data/lib/crisphive/models/job_request_absence_resolved_job.rb +499 -0
- data/lib/crisphive/models/job_request_absence_solver.rb +289 -0
- data/lib/crisphive/models/job_request_absence_time_off.rb +281 -0
- data/lib/crisphive/models/job_request_absence_unresolved_job.rb +364 -0
- data/lib/crisphive/models/job_request_action_summary.rb +1 -1
- data/lib/crisphive/models/job_request_attention_summary.rb +2 -2
- data/lib/crisphive/models/job_request_blocker.rb +363 -0
- data/lib/crisphive/models/job_request_blocker_ref.rb +223 -0
- data/lib/crisphive/models/job_request_book_and_confirm_customer.rb +302 -0
- data/lib/crisphive/models/job_request_book_and_confirm_emergency.rb +315 -0
- data/lib/crisphive/models/job_request_book_and_confirm_emergency_result.rb +279 -0
- data/lib/crisphive/models/job_request_book_and_confirm_refusal.rb +280 -0
- data/lib/crisphive/models/job_request_book_and_confirm_request.rb +466 -0
- data/lib/crisphive/models/job_request_book_and_confirm_response.rb +295 -0
- data/lib/crisphive/models/job_request_confirm_request.rb +14 -4
- data/lib/crisphive/models/job_request_create_request.rb +1 -1
- data/lib/crisphive/models/job_request_emergency_candidate.rb +26 -4
- data/lib/crisphive/models/job_request_emergency_candidates.rb +1 -1
- data/lib/crisphive/models/job_request_emergency_candidates_request.rb +24 -11
- data/lib/crisphive/models/job_request_emergency_commit_request.rb +11 -1
- data/lib/crisphive/models/job_request_emergency_inline_job.rb +353 -0
- data/lib/crisphive/models/job_request_emergency_plan.rb +25 -3
- data/lib/crisphive/models/job_request_emergency_preview_request.rb +24 -11
- data/lib/crisphive/models/job_request_move_commit_req.rb +11 -1
- data/lib/crisphive/models/job_request_move_plan.rb +11 -1
- data/lib/crisphive/models/job_request_move_preview_req.rb +11 -1
- data/lib/crisphive/models/job_request_move_warning.rb +32 -8
- data/lib/crisphive/models/job_request_priority_update_result.rb +217 -0
- data/lib/crisphive/models/job_request_quote_request.rb +14 -11
- data/lib/crisphive/models/job_request_reassign_fallback.rb +287 -0
- data/lib/crisphive/models/job_request_skill_summary.rb +1 -1
- data/lib/crisphive/models/job_request_status_summary.rb +1 -1
- data/lib/crisphive/models/job_request_time_segments.rb +2 -2
- data/lib/crisphive/models/job_type.rb +42 -2
- data/lib/crisphive/models/job_type_create_request.rb +399 -0
- data/lib/crisphive/models/job_type_create_response.rb +215 -0
- data/lib/crisphive/models/job_type_update_request.rb +400 -0
- data/lib/crisphive/models/list_assignable_groups200_response.rb +255 -0
- data/lib/crisphive/models/list_technician_time_off200_response.rb +253 -0
- data/lib/crisphive/models/list_webhook_event_types200_response.rb +255 -0
- data/lib/crisphive/models/quote_job_request200_response.rb +253 -0
- data/lib/crisphive/models/service_area.rb +21 -1
- data/lib/crisphive/models/service_area_create_request.rb +455 -0
- data/lib/crisphive/models/service_area_create_response.rb +215 -0
- data/lib/crisphive/models/service_area_update_request.rb +451 -0
- data/lib/crisphive/models/skill_category_create_request.rb +270 -0
- data/lib/crisphive/models/skill_category_create_response.rb +215 -0
- data/lib/crisphive/models/skill_create_request.rb +270 -0
- data/lib/crisphive/models/skill_create_response.rb +215 -0
- data/lib/crisphive/models/skill_update_request.rb +281 -0
- data/lib/crisphive/models/technician.rb +64 -2
- data/lib/crisphive/models/technician_create_request.rb +14 -11
- data/lib/crisphive/models/technician_time_off.rb +334 -0
- data/lib/crisphive/models/technician_time_off_create_request.rb +285 -0
- data/lib/crisphive/models/technician_time_off_create_response.rb +215 -0
- data/lib/crisphive/models/technician_time_off_list.rb +246 -0
- data/lib/crisphive/models/technician_update_request.rb +2 -2
- data/lib/crisphive/models/vehicle_create_request.rb +420 -0
- data/lib/crisphive/models/vehicle_create_response.rb +215 -0
- data/lib/crisphive/models/vehicle_update_request.rb +440 -0
- data/lib/crisphive/models/webhook_create_request.rb +320 -0
- data/lib/crisphive/models/webhook_create_response.rb +391 -0
- data/lib/crisphive/models/webhook_verification.rb +235 -0
- data/lib/crisphive/version.rb +1 -1
- data/lib/crisphive.rb +66 -0
- metadata +68 -2
|
@@ -19,6 +19,140 @@ module Crisphive
|
|
|
19
19
|
def initialize(api_client = ApiClient.default)
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
|
+
# Add a job type to the catalog
|
|
23
|
+
# Creates a kind of work customers can book, such as \"Annual boiler service\" or \"Drain unblocking\". Job types classify bookings: createJobRequest takes an optional `job_type_id` from this catalog and the job keeps the type's name as it was at booking time. `name` is the only required field and must be unique in the business (JOB_TYPE_DUPLICATE). `status` defaults to active. An inactive type stays in the catalog but cannot be chosen for new job requests; use that rather than deleting a type you may revive. Send an Idempotency-Key header (the `idempotency_key` argument over MCP) so a retried call replays the original response instead of creating a duplicate type. Optional default_duration_minutes (+ default_mobilization_minutes / default_demobilization_minutes) set how long this kind of work usually takes: quoteJobRequest uses them when it is sent no job_duration_minutes, so an automation or voice agent can schedule the job without knowing the length. A buffer needs a duration (JOB_TYPE_INVALID_DEFAULT_DURATION). This defines the catalog, not a booking. To book actual work use createJobRequest and reference the job type there.
|
|
24
|
+
# @param job_type_create_request [JobTypeCreateRequest] Job type
|
|
25
|
+
# @param [Hash] opts the optional parameters
|
|
26
|
+
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
27
|
+
# @return [CreateJobType200Response]
|
|
28
|
+
def create_job_type(job_type_create_request, opts = {})
|
|
29
|
+
data, _status_code, _headers = create_job_type_with_http_info(job_type_create_request, opts)
|
|
30
|
+
data
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Add a job type to the catalog
|
|
34
|
+
# Creates a kind of work customers can book, such as \"Annual boiler service\" or \"Drain unblocking\". Job types classify bookings: createJobRequest takes an optional `job_type_id` from this catalog and the job keeps the type's name as it was at booking time. `name` is the only required field and must be unique in the business (JOB_TYPE_DUPLICATE). `status` defaults to active. An inactive type stays in the catalog but cannot be chosen for new job requests; use that rather than deleting a type you may revive. Send an Idempotency-Key header (the `idempotency_key` argument over MCP) so a retried call replays the original response instead of creating a duplicate type. Optional default_duration_minutes (+ default_mobilization_minutes / default_demobilization_minutes) set how long this kind of work usually takes: quoteJobRequest uses them when it is sent no job_duration_minutes, so an automation or voice agent can schedule the job without knowing the length. A buffer needs a duration (JOB_TYPE_INVALID_DEFAULT_DURATION). This defines the catalog, not a booking. To book actual work use createJobRequest and reference the job type there.
|
|
35
|
+
# @param job_type_create_request [JobTypeCreateRequest] Job type
|
|
36
|
+
# @param [Hash] opts the optional parameters
|
|
37
|
+
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
38
|
+
# @return [Array<(CreateJobType200Response, Integer, Hash)>] CreateJobType200Response data, response status code and response headers
|
|
39
|
+
def create_job_type_with_http_info(job_type_create_request, opts = {})
|
|
40
|
+
if @api_client.config.debugging
|
|
41
|
+
@api_client.config.logger.debug 'Calling API: JobTypesApi.create_job_type ...'
|
|
42
|
+
end
|
|
43
|
+
# verify the required parameter 'job_type_create_request' is set
|
|
44
|
+
if @api_client.config.client_side_validation && job_type_create_request.nil?
|
|
45
|
+
fail ArgumentError, "Missing the required parameter 'job_type_create_request' when calling JobTypesApi.create_job_type"
|
|
46
|
+
end
|
|
47
|
+
# resource path
|
|
48
|
+
local_var_path = '/job-types'
|
|
49
|
+
|
|
50
|
+
# query parameters
|
|
51
|
+
query_params = opts[:query_params] || {}
|
|
52
|
+
|
|
53
|
+
# header parameters
|
|
54
|
+
header_params = opts[:header_params] || {}
|
|
55
|
+
# HTTP header 'Accept' (if needed)
|
|
56
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
57
|
+
# HTTP header 'Content-Type'
|
|
58
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
59
|
+
if !content_type.nil?
|
|
60
|
+
header_params['Content-Type'] = content_type
|
|
61
|
+
end
|
|
62
|
+
header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
|
|
63
|
+
|
|
64
|
+
# form parameters
|
|
65
|
+
form_params = opts[:form_params] || {}
|
|
66
|
+
|
|
67
|
+
# http body (model)
|
|
68
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(job_type_create_request)
|
|
69
|
+
|
|
70
|
+
# return_type
|
|
71
|
+
return_type = opts[:debug_return_type] || 'CreateJobType200Response'
|
|
72
|
+
|
|
73
|
+
# auth_names
|
|
74
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
75
|
+
|
|
76
|
+
new_options = opts.merge(
|
|
77
|
+
:operation => :"JobTypesApi.create_job_type",
|
|
78
|
+
:header_params => header_params,
|
|
79
|
+
:query_params => query_params,
|
|
80
|
+
:form_params => form_params,
|
|
81
|
+
:body => post_body,
|
|
82
|
+
:auth_names => auth_names,
|
|
83
|
+
:return_type => return_type
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
|
|
87
|
+
if @api_client.config.debugging
|
|
88
|
+
@api_client.config.logger.debug "API called: JobTypesApi#create_job_type\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
89
|
+
end
|
|
90
|
+
return data, status_code, headers
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Remove a job type from the catalog
|
|
94
|
+
# Soft-deletes the entry: it disappears from the catalog and can no longer be selected for new bookings. Jobs already booked against it are unaffected and keep showing the name they were booked with. Prefer updateJobType with `status=inactive` in almost every case: it has the same effect on the booking form and is trivially reversible. Delete is for a type created in error or one that will never return. Rows the platform ships with (`is_system=true`) cannot be deleted and are refused with JOB_TYPE_SYSTEM_READ_ONLY.
|
|
95
|
+
# @param id [String] Job Type ID
|
|
96
|
+
# @param [Hash] opts the optional parameters
|
|
97
|
+
# @return [ResponseEnvelope]
|
|
98
|
+
def delete_job_type(id, opts = {})
|
|
99
|
+
data, _status_code, _headers = delete_job_type_with_http_info(id, opts)
|
|
100
|
+
data
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Remove a job type from the catalog
|
|
104
|
+
# Soft-deletes the entry: it disappears from the catalog and can no longer be selected for new bookings. Jobs already booked against it are unaffected and keep showing the name they were booked with. Prefer updateJobType with `status=inactive` in almost every case: it has the same effect on the booking form and is trivially reversible. Delete is for a type created in error or one that will never return. Rows the platform ships with (`is_system=true`) cannot be deleted and are refused with JOB_TYPE_SYSTEM_READ_ONLY.
|
|
105
|
+
# @param id [String] Job Type ID
|
|
106
|
+
# @param [Hash] opts the optional parameters
|
|
107
|
+
# @return [Array<(ResponseEnvelope, Integer, Hash)>] ResponseEnvelope data, response status code and response headers
|
|
108
|
+
def delete_job_type_with_http_info(id, opts = {})
|
|
109
|
+
if @api_client.config.debugging
|
|
110
|
+
@api_client.config.logger.debug 'Calling API: JobTypesApi.delete_job_type ...'
|
|
111
|
+
end
|
|
112
|
+
# verify the required parameter 'id' is set
|
|
113
|
+
if @api_client.config.client_side_validation && id.nil?
|
|
114
|
+
fail ArgumentError, "Missing the required parameter 'id' when calling JobTypesApi.delete_job_type"
|
|
115
|
+
end
|
|
116
|
+
# resource path
|
|
117
|
+
local_var_path = '/job-types/{id}'.sub('{' + 'id' + '}', CGI.escape(id.to_s))
|
|
118
|
+
|
|
119
|
+
# query parameters
|
|
120
|
+
query_params = opts[:query_params] || {}
|
|
121
|
+
|
|
122
|
+
# header parameters
|
|
123
|
+
header_params = opts[:header_params] || {}
|
|
124
|
+
# HTTP header 'Accept' (if needed)
|
|
125
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
126
|
+
|
|
127
|
+
# form parameters
|
|
128
|
+
form_params = opts[:form_params] || {}
|
|
129
|
+
|
|
130
|
+
# http body (model)
|
|
131
|
+
post_body = opts[:debug_body]
|
|
132
|
+
|
|
133
|
+
# return_type
|
|
134
|
+
return_type = opts[:debug_return_type] || 'ResponseEnvelope'
|
|
135
|
+
|
|
136
|
+
# auth_names
|
|
137
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
138
|
+
|
|
139
|
+
new_options = opts.merge(
|
|
140
|
+
:operation => :"JobTypesApi.delete_job_type",
|
|
141
|
+
:header_params => header_params,
|
|
142
|
+
:query_params => query_params,
|
|
143
|
+
:form_params => form_params,
|
|
144
|
+
:body => post_body,
|
|
145
|
+
:auth_names => auth_names,
|
|
146
|
+
:return_type => return_type
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
data, status_code, headers = @api_client.call_api(:DELETE, local_var_path, new_options)
|
|
150
|
+
if @api_client.config.debugging
|
|
151
|
+
@api_client.config.logger.debug "API called: JobTypesApi#delete_job_type\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
152
|
+
end
|
|
153
|
+
return data, status_code, headers
|
|
154
|
+
end
|
|
155
|
+
|
|
22
156
|
# Get a job type
|
|
23
157
|
# Returns one entry of the business's service catalog (job/work-order type) with its localized display name — e.g. an HVAC tune-up, drain cleaning or electrical inspection offering.
|
|
24
158
|
# @param id [String] Job Type ID
|
|
@@ -141,5 +275,79 @@ module Crisphive
|
|
|
141
275
|
end
|
|
142
276
|
return data, status_code, headers
|
|
143
277
|
end
|
|
278
|
+
|
|
279
|
+
# Rename a job type or change its availability
|
|
280
|
+
# Edits a catalog entry in place. A rename applies to NEW bookings only: every job stores the job-type name it was booked with, so existing and completed jobs keep their original label. Partial update: omit a field to keep it. `name` rejects \"\" because a type must stay identifiable, and must stay unique (JOB_TYPE_DUPLICATE). Setting `status` to inactive is the reversible way to take a type off the booking form; inactive types are refused for new job requests. Default quote bundle: default_duration_minutes / default_mobilization_minutes / default_demobilization_minutes follow the same partial rule; omit to keep, 0 to clear, a value to set. Clearing the duration while a buffer stays is refused (JOB_TYPE_INVALID_DEFAULT_DURATION). Rows the platform ships with (`is_system=true`, e.g. the default \"General\" type) keep their name and status read-only (JOB_TYPE_SYSTEM_READ_ONLY); their default quote bundle IS editable. Create your own type if you need different wording.
|
|
281
|
+
# @param id [String] Job Type ID
|
|
282
|
+
# @param job_type_update_request [JobTypeUpdateRequest] Job type
|
|
283
|
+
# @param [Hash] opts the optional parameters
|
|
284
|
+
# @return [ResponseEnvelope]
|
|
285
|
+
def update_job_type(id, job_type_update_request, opts = {})
|
|
286
|
+
data, _status_code, _headers = update_job_type_with_http_info(id, job_type_update_request, opts)
|
|
287
|
+
data
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Rename a job type or change its availability
|
|
291
|
+
# Edits a catalog entry in place. A rename applies to NEW bookings only: every job stores the job-type name it was booked with, so existing and completed jobs keep their original label. Partial update: omit a field to keep it. `name` rejects \"\" because a type must stay identifiable, and must stay unique (JOB_TYPE_DUPLICATE). Setting `status` to inactive is the reversible way to take a type off the booking form; inactive types are refused for new job requests. Default quote bundle: default_duration_minutes / default_mobilization_minutes / default_demobilization_minutes follow the same partial rule; omit to keep, 0 to clear, a value to set. Clearing the duration while a buffer stays is refused (JOB_TYPE_INVALID_DEFAULT_DURATION). Rows the platform ships with (`is_system=true`, e.g. the default \"General\" type) keep their name and status read-only (JOB_TYPE_SYSTEM_READ_ONLY); their default quote bundle IS editable. Create your own type if you need different wording.
|
|
292
|
+
# @param id [String] Job Type ID
|
|
293
|
+
# @param job_type_update_request [JobTypeUpdateRequest] Job type
|
|
294
|
+
# @param [Hash] opts the optional parameters
|
|
295
|
+
# @return [Array<(ResponseEnvelope, Integer, Hash)>] ResponseEnvelope data, response status code and response headers
|
|
296
|
+
def update_job_type_with_http_info(id, job_type_update_request, opts = {})
|
|
297
|
+
if @api_client.config.debugging
|
|
298
|
+
@api_client.config.logger.debug 'Calling API: JobTypesApi.update_job_type ...'
|
|
299
|
+
end
|
|
300
|
+
# verify the required parameter 'id' is set
|
|
301
|
+
if @api_client.config.client_side_validation && id.nil?
|
|
302
|
+
fail ArgumentError, "Missing the required parameter 'id' when calling JobTypesApi.update_job_type"
|
|
303
|
+
end
|
|
304
|
+
# verify the required parameter 'job_type_update_request' is set
|
|
305
|
+
if @api_client.config.client_side_validation && job_type_update_request.nil?
|
|
306
|
+
fail ArgumentError, "Missing the required parameter 'job_type_update_request' when calling JobTypesApi.update_job_type"
|
|
307
|
+
end
|
|
308
|
+
# resource path
|
|
309
|
+
local_var_path = '/job-types/{id}'.sub('{' + 'id' + '}', CGI.escape(id.to_s))
|
|
310
|
+
|
|
311
|
+
# query parameters
|
|
312
|
+
query_params = opts[:query_params] || {}
|
|
313
|
+
|
|
314
|
+
# header parameters
|
|
315
|
+
header_params = opts[:header_params] || {}
|
|
316
|
+
# HTTP header 'Accept' (if needed)
|
|
317
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
318
|
+
# HTTP header 'Content-Type'
|
|
319
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
320
|
+
if !content_type.nil?
|
|
321
|
+
header_params['Content-Type'] = content_type
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# form parameters
|
|
325
|
+
form_params = opts[:form_params] || {}
|
|
326
|
+
|
|
327
|
+
# http body (model)
|
|
328
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(job_type_update_request)
|
|
329
|
+
|
|
330
|
+
# return_type
|
|
331
|
+
return_type = opts[:debug_return_type] || 'ResponseEnvelope'
|
|
332
|
+
|
|
333
|
+
# auth_names
|
|
334
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
335
|
+
|
|
336
|
+
new_options = opts.merge(
|
|
337
|
+
:operation => :"JobTypesApi.update_job_type",
|
|
338
|
+
:header_params => header_params,
|
|
339
|
+
:query_params => query_params,
|
|
340
|
+
:form_params => form_params,
|
|
341
|
+
:body => post_body,
|
|
342
|
+
:auth_names => auth_names,
|
|
343
|
+
:return_type => return_type
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
|
|
347
|
+
if @api_client.config.debugging
|
|
348
|
+
@api_client.config.logger.debug "API called: JobTypesApi#update_job_type\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
349
|
+
end
|
|
350
|
+
return data, status_code, headers
|
|
351
|
+
end
|
|
144
352
|
end
|
|
145
353
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
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 'cgi'
|
|
14
|
+
|
|
15
|
+
module Crisphive
|
|
16
|
+
class PermissionApi
|
|
17
|
+
attr_accessor :api_client
|
|
18
|
+
|
|
19
|
+
def initialize(api_client = ApiClient.default)
|
|
20
|
+
@api_client = api_client
|
|
21
|
+
end
|
|
22
|
+
# List groups the caller may assign to a member
|
|
23
|
+
# Returns the role groups the CURRENT caller is allowed to hand out when creating or re-roling a team member, filtered server-side by the role-assignment ceiling (system groups: at or below the caller's own rank, inclusive; custom groups: only those whose permissions are a subset of the caller's). Build the member-create role dropdown from THIS list — the same rule is enforced on POST/PUT /business/technicians, so anything shown here is guaranteed to be accepted.
|
|
24
|
+
# @param [Hash] opts the optional parameters
|
|
25
|
+
# @return [ListAssignableGroups200Response]
|
|
26
|
+
def list_assignable_groups(opts = {})
|
|
27
|
+
data, _status_code, _headers = list_assignable_groups_with_http_info(opts)
|
|
28
|
+
data
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# List groups the caller may assign to a member
|
|
32
|
+
# Returns the role groups the CURRENT caller is allowed to hand out when creating or re-roling a team member, filtered server-side by the role-assignment ceiling (system groups: at or below the caller's own rank, inclusive; custom groups: only those whose permissions are a subset of the caller's). Build the member-create role dropdown from THIS list — the same rule is enforced on POST/PUT /business/technicians, so anything shown here is guaranteed to be accepted.
|
|
33
|
+
# @param [Hash] opts the optional parameters
|
|
34
|
+
# @return [Array<(ListAssignableGroups200Response, Integer, Hash)>] ListAssignableGroups200Response data, response status code and response headers
|
|
35
|
+
def list_assignable_groups_with_http_info(opts = {})
|
|
36
|
+
if @api_client.config.debugging
|
|
37
|
+
@api_client.config.logger.debug 'Calling API: PermissionApi.list_assignable_groups ...'
|
|
38
|
+
end
|
|
39
|
+
# resource path
|
|
40
|
+
local_var_path = '/permission/groups/assignable'
|
|
41
|
+
|
|
42
|
+
# query parameters
|
|
43
|
+
query_params = opts[:query_params] || {}
|
|
44
|
+
|
|
45
|
+
# header parameters
|
|
46
|
+
header_params = opts[:header_params] || {}
|
|
47
|
+
# HTTP header 'Accept' (if needed)
|
|
48
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
49
|
+
|
|
50
|
+
# form parameters
|
|
51
|
+
form_params = opts[:form_params] || {}
|
|
52
|
+
|
|
53
|
+
# http body (model)
|
|
54
|
+
post_body = opts[:debug_body]
|
|
55
|
+
|
|
56
|
+
# return_type
|
|
57
|
+
return_type = opts[:debug_return_type] || 'ListAssignableGroups200Response'
|
|
58
|
+
|
|
59
|
+
# auth_names
|
|
60
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
61
|
+
|
|
62
|
+
new_options = opts.merge(
|
|
63
|
+
:operation => :"PermissionApi.list_assignable_groups",
|
|
64
|
+
:header_params => header_params,
|
|
65
|
+
:query_params => query_params,
|
|
66
|
+
:form_params => form_params,
|
|
67
|
+
:body => post_body,
|
|
68
|
+
:auth_names => auth_names,
|
|
69
|
+
:return_type => return_type
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
|
|
73
|
+
if @api_client.config.debugging
|
|
74
|
+
@api_client.config.logger.debug "API called: PermissionApi#list_assignable_groups\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
75
|
+
end
|
|
76
|
+
return data, status_code, headers
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -19,6 +19,140 @@ module Crisphive
|
|
|
19
19
|
def initialize(api_client = ApiClient.default)
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
|
+
# Define a territory the business serves
|
|
23
|
+
# Creates a service area: a named region used as a HARD filter when deciding who can take a job. A technician assigned to no area covering the job's address is never offered by listNearbyTechnicians, listMatchingSlots or listCrewCandidates, and never auto-assigned at confirm, whatever their skills or availability say. `name` is the only required field and must be unique (SERVICE_AREA_DUPLICATE_NAME). Coverage is matched two ways: with a `boundary` (GeoJSON polygon), a geocoded address must fall inside the polygon; without one, the area matches addresses by equality on its postal_code, city or district. A polygon is the precise option; the administrative fields are the fallback, and also what matches jobs whose address could not be geocoded. An invalid polygon is refused with SERVICE_AREA_INVALID_BOUNDARY. Creating the area does not staff it. Assign technicians with replaceTechnicianServiceAreas, or pass `service_area_ids` to createTechnician. Send an Idempotency-Key header (the `idempotency_key` argument over MCP) so a retry does not create a duplicate area.
|
|
24
|
+
# @param service_area_create_request [ServiceAreaCreateRequest] Service area details
|
|
25
|
+
# @param [Hash] opts the optional parameters
|
|
26
|
+
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
27
|
+
# @return [CreateServiceArea200Response]
|
|
28
|
+
def create_service_area(service_area_create_request, opts = {})
|
|
29
|
+
data, _status_code, _headers = create_service_area_with_http_info(service_area_create_request, opts)
|
|
30
|
+
data
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Define a territory the business serves
|
|
34
|
+
# Creates a service area: a named region used as a HARD filter when deciding who can take a job. A technician assigned to no area covering the job's address is never offered by listNearbyTechnicians, listMatchingSlots or listCrewCandidates, and never auto-assigned at confirm, whatever their skills or availability say. `name` is the only required field and must be unique (SERVICE_AREA_DUPLICATE_NAME). Coverage is matched two ways: with a `boundary` (GeoJSON polygon), a geocoded address must fall inside the polygon; without one, the area matches addresses by equality on its postal_code, city or district. A polygon is the precise option; the administrative fields are the fallback, and also what matches jobs whose address could not be geocoded. An invalid polygon is refused with SERVICE_AREA_INVALID_BOUNDARY. Creating the area does not staff it. Assign technicians with replaceTechnicianServiceAreas, or pass `service_area_ids` to createTechnician. Send an Idempotency-Key header (the `idempotency_key` argument over MCP) so a retry does not create a duplicate area.
|
|
35
|
+
# @param service_area_create_request [ServiceAreaCreateRequest] Service area details
|
|
36
|
+
# @param [Hash] opts the optional parameters
|
|
37
|
+
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
38
|
+
# @return [Array<(CreateServiceArea200Response, Integer, Hash)>] CreateServiceArea200Response data, response status code and response headers
|
|
39
|
+
def create_service_area_with_http_info(service_area_create_request, opts = {})
|
|
40
|
+
if @api_client.config.debugging
|
|
41
|
+
@api_client.config.logger.debug 'Calling API: ServiceAreaApi.create_service_area ...'
|
|
42
|
+
end
|
|
43
|
+
# verify the required parameter 'service_area_create_request' is set
|
|
44
|
+
if @api_client.config.client_side_validation && service_area_create_request.nil?
|
|
45
|
+
fail ArgumentError, "Missing the required parameter 'service_area_create_request' when calling ServiceAreaApi.create_service_area"
|
|
46
|
+
end
|
|
47
|
+
# resource path
|
|
48
|
+
local_var_path = '/service-areas'
|
|
49
|
+
|
|
50
|
+
# query parameters
|
|
51
|
+
query_params = opts[:query_params] || {}
|
|
52
|
+
|
|
53
|
+
# header parameters
|
|
54
|
+
header_params = opts[:header_params] || {}
|
|
55
|
+
# HTTP header 'Accept' (if needed)
|
|
56
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
57
|
+
# HTTP header 'Content-Type'
|
|
58
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
59
|
+
if !content_type.nil?
|
|
60
|
+
header_params['Content-Type'] = content_type
|
|
61
|
+
end
|
|
62
|
+
header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
|
|
63
|
+
|
|
64
|
+
# form parameters
|
|
65
|
+
form_params = opts[:form_params] || {}
|
|
66
|
+
|
|
67
|
+
# http body (model)
|
|
68
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(service_area_create_request)
|
|
69
|
+
|
|
70
|
+
# return_type
|
|
71
|
+
return_type = opts[:debug_return_type] || 'CreateServiceArea200Response'
|
|
72
|
+
|
|
73
|
+
# auth_names
|
|
74
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
75
|
+
|
|
76
|
+
new_options = opts.merge(
|
|
77
|
+
:operation => :"ServiceAreaApi.create_service_area",
|
|
78
|
+
:header_params => header_params,
|
|
79
|
+
:query_params => query_params,
|
|
80
|
+
:form_params => form_params,
|
|
81
|
+
:body => post_body,
|
|
82
|
+
:auth_names => auth_names,
|
|
83
|
+
:return_type => return_type
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
|
|
87
|
+
if @api_client.config.debugging
|
|
88
|
+
@api_client.config.logger.debug "API called: ServiceAreaApi#create_service_area\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
89
|
+
end
|
|
90
|
+
return data, status_code, headers
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Stop serving a territory
|
|
94
|
+
# Soft-deletes the service area: it disappears from listServiceAreas and stops counting for coverage immediately. Technician assignments to it are left in place but no longer grant coverage. The consequence is easy to underestimate: technicians whose only coverage was this area become unmatchable for addresses inside it. Jobs already assigned keep their technician, but any re-plan (reassign, board move, confirm of a pending job, the slot picker) can find no feasible crew there. Before deleting, re-check listCrewCandidates on upcoming jobs in that territory. If you are reshaping coverage rather than withdrawing from it, edit the polygon or postal/city fields with updateServiceArea instead; that keeps the area and its technician assignments working.
|
|
95
|
+
# @param id [String] Service Area ID
|
|
96
|
+
# @param [Hash] opts the optional parameters
|
|
97
|
+
# @return [ResponseEnvelope]
|
|
98
|
+
def delete_service_area(id, opts = {})
|
|
99
|
+
data, _status_code, _headers = delete_service_area_with_http_info(id, opts)
|
|
100
|
+
data
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Stop serving a territory
|
|
104
|
+
# Soft-deletes the service area: it disappears from listServiceAreas and stops counting for coverage immediately. Technician assignments to it are left in place but no longer grant coverage. The consequence is easy to underestimate: technicians whose only coverage was this area become unmatchable for addresses inside it. Jobs already assigned keep their technician, but any re-plan (reassign, board move, confirm of a pending job, the slot picker) can find no feasible crew there. Before deleting, re-check listCrewCandidates on upcoming jobs in that territory. If you are reshaping coverage rather than withdrawing from it, edit the polygon or postal/city fields with updateServiceArea instead; that keeps the area and its technician assignments working.
|
|
105
|
+
# @param id [String] Service Area ID
|
|
106
|
+
# @param [Hash] opts the optional parameters
|
|
107
|
+
# @return [Array<(ResponseEnvelope, Integer, Hash)>] ResponseEnvelope data, response status code and response headers
|
|
108
|
+
def delete_service_area_with_http_info(id, opts = {})
|
|
109
|
+
if @api_client.config.debugging
|
|
110
|
+
@api_client.config.logger.debug 'Calling API: ServiceAreaApi.delete_service_area ...'
|
|
111
|
+
end
|
|
112
|
+
# verify the required parameter 'id' is set
|
|
113
|
+
if @api_client.config.client_side_validation && id.nil?
|
|
114
|
+
fail ArgumentError, "Missing the required parameter 'id' when calling ServiceAreaApi.delete_service_area"
|
|
115
|
+
end
|
|
116
|
+
# resource path
|
|
117
|
+
local_var_path = '/service-areas/{id}'.sub('{' + 'id' + '}', CGI.escape(id.to_s))
|
|
118
|
+
|
|
119
|
+
# query parameters
|
|
120
|
+
query_params = opts[:query_params] || {}
|
|
121
|
+
|
|
122
|
+
# header parameters
|
|
123
|
+
header_params = opts[:header_params] || {}
|
|
124
|
+
# HTTP header 'Accept' (if needed)
|
|
125
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
126
|
+
|
|
127
|
+
# form parameters
|
|
128
|
+
form_params = opts[:form_params] || {}
|
|
129
|
+
|
|
130
|
+
# http body (model)
|
|
131
|
+
post_body = opts[:debug_body]
|
|
132
|
+
|
|
133
|
+
# return_type
|
|
134
|
+
return_type = opts[:debug_return_type] || 'ResponseEnvelope'
|
|
135
|
+
|
|
136
|
+
# auth_names
|
|
137
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
138
|
+
|
|
139
|
+
new_options = opts.merge(
|
|
140
|
+
:operation => :"ServiceAreaApi.delete_service_area",
|
|
141
|
+
:header_params => header_params,
|
|
142
|
+
:query_params => query_params,
|
|
143
|
+
:form_params => form_params,
|
|
144
|
+
:body => post_body,
|
|
145
|
+
:auth_names => auth_names,
|
|
146
|
+
:return_type => return_type
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
data, status_code, headers = @api_client.call_api(:DELETE, local_var_path, new_options)
|
|
150
|
+
if @api_client.config.debugging
|
|
151
|
+
@api_client.config.logger.debug "API called: ServiceAreaApi#delete_service_area\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
152
|
+
end
|
|
153
|
+
return data, status_code, headers
|
|
154
|
+
end
|
|
155
|
+
|
|
22
156
|
# Get a service area
|
|
23
157
|
# Returns one service area — a geographic coverage zone (service territory) the business operates in, with its name and geometry metadata. Reference its UUID as `service_area_id` on customer records for territory-aware dispatch.
|
|
24
158
|
# @param id [String] Service Area ID
|
|
@@ -144,5 +278,79 @@ module Crisphive
|
|
|
144
278
|
end
|
|
145
279
|
return data, status_code, headers
|
|
146
280
|
end
|
|
281
|
+
|
|
282
|
+
# Adjust a territory's details or its boundary
|
|
283
|
+
# Edits a service area in place, keeping its id and every technician already assigned to it. Partial update: omit a field to keep it, send \"\" to clear an optional text field; `name` rejects \"\". `boundary` is the one to watch: omitting it KEEPS the stored polygon, while sending one REPLACES it outright (no partial merge of geometry). This tool cannot remove a polygon once set. A boundary or postal/city change takes effect for every NEW matching decision (quote checks, confirm, reassign, board moves, slot pickers), including for jobs already on the calendar when they are next re-planned. Jobs already assigned are not re-evaluated automatically, so after moving an edge, re-check listCrewCandidates on upcoming jobs near it.
|
|
284
|
+
# @param id [String] Service Area ID
|
|
285
|
+
# @param service_area_update_request [ServiceAreaUpdateRequest] Service area details
|
|
286
|
+
# @param [Hash] opts the optional parameters
|
|
287
|
+
# @return [ResponseEnvelope]
|
|
288
|
+
def update_service_area(id, service_area_update_request, opts = {})
|
|
289
|
+
data, _status_code, _headers = update_service_area_with_http_info(id, service_area_update_request, opts)
|
|
290
|
+
data
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Adjust a territory's details or its boundary
|
|
294
|
+
# Edits a service area in place, keeping its id and every technician already assigned to it. Partial update: omit a field to keep it, send \"\" to clear an optional text field; `name` rejects \"\". `boundary` is the one to watch: omitting it KEEPS the stored polygon, while sending one REPLACES it outright (no partial merge of geometry). This tool cannot remove a polygon once set. A boundary or postal/city change takes effect for every NEW matching decision (quote checks, confirm, reassign, board moves, slot pickers), including for jobs already on the calendar when they are next re-planned. Jobs already assigned are not re-evaluated automatically, so after moving an edge, re-check listCrewCandidates on upcoming jobs near it.
|
|
295
|
+
# @param id [String] Service Area ID
|
|
296
|
+
# @param service_area_update_request [ServiceAreaUpdateRequest] Service area details
|
|
297
|
+
# @param [Hash] opts the optional parameters
|
|
298
|
+
# @return [Array<(ResponseEnvelope, Integer, Hash)>] ResponseEnvelope data, response status code and response headers
|
|
299
|
+
def update_service_area_with_http_info(id, service_area_update_request, opts = {})
|
|
300
|
+
if @api_client.config.debugging
|
|
301
|
+
@api_client.config.logger.debug 'Calling API: ServiceAreaApi.update_service_area ...'
|
|
302
|
+
end
|
|
303
|
+
# verify the required parameter 'id' is set
|
|
304
|
+
if @api_client.config.client_side_validation && id.nil?
|
|
305
|
+
fail ArgumentError, "Missing the required parameter 'id' when calling ServiceAreaApi.update_service_area"
|
|
306
|
+
end
|
|
307
|
+
# verify the required parameter 'service_area_update_request' is set
|
|
308
|
+
if @api_client.config.client_side_validation && service_area_update_request.nil?
|
|
309
|
+
fail ArgumentError, "Missing the required parameter 'service_area_update_request' when calling ServiceAreaApi.update_service_area"
|
|
310
|
+
end
|
|
311
|
+
# resource path
|
|
312
|
+
local_var_path = '/service-areas/{id}'.sub('{' + 'id' + '}', CGI.escape(id.to_s))
|
|
313
|
+
|
|
314
|
+
# query parameters
|
|
315
|
+
query_params = opts[:query_params] || {}
|
|
316
|
+
|
|
317
|
+
# header parameters
|
|
318
|
+
header_params = opts[:header_params] || {}
|
|
319
|
+
# HTTP header 'Accept' (if needed)
|
|
320
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
321
|
+
# HTTP header 'Content-Type'
|
|
322
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
323
|
+
if !content_type.nil?
|
|
324
|
+
header_params['Content-Type'] = content_type
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# form parameters
|
|
328
|
+
form_params = opts[:form_params] || {}
|
|
329
|
+
|
|
330
|
+
# http body (model)
|
|
331
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(service_area_update_request)
|
|
332
|
+
|
|
333
|
+
# return_type
|
|
334
|
+
return_type = opts[:debug_return_type] || 'ResponseEnvelope'
|
|
335
|
+
|
|
336
|
+
# auth_names
|
|
337
|
+
auth_names = opts[:debug_auth_names] || ['ApiKeyAuth']
|
|
338
|
+
|
|
339
|
+
new_options = opts.merge(
|
|
340
|
+
:operation => :"ServiceAreaApi.update_service_area",
|
|
341
|
+
:header_params => header_params,
|
|
342
|
+
:query_params => query_params,
|
|
343
|
+
:form_params => form_params,
|
|
344
|
+
:body => post_body,
|
|
345
|
+
:auth_names => auth_names,
|
|
346
|
+
:return_type => return_type
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
|
|
350
|
+
if @api_client.config.debugging
|
|
351
|
+
@api_client.config.logger.debug "API called: ServiceAreaApi#update_service_area\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
352
|
+
end
|
|
353
|
+
return data, status_code, headers
|
|
354
|
+
end
|
|
147
355
|
end
|
|
148
356
|
end
|
|
@@ -20,7 +20,7 @@ module Crisphive
|
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
22
|
# Add a technician
|
|
23
|
-
# Creates a technician membership under the current business. If the phone/email matches an existing user, their account is linked. Otherwise a new user identity is created (
|
|
23
|
+
# Creates a technician membership under the current business. If the phone/email matches an existing user, their account is linked. Otherwise a new user identity is created. Either way the membership starts active. The new member is notified (live mode only, best-effort): an email when `email` is supplied, an SMS when `phone` is supplied, both when both — informational only, no activation step (login stays passwordless: magic link / OTP). Re-adding someone: if the person is currently SUSPENDED on this business (a dashboard action — not reachable via this API), the create REACTIVATES that existing membership (same technician id, their existing group; also notified). A technician REMOVED with deleteTechnician is a closed membership: re-adding the same email/phone links the SAME underlying person (no duplicate identity) but creates a FRESH membership with a NEW id — history stays under the old one. Owner/Administrator groups cannot be assigned via API key, and not at all in sandbox mode. `assignment_tier` (what the scheduler assigns jobs by) is ignored — stored empty, no error — for the Booking Coordinator, Administrator and Viewer roles, which are never assigned jobs; a reactivated member of those roles also comes back without a tier. Optional relations (all validated; any missing id → 404 TECHNICIAN_NOT_FOUND with `missing_ids`): `buddy_ids` sets this technician's buddy list (use when creating a lead); `lead_ids` adds this technician as a buddy of each named lead (use when creating a buddy — the buddy-side way to attach the same lead↔buddy relation); `service_area_ids` assigns the technician to those service areas. `start_location_type=office` snapshots the business address + coordinates into the technician at create time; `address`, `start_location_lat`, `start_location_long` in the body are ignored. Requires the business to have coordinates set (else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
24
24
|
# @param technician_create_request [TechnicianCreateRequest] Technician details
|
|
25
25
|
# @param [Hash] opts the optional parameters
|
|
26
26
|
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
@@ -31,7 +31,7 @@ module Crisphive
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# Add a technician
|
|
34
|
-
# Creates a technician membership under the current business. If the phone/email matches an existing user, their account is linked. Otherwise a new user identity is created (
|
|
34
|
+
# Creates a technician membership under the current business. If the phone/email matches an existing user, their account is linked. Otherwise a new user identity is created. Either way the membership starts active. The new member is notified (live mode only, best-effort): an email when `email` is supplied, an SMS when `phone` is supplied, both when both — informational only, no activation step (login stays passwordless: magic link / OTP). Re-adding someone: if the person is currently SUSPENDED on this business (a dashboard action — not reachable via this API), the create REACTIVATES that existing membership (same technician id, their existing group; also notified). A technician REMOVED with deleteTechnician is a closed membership: re-adding the same email/phone links the SAME underlying person (no duplicate identity) but creates a FRESH membership with a NEW id — history stays under the old one. Owner/Administrator groups cannot be assigned via API key, and not at all in sandbox mode. `assignment_tier` (what the scheduler assigns jobs by) is ignored — stored empty, no error — for the Booking Coordinator, Administrator and Viewer roles, which are never assigned jobs; a reactivated member of those roles also comes back without a tier. Optional relations (all validated; any missing id → 404 TECHNICIAN_NOT_FOUND with `missing_ids`): `buddy_ids` sets this technician's buddy list (use when creating a lead); `lead_ids` adds this technician as a buddy of each named lead (use when creating a buddy — the buddy-side way to attach the same lead↔buddy relation); `service_area_ids` assigns the technician to those service areas. `start_location_type=office` snapshots the business address + coordinates into the technician at create time; `address`, `start_location_lat`, `start_location_long` in the body are ignored. Requires the business to have coordinates set (else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
35
35
|
# @param technician_create_request [TechnicianCreateRequest] Technician details
|
|
36
36
|
# @param [Hash] opts the optional parameters
|
|
37
37
|
# @option opts [String] :idempotency_key Unique key making retries safe: a repeat send with the same key replays the original response (header Idempotent-Replayed: true) instead of re-running the operation. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSE.
|
|
@@ -90,8 +90,8 @@ module Crisphive
|
|
|
90
90
|
return data, status_code, headers
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
# Remove a technician
|
|
94
|
-
#
|
|
93
|
+
# Remove a technician from the business
|
|
94
|
+
# Closes the technician's membership: the profile is set to deactive and soft-deleted, and their access to this business ends on their next request. In the same operation they are removed from every other technician's buddy list, vehicles they own are released, and any personal-calendar connection they made for this business is revoked. Fires the technician.deleted webhook. Their underlying user identity is untouched, and so are memberships at other businesses. Removal is REFUSED while the member is still staffed on an open job, as the lead or through a crew session, where open means not completed, not archived and not deleted (409 TECHNICIAN_HAS_OPEN_JOBS; nothing is written). data.open_job_count is the exact count and is always present. data.jobs lists up to 20 of them (id, short_code, current_status_key, scheduled_at when confirmed) ONLY when the caller also holds job_manage (a credential that may manage the team but not the job board gets the count alone; the key is then absent). Re-staff them first: reassign each with listCrewCandidates, re-plan whole days with previewAbsenceResolve / commitAbsenceResolve (which needs a time-off record covering those days; create one with createTechnicianTimeOff), or, from the dashboard, complete or archive the job. To cut someone's access immediately while their work is re-staffed, suspend them from the dashboard: suspension is not gated. This is a closed membership, not a pause. Re-adding the same email or phone later with createTechnician links the SAME person but opens a FRESH membership with a NEW technician id and none of the old buddy, vehicle or area links. If you expect the person back, suspend them from the dashboard instead; a suspended member is reactivated in place by createTechnician, keeping their id and group. The last active Owner cannot be removed (TECHNICIAN_LAST_OWNER). API keys the person created are NOT revoked (an HR action must not take an integration down); if any are still active, the business Owners and Administrators are emailed a list of them.
|
|
95
95
|
# @param id [String] Technician ID
|
|
96
96
|
# @param [Hash] opts the optional parameters
|
|
97
97
|
# @return [ResponseEnvelope]
|
|
@@ -100,8 +100,8 @@ module Crisphive
|
|
|
100
100
|
data
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
# Remove a technician
|
|
104
|
-
#
|
|
103
|
+
# Remove a technician from the business
|
|
104
|
+
# Closes the technician's membership: the profile is set to deactive and soft-deleted, and their access to this business ends on their next request. In the same operation they are removed from every other technician's buddy list, vehicles they own are released, and any personal-calendar connection they made for this business is revoked. Fires the technician.deleted webhook. Their underlying user identity is untouched, and so are memberships at other businesses. Removal is REFUSED while the member is still staffed on an open job, as the lead or through a crew session, where open means not completed, not archived and not deleted (409 TECHNICIAN_HAS_OPEN_JOBS; nothing is written). data.open_job_count is the exact count and is always present. data.jobs lists up to 20 of them (id, short_code, current_status_key, scheduled_at when confirmed) ONLY when the caller also holds job_manage (a credential that may manage the team but not the job board gets the count alone; the key is then absent). Re-staff them first: reassign each with listCrewCandidates, re-plan whole days with previewAbsenceResolve / commitAbsenceResolve (which needs a time-off record covering those days; create one with createTechnicianTimeOff), or, from the dashboard, complete or archive the job. To cut someone's access immediately while their work is re-staffed, suspend them from the dashboard: suspension is not gated. This is a closed membership, not a pause. Re-adding the same email or phone later with createTechnician links the SAME person but opens a FRESH membership with a NEW technician id and none of the old buddy, vehicle or area links. If you expect the person back, suspend them from the dashboard instead; a suspended member is reactivated in place by createTechnician, keeping their id and group. The last active Owner cannot be removed (TECHNICIAN_LAST_OWNER). API keys the person created are NOT revoked (an HR action must not take an integration down); if any are still active, the business Owners and Administrators are emailed a list of them.
|
|
105
105
|
# @param id [String] Technician ID
|
|
106
106
|
# @param [Hash] opts the optional parameters
|
|
107
107
|
# @return [Array<(ResponseEnvelope, Integer, Hash)>] ResponseEnvelope data, response status code and response headers
|
|
@@ -591,7 +591,7 @@ module Crisphive
|
|
|
591
591
|
end
|
|
592
592
|
|
|
593
593
|
# Update a technician
|
|
594
|
-
# Updates mutable technician profile fields. `start_location_type=office` re-snapshots the current business address + coordinates (body `address`/`start_location_lat`/`start_location_long` ignored; requires business coordinates, else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
594
|
+
# Updates mutable technician profile fields. `assignment_tier` is ignored (stored empty, no error) for the Booking Coordinator, Administrator and Viewer roles, so moving a member into one of them clears the tier and frees their technician seat. `start_location_type=office` re-snapshots the current business address + coordinates (body `address`/`start_location_lat`/`start_location_long` ignored; requires business coordinates, else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
595
595
|
# @param id [String] Technician ID
|
|
596
596
|
# @param technician_update_request [TechnicianUpdateRequest] Technician details
|
|
597
597
|
# @param [Hash] opts the optional parameters
|
|
@@ -602,7 +602,7 @@ module Crisphive
|
|
|
602
602
|
end
|
|
603
603
|
|
|
604
604
|
# Update a technician
|
|
605
|
-
# Updates mutable technician profile fields. `start_location_type=office` re-snapshots the current business address + coordinates (body `address`/`start_location_lat`/`start_location_long` ignored; requires business coordinates, else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
605
|
+
# Updates mutable technician profile fields. `assignment_tier` is ignored (stored empty, no error) for the Booking Coordinator, Administrator and Viewer roles, so moving a member into one of them clears the tier and frees their technician seat. `start_location_type=office` re-snapshots the current business address + coordinates (body `address`/`start_location_lat`/`start_location_long` ignored; requires business coordinates, else 400 BUSINESS_LOCATION_MISSING). `start_location_type=home` (or empty) uses the address + coordinates from the body.
|
|
606
606
|
# @param id [String] Technician ID
|
|
607
607
|
# @param technician_update_request [TechnicianUpdateRequest] Technician details
|
|
608
608
|
# @param [Hash] opts the optional parameters
|