@fleetbase/fleetops-engine 0.6.30 → 0.6.32
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/orders.js +1 -1
- package/addon/components/driver/form.js +5 -1
- package/addon/services/leaflet-routing-control.js +1 -1
- package/addon/services/movement-tracker.js +2 -1
- package/addon/services/route-optimization.js +1 -1
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
- package/server/src/Http/Filter/OrderFilter.php +1 -1
- package/server/src/Http/Resources/v1/Order.php +1 -0
- package/server/src/Models/Driver.php +2 -2
- package/server/src/Observers/OrderObserver.php +50 -0
|
@@ -42,7 +42,7 @@ export default class CustomerOrdersComponent extends Component {
|
|
|
42
42
|
|
|
43
43
|
get modalsManager() {
|
|
44
44
|
const owner = getOwner(this);
|
|
45
|
-
const application =
|
|
45
|
+
const application = this.universe.getApplicationInstance();
|
|
46
46
|
const modalsManager = application ? application.lookup('service:modals-manager') : owner.lookup('service:modals-manager');
|
|
47
47
|
return modalsManager;
|
|
48
48
|
}
|
|
@@ -8,6 +8,7 @@ export default class DriverFormComponent extends Component {
|
|
|
8
8
|
@service currentUser;
|
|
9
9
|
@service notifications;
|
|
10
10
|
@service modalsManager;
|
|
11
|
+
@service('universe/extension-manager') extensionManager;
|
|
11
12
|
|
|
12
13
|
get userAccountActionButtons() {
|
|
13
14
|
return [
|
|
@@ -15,7 +16,10 @@ export default class DriverFormComponent extends Component {
|
|
|
15
16
|
icon: 'user-plus',
|
|
16
17
|
size: 'xs',
|
|
17
18
|
permission: 'iam create user',
|
|
18
|
-
onClick: () => {
|
|
19
|
+
onClick: async () => {
|
|
20
|
+
// Load IAM engine for user-form modal component
|
|
21
|
+
await this.extensionManager.ensureEngineLoaded('@fleetbase/iam-engine');
|
|
22
|
+
|
|
19
23
|
const user = this.store.createRecord('user', {
|
|
20
24
|
status: 'pending',
|
|
21
25
|
type: 'user',
|
|
@@ -67,7 +67,7 @@ export default class LeafletRoutingControlService extends Service {
|
|
|
67
67
|
|
|
68
68
|
#initializeRegistry() {
|
|
69
69
|
const registry = 'registry:routing-controls';
|
|
70
|
-
const application =
|
|
70
|
+
const application = this.universe.getApplicationInstance();
|
|
71
71
|
if (!application.hasRegistration(registry)) {
|
|
72
72
|
application.register(registry, new RoutingControlRegistry(), { instantiate: false });
|
|
73
73
|
}
|
|
@@ -122,6 +122,7 @@ export class EventBuffer {
|
|
|
122
122
|
|
|
123
123
|
export default class MovementTrackerService extends Service {
|
|
124
124
|
@service socket;
|
|
125
|
+
@service universe;
|
|
125
126
|
@tracked channels = [];
|
|
126
127
|
@tracked buffers = new Map();
|
|
127
128
|
|
|
@@ -131,7 +132,7 @@ export default class MovementTrackerService extends Service {
|
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
#getOwner(owner = null) {
|
|
134
|
-
return owner ??
|
|
135
|
+
return owner ?? this.universe.getApplicationInstance() ?? getOwner(this);
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
#getBuffer(key, model, opts = {}) {
|
|
@@ -57,7 +57,7 @@ export default class RouteOptimizationService extends Service {
|
|
|
57
57
|
|
|
58
58
|
#initializeRegistry() {
|
|
59
59
|
const registry = 'registry:route-optimization-engines';
|
|
60
|
-
const application =
|
|
60
|
+
const application = this.universe.getApplicationInstance();
|
|
61
61
|
if (!application.hasRegistration(registry)) {
|
|
62
62
|
application.register(registry, new RouteOptimizationRegistry(), { instantiate: false });
|
|
63
63
|
}
|
package/composer.json
CHANGED
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/fleetops-engine",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.32",
|
|
4
4
|
"description": "Fleet & Transport Management Extension for Fleetbase",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "fleet-ops"
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@babel/core": "^7.23.2",
|
|
45
|
-
"@fleetbase/ember-core": "^0.3.
|
|
46
|
-
"@fleetbase/ember-ui": "^0.3.
|
|
47
|
-
"@fleetbase/fleetops-data": "^0.1.
|
|
45
|
+
"@fleetbase/ember-core": "^0.3.10",
|
|
46
|
+
"@fleetbase/ember-ui": "^0.3.17",
|
|
47
|
+
"@fleetbase/fleetops-data": "^0.1.25",
|
|
48
48
|
"@fleetbase/leaflet-routing-machine": "^3.2.17",
|
|
49
49
|
"@fortawesome/ember-fontawesome": "^2.0.0",
|
|
50
50
|
"@fortawesome/fontawesome-svg-core": "6.4.0",
|
|
@@ -139,6 +139,7 @@ class LiveController extends Controller
|
|
|
139
139
|
|
|
140
140
|
if ($active) {
|
|
141
141
|
$query->whereHas('driverAssigned');
|
|
142
|
+
$query->whereNotIn('status', ['created', 'completed', 'expired', 'order_canceled', 'canceled', 'pending']);
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
if ($unassigned) {
|
|
@@ -166,7 +167,7 @@ class LiveController extends Controller
|
|
|
166
167
|
|
|
167
168
|
return LiveCacheService::remember('drivers', $cacheParams, function () use ($bounds) {
|
|
168
169
|
$query = Driver::where(['company_uuid' => session('company')])
|
|
169
|
-
->with(['user', 'vehicle'
|
|
170
|
+
->with(['user', 'vehicle'])
|
|
170
171
|
->applyDirectivesForPermissions('fleet-ops list driver');
|
|
171
172
|
|
|
172
173
|
// Filter out drivers with invalid coordinates
|
|
@@ -116,7 +116,7 @@ class OrderFilter extends Filter
|
|
|
116
116
|
$this->builder->where(
|
|
117
117
|
function ($q) {
|
|
118
118
|
$q->whereHas('driverAssigned');
|
|
119
|
-
$q->whereNotIn('status', ['created', '
|
|
119
|
+
$q->whereNotIn('status', ['created', 'completed', 'expired', 'order_canceled', 'canceled', 'pending']);
|
|
120
120
|
}
|
|
121
121
|
);
|
|
122
122
|
}
|
|
@@ -84,6 +84,7 @@ class Order extends FleetbaseResource
|
|
|
84
84
|
'pod_method' => $this->pod_method,
|
|
85
85
|
'pod_required' => (bool) data_get($this, 'pod_required', false),
|
|
86
86
|
'dispatched' => (bool) data_get($this, 'dispatched', false),
|
|
87
|
+
'started' => (bool) data_get($this, 'started', false),
|
|
87
88
|
'adhoc' => (bool) data_get($this, 'adhoc', false),
|
|
88
89
|
'adhoc_distance' => (int) $this->getAdhocDistance(),
|
|
89
90
|
'distance' => (int) $this->distance,
|
|
@@ -262,12 +262,12 @@ class Driver extends Model
|
|
|
262
262
|
|
|
263
263
|
public function currentJob(): BelongsTo|Builder
|
|
264
264
|
{
|
|
265
|
-
return $this->belongsTo(Order::class)->
|
|
265
|
+
return $this->belongsTo(Order::class)->without(['driver']);
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
public function currentOrder(): BelongsTo|Builder
|
|
269
269
|
{
|
|
270
|
-
return $this->belongsTo(Order::class, 'current_job_uuid')->
|
|
270
|
+
return $this->belongsTo(Order::class, 'current_job_uuid')->without(['driver']);
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
public function jobs(): HasMany|Builder
|
|
@@ -18,6 +18,20 @@ class OrderObserver
|
|
|
18
18
|
$this->invalidateCache($order);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Handle the Order "updating" event.
|
|
23
|
+
*
|
|
24
|
+
* This event is fired before the order is persisted to the database.
|
|
25
|
+
* It is used to mutate attributes as part of the same update operation
|
|
26
|
+
* without triggering additional save cycles.
|
|
27
|
+
*
|
|
28
|
+
* @param Order $order The order being updated
|
|
29
|
+
*/
|
|
30
|
+
public function updating(Order $order): void
|
|
31
|
+
{
|
|
32
|
+
$this->ensureOrderStarted($order);
|
|
33
|
+
}
|
|
34
|
+
|
|
21
35
|
/**
|
|
22
36
|
* Handle the Order "updated" event.
|
|
23
37
|
*
|
|
@@ -62,4 +76,40 @@ class OrderObserver
|
|
|
62
76
|
Cache::forget("order:{$order->uuid}:tracker");
|
|
63
77
|
}
|
|
64
78
|
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Detects when an order has just transitioned to the "started" status
|
|
82
|
+
* and initializes start-related fields.
|
|
83
|
+
*
|
|
84
|
+
* This method should be called during the "updating" lifecycle event
|
|
85
|
+
* to ensure that the changes are persisted as part of the same database
|
|
86
|
+
* update and do not trigger additional observer events.
|
|
87
|
+
*
|
|
88
|
+
* An order is considered "started" when:
|
|
89
|
+
* - The "status" attribute is being changed in the current update
|
|
90
|
+
* - The previous status was not "started"
|
|
91
|
+
* - The new status is "started"
|
|
92
|
+
*
|
|
93
|
+
* When these conditions are met, the order's start timestamp and
|
|
94
|
+
* started flag are set if they have not already been initialized.
|
|
95
|
+
*
|
|
96
|
+
* @param Order $order The order being evaluated for a start transition
|
|
97
|
+
*/
|
|
98
|
+
protected function ensureOrderStarted(Order $order): void
|
|
99
|
+
{
|
|
100
|
+
if (
|
|
101
|
+
$order->isDirty('status')
|
|
102
|
+
&& $order->getOriginal('status') === 'dispatched'
|
|
103
|
+
&& $order->status === 'started'
|
|
104
|
+
) {
|
|
105
|
+
// Only set defaults if not explicitly provided
|
|
106
|
+
if (is_null($order->started_at)) {
|
|
107
|
+
$order->started_at = now();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!$order->started) {
|
|
111
|
+
$order->started = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
65
115
|
}
|