@fleetbase/fleetops-engine 0.6.24 → 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 (51) 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/DriverController.php +14 -4
  44. package/server/src/Http/Controllers/Api/v1/OrderController.php +1 -1
  45. package/server/src/Http/Controllers/Api/v1/VehicleController.php +2 -2
  46. package/server/src/Http/Controllers/Internal/v1/OrderController.php +8 -3
  47. package/server/src/Http/Resources/v1/Driver.php +1 -1
  48. package/server/src/Http/Resources/v1/Vehicle.php +197 -19
  49. package/server/src/Http/Resources/v1/VehicleWithoutDriver.php +211 -28
  50. package/server/src/Models/Driver.php +15 -8
  51. package/server/src/Models/Vehicle.php +101 -15
@@ -165,8 +165,13 @@ class OrderController extends FleetOpsController
165
165
  );
166
166
  }
167
167
 
168
- // dispatch if flagged true
169
- $order->firstDispatchWithActivity();
168
+ // Check dispatch flag with backward compatibility (default true)
169
+ $shouldDispatch = isset($input['dispatched']) ? (bool) $input['dispatched'] : true;
170
+
171
+ // dispatch if flagged true, otherwise ensure order stays in created state
172
+ if ($shouldDispatch) {
173
+ $order->firstDispatchWithActivity();
174
+ }
170
175
 
171
176
  // set driving distance and time
172
177
  $order->setPreliminaryDistanceAndTime();
@@ -190,7 +195,7 @@ class OrderController extends FleetOpsController
190
195
 
191
196
  return ['order' => new $this->resource($record)];
192
197
  } catch (QueryException $e) {
193
- return response()->error(env('DEBUG') ? $e->getMessage() : 'Error occurred while trying to create a ' . $this->resourceSingularlName);
198
+ return response()->error(app()->hasDebugModeEnabled() ? $e->getMessage() : 'Error occurred while trying to create a ' . $this->resourceSingularlName);
194
199
  } catch (FleetbaseRequestValidationException $e) {
195
200
  return response()->error($e->getErrors());
196
201
  } catch (\Exception $e) {
@@ -46,7 +46,7 @@ class Driver extends FleetbaseResource
46
46
  'vendor_name' => $this->when(Http::isInternalRequest(), $this->vendor_name),
47
47
  'vehicle' => $this->whenLoaded('vehicle', fn () => new VehicleWithoutDriver($this->vehicle)),
48
48
  'current_job' => $this->whenLoaded('currentJob', fn () => new Order($this->currentJob)),
49
- 'current_job_id' => $this->when(Http::isInternalRequest(), data_get($this, 'currentJob.public_id')),
49
+ 'current_job_id' => $this->when(Http::isInternalRequest(), data_get($this, 'currentJob.tracking')),
50
50
  'jobs' => $this->whenLoaded('jobs', fn () => $this->getJobs()),
51
51
  'vendor' => $this->whenLoaded('vendor', fn () => new Vendor($this->vendor)),
52
52
  'fleets' => $this->whenLoaded('fleets', fn () => Fleet::collection($this->fleets()->without('drivers')->get())),
@@ -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
  }
@@ -234,6 +234,9 @@ class Driver extends Model
234
234
  'avatar_url',
235
235
  'public_id',
236
236
  'location',
237
+ 'online',
238
+ 'updated_at',
239
+ 'created_at',
237
240
  'speed',
238
241
  'heading',
239
242
  'altitude',
@@ -516,19 +519,23 @@ class Driver extends Model
516
519
  }
517
520
 
518
521
  /**
519
- * Unassigns the current order from the driver if a driver is assigned.
522
+ * Alias for `unassignCurrentJob`: Unassigns the current order from the driver.
520
523
  *
521
524
  * @return bool True if the driver was unassigned and the changes were saved, false otherwise
522
525
  */
523
- public function unassignCurrentOrder()
526
+ public function unassignCurrentOrder(): bool
524
527
  {
525
- if (!empty($this->driver_assigned_uuid)) {
526
- $this->driver_assigned_uuid = null;
527
-
528
- return $this->save();
529
- }
528
+ return $this->unassignCurrentJob();
529
+ }
530
530
 
531
- 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]);
532
539
  }
533
540
 
534
541
  /**