@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
package/server/migrations/2025_12_16_000003_add_performance_indexes_to_fleetops_core_tables.php
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration {
|
|
8
|
+
/**
|
|
9
|
+
* Run the migrations.
|
|
10
|
+
*
|
|
11
|
+
* Performance-optimized composite indexes for core FleetOps tables.
|
|
12
|
+
* These indexes are specifically designed to optimize the most common and heaviest query patterns:
|
|
13
|
+
*
|
|
14
|
+
* 1. orders?unassigned=1
|
|
15
|
+
* - Filters: company_uuid, driver_assigned_uuid IS NULL, status NOT IN (...)
|
|
16
|
+
* - Needs: (company_uuid, driver_assigned_uuid, status)
|
|
17
|
+
*
|
|
18
|
+
* 2. orders?active=1&with_tracker_data=1
|
|
19
|
+
* - Filters: company_uuid, driver_assigned_uuid IS NOT NULL, status NOT IN (...)
|
|
20
|
+
* - Needs: (company_uuid, driver_assigned_uuid, status)
|
|
21
|
+
* - Also needs efficient joins with tracking_numbers, payloads, places, waypoints
|
|
22
|
+
*
|
|
23
|
+
* 3. General order queries with sorting by created_at
|
|
24
|
+
* - Needs: (company_uuid, created_at)
|
|
25
|
+
*
|
|
26
|
+
* 4. Relationship lookups (payload -> waypoints, places, entities)
|
|
27
|
+
* - Needs: Foreign key indexes on relationship columns
|
|
28
|
+
*/
|
|
29
|
+
public function up(): void
|
|
30
|
+
{
|
|
31
|
+
// ========================================
|
|
32
|
+
// ORDERS TABLE - Critical for performance
|
|
33
|
+
// ========================================
|
|
34
|
+
Schema::table('orders', function (Blueprint $table) {
|
|
35
|
+
// CRITICAL: Optimize unassigned and active filters
|
|
36
|
+
// This index supports both unassigned=1 and active=1 queries
|
|
37
|
+
if (!$this->indexExists('orders', 'orders_company_driver_status_idx')) {
|
|
38
|
+
$table->index(['company_uuid', 'driver_assigned_uuid', 'status'], 'orders_company_driver_status_idx');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Optimize general queries with sorting
|
|
42
|
+
if (!$this->indexExists('orders', 'orders_company_created_idx')) {
|
|
43
|
+
$table->index(['company_uuid', 'created_at'], 'orders_company_created_idx');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Optimize scheduled_at queries (for scheduled orders)
|
|
47
|
+
if (!$this->indexExists('orders', 'orders_company_scheduled_idx')) {
|
|
48
|
+
$table->index(['company_uuid', 'scheduled_at'], 'orders_company_scheduled_idx');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Optimize dispatched queries
|
|
52
|
+
if (!$this->indexExists('orders', 'orders_company_dispatched_idx')) {
|
|
53
|
+
$table->index(['company_uuid', 'dispatched', 'dispatched_at'], 'orders_company_dispatched_idx');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Optimize payload lookups (for eager loading)
|
|
57
|
+
if (!$this->indexExists('orders', 'orders_payload_uuid_idx')) {
|
|
58
|
+
$table->index('payload_uuid', 'orders_payload_uuid_idx');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Optimize tracking number lookups
|
|
62
|
+
if (!$this->indexExists('orders', 'orders_tracking_number_uuid_idx')) {
|
|
63
|
+
$table->index('tracking_number_uuid', 'orders_tracking_number_uuid_idx');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Optimize driver/vehicle assignment lookups
|
|
67
|
+
if (!$this->indexExists('orders', 'orders_vehicle_assigned_uuid_idx')) {
|
|
68
|
+
$table->index('vehicle_assigned_uuid', 'orders_vehicle_assigned_uuid_idx');
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ========================================
|
|
73
|
+
// PAYLOADS TABLE
|
|
74
|
+
// ========================================
|
|
75
|
+
Schema::table('payloads', function (Blueprint $table) {
|
|
76
|
+
// Optimize company queries
|
|
77
|
+
if (!$this->indexExists('payloads', 'payloads_company_created_idx')) {
|
|
78
|
+
$table->index(['company_uuid', 'created_at'], 'payloads_company_created_idx');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Optimize pickup/dropoff/return lookups (for order queries)
|
|
82
|
+
if (!$this->indexExists('payloads', 'payloads_pickup_uuid_idx')) {
|
|
83
|
+
$table->index('pickup_uuid', 'payloads_pickup_uuid_idx');
|
|
84
|
+
}
|
|
85
|
+
if (!$this->indexExists('payloads', 'payloads_dropoff_uuid_idx')) {
|
|
86
|
+
$table->index('dropoff_uuid', 'payloads_dropoff_uuid_idx');
|
|
87
|
+
}
|
|
88
|
+
if (!$this->indexExists('payloads', 'payloads_return_uuid_idx')) {
|
|
89
|
+
$table->index('return_uuid', 'payloads_return_uuid_idx');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// ========================================
|
|
94
|
+
// WAYPOINTS TABLE
|
|
95
|
+
// ========================================
|
|
96
|
+
Schema::table('waypoints', function (Blueprint $table) {
|
|
97
|
+
// Optimize payload -> waypoints relationship queries
|
|
98
|
+
if (!$this->indexExists('waypoints', 'waypoints_payload_created_idx')) {
|
|
99
|
+
$table->index(['payload_uuid', 'created_at'], 'waypoints_payload_created_idx');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Optimize company queries
|
|
103
|
+
if (!$this->indexExists('waypoints', 'waypoints_company_created_idx')) {
|
|
104
|
+
$table->index(['company_uuid', 'created_at'], 'waypoints_company_created_idx');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Optimize place lookups
|
|
108
|
+
if (!$this->indexExists('waypoints', 'waypoints_place_uuid_idx')) {
|
|
109
|
+
$table->index('place_uuid', 'waypoints_place_uuid_idx');
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// ========================================
|
|
114
|
+
// ENTITIES TABLE
|
|
115
|
+
// ========================================
|
|
116
|
+
Schema::table('entities', function (Blueprint $table) {
|
|
117
|
+
// Optimize payload -> entities relationship queries
|
|
118
|
+
if (!$this->indexExists('entities', 'entities_payload_created_idx')) {
|
|
119
|
+
$table->index(['payload_uuid', 'created_at'], 'entities_payload_created_idx');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Optimize company queries
|
|
123
|
+
if (!$this->indexExists('entities', 'entities_company_created_idx')) {
|
|
124
|
+
$table->index(['company_uuid', 'created_at'], 'entities_company_created_idx');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Optimize destination lookups
|
|
128
|
+
if (!$this->indexExists('entities', 'entities_destination_uuid_idx')) {
|
|
129
|
+
$table->index('destination_uuid', 'entities_destination_uuid_idx');
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// ========================================
|
|
134
|
+
// PLACES TABLE
|
|
135
|
+
// ========================================
|
|
136
|
+
Schema::table('places', function (Blueprint $table) {
|
|
137
|
+
// Optimize company queries
|
|
138
|
+
if (!$this->indexExists('places', 'places_company_created_idx')) {
|
|
139
|
+
$table->index(['company_uuid', 'created_at'], 'places_company_created_idx');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Optimize owner lookups (polymorphic)
|
|
143
|
+
if (!$this->indexExists('places', 'places_owner_idx')) {
|
|
144
|
+
$table->index(['owner_uuid', 'owner_type'], 'places_owner_idx');
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// ========================================
|
|
149
|
+
// DRIVERS TABLE
|
|
150
|
+
// ========================================
|
|
151
|
+
Schema::table('drivers', function (Blueprint $table) {
|
|
152
|
+
// Optimize company queries with status filter
|
|
153
|
+
if (!$this->indexExists('drivers', 'drivers_company_status_online_idx')) {
|
|
154
|
+
$table->index(['company_uuid', 'status', 'online'], 'drivers_company_status_online_idx');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Optimize general queries
|
|
158
|
+
if (!$this->indexExists('drivers', 'drivers_company_created_idx')) {
|
|
159
|
+
$table->index(['company_uuid', 'created_at'], 'drivers_company_created_idx');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Optimize user lookups
|
|
163
|
+
if (!$this->indexExists('drivers', 'drivers_user_uuid_idx')) {
|
|
164
|
+
$table->index('user_uuid', 'drivers_user_uuid_idx');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Optimize vendor lookups
|
|
168
|
+
if (!$this->indexExists('drivers', 'drivers_vendor_uuid_idx')) {
|
|
169
|
+
$table->index('vendor_uuid', 'drivers_vendor_uuid_idx');
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// ========================================
|
|
174
|
+
// VEHICLES TABLE
|
|
175
|
+
// ========================================
|
|
176
|
+
Schema::table('vehicles', function (Blueprint $table) {
|
|
177
|
+
// Optimize company queries with status filter
|
|
178
|
+
if (!$this->indexExists('vehicles', 'vehicles_company_status_online_idx')) {
|
|
179
|
+
$table->index(['company_uuid', 'status', 'online'], 'vehicles_company_status_online_idx');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Optimize general queries
|
|
183
|
+
if (!$this->indexExists('vehicles', 'vehicles_company_created_idx')) {
|
|
184
|
+
$table->index(['company_uuid', 'created_at'], 'vehicles_company_created_idx');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Optimize vendor lookups
|
|
188
|
+
if (!$this->indexExists('vehicles', 'vehicles_vendor_uuid_idx')) {
|
|
189
|
+
$table->index('vendor_uuid', 'vehicles_vendor_uuid_idx');
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// ========================================
|
|
194
|
+
// VENDORS TABLE
|
|
195
|
+
// ========================================
|
|
196
|
+
Schema::table('vendors', function (Blueprint $table) {
|
|
197
|
+
// Optimize company queries with status filter
|
|
198
|
+
if (!$this->indexExists('vendors', 'vendors_company_status_idx')) {
|
|
199
|
+
$table->index(['company_uuid', 'status'], 'vendors_company_status_idx');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Already has company_uuid and created_at indexes
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// ========================================
|
|
206
|
+
// CONTACTS TABLE
|
|
207
|
+
// ========================================
|
|
208
|
+
Schema::table('contacts', function (Blueprint $table) {
|
|
209
|
+
// Optimize company queries
|
|
210
|
+
if (!$this->indexExists('contacts', 'contacts_company_created_idx')) {
|
|
211
|
+
$table->index(['company_uuid', 'created_at'], 'contacts_company_created_idx');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Optimize company queries with type filter
|
|
215
|
+
if (!$this->indexExists('contacts', 'contacts_company_type_idx')) {
|
|
216
|
+
$table->index(['company_uuid', 'type'], 'contacts_company_type_idx');
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// ========================================
|
|
221
|
+
// ROUTES TABLE
|
|
222
|
+
// ========================================
|
|
223
|
+
Schema::table('routes', function (Blueprint $table) {
|
|
224
|
+
// Optimize company queries
|
|
225
|
+
if (!$this->indexExists('routes', 'routes_company_created_idx')) {
|
|
226
|
+
$table->index(['company_uuid', 'created_at'], 'routes_company_created_idx');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Note: routes table doesn't have a status column in this schema
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ========================================
|
|
233
|
+
// TRACKING_NUMBERS TABLE
|
|
234
|
+
// ========================================
|
|
235
|
+
Schema::table('tracking_numbers', function (Blueprint $table) {
|
|
236
|
+
// Optimize company queries
|
|
237
|
+
if (!$this->indexExists('tracking_numbers', 'tracking_numbers_company_created_idx')) {
|
|
238
|
+
$table->index(['company_uuid', 'created_at'], 'tracking_numbers_company_created_idx');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Optimize tracking_number lookups (for public tracking)
|
|
242
|
+
if (!$this->indexExists('tracking_numbers', 'tracking_numbers_tracking_number_idx')) {
|
|
243
|
+
$table->index('tracking_number', 'tracking_numbers_tracking_number_idx');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Optimize owner lookups (polymorphic)
|
|
247
|
+
if (!$this->indexExists('tracking_numbers', 'tracking_numbers_owner_idx')) {
|
|
248
|
+
$table->index(['owner_uuid', 'owner_type'], 'tracking_numbers_owner_idx');
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// ========================================
|
|
253
|
+
// TRACKING_STATUSES TABLE
|
|
254
|
+
// ========================================
|
|
255
|
+
Schema::table('tracking_statuses', function (Blueprint $table) {
|
|
256
|
+
// Optimize tracking_number_uuid lookups (for order tracking history)
|
|
257
|
+
if (!$this->indexExists('tracking_statuses', 'tracking_statuses_tracking_created_idx')) {
|
|
258
|
+
$table->index(['tracking_number_uuid', 'created_at'], 'tracking_statuses_tracking_created_idx');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Optimize company queries
|
|
262
|
+
if (!$this->indexExists('tracking_statuses', 'tracking_statuses_company_created_idx')) {
|
|
263
|
+
$table->index(['company_uuid', 'created_at'], 'tracking_statuses_company_created_idx');
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Reverse the migrations.
|
|
270
|
+
*/
|
|
271
|
+
public function down(): void
|
|
272
|
+
{
|
|
273
|
+
// ORDERS
|
|
274
|
+
Schema::table('orders', function (Blueprint $table) {
|
|
275
|
+
if ($this->indexExists('orders', 'orders_company_driver_status_idx')) {
|
|
276
|
+
$table->dropIndex('orders_company_driver_status_idx');
|
|
277
|
+
}
|
|
278
|
+
if ($this->indexExists('orders', 'orders_company_created_idx')) {
|
|
279
|
+
$table->dropIndex('orders_company_created_idx');
|
|
280
|
+
}
|
|
281
|
+
if ($this->indexExists('orders', 'orders_company_scheduled_idx')) {
|
|
282
|
+
$table->dropIndex('orders_company_scheduled_idx');
|
|
283
|
+
}
|
|
284
|
+
if ($this->indexExists('orders', 'orders_company_dispatched_idx')) {
|
|
285
|
+
$table->dropIndex('orders_company_dispatched_idx');
|
|
286
|
+
}
|
|
287
|
+
if ($this->indexExists('orders', 'orders_payload_uuid_idx')) {
|
|
288
|
+
$table->dropIndex('orders_payload_uuid_idx');
|
|
289
|
+
}
|
|
290
|
+
if ($this->indexExists('orders', 'orders_tracking_number_uuid_idx')) {
|
|
291
|
+
$table->dropIndex('orders_tracking_number_uuid_idx');
|
|
292
|
+
}
|
|
293
|
+
if ($this->indexExists('orders', 'orders_vehicle_assigned_uuid_idx')) {
|
|
294
|
+
$table->dropIndex('orders_vehicle_assigned_uuid_idx');
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// PAYLOADS
|
|
299
|
+
Schema::table('payloads', function (Blueprint $table) {
|
|
300
|
+
if ($this->indexExists('payloads', 'payloads_company_created_idx')) {
|
|
301
|
+
$table->dropIndex('payloads_company_created_idx');
|
|
302
|
+
}
|
|
303
|
+
if ($this->indexExists('payloads', 'payloads_pickup_uuid_idx')) {
|
|
304
|
+
$table->dropIndex('payloads_pickup_uuid_idx');
|
|
305
|
+
}
|
|
306
|
+
if ($this->indexExists('payloads', 'payloads_dropoff_uuid_idx')) {
|
|
307
|
+
$table->dropIndex('payloads_dropoff_uuid_idx');
|
|
308
|
+
}
|
|
309
|
+
if ($this->indexExists('payloads', 'payloads_return_uuid_idx')) {
|
|
310
|
+
$table->dropIndex('payloads_return_uuid_idx');
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// WAYPOINTS
|
|
315
|
+
Schema::table('waypoints', function (Blueprint $table) {
|
|
316
|
+
if ($this->indexExists('waypoints', 'waypoints_payload_created_idx')) {
|
|
317
|
+
$table->dropIndex('waypoints_payload_created_idx');
|
|
318
|
+
}
|
|
319
|
+
if ($this->indexExists('waypoints', 'waypoints_company_created_idx')) {
|
|
320
|
+
$table->dropIndex('waypoints_company_created_idx');
|
|
321
|
+
}
|
|
322
|
+
if ($this->indexExists('waypoints', 'waypoints_place_uuid_idx')) {
|
|
323
|
+
$table->dropIndex('waypoints_place_uuid_idx');
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// ENTITIES
|
|
328
|
+
Schema::table('entities', function (Blueprint $table) {
|
|
329
|
+
if ($this->indexExists('entities', 'entities_payload_created_idx')) {
|
|
330
|
+
$table->dropIndex('entities_payload_created_idx');
|
|
331
|
+
}
|
|
332
|
+
if ($this->indexExists('entities', 'entities_company_created_idx')) {
|
|
333
|
+
$table->dropIndex('entities_company_created_idx');
|
|
334
|
+
}
|
|
335
|
+
if ($this->indexExists('entities', 'entities_destination_uuid_idx')) {
|
|
336
|
+
$table->dropIndex('entities_destination_uuid_idx');
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// PLACES
|
|
341
|
+
Schema::table('places', function (Blueprint $table) {
|
|
342
|
+
if ($this->indexExists('places', 'places_company_created_idx')) {
|
|
343
|
+
$table->dropIndex('places_company_created_idx');
|
|
344
|
+
}
|
|
345
|
+
if ($this->indexExists('places', 'places_owner_idx')) {
|
|
346
|
+
$table->dropIndex('places_owner_idx');
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// DRIVERS
|
|
351
|
+
Schema::table('drivers', function (Blueprint $table) {
|
|
352
|
+
if ($this->indexExists('drivers', 'drivers_company_status_online_idx')) {
|
|
353
|
+
$table->dropIndex('drivers_company_status_online_idx');
|
|
354
|
+
}
|
|
355
|
+
if ($this->indexExists('drivers', 'drivers_company_created_idx')) {
|
|
356
|
+
$table->dropIndex('drivers_company_created_idx');
|
|
357
|
+
}
|
|
358
|
+
if ($this->indexExists('drivers', 'drivers_user_uuid_idx')) {
|
|
359
|
+
$table->dropIndex('drivers_user_uuid_idx');
|
|
360
|
+
}
|
|
361
|
+
if ($this->indexExists('drivers', 'drivers_vendor_uuid_idx')) {
|
|
362
|
+
$table->dropIndex('drivers_vendor_uuid_idx');
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// VEHICLES
|
|
367
|
+
Schema::table('vehicles', function (Blueprint $table) {
|
|
368
|
+
if ($this->indexExists('vehicles', 'vehicles_company_status_online_idx')) {
|
|
369
|
+
$table->dropIndex('vehicles_company_status_online_idx');
|
|
370
|
+
}
|
|
371
|
+
if ($this->indexExists('vehicles', 'vehicles_company_created_idx')) {
|
|
372
|
+
$table->dropIndex('vehicles_company_created_idx');
|
|
373
|
+
}
|
|
374
|
+
if ($this->indexExists('vehicles', 'vehicles_vendor_uuid_idx')) {
|
|
375
|
+
$table->dropIndex('vehicles_vendor_uuid_idx');
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// VENDORS
|
|
380
|
+
Schema::table('vendors', function (Blueprint $table) {
|
|
381
|
+
if ($this->indexExists('vendors', 'vendors_company_status_idx')) {
|
|
382
|
+
$table->dropIndex('vendors_company_status_idx');
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// CONTACTS
|
|
387
|
+
Schema::table('contacts', function (Blueprint $table) {
|
|
388
|
+
if ($this->indexExists('contacts', 'contacts_company_created_idx')) {
|
|
389
|
+
$table->dropIndex('contacts_company_created_idx');
|
|
390
|
+
}
|
|
391
|
+
if ($this->indexExists('contacts', 'contacts_company_type_idx')) {
|
|
392
|
+
$table->dropIndex('contacts_company_type_idx');
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// ROUTES
|
|
397
|
+
Schema::table('routes', function (Blueprint $table) {
|
|
398
|
+
if ($this->indexExists('routes', 'routes_company_created_idx')) {
|
|
399
|
+
$table->dropIndex('routes_company_created_idx');
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// TRACKING_NUMBERS
|
|
404
|
+
Schema::table('tracking_numbers', function (Blueprint $table) {
|
|
405
|
+
if ($this->indexExists('tracking_numbers', 'tracking_numbers_company_created_idx')) {
|
|
406
|
+
$table->dropIndex('tracking_numbers_company_created_idx');
|
|
407
|
+
}
|
|
408
|
+
if ($this->indexExists('tracking_numbers', 'tracking_numbers_tracking_number_idx')) {
|
|
409
|
+
$table->dropIndex('tracking_numbers_tracking_number_idx');
|
|
410
|
+
}
|
|
411
|
+
if ($this->indexExists('tracking_numbers', 'tracking_numbers_owner_idx')) {
|
|
412
|
+
$table->dropIndex('tracking_numbers_owner_idx');
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// TRACKING_STATUSES
|
|
417
|
+
Schema::table('tracking_statuses', function (Blueprint $table) {
|
|
418
|
+
if ($this->indexExists('tracking_statuses', 'tracking_statuses_tracking_created_idx')) {
|
|
419
|
+
$table->dropIndex('tracking_statuses_tracking_created_idx');
|
|
420
|
+
}
|
|
421
|
+
if ($this->indexExists('tracking_statuses', 'tracking_statuses_company_created_idx')) {
|
|
422
|
+
$table->dropIndex('tracking_statuses_company_created_idx');
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Check if an index exists on a table.
|
|
429
|
+
*/
|
|
430
|
+
protected function indexExists(string $table, string $index): bool
|
|
431
|
+
{
|
|
432
|
+
try {
|
|
433
|
+
$connection = Schema::getConnection();
|
|
434
|
+
$doctrineSchemaManager = $connection->getDoctrineSchemaManager();
|
|
435
|
+
$indexes = $doctrineSchemaManager->listTableIndexes($table);
|
|
436
|
+
|
|
437
|
+
return isset($indexes[$index]);
|
|
438
|
+
} catch (Exception $e) {
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
};
|
|
@@ -135,8 +135,13 @@ class DispatchAdhocOrders extends Command
|
|
|
135
135
|
->withoutGlobalScopes();
|
|
136
136
|
|
|
137
137
|
if (!$testing) {
|
|
138
|
-
$driverQuery->
|
|
139
|
-
|
|
138
|
+
$driverQuery->whereNotNull('location')->whereRaw('
|
|
139
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
140
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
141
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
142
|
+
');
|
|
143
|
+
$driverQuery->distanceSphere('location', $pickup, $distance);
|
|
144
|
+
$driverQuery->distanceSphereValue('location', $pickup);
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
return $driverQuery->get();
|
|
@@ -551,6 +551,7 @@ class DriverController extends Controller
|
|
|
551
551
|
// generate verification token
|
|
552
552
|
try {
|
|
553
553
|
VerificationCode::generateSmsVerificationFor($user, 'driver_login', [
|
|
554
|
+
'company_uuid' => $company->uuid,
|
|
554
555
|
'messageCallback' => function ($verification) use ($company) {
|
|
555
556
|
return 'Your ' . data_get($company, 'name', config('app.name')) . ' verification code is ' . $verification->code;
|
|
556
557
|
},
|
|
@@ -566,6 +567,7 @@ class DriverController extends Controller
|
|
|
566
567
|
if ($user->email) {
|
|
567
568
|
try {
|
|
568
569
|
VerificationCode::generateEmailVerificationFor($user, 'driver_login', [
|
|
570
|
+
'company_uuid' => $company->uuid,
|
|
569
571
|
'messageCallback' => function ($verification) use ($company) {
|
|
570
572
|
return 'Your ' . data_get($company, 'name', config('app.name')) . ' verification code is ' . $verification->code;
|
|
571
573
|
},
|
|
@@ -629,9 +629,19 @@ class OrderController extends Controller
|
|
|
629
629
|
|
|
630
630
|
$query->whereHas('payload', function ($q) use ($location, $distance) {
|
|
631
631
|
$q->whereHas('pickup', function ($q) use ($location, $distance) {
|
|
632
|
+
$q->whereNotNull('location')->whereRaw('
|
|
633
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
634
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
635
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
636
|
+
');
|
|
632
637
|
$q->distanceSphere('location', $location, $distance);
|
|
633
638
|
$q->distanceSphereValue('location', $location);
|
|
634
639
|
})->orWhereHas('waypoints', function ($q) use ($location, $distance) {
|
|
640
|
+
$q->whereNotNull('location')->whereRaw('
|
|
641
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
642
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
643
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
644
|
+
');
|
|
635
645
|
$q->distanceSphere('location', $location, $distance);
|
|
636
646
|
$q->distanceSphereValue('location', $location);
|
|
637
647
|
});
|
|
@@ -648,9 +658,19 @@ class OrderController extends Controller
|
|
|
648
658
|
if ($driver) {
|
|
649
659
|
$query->whereHas('payload', function ($q) use ($driver, $distance) {
|
|
650
660
|
$q->whereHas('pickup', function ($q) use ($driver, $distance) {
|
|
661
|
+
$q->whereNotNull('location')->whereRaw('
|
|
662
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
663
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
664
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
665
|
+
');
|
|
651
666
|
$q->distanceSphere('location', $driver->location, $distance);
|
|
652
667
|
$q->distanceSphereValue('location', $driver->location);
|
|
653
668
|
})->orWhereHas('waypoints', function ($q) use ($driver, $distance) {
|
|
669
|
+
$q->whereNotNull('location')->whereRaw('
|
|
670
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
671
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
672
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
673
|
+
');
|
|
654
674
|
$q->distanceSphere('location', $driver->location, $distance);
|
|
655
675
|
$q->distanceSphereValue('location', $driver->location);
|
|
656
676
|
});
|
|
@@ -668,9 +688,19 @@ class OrderController extends Controller
|
|
|
668
688
|
if ($nearby instanceof Place) {
|
|
669
689
|
$query->whereHas('payload', function ($q) use ($nearby, $distance) {
|
|
670
690
|
$q->whereHas('pickup', function ($q) use ($nearby, $distance) {
|
|
691
|
+
$q->whereNotNull('location')->whereRaw('
|
|
692
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
693
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
694
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
695
|
+
');
|
|
671
696
|
$q->distanceSphere('location', $nearby->location, $distance);
|
|
672
697
|
$q->distanceSphereValue('location', $nearby->location);
|
|
673
698
|
})->orWhereHas('waypoints', function ($q) use ($nearby, $distance) {
|
|
699
|
+
$q->whereNotNull('location')->whereRaw('
|
|
700
|
+
ST_Y(location) BETWEEN -90 AND 90
|
|
701
|
+
AND ST_X(location) BETWEEN -180 AND 180
|
|
702
|
+
AND NOT (ST_X(location) = 0 AND ST_Y(location) = 0)
|
|
703
|
+
');
|
|
674
704
|
$q->distanceSphere('location', $nearby->location, $distance);
|
|
675
705
|
$q->distanceSphereValue('location', $nearby->location);
|
|
676
706
|
});
|