@fleetbase/fleetops-engine 0.6.29 → 0.6.31
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.
- package/addon/components/customer/create-order-form.hbs +1 -1
- package/addon/components/customer/order-form.hbs +34 -34
- package/addon/components/customer/orders.hbs +2 -2
- package/addon/components/display-place.hbs +1 -1
- package/addon/components/driver/form.js +5 -1
- package/addon/components/driver/pill.hbs +16 -17
- package/addon/components/driver/pill.js +5 -1
- package/addon/components/map/leaflet-live-map.js +35 -3
- package/addon/components/map/order-list-overlay/order.hbs +1 -0
- package/addon/components/map/order-list-overlay/order.js +42 -0
- package/addon/components/modals/bulk-assign-driver.hbs +2 -2
- package/addon/components/order/details/detail.hbs +6 -6
- package/addon/components/order/details/notes.js +1 -1
- package/addon/components/order/route-editor.hbs +3 -3
- package/addon/components/order-tracking-lookup.hbs +1 -1
- package/addon/components/service-rate/details.hbs +117 -75
- package/addon/components/service-rate/form.hbs +7 -4
- package/addon/components/service-rate/form.js +6 -0
- package/addon/components/vehicle/pill.hbs +32 -33
- package/addon/components/vehicle/pill.js +5 -1
- package/addon/controllers/operations/orders/index.js +1 -1
- package/addon/controllers/operations/scheduler/index.js +17 -2
- package/addon/controllers/operations/service-rates/index/edit.js +1 -7
- package/addon/controllers/operations/service-rates/index/new.js +0 -7
- package/addon/controllers/operations/service-rates/index.js +10 -2
- package/addon/routes/operations/orders/index/details.js +7 -0
- package/addon/routes/operations/scheduler/index.js +3 -3
- package/addon/services/driver-actions.js +20 -4
- package/addon/services/leaflet-routing-control.js +7 -1
- package/addon/services/order-list-overlay.js +0 -1
- package/addon/services/place-actions.js +20 -4
- package/addon/services/service-rate-actions.js +31 -0
- package/addon/services/vehicle-actions.js +20 -4
- package/addon/templates/operations/scheduler/index.hbs +2 -2
- package/addon/utils/create-full-calendar-event-from-order.js +6 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/migrations/2025_12_16_000001_add_subject_created_at_index_to_positions.php +40 -0
- package/server/migrations/2025_12_16_000003_add_performance_indexes_to_fleetops_core_tables.php +442 -0
- package/server/src/Console/Commands/DispatchAdhocOrders.php +7 -2
- package/server/src/Http/Controllers/Api/v1/DriverController.php +2 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +30 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +184 -86
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +14 -1
- package/server/src/Http/Controllers/Internal/v1/PlaceController.php +5 -0
- package/server/src/Http/Filter/DriverFilter.php +10 -0
- package/server/src/Http/Filter/OrderFilter.php +8 -1
- package/server/src/Http/Resources/v1/Contact.php +2 -2
- package/server/src/Http/Resources/v1/Entity.php +1 -1
- package/server/src/Http/Resources/v1/Index/Customer.php +33 -0
- package/server/src/Http/Resources/v1/Index/Driver.php +45 -0
- package/server/src/Http/Resources/v1/Index/Facilitator.php +33 -0
- package/server/src/Http/Resources/v1/Index/Order.php +127 -0
- package/server/src/Http/Resources/v1/Index/Payload.php +57 -0
- package/server/src/Http/Resources/v1/Index/Place.php +45 -0
- package/server/src/Http/Resources/v1/Index/TrackingNumber.php +25 -0
- package/server/src/Http/Resources/v1/Index/Vehicle.php +50 -0
- package/server/src/Http/Resources/v1/Order.php +41 -14
- package/server/src/Http/Resources/v1/Place.php +1 -1
- package/server/src/Http/Resources/v1/Position.php +2 -1
- package/server/src/Http/Resources/v1/ServiceRate.php +4 -4
- package/server/src/Http/Resources/v1/ServiceRateFee.php +12 -12
- package/server/src/Http/Resources/v1/ServiceRateParcelFee.php +14 -7
- package/server/src/Http/Resources/v1/TrackingNumber.php +1 -1
- package/server/src/Http/Resources/v1/Waypoint.php +1 -1
- package/server/src/Listeners/HandleOrderDispatched.php +5 -0
- package/server/src/Models/Contact.php +2 -0
- package/server/src/Models/Device.php +2 -0
- package/server/src/Models/DeviceEvent.php +2 -0
- package/server/src/Models/Driver.php +2 -0
- package/server/src/Models/FuelReport.php +2 -0
- package/server/src/Models/Issue.php +2 -0
- package/server/src/Models/Order.php +12 -5
- package/server/src/Models/Place.php +2 -0
- package/server/src/Models/Position.php +2 -0
- package/server/src/Models/ServiceArea.php +2 -0
- package/server/src/Models/ServiceRate.php +5 -1
- package/server/src/Models/ServiceRateFee.php +3 -17
- package/server/src/Models/ServiceRateParcelFee.php +1 -12
- package/server/src/Models/Vehicle.php +2 -0
- package/server/src/Models/Vendor.php +2 -0
- package/server/src/Models/Zone.php +2 -0
- package/server/src/Observers/DriverObserver.php +23 -0
- package/server/src/Observers/OrderObserver.php +31 -0
- package/server/src/Observers/PlaceObserver.php +31 -0
- package/server/src/Observers/ServiceRateObserver.php +0 -18
- package/server/src/Observers/VehicleObserver.php +7 -0
- package/server/src/Support/LiveCacheService.php +165 -0
- package/server/src/Support/OSRM.php +49 -22
- package/server/src/Support/OrderTracker.php +100 -28
- package/translations/en-us.yaml +3 -1
|
@@ -4,14 +4,15 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Filter\PlaceFilter;
|
|
6
6
|
use Fleetbase\FleetOps\Http\Resources\v1\Driver as DriverResource;
|
|
7
|
-
use Fleetbase\FleetOps\Http\Resources\v1\Order as
|
|
8
|
-
use Fleetbase\FleetOps\Http\Resources\v1\Place as
|
|
9
|
-
use Fleetbase\FleetOps\Http\Resources\v1\Vehicle as
|
|
7
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Index\Order as OrderIndexResource;
|
|
8
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Index\Place as PlaceIndexResource;
|
|
9
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Index\Vehicle as VehicleIndexResource;
|
|
10
10
|
use Fleetbase\FleetOps\Models\Driver;
|
|
11
11
|
use Fleetbase\FleetOps\Models\Order;
|
|
12
12
|
use Fleetbase\FleetOps\Models\Place;
|
|
13
13
|
use Fleetbase\FleetOps\Models\Route;
|
|
14
14
|
use Fleetbase\FleetOps\Models\Vehicle;
|
|
15
|
+
use Fleetbase\FleetOps\Support\LiveCacheService;
|
|
15
16
|
use Fleetbase\Http\Controllers\Controller;
|
|
16
17
|
use Illuminate\Http\Request;
|
|
17
18
|
|
|
@@ -27,20 +28,23 @@ class LiveController extends Controller
|
|
|
27
28
|
*/
|
|
28
29
|
public function coordinates()
|
|
29
30
|
{
|
|
30
|
-
|
|
31
|
+
return LiveCacheService::remember('coordinates', [], function () {
|
|
32
|
+
$coordinates = [];
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// Fetch active orders for the current company
|
|
35
|
+
$orders = Order::where('company_uuid', session('company'))
|
|
36
|
+
->whereNotIn('status', ['canceled', 'completed'])
|
|
37
|
+
->with(['payload.dropoff', 'payload.pickup'])
|
|
38
|
+
->applyDirectivesForPermissions('fleet-ops list order')
|
|
39
|
+
->get();
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// Loop through each order to get its current destination location
|
|
42
|
+
foreach ($orders as $order) {
|
|
43
|
+
$coordinates[] = $order->getCurrentDestinationLocation();
|
|
44
|
+
}
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
return response()->json($coordinates);
|
|
47
|
+
});
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
@@ -50,31 +54,34 @@ class LiveController extends Controller
|
|
|
50
54
|
*/
|
|
51
55
|
public function routes()
|
|
52
56
|
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
$q
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
$
|
|
65
|
-
|
|
66
|
-
$q
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
return LiveCacheService::remember('routes', [], function () {
|
|
58
|
+
// Fetch routes that are not canceled or completed and have an assigned driver
|
|
59
|
+
$routes = Route::where('company_uuid', session('company'))
|
|
60
|
+
->whereHas(
|
|
61
|
+
'order',
|
|
62
|
+
function ($q) {
|
|
63
|
+
$q->whereNotIn('status', ['canceled', 'completed', 'expired']);
|
|
64
|
+
$q->whereNotNull('driver_assigned_uuid');
|
|
65
|
+
$q->whereNull('deleted_at');
|
|
66
|
+
$q->whereHas('trackingNumber');
|
|
67
|
+
$q->whereHas('trackingStatuses');
|
|
68
|
+
$q->whereHas('payload', function ($query) {
|
|
69
|
+
$query->where(
|
|
70
|
+
function ($q) {
|
|
71
|
+
$q->whereHas('waypoints');
|
|
72
|
+
$q->orWhereHas('pickup');
|
|
73
|
+
$q->orWhereHas('dropoff');
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
->with(['order.payload', 'order.trackingNumber', 'order.trackingStatuses', 'order.driverAssigned'])
|
|
80
|
+
->applyDirectivesForPermissions('fleet-ops list route')
|
|
81
|
+
->get();
|
|
82
|
+
|
|
83
|
+
return response()->json($routes);
|
|
84
|
+
});
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
/**
|
|
@@ -84,11 +91,19 @@ class LiveController extends Controller
|
|
|
84
91
|
*/
|
|
85
92
|
public function orders(Request $request)
|
|
86
93
|
{
|
|
87
|
-
$exclude
|
|
88
|
-
$active
|
|
89
|
-
$unassigned
|
|
94
|
+
$exclude = $request->array('exclude');
|
|
95
|
+
$active = $request->boolean('active');
|
|
96
|
+
$unassigned = $request->boolean('unassigned');
|
|
97
|
+
|
|
98
|
+
// Cache key includes all parameters that affect the query
|
|
99
|
+
$cacheParams = [
|
|
100
|
+
'exclude' => $exclude,
|
|
101
|
+
'active' => $active,
|
|
102
|
+
'unassigned' => $unassigned,
|
|
103
|
+
];
|
|
90
104
|
|
|
91
|
-
|
|
105
|
+
return LiveCacheService::remember('orders', $cacheParams, function () use ($exclude, $active, $unassigned) {
|
|
106
|
+
$query = Order::where('company_uuid', session('company'))
|
|
92
107
|
->whereHas('payload', function ($query) {
|
|
93
108
|
$query->where(
|
|
94
109
|
function ($q) {
|
|
@@ -97,7 +112,6 @@ class LiveController extends Controller
|
|
|
97
112
|
$q->orWhereHas('dropoff');
|
|
98
113
|
}
|
|
99
114
|
);
|
|
100
|
-
$query->with(['entities', 'waypoints', 'dropoff', 'pickup', 'return']);
|
|
101
115
|
})
|
|
102
116
|
->whereNotIn('status', ['canceled', 'completed', 'expired'])
|
|
103
117
|
->whereHas('trackingNumber')
|
|
@@ -105,35 +119,39 @@ class LiveController extends Controller
|
|
|
105
119
|
->whereNotIn('public_id', $exclude)
|
|
106
120
|
->whereNull('deleted_at')
|
|
107
121
|
->applyDirectivesForPermissions('fleet-ops list order')
|
|
108
|
-
->with([
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
->with([
|
|
123
|
+
'payload.entities',
|
|
124
|
+
'payload.waypoints',
|
|
125
|
+
'payload.dropoff',
|
|
126
|
+
'payload.pickup',
|
|
127
|
+
'payload.return',
|
|
128
|
+
'trackingNumber',
|
|
129
|
+
'trackingStatuses',
|
|
130
|
+
'driverAssigned' => function ($query) {
|
|
131
|
+
$query->without(['jobs', 'currentJob']);
|
|
132
|
+
},
|
|
133
|
+
'vehicleAssigned' => function ($query) {
|
|
134
|
+
$query->without(['fleets', 'vendor']);
|
|
135
|
+
},
|
|
136
|
+
'customer',
|
|
137
|
+
'facilitator',
|
|
138
|
+
]);
|
|
117
139
|
|
|
118
|
-
|
|
140
|
+
if ($active) {
|
|
141
|
+
$query->whereHas('driverAssigned');
|
|
142
|
+
}
|
|
119
143
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// load required relations
|
|
124
|
-
$order->loadMissing(['trackingNumber', 'payload', 'trackingStatuses']);
|
|
144
|
+
if ($unassigned) {
|
|
145
|
+
$query->whereNull('driver_assigned_uuid');
|
|
146
|
+
}
|
|
125
147
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
$order->tracker_data = $order->tracker()->toArray();
|
|
129
|
-
$order->eta = $order->tracker()->eta();
|
|
130
|
-
}
|
|
148
|
+
$query->limit(60); // max 60 latest
|
|
149
|
+
$query->latest();
|
|
131
150
|
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
);
|
|
151
|
+
$orders = $query->get();
|
|
135
152
|
|
|
136
|
-
|
|
153
|
+
return OrderIndexResource::collection($orders);
|
|
154
|
+
});
|
|
137
155
|
}
|
|
138
156
|
|
|
139
157
|
/**
|
|
@@ -141,13 +159,40 @@ class LiveController extends Controller
|
|
|
141
159
|
*
|
|
142
160
|
* @return \Illuminate\Http\JsonResponse
|
|
143
161
|
*/
|
|
144
|
-
public function drivers()
|
|
162
|
+
public function drivers(Request $request)
|
|
145
163
|
{
|
|
146
|
-
$
|
|
147
|
-
|
|
148
|
-
|
|
164
|
+
$bounds = $request->input('bounds'); // Map viewport bounds: [south, west, north, east]
|
|
165
|
+
$cacheParams = ['bounds' => $bounds];
|
|
166
|
+
|
|
167
|
+
return LiveCacheService::remember('drivers', $cacheParams, function () use ($bounds) {
|
|
168
|
+
$query = Driver::where(['company_uuid' => session('company')])
|
|
169
|
+
->with(['user', 'vehicle', 'currentJob'])
|
|
170
|
+
->applyDirectivesForPermissions('fleet-ops list driver');
|
|
171
|
+
|
|
172
|
+
// Filter out drivers with invalid coordinates
|
|
173
|
+
$query->whereNotNull('location')
|
|
174
|
+
->whereRaw('
|
|
175
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
176
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
177
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
178
|
+
');
|
|
179
|
+
|
|
180
|
+
// Apply spatial filtering if bounds are provided
|
|
181
|
+
if ($bounds && is_array($bounds) && count($bounds) === 4) {
|
|
182
|
+
[$south, $west, $north, $east] = $bounds;
|
|
183
|
+
|
|
184
|
+
// Use MySQL spatial functions for POINT column
|
|
185
|
+
// ST_Within checks if location is within the bounding box
|
|
186
|
+
$query->whereRaw(
|
|
187
|
+
'ST_Within(location, ST_MakeEnvelope(POINT(?, ?), POINT(?, ?)))',
|
|
188
|
+
[$west, $south, $east, $north]
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
$drivers = $query->get();
|
|
149
193
|
|
|
150
|
-
|
|
194
|
+
return DriverResource::collection($drivers);
|
|
195
|
+
});
|
|
151
196
|
}
|
|
152
197
|
|
|
153
198
|
/**
|
|
@@ -155,15 +200,41 @@ class LiveController extends Controller
|
|
|
155
200
|
*
|
|
156
201
|
* @return \Illuminate\Http\JsonResponse
|
|
157
202
|
*/
|
|
158
|
-
public function vehicles()
|
|
203
|
+
public function vehicles(Request $request)
|
|
159
204
|
{
|
|
160
|
-
//
|
|
161
|
-
$
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
205
|
+
$bounds = $request->input('bounds'); // Map viewport bounds: [south, west, north, east]
|
|
206
|
+
$cacheParams = ['bounds' => $bounds];
|
|
207
|
+
|
|
208
|
+
return LiveCacheService::remember('vehicles', $cacheParams, function () use ($bounds) {
|
|
209
|
+
// Fetch vehicles that are online
|
|
210
|
+
$query = Vehicle::where(['company_uuid' => session('company')])
|
|
211
|
+
->with(['devices', 'driver'])
|
|
212
|
+
->applyDirectivesForPermissions('fleet-ops list vehicle');
|
|
213
|
+
|
|
214
|
+
// Filter out vehicles with invalid coordinates
|
|
215
|
+
$query->whereNotNull('location')
|
|
216
|
+
->whereRaw('
|
|
217
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
218
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
219
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
220
|
+
');
|
|
221
|
+
|
|
222
|
+
// Apply spatial filtering if bounds are provided
|
|
223
|
+
if ($bounds && is_array($bounds) && count($bounds) === 4) {
|
|
224
|
+
[$south, $west, $north, $east] = $bounds;
|
|
225
|
+
|
|
226
|
+
// Use MySQL spatial functions for POINT column
|
|
227
|
+
// ST_Within checks if location is within the bounding box
|
|
228
|
+
$query->whereRaw(
|
|
229
|
+
'ST_Within(location, ST_MakeEnvelope(POINT(?, ?), POINT(?, ?)))',
|
|
230
|
+
[$west, $south, $east, $north]
|
|
231
|
+
);
|
|
232
|
+
}
|
|
165
233
|
|
|
166
|
-
|
|
234
|
+
$vehicles = $query->get();
|
|
235
|
+
|
|
236
|
+
return VehicleIndexResource::collection($vehicles);
|
|
237
|
+
});
|
|
167
238
|
}
|
|
168
239
|
|
|
169
240
|
/**
|
|
@@ -173,12 +244,39 @@ class LiveController extends Controller
|
|
|
173
244
|
*/
|
|
174
245
|
public function places(Request $request)
|
|
175
246
|
{
|
|
176
|
-
//
|
|
177
|
-
$
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
247
|
+
// Cache key includes filter parameters
|
|
248
|
+
$cacheParams = $request->only(['query', 'type', 'country', 'limit', 'bounds']);
|
|
249
|
+
|
|
250
|
+
return LiveCacheService::remember('places', $cacheParams, function () use ($request) {
|
|
251
|
+
// Query places based on filters
|
|
252
|
+
$query = Place::where(['company_uuid' => session('company')])
|
|
253
|
+
->filter(new PlaceFilter($request))
|
|
254
|
+
->applyDirectivesForPermissions('fleet-ops list place');
|
|
255
|
+
|
|
256
|
+
// Filter out places with invalid coordinates
|
|
257
|
+
$query->whereNotNull('location')
|
|
258
|
+
->whereRaw('
|
|
259
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
260
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
261
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
262
|
+
');
|
|
263
|
+
|
|
264
|
+
// Apply spatial filtering if bounds are provided
|
|
265
|
+
$bounds = $request->input('bounds');
|
|
266
|
+
if ($bounds && is_array($bounds) && count($bounds) === 4) {
|
|
267
|
+
[$south, $west, $north, $east] = $bounds;
|
|
268
|
+
|
|
269
|
+
// Use MySQL spatial functions for POINT column
|
|
270
|
+
// ST_Within checks if location is within the bounding box
|
|
271
|
+
$query->whereRaw(
|
|
272
|
+
'ST_Within(location, ST_MakeEnvelope(POINT(?, ?), POINT(?, ?)))',
|
|
273
|
+
[$west, $south, $east, $north]
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
$places = $query->get();
|
|
181
278
|
|
|
182
|
-
|
|
279
|
+
return PlaceIndexResource::collection($places);
|
|
280
|
+
});
|
|
183
281
|
}
|
|
184
282
|
}
|
|
@@ -12,6 +12,7 @@ use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
|
12
12
|
use Fleetbase\FleetOps\Http\Requests\BulkDispatchRequest;
|
|
13
13
|
use Fleetbase\FleetOps\Http\Requests\CancelOrderRequest;
|
|
14
14
|
use Fleetbase\FleetOps\Http\Requests\Internal\CreateOrderRequest;
|
|
15
|
+
use Fleetbase\FleetOps\Http\Resources\v1\Index\Order as OrderIndexResource;
|
|
15
16
|
use Fleetbase\FleetOps\Http\Resources\v1\Order as OrderResource;
|
|
16
17
|
use Fleetbase\FleetOps\Http\Resources\v1\Proof as ProofResource;
|
|
17
18
|
use Fleetbase\FleetOps\Imports\OrdersImport;
|
|
@@ -36,6 +37,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
|
36
37
|
use Illuminate\Database\QueryException;
|
|
37
38
|
use Illuminate\Http\Request;
|
|
38
39
|
use Illuminate\Support\Collection;
|
|
40
|
+
use Illuminate\Support\Facades\Cache;
|
|
39
41
|
use Illuminate\Support\Facades\DB;
|
|
40
42
|
use Illuminate\Support\Facades\Validator;
|
|
41
43
|
use Illuminate\Support\Str;
|
|
@@ -50,6 +52,13 @@ class OrderController extends FleetOpsController
|
|
|
50
52
|
*/
|
|
51
53
|
public $resource = 'order';
|
|
52
54
|
|
|
55
|
+
/**
|
|
56
|
+
* The lightweight resource for index/list views.
|
|
57
|
+
*
|
|
58
|
+
* @var string
|
|
59
|
+
*/
|
|
60
|
+
public $indexResource = OrderIndexResource::class;
|
|
61
|
+
|
|
53
62
|
/**
|
|
54
63
|
* Handle order waypoint changes if any.
|
|
55
64
|
*/
|
|
@@ -760,7 +769,11 @@ class OrderController extends FleetOpsController
|
|
|
760
769
|
return response()->error('No order found.');
|
|
761
770
|
}
|
|
762
771
|
|
|
763
|
-
|
|
772
|
+
// Cache tracker data for 30 seconds with order-specific key
|
|
773
|
+
$cacheKey = "order:{$order->uuid}:tracker";
|
|
774
|
+
$trackerInfo = Cache::remember($cacheKey, 30, function () use ($order) {
|
|
775
|
+
return $order->tracker()->toArray();
|
|
776
|
+
});
|
|
764
777
|
|
|
765
778
|
return response()->json($trackerInfo);
|
|
766
779
|
}
|
|
@@ -56,6 +56,11 @@ class PlaceController extends FleetOpsController
|
|
|
56
56
|
|
|
57
57
|
if ($latitude && $longitude) {
|
|
58
58
|
$point = new Point($latitude, $longitude);
|
|
59
|
+
$query->whereNotNull('location')->whereRaw('
|
|
60
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
61
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
62
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
63
|
+
');
|
|
59
64
|
$query->orderByDistanceSphere('location', $point, 'asc');
|
|
60
65
|
} else {
|
|
61
66
|
$query->orderBy('name', 'desc');
|
|
@@ -169,6 +169,11 @@ class DriverFilter extends Filter
|
|
|
169
169
|
if (Utils::isCoordinates($nearby)) {
|
|
170
170
|
$location = Utils::getPointFromMixed($nearby);
|
|
171
171
|
|
|
172
|
+
$this->builder->whereNotNull('location')->whereRaw('
|
|
173
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
174
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
175
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
176
|
+
');
|
|
172
177
|
$this->builder->distanceSphere('location', $location, $distance);
|
|
173
178
|
$this->builder->distanceSphereValue('location', $location);
|
|
174
179
|
|
|
@@ -181,6 +186,11 @@ class DriverFilter extends Filter
|
|
|
181
186
|
$place = Place::createFromMixed($nearby, [], false);
|
|
182
187
|
|
|
183
188
|
if ($nearby instanceof Place) {
|
|
189
|
+
$this->builder->whereNotNull('location')->whereRaw('
|
|
190
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
191
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
192
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
193
|
+
');
|
|
184
194
|
$this->builder->distanceSphere('location', $place->location, $distance);
|
|
185
195
|
$this->builder->distanceSphereValue('location', $place->location);
|
|
186
196
|
|
|
@@ -50,7 +50,14 @@ class OrderFilter extends Filter
|
|
|
50
50
|
'payload.return',
|
|
51
51
|
'trackingNumber',
|
|
52
52
|
'trackingStatuses',
|
|
53
|
-
'driverAssigned'
|
|
53
|
+
'driverAssigned' => function ($query) {
|
|
54
|
+
$query->without(['jobs', 'currentJob']);
|
|
55
|
+
},
|
|
56
|
+
'vehicleAssigned' => function ($query) {
|
|
57
|
+
$query->without(['fleets', 'vendor']);
|
|
58
|
+
},
|
|
59
|
+
'customer',
|
|
60
|
+
'facilitator',
|
|
54
61
|
]);
|
|
55
62
|
}
|
|
56
63
|
|
|
@@ -42,8 +42,8 @@ class Contact extends FleetbaseResource
|
|
|
42
42
|
'address' => $this->when(Http::isInternalRequest(), data_get($this, 'place.address')),
|
|
43
43
|
'address_street' => $this->when(Http::isInternalRequest(), data_get($this, 'place.street1')),
|
|
44
44
|
'type' => $this->type ?? null,
|
|
45
|
-
'customer_type' => $this->when(isset($this->customer_type), $this->customer_type),
|
|
46
|
-
'facilitator_type' => $this->when(isset($this->facilitator_type), $this->facilitator_type),
|
|
45
|
+
'customer_type' => $this->when(isset($this->customer_type), Utils::toEmberResourceType($this->customer_type)),
|
|
46
|
+
'facilitator_type' => $this->when(isset($this->facilitator_type), Utils::toEmberResourceType($this->facilitator_type)),
|
|
47
47
|
'meta' => data_get($this, 'meta', Utils::createObject()),
|
|
48
48
|
'slug' => $this->slug ?? null,
|
|
49
49
|
'updated_at' => $this->updated_at,
|
|
@@ -24,7 +24,7 @@ class Entity extends FleetbaseResource
|
|
|
24
24
|
'photo_uuid' => $this->when(Http::isInternalRequest(), $this->photo_uuid),
|
|
25
25
|
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
26
26
|
'customer_uuid' => $this->when(Http::isInternalRequest(), $this->customer_uuid),
|
|
27
|
-
'customer_type' => $this->when(Http::isInternalRequest(), $this->customer_type),
|
|
27
|
+
'customer_type' => $this->when(Http::isInternalRequest(), $this->customer_type ? Utils::toEmberResourceType($this->customer_type) : null),
|
|
28
28
|
'supplier_uuid' => $this->when(Http::isInternalRequest(), $this->supplier_uuid),
|
|
29
29
|
'destination_uuid' => $this->when(Http::isInternalRequest(), $this->destination_uuid),
|
|
30
30
|
'payload_uuid' => $this->when(Http::isInternalRequest(), $this->payload_uuid),
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Http\Resources\v1\Index;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Lightweight Customer resource for index views.
|
|
10
|
+
* Handles polymorphic customer types (Contact, Vendor, etc.) with minimal data.
|
|
11
|
+
*/
|
|
12
|
+
class Customer extends FleetbaseResource
|
|
13
|
+
{
|
|
14
|
+
/**
|
|
15
|
+
* Transform the resource into an array.
|
|
16
|
+
*
|
|
17
|
+
* @param \Illuminate\Http\Request $request
|
|
18
|
+
*/
|
|
19
|
+
public function toArray($request): array
|
|
20
|
+
{
|
|
21
|
+
$isInternal = Http::isInternalRequest();
|
|
22
|
+
|
|
23
|
+
return [
|
|
24
|
+
'id' => $this->when($isInternal, $this->id, $this->public_id),
|
|
25
|
+
'uuid' => $this->when($isInternal, $this->uuid),
|
|
26
|
+
'public_id' => $this->when($isInternal, $this->public_id),
|
|
27
|
+
'company_uuid' => $this->when($isInternal, $this->company_uuid),
|
|
28
|
+
'name' => $this->name,
|
|
29
|
+
'phone' => $this->phone ?? null,
|
|
30
|
+
'email' => $this->email ?? null,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Http\Resources\v1\Index;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point;
|
|
7
|
+
use Fleetbase\Support\Http;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Lightweight Driver resource for index views.
|
|
11
|
+
* Only includes essential identification and display information.
|
|
12
|
+
*/
|
|
13
|
+
class Driver extends FleetbaseResource
|
|
14
|
+
{
|
|
15
|
+
/**
|
|
16
|
+
* Transform the resource into an array.
|
|
17
|
+
*
|
|
18
|
+
* @param \Illuminate\Http\Request $request
|
|
19
|
+
*/
|
|
20
|
+
public function toArray($request): array
|
|
21
|
+
{
|
|
22
|
+
$isInternal = Http::isInternalRequest();
|
|
23
|
+
|
|
24
|
+
return [
|
|
25
|
+
'id' => $this->when($isInternal, $this->id, $this->public_id),
|
|
26
|
+
'uuid' => $this->when($isInternal, $this->uuid),
|
|
27
|
+
'public_id' => $this->when($isInternal, $this->public_id),
|
|
28
|
+
'company_uuid' => $this->when($isInternal, $this->company_uuid),
|
|
29
|
+
'user_uuid' => $this->when($isInternal, $this->user_uuid),
|
|
30
|
+
'vehicle_uuid' => $this->when($isInternal, $this->vehicle_uuid),
|
|
31
|
+
'vendor_uuid' => $this->when($isInternal, $this->vendor_uuid),
|
|
32
|
+
'current_job_uuid'=> $this->when($isInternal, $this->current_job_uuid),
|
|
33
|
+
'name' => $this->name,
|
|
34
|
+
'vehicle_name' => $this->when($isInternal, $this->vehicle_name),
|
|
35
|
+
'phone' => $this->phone,
|
|
36
|
+
'photo_url' => $this->photo_url,
|
|
37
|
+
'status' => $this->status,
|
|
38
|
+
'location' => $this->wasRecentlyCreated ? new Point(0, 0) : data_get($this, 'location', new Point(0, 0)),
|
|
39
|
+
'heading' => (int) data_get($this, 'heading', 0),
|
|
40
|
+
'altitude' => (int) data_get($this, 'altitude', 0),
|
|
41
|
+
'speed' => (int) data_get($this, 'speed', 0),
|
|
42
|
+
'online' => data_get($this, 'online', false),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Http\Resources\v1\Index;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Lightweight Facilitator resource for index views.
|
|
10
|
+
* Handles polymorphic facilitator types (Contact, Vendor, IntegratedVendor) with minimal data.
|
|
11
|
+
*/
|
|
12
|
+
class Facilitator extends FleetbaseResource
|
|
13
|
+
{
|
|
14
|
+
/**
|
|
15
|
+
* Transform the resource into an array.
|
|
16
|
+
*
|
|
17
|
+
* @param \Illuminate\Http\Request $request
|
|
18
|
+
*/
|
|
19
|
+
public function toArray($request): array
|
|
20
|
+
{
|
|
21
|
+
$isInternal = Http::isInternalRequest();
|
|
22
|
+
|
|
23
|
+
return [
|
|
24
|
+
'id' => $this->when($isInternal, $this->id, $this->public_id),
|
|
25
|
+
'uuid' => $this->when($isInternal, $this->uuid),
|
|
26
|
+
'public_id' => $this->when($isInternal, $this->public_id),
|
|
27
|
+
'company_uuid' => $this->when($isInternal, $this->company_uuid),
|
|
28
|
+
'name' => $this->name,
|
|
29
|
+
'phone' => $this->phone ?? null,
|
|
30
|
+
'email' => $this->email ?? null,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
}
|