@fleetbase/fleetops-engine 0.6.25 → 0.6.26

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 (48) hide show
  1. package/DRIVER_SCHEDULING.md +186 -0
  2. package/addon/components/driver/schedule.hbs +100 -0
  3. package/addon/components/driver/schedule.js +267 -0
  4. package/addon/components/order/kanban-card.hbs +2 -2
  5. package/addon/components/vehicle/details.hbs +594 -4
  6. package/addon/components/vehicle/form.hbs +467 -41
  7. package/addon/controllers/analytics/reports/index.js +3 -2
  8. package/addon/controllers/connectivity/devices/index.js +3 -3
  9. package/addon/controllers/connectivity/events/index.js +3 -2
  10. package/addon/controllers/connectivity/sensors/index.js +3 -5
  11. package/addon/controllers/connectivity/telematics/index.js +3 -1
  12. package/addon/controllers/maintenance/equipment/index.js +4 -4
  13. package/addon/controllers/maintenance/parts/index.js +4 -4
  14. package/addon/controllers/maintenance/work-orders/index.js +4 -4
  15. package/addon/controllers/management/contacts/customers.js +12 -10
  16. package/addon/controllers/management/contacts/index.js +3 -10
  17. package/addon/controllers/management/drivers/index/details.js +26 -13
  18. package/addon/controllers/management/drivers/index.js +4 -16
  19. package/addon/controllers/management/fleets/index.js +3 -13
  20. package/addon/controllers/management/fuel-reports/index.js +3 -10
  21. package/addon/controllers/management/issues/index.js +3 -12
  22. package/addon/controllers/management/places/index.js +4 -12
  23. package/addon/controllers/management/vehicles/index.js +3 -13
  24. package/addon/controllers/management/vendors/index.js +3 -13
  25. package/addon/controllers/operations/orders/index.js +5 -22
  26. package/addon/controllers/operations/scheduler/index.js +195 -6
  27. package/addon/controllers/operations/service-rates/index.js +34 -34
  28. package/addon/controllers/settings/payments/index.js +0 -6
  29. package/addon/routes.js +1 -0
  30. package/addon/services/driver-scheduling.js +171 -0
  31. package/addon/services/leaflet-layer-visibility-manager.js +4 -1
  32. package/addon/services/service-rate-actions.js +5 -1
  33. package/addon/templates/management/drivers/index/details/positions.hbs +1 -2
  34. package/addon/templates/management/drivers/index/details/schedule.hbs +1 -2
  35. package/addon/templates/operations/scheduler/index.hbs +48 -10
  36. package/addon/utils/fleet-ops-options.js +86 -0
  37. package/app/services/driver-scheduling.js +1 -0
  38. package/composer.json +1 -1
  39. package/extension.json +1 -1
  40. package/package.json +3 -3
  41. package/server/migrations/2025_11_17_033648_add_additional_columns_to_vehicles_table.php +142 -0
  42. package/server/src/Constraints/HOSConstraint.php +244 -0
  43. package/server/src/Http/Controllers/Api/v1/OrderController.php +1 -1
  44. package/server/src/Http/Controllers/Internal/v1/OrderController.php +8 -3
  45. package/server/src/Http/Resources/v1/Vehicle.php +197 -19
  46. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +211 -28
  47. package/server/src/Models/Driver.php +12 -8
  48. package/server/src/Models/Vehicle.php +101 -15
@@ -19,69 +19,247 @@ class Vehicle extends FleetbaseResource
19
19
  public function toArray($request)
20
20
  {
21
21
  return $this->withCustomFields([
22
+ // Identity
22
23
  'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
23
24
  'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
24
25
  'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
26
+ 'internal_id' => $this->internal_id,
27
+ 'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
28
+ 'vendor_uuid' => $this->when(Http::isInternalRequest(), $this->vendor_uuid),
29
+ 'category_uuid' => $this->when(Http::isInternalRequest(), $this->category_uuid),
30
+ 'warranty_uuid' => $this->when(Http::isInternalRequest(), $this->warranty_uuid),
31
+ 'telematic_uuid' => $this->when(Http::isInternalRequest(), $this->telematic_uuid),
32
+ // Media
25
33
  'photo_uuid' => $this->when(Http::isInternalRequest(), $this->photo_uuid),
34
+ 'photo_url' => $this->photo_url,
35
+ 'avatar_url' => $this->avatar_url,
36
+ 'avatar_value' => $this->when(Http::isInternalRequest(), $this->getOriginal('avatar_url')),
37
+ // Basic info
26
38
  'name' => $this->name,
27
39
  'display_name' => $this->when(Http::isInternalRequest(), $this->display_name),
28
- 'vin' => $this->vin ?? null,
40
+ 'description' => $this->description,
41
+ 'driver_name' => $this->when(Http::isInternalRequest(), $this->driver_name),
42
+ 'vendor_name' => $this->when(Http::isInternalRequest(), $this->vendor_name),
43
+ // Relationships
29
44
  'driver' => $this->whenLoaded('driver', fn () => new Driver($this->driver)),
30
45
  'devices' => $this->whenLoaded('devices', fn () => $this->devices),
31
- 'photo_url' => $this->photo_url,
32
- 'avatar_url' => $this->avatar_url,
33
- 'avatar_value' => $this->when(Http::isInternalRequest(), $this->getOriginal('avatar_url')),
46
+ // Vehicle identification
34
47
  'make' => $this->make,
35
48
  'model' => $this->model,
49
+ 'model_type' => $this->model_type,
36
50
  'year' => $this->year,
37
51
  'trim' => $this->trim,
38
52
  'type' => $this->type,
53
+ 'class' => $this->class,
54
+ 'color' => $this->color,
55
+ 'serial_number' => $this->serial_number,
39
56
  'plate_number' => $this->plate_number,
40
- 'vin' => $this->vin,
41
- 'vin_data' => $this->vin_data,
57
+ 'call_sign' => $this->call_sign,
58
+ // VIN & specs blobs
59
+ 'vin' => $this->vin ?? null,
60
+ 'vin_data' => data_get($this, 'vin_data', Utils::createObject()),
61
+ 'specs' => data_get($this, 'specs', Utils::createObject()),
62
+ 'details' => data_get($this, 'details', Utils::createObject()),
63
+ // Status / assignment
42
64
  'status' => $this->status,
43
- 'online' => $this->online,
65
+ 'online' => (bool) $this->online,
66
+ 'slug' => $this->slug,
67
+ 'financing_status' => $this->financing_status,
68
+ // Measurement & usage
69
+ 'measurement_system' => $this->measurement_system,
70
+ 'odometer' => $this->odometer,
71
+ 'odometer_unit' => $this->odometer_unit,
72
+ 'odometer_at_purchase' => $this->odometer_at_purchase,
73
+ 'fuel_type' => $this->fuel_type,
74
+ 'fuel_volume_unit' => $this->fuel_volume_unit,
75
+ // Body & usage
76
+ 'body_type' => $this->body_type,
77
+ 'body_sub_type' => $this->body_sub_type,
78
+ 'usage_type' => $this->usage_type,
79
+ 'ownership_type' => $this->ownership_type,
80
+ 'transmission' => $this->transmission,
81
+ // Engine & powertrain
82
+ 'engine_number' => $this->engine_number,
83
+ 'engine_make' => $this->engine_make,
84
+ 'engine_model' => $this->engine_model,
85
+ 'engine_family' => $this->engine_family,
86
+ 'engine_configuration' => $this->engine_configuration,
87
+ 'engine_size' => $this->engine_size,
88
+ 'engine_displacement' => $this->engine_displacement,
89
+ 'cylinder_arrangement' => $this->cylinder_arrangement,
90
+ 'number_of_cylinders' => $this->number_of_cylinders,
91
+ 'horsepower' => $this->horsepower,
92
+ 'horsepower_rpm' => $this->horsepower_rpm,
93
+ 'torque' => $this->torque,
94
+ 'torque_rpm' => $this->torque_rpm,
95
+ // Capacity & dimensions
96
+ 'fuel_capacity' => $this->fuel_capacity,
97
+ 'payload_capacity' => $this->payload_capacity,
98
+ 'towing_capacity' => $this->towing_capacity,
99
+ 'seating_capacity' => $this->seating_capacity,
100
+ 'weight' => $this->weight,
101
+ 'length' => $this->length,
102
+ 'width' => $this->width,
103
+ 'height' => $this->height,
104
+ 'cargo_volume' => $this->cargo_volume,
105
+ 'passenger_volume' => $this->passenger_volume,
106
+ 'interior_volume' => $this->interior_volume,
107
+ 'ground_clearance' => $this->ground_clearance,
108
+ 'bed_length' => $this->bed_length,
109
+ // Regulatory / compliance
110
+ 'emission_standard' => $this->emission_standard,
111
+ 'dpf_equipped' => $this->dpf_equipped,
112
+ 'scr_equipped' => $this->scr_equipped,
113
+ 'gvwr' => $this->gvwr,
114
+ 'gcwr' => $this->gcwr,
115
+ // Lifecycle / service life
116
+ 'estimated_service_life_distance' => $this->estimated_service_life_distance,
117
+ 'estimated_service_life_distance_unit' => $this->estimated_service_life_distance_unit,
118
+ 'estimated_service_life_months' => $this->estimated_service_life_months,
119
+ // Financing
120
+ 'currency' => $this->currency,
121
+ 'acquisition_cost' => $this->acquisition_cost,
122
+ 'current_value' => $this->current_value,
123
+ 'insurance_value' => $this->insurance_value,
124
+ 'depreciation_rate' => $this->depreciation_rate,
125
+ 'loan_amount' => $this->loan_amount,
126
+ 'loan_number_of_payments'=> $this->loan_number_of_payments,
127
+ 'loan_first_payment' => $this->loan_first_payment,
128
+ // Dates
129
+ 'purchased_at' => $this->purchased_at,
130
+ 'lease_expires_at' => $this->lease_expires_at,
131
+ 'deleted_at' => $this->deleted_at,
132
+ 'updated_at' => $this->updated_at,
133
+ 'created_at' => $this->created_at,
134
+ // Location & telematics
44
135
  'location' => data_get($this, 'location', new Point(0, 0)),
45
136
  'heading' => (int) data_get($this, 'heading', 0),
46
137
  'altitude' => (int) data_get($this, 'altitude', 0),
47
138
  'speed' => (int) data_get($this, 'speed', 0),
139
+ 'telematics' => data_get($this, 'telematics'),
140
+ // Notes & meta
141
+ 'notes' => $this->notes,
48
142
  'meta' => data_get($this, 'meta', Utils::createObject()),
49
- 'updated_at' => $this->updated_at,
50
- 'created_at' => $this->created_at,
51
143
  ]);
52
144
  }
53
145
 
54
146
  /**
55
- * Transform the resource into an webhook payload.
147
+ * Transform the resource into a webhook payload.
56
148
  *
57
149
  * @return array
58
150
  */
59
151
  public function toWebhookPayload()
60
152
  {
61
153
  return [
154
+ // Identity
62
155
  'id' => $this->public_id,
156
+ 'internal_id' => $this->internal_id,
157
+ // Basic info
63
158
  'name' => $this->name,
159
+ 'display_name' => $this->display_name,
160
+ 'description' => $this->description,
161
+ // Vehicle identification
64
162
  'vin' => $this->vin,
65
- 'driver' => $this->whenLoaded('driver', fn () => new Driver($this->driver)),
66
- 'photo_url' => $this->photoUrl,
67
- 'avatar_url' => $this->avatar_url,
163
+ 'plate_number' => $this->plate_number,
164
+ 'serial_number' => $this->serial_number,
68
165
  'make' => $this->make,
69
166
  'model' => $this->model,
167
+ 'model_type' => $this->model_type,
70
168
  'year' => $this->year,
71
169
  'trim' => $this->trim,
72
170
  'type' => $this->type,
73
- 'plate_number' => $this->plate_number,
74
- 'vin' => $this->vin,
75
- 'vin_data' => $this->vin_data,
171
+ 'class' => $this->class,
172
+ 'color' => $this->color,
173
+ 'call_sign' => $this->call_sign,
174
+ // Media
175
+ 'photo_url' => $this->photo_url,
176
+ 'avatar_url' => $this->avatar_url,
177
+ // Relationships
178
+ 'driver' => $this->whenLoaded('driver', fn () => new Driver($this->driver)),
179
+ // Status / assignment
76
180
  'status' => $this->status,
77
- 'online' => $this->online,
181
+ 'online' => (bool) $this->online,
182
+ 'slug' => $this->slug,
183
+ 'financing_status' => $this->financing_status,
184
+ // Measurement & usage
185
+ 'measurement_system' => $this->measurement_system,
186
+ 'odometer' => $this->odometer,
187
+ 'odometer_unit' => $this->odometer_unit,
188
+ 'odometer_at_purchase' => $this->odometer_at_purchase,
189
+ 'fuel_type' => $this->fuel_type,
190
+ 'fuel_volume_unit' => $this->fuel_volume_unit,
191
+ // Body & usage
192
+ 'body_type' => $this->body_type,
193
+ 'body_sub_type' => $this->body_sub_type,
194
+ 'usage_type' => $this->usage_type,
195
+ 'ownership_type' => $this->ownership_type,
196
+ 'transmission' => $this->transmission,
197
+ // Engine & powertrain
198
+ 'engine_number' => $this->engine_number,
199
+ 'engine_make' => $this->engine_make,
200
+ 'engine_model' => $this->engine_model,
201
+ 'engine_family' => $this->engine_family,
202
+ 'engine_configuration' => $this->engine_configuration,
203
+ 'engine_size' => $this->engine_size,
204
+ 'engine_displacement' => $this->engine_displacement,
205
+ 'cylinder_arrangement' => $this->cylinder_arrangement,
206
+ 'number_of_cylinders' => $this->number_of_cylinders,
207
+ 'horsepower' => $this->horsepower,
208
+ 'horsepower_rpm' => $this->horsepower_rpm,
209
+ 'torque' => $this->torque,
210
+ 'torque_rpm' => $this->torque_rpm,
211
+ // Capacity & dimensions
212
+ 'fuel_capacity' => $this->fuel_capacity,
213
+ 'payload_capacity' => $this->payload_capacity,
214
+ 'towing_capacity' => $this->towing_capacity,
215
+ 'seating_capacity' => $this->seating_capacity,
216
+ 'weight' => $this->weight,
217
+ 'length' => $this->length,
218
+ 'width' => $this->width,
219
+ 'height' => $this->height,
220
+ 'cargo_volume' => $this->cargo_volume,
221
+ 'passenger_volume' => $this->passenger_volume,
222
+ 'interior_volume' => $this->interior_volume,
223
+ 'ground_clearance' => $this->ground_clearance,
224
+ 'bed_length' => $this->bed_length,
225
+ // Regulatory / compliance
226
+ 'emission_standard' => $this->emission_standard,
227
+ 'dpf_equipped' => $this->dpf_equipped,
228
+ 'scr_equipped' => $this->scr_equipped,
229
+ 'gvwr' => $this->gvwr,
230
+ 'gcwr' => $this->gcwr,
231
+ // Lifecycle / service life
232
+ 'estimated_service_life_distance' => $this->estimated_service_life_distance,
233
+ 'estimated_service_life_distance_unit' => $this->estimated_service_life_distance_unit,
234
+ 'estimated_service_life_months' => $this->estimated_service_life_months,
235
+ // Financing / values
236
+ 'currency' => $this->currency,
237
+ 'acquisition_cost' => $this->acquisition_cost,
238
+ 'current_value' => $this->current_value,
239
+ 'insurance_value' => $this->insurance_value,
240
+ 'depreciation_rate' => $this->depreciation_rate,
241
+ 'loan_amount' => $this->loan_amount,
242
+ 'loan_number_of_payments' => $this->loan_number_of_payments,
243
+ 'loan_first_payment' => $this->loan_first_payment,
244
+ // Dates
245
+ 'purchased_at' => $this->purchased_at,
246
+ 'lease_expires_at' => $this->lease_expires_at,
247
+ 'deleted_at' => $this->deleted_at,
248
+ 'updated_at' => $this->updated_at,
249
+ 'created_at' => $this->created_at,
250
+ // Location & telematics
78
251
  'location' => data_get($this, 'location', new Point(0, 0)),
79
252
  'heading' => (int) data_get($this, 'heading', 0),
80
253
  'altitude' => (int) data_get($this, 'altitude', 0),
81
254
  'speed' => (int) data_get($this, 'speed', 0),
255
+ 'telematics' => data_get($this, 'telematics'),
256
+ // Specs and details
257
+ 'vin_data' => data_get($this, 'vin_data', Utils::createObject()),
258
+ 'specs' => data_get($this, 'specs', Utils::createObject()),
259
+ 'details' => data_get($this, 'details', Utils::createObject()),
260
+ // Notes & meta
261
+ 'notes' => $this->notes,
82
262
  'meta' => data_get($this, 'meta', Utils::createObject()),
83
- 'updated_at' => $this->updated_at,
84
- 'created_at' => $this->created_at,
85
263
  ];
86
264
  }
87
265
  }
@@ -18,35 +18,128 @@ class VehicleWithoutDriver extends FleetbaseResource
18
18
  */
19
19
  public function toArray($request)
20
20
  {
21
- return [
21
+ return $this->withCustomFields([
22
+ // Identity
22
23
  'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
23
24
  'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
24
25
  'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
25
26
  'internal_id' => $this->internal_id,
26
- 'name' => $this->display_name,
27
- 'display_name' => $this->when(Http::isInternalRequest(), $this->display_name),
28
- 'vin' => $this->vin ?? null,
29
- 'devices' => $this->whenLoaded('devices', fn () => $this->devices),
27
+ 'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
28
+ 'vendor_uuid' => $this->when(Http::isInternalRequest(), $this->vendor_uuid),
29
+ 'category_uuid' => $this->when(Http::isInternalRequest(), $this->category_uuid),
30
+ 'warranty_uuid' => $this->when(Http::isInternalRequest(), $this->warranty_uuid),
31
+ 'telematic_uuid' => $this->when(Http::isInternalRequest(), $this->telematic_uuid),
32
+ // Media
33
+ 'photo_uuid' => $this->when(Http::isInternalRequest(), $this->photo_uuid),
30
34
  'photo_url' => $this->photo_url,
31
35
  'avatar_url' => $this->avatar_url,
36
+ 'avatar_value' => $this->when(Http::isInternalRequest(), $this->getOriginal('avatar_url')),
37
+ // Basic info
38
+ 'name' => $this->name,
39
+ 'display_name' => $this->when(Http::isInternalRequest(), $this->display_name),
40
+ 'description' => $this->description,
41
+ 'driver_name' => $this->when(Http::isInternalRequest(), $this->driver_name),
42
+ 'vendor_name' => $this->when(Http::isInternalRequest(), $this->vendor_name),
43
+ // Relationships
44
+ 'devices' => $this->whenLoaded('devices', fn () => $this->devices),
45
+ // Vehicle identification
32
46
  'make' => $this->make,
33
47
  'model' => $this->model,
48
+ 'model_type' => $this->model_type,
34
49
  'year' => $this->year,
35
50
  'trim' => $this->trim,
36
51
  'type' => $this->type,
52
+ 'class' => $this->class,
53
+ 'color' => $this->color,
54
+ 'serial_number' => $this->serial_number,
37
55
  'plate_number' => $this->plate_number,
38
- 'vin' => $this->vin,
39
- 'vin_data' => $this->vin_data,
56
+ 'call_sign' => $this->call_sign,
57
+ // VIN & specs blobs
58
+ 'vin' => $this->vin ?? null,
59
+ 'vin_data' => data_get($this, 'vin_data', Utils::createObject()),
60
+ 'specs' => data_get($this, 'specs', Utils::createObject()),
61
+ 'details' => data_get($this, 'details', Utils::createObject()),
62
+ // Status / assignment
40
63
  'status' => $this->status,
41
- 'online' => $this->online,
64
+ 'online' => (bool) $this->online,
65
+ 'slug' => $this->slug,
66
+ 'financing_status' => $this->financing_status,
67
+ // Measurement & usage
68
+ 'measurement_system' => $this->measurement_system,
69
+ 'odometer' => $this->odometer,
70
+ 'odometer_unit' => $this->odometer_unit,
71
+ 'odometer_at_purchase' => $this->odometer_at_purchase,
72
+ 'fuel_type' => $this->fuel_type,
73
+ 'fuel_volume_unit' => $this->fuel_volume_unit,
74
+ // Body & usage
75
+ 'body_type' => $this->body_type,
76
+ 'body_sub_type' => $this->body_sub_type,
77
+ 'usage_type' => $this->usage_type,
78
+ 'ownership_type' => $this->ownership_type,
79
+ 'transmission' => $this->transmission,
80
+ // Engine & powertrain
81
+ 'engine_number' => $this->engine_number,
82
+ 'engine_make' => $this->engine_make,
83
+ 'engine_model' => $this->engine_model,
84
+ 'engine_family' => $this->engine_family,
85
+ 'engine_configuration' => $this->engine_configuration,
86
+ 'engine_size' => $this->engine_size,
87
+ 'engine_displacement' => $this->engine_displacement,
88
+ 'cylinder_arrangement' => $this->cylinder_arrangement,
89
+ 'number_of_cylinders' => $this->number_of_cylinders,
90
+ 'horsepower' => $this->horsepower,
91
+ 'horsepower_rpm' => $this->horsepower_rpm,
92
+ 'torque' => $this->torque,
93
+ 'torque_rpm' => $this->torque_rpm,
94
+ // Capacity & dimensions
95
+ 'fuel_capacity' => $this->fuel_capacity,
96
+ 'payload_capacity' => $this->payload_capacity,
97
+ 'towing_capacity' => $this->towing_capacity,
98
+ 'seating_capacity' => $this->seating_capacity,
99
+ 'weight' => $this->weight,
100
+ 'length' => $this->length,
101
+ 'width' => $this->width,
102
+ 'height' => $this->height,
103
+ 'cargo_volume' => $this->cargo_volume,
104
+ 'passenger_volume' => $this->passenger_volume,
105
+ 'interior_volume' => $this->interior_volume,
106
+ 'ground_clearance' => $this->ground_clearance,
107
+ 'bed_length' => $this->bed_length,
108
+ // Regulatory / compliance
109
+ 'emission_standard' => $this->emission_standard,
110
+ 'dpf_equipped' => $this->dpf_equipped,
111
+ 'scr_equipped' => $this->scr_equipped,
112
+ 'gvwr' => $this->gvwr,
113
+ 'gcwr' => $this->gcwr,
114
+ // Lifecycle / service life
115
+ 'estimated_service_life_distance' => $this->estimated_service_life_distance,
116
+ 'estimated_service_life_distance_unit' => $this->estimated_service_life_distance_unit,
117
+ 'estimated_service_life_months' => $this->estimated_service_life_months,
118
+ // Financing
119
+ 'currency' => $this->currency,
120
+ 'acquisition_cost' => $this->acquisition_cost,
121
+ 'current_value' => $this->current_value,
122
+ 'insurance_value' => $this->insurance_value,
123
+ 'depreciation_rate' => $this->depreciation_rate,
124
+ 'loan_amount' => $this->loan_amount,
125
+ 'loan_number_of_payments'=> $this->loan_number_of_payments,
126
+ 'loan_first_payment' => $this->loan_first_payment,
127
+ // Dates
128
+ 'purchased_at' => $this->purchased_at,
129
+ 'lease_expires_at' => $this->lease_expires_at,
130
+ 'deleted_at' => $this->deleted_at,
131
+ 'updated_at' => $this->updated_at,
132
+ 'created_at' => $this->created_at,
133
+ // Location & telematics
42
134
  'location' => data_get($this, 'location', new Point(0, 0)),
43
135
  'heading' => (int) data_get($this, 'heading', 0),
44
136
  'altitude' => (int) data_get($this, 'altitude', 0),
45
137
  'speed' => (int) data_get($this, 'speed', 0),
138
+ 'telematics' => data_get($this, 'telematics'),
139
+ // Notes & meta
140
+ 'notes' => $this->notes,
46
141
  'meta' => data_get($this, 'meta', Utils::createObject()),
47
- 'updated_at' => $this->updated_at,
48
- 'created_at' => $this->created_at,
49
- ];
142
+ ]);
50
143
  }
51
144
 
52
145
  /**
@@ -57,23 +150,113 @@ class VehicleWithoutDriver extends FleetbaseResource
57
150
  public function toWebhookPayload()
58
151
  {
59
152
  return [
60
- 'id' => $this->public_id,
61
- 'internal_id' => $this->internal_id,
62
- 'name' => $this->name,
63
- 'vin' => data_get($this, 'vin'),
64
- 'photo' => data_get($this, 'photoUrl'),
65
- 'make' => data_get($this, 'make'),
66
- 'model' => data_get($this, 'model'),
67
- 'year' => data_get($this, 'year'),
68
- 'trim' => data_get($this, 'trim'),
69
- 'type' => data_get($this, 'type'),
70
- 'plate_number' => data_get($this, 'plate_number'),
71
- 'vin_data' => $this->vin_data,
72
- 'status' => $this->status,
73
- 'online' => $this->online,
74
- 'meta' => data_get($this, 'meta', Utils::createObject()),
75
- 'updated_at' => $this->updated_at,
76
- 'created_at' => $this->created_at,
153
+ // Identity
154
+ 'id' => $this->public_id,
155
+ 'internal_id' => $this->internal_id,
156
+ // Basic info
157
+ 'name' => $this->name,
158
+ 'display_name' => $this->display_name,
159
+ 'description' => $this->description,
160
+ // Vehicle identification
161
+ 'vin' => $this->vin,
162
+ 'plate_number' => $this->plate_number,
163
+ 'serial_number' => $this->serial_number,
164
+ 'make' => $this->make,
165
+ 'model' => $this->model,
166
+ 'model_type' => $this->model_type,
167
+ 'year' => $this->year,
168
+ 'trim' => $this->trim,
169
+ 'type' => $this->type,
170
+ 'class' => $this->class,
171
+ 'color' => $this->color,
172
+ 'call_sign' => $this->call_sign,
173
+ // Media
174
+ 'photo_url' => $this->photo_url,
175
+ 'avatar_url' => $this->avatar_url,
176
+ // Status / assignment
177
+ 'status' => $this->status,
178
+ 'online' => (bool) $this->online,
179
+ 'slug' => $this->slug,
180
+ 'financing_status' => $this->financing_status,
181
+ // Measurement & usage
182
+ 'measurement_system' => $this->measurement_system,
183
+ 'odometer' => $this->odometer,
184
+ 'odometer_unit' => $this->odometer_unit,
185
+ 'odometer_at_purchase' => $this->odometer_at_purchase,
186
+ 'fuel_type' => $this->fuel_type,
187
+ 'fuel_volume_unit' => $this->fuel_volume_unit,
188
+ // Body & usage
189
+ 'body_type' => $this->body_type,
190
+ 'body_sub_type' => $this->body_sub_type,
191
+ 'usage_type' => $this->usage_type,
192
+ 'ownership_type' => $this->ownership_type,
193
+ 'transmission' => $this->transmission,
194
+ // Engine & powertrain
195
+ 'engine_number' => $this->engine_number,
196
+ 'engine_make' => $this->engine_make,
197
+ 'engine_model' => $this->engine_model,
198
+ 'engine_family' => $this->engine_family,
199
+ 'engine_configuration' => $this->engine_configuration,
200
+ 'engine_size' => $this->engine_size,
201
+ 'engine_displacement' => $this->engine_displacement,
202
+ 'cylinder_arrangement' => $this->cylinder_arrangement,
203
+ 'number_of_cylinders' => $this->number_of_cylinders,
204
+ 'horsepower' => $this->horsepower,
205
+ 'horsepower_rpm' => $this->horsepower_rpm,
206
+ 'torque' => $this->torque,
207
+ 'torque_rpm' => $this->torque_rpm,
208
+ // Capacity & dimensions
209
+ 'fuel_capacity' => $this->fuel_capacity,
210
+ 'payload_capacity' => $this->payload_capacity,
211
+ 'towing_capacity' => $this->towing_capacity,
212
+ 'seating_capacity' => $this->seating_capacity,
213
+ 'weight' => $this->weight,
214
+ 'length' => $this->length,
215
+ 'width' => $this->width,
216
+ 'height' => $this->height,
217
+ 'cargo_volume' => $this->cargo_volume,
218
+ 'passenger_volume' => $this->passenger_volume,
219
+ 'interior_volume' => $this->interior_volume,
220
+ 'ground_clearance' => $this->ground_clearance,
221
+ 'bed_length' => $this->bed_length,
222
+ // Regulatory / compliance
223
+ 'emission_standard' => $this->emission_standard,
224
+ 'dpf_equipped' => $this->dpf_equipped,
225
+ 'scr_equipped' => $this->scr_equipped,
226
+ 'gvwr' => $this->gvwr,
227
+ 'gcwr' => $this->gcwr,
228
+ // Lifecycle / service life
229
+ 'estimated_service_life_distance' => $this->estimated_service_life_distance,
230
+ 'estimated_service_life_distance_unit' => $this->estimated_service_life_distance_unit,
231
+ 'estimated_service_life_months' => $this->estimated_service_life_months,
232
+ // Financing / values
233
+ 'currency' => $this->currency,
234
+ 'acquisition_cost' => $this->acquisition_cost,
235
+ 'current_value' => $this->current_value,
236
+ 'insurance_value' => $this->insurance_value,
237
+ 'depreciation_rate' => $this->depreciation_rate,
238
+ 'loan_amount' => $this->loan_amount,
239
+ 'loan_number_of_payments' => $this->loan_number_of_payments,
240
+ 'loan_first_payment' => $this->loan_first_payment,
241
+ // Dates
242
+ 'purchased_at' => $this->purchased_at,
243
+ 'lease_expires_at' => $this->lease_expires_at,
244
+ 'deleted_at' => $this->deleted_at,
245
+ 'updated_at' => $this->updated_at,
246
+ 'created_at' => $this->created_at,
247
+ // Location & telematics
248
+ 'location' => data_get($this, 'location', new Point(0, 0)),
249
+ 'heading' => (int) data_get($this, 'heading', 0),
250
+ 'altitude' => (int) data_get($this, 'altitude', 0),
251
+ 'speed' => (int) data_get($this, 'speed', 0),
252
+ 'telematics' => data_get($this, 'telematics'),
253
+ // Specs and details
254
+ 'vin_data' => data_get($this, 'vin_data', Utils::createObject()),
255
+ 'specs' => data_get($this, 'specs', Utils::createObject()),
256
+ 'details' => data_get($this, 'details', Utils::createObject()),
257
+ // Notes & meta
258
+ 'notes' => $this->notes,
259
+ 'meta' => data_get($this, 'meta', Utils::createObject()),
77
260
  ];
78
261
  }
79
262
  }
@@ -519,19 +519,23 @@ class Driver extends Model
519
519
  }
520
520
 
521
521
  /**
522
- * Unassigns the current order from the driver if a driver is assigned.
522
+ * Alias for `unassignCurrentJob`: Unassigns the current order from the driver.
523
523
  *
524
524
  * @return bool True if the driver was unassigned and the changes were saved, false otherwise
525
525
  */
526
- public function unassignCurrentOrder()
526
+ public function unassignCurrentOrder(): bool
527
527
  {
528
- if (!empty($this->driver_assigned_uuid)) {
529
- $this->driver_assigned_uuid = null;
530
-
531
- return $this->save();
532
- }
528
+ return $this->unassignCurrentJob();
529
+ }
533
530
 
534
- return false;
531
+ /**
532
+ * Unassigns the current order from the driver.
533
+ *
534
+ * @return bool True if the driver was unassigned and the changes were saved, false otherwise
535
+ */
536
+ public function unassignCurrentJob(): bool
537
+ {
538
+ return $this->update(['current_job_uuid' => null]);
535
539
  }
536
540
 
537
541
  /**