@fleetbase/fleetops-engine 0.6.8 → 0.6.9
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/activity-event-selector.js +4 -0
- package/addon/components/display-place.hbs +27 -3
- package/addon/components/route-list.hbs +3 -3
- package/addon/controllers/operations/orders/index.js +0 -4
- package/addon/routes/operations/orders/index/view.js +18 -1
- package/addon/services/movement-tracker.js +1 -1
- package/addon/styles/fleetops-engine.css +7 -0
- package/addon/templates/operations/orders/index/new.hbs +2 -2
- package/addon/templates/operations/orders/index/view.hbs +5 -1
- package/addon/templates/operations/orders/index.hbs +6 -1
- package/addon/templates/settings/notifications.hbs +9 -1
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +2 -2
- package/server/src/Events/OrderCanceled.php +6 -0
- package/server/src/Events/OrderCompleted.php +6 -0
- package/server/src/Events/OrderDispatched.php +6 -0
- package/server/src/Events/OrderFailed.php +6 -0
- package/server/src/Events/WaypointActivityChanged.php +119 -0
- package/server/src/Events/WaypointCompleted.php +119 -0
- package/server/src/Flow/Activity.php +28 -10
- package/server/src/Flow/Event.php +26 -2
- package/server/src/Http/Controllers/Api/v1/DriverController.php +19 -2
- package/server/src/Http/Controllers/Api/v1/OrderController.php +274 -164
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +15 -8
- package/server/src/Http/Filter/OrderFilter.php +4 -4
- package/server/src/Http/Resources/v1/Payload.php +1 -1
- package/server/src/Listeners/HandleOrderCanceled.php +0 -10
- package/server/src/Listeners/NotifyOrderEvent.php +4 -4
- package/server/src/Models/OrderConfig.php +50 -35
- package/server/src/Models/Payload.php +26 -7
- package/server/src/Models/Waypoint.php +10 -0
- package/server/src/Notifications/OrderAssigned.php +3 -5
- package/server/src/Notifications/OrderCanceled.php +32 -12
- package/server/src/Notifications/OrderCompleted.php +31 -11
- package/server/src/Notifications/OrderDispatchFailed.php +3 -5
- package/server/src/Notifications/OrderDispatched.php +31 -11
- package/server/src/Notifications/OrderFailed.php +32 -12
- package/server/src/Notifications/OrderPing.php +2 -6
- package/server/src/Notifications/OrderSplit.php +1 -1
- package/server/src/Notifications/WaypointCompleted.php +157 -0
|
@@ -45,6 +45,10 @@ export default class ActivityEventSelectorComponent extends Component {
|
|
|
45
45
|
name: 'order.canceled',
|
|
46
46
|
description: 'Triggers when an order is canceled by a user, driver, or system process.',
|
|
47
47
|
},
|
|
48
|
+
'order.completed': {
|
|
49
|
+
name: 'order.completed',
|
|
50
|
+
description: 'Triggers when an order is completed by a driver, or system process.',
|
|
51
|
+
},
|
|
48
52
|
};
|
|
49
53
|
|
|
50
54
|
/**
|
|
@@ -11,9 +11,33 @@
|
|
|
11
11
|
</span>
|
|
12
12
|
</div>
|
|
13
13
|
{{else}}
|
|
14
|
-
{{
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
<div class="flex flex-row item-center space-x-2 {{if (or place.status_code @eta) 'mb-2'}}">
|
|
15
|
+
{{#if place.status_code}}
|
|
16
|
+
<Badge @status={{place.status_code}} />
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if @eta}}
|
|
19
|
+
<Badge @status="warning" @hideStatusDot={{true}}><span class="font-bold">ETA:</span> {{format-duration @eta}}</Badge>
|
|
20
|
+
{{/if}}
|
|
21
|
+
{{#if @waypointActions}}
|
|
22
|
+
<DropdownButton @iconClass="icon-text-height" @size="xs" @buttonClass="fleetops-btn-xxs" @icon="ellipsis-h" @iconPrefix="fas" @contentClass="dropdown-menu" as |dd|>
|
|
23
|
+
<div class="next-dd-menu mt-1 mx-0" aria-labelledby="user-menu">
|
|
24
|
+
<div class="px-1">
|
|
25
|
+
<div class="text-sm flex flex-row items-center px-3 py-1 rounded-md my-1 text-gray-300">
|
|
26
|
+
{{t "fleet-ops.operations.orders.index.view.waypoint-actions"}}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="next-dd-menu-seperator"></div>
|
|
30
|
+
{{#each-in @waypointActions as |actionId action|}}
|
|
31
|
+
<div class="px-1">
|
|
32
|
+
<a href="javascript:;" class="next-dd-item" disabled={{cannot "fleet-ops view order"}} {{on "click" (fn action.fn place dd)}}>
|
|
33
|
+
{{action.label}}
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
{{/each-in}}
|
|
37
|
+
</div>
|
|
38
|
+
</DropdownButton>
|
|
39
|
+
{{/if}}
|
|
40
|
+
</div>
|
|
17
41
|
<address class={{@addressClass}}>
|
|
18
42
|
{{#if place.name}}
|
|
19
43
|
{{place.name}}<br />
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<div class="index-count">1</div>
|
|
7
7
|
</div>
|
|
8
8
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
9
|
-
<DisplayPlace @place={{@order.payload.firstWaypoint}} @eta={{get @eta @order.payload.firstWaypoint.id}} />
|
|
9
|
+
<DisplayPlace @place={{@order.payload.firstWaypoint}} @eta={{get @eta @order.payload.firstWaypoint.id}} @waypointActions={{@waypointActions}} />
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
12
12
|
{{/if}}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<div class="index-count">{{add index 2}}</div>
|
|
29
29
|
</div>
|
|
30
30
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
31
|
-
<DisplayPlace @place={{waypoint}} @eta={{get @eta waypoint.id}} />
|
|
31
|
+
<DisplayPlace @place={{waypoint}} @eta={{get @eta waypoint.id}} @waypointActions={{@waypointActions}} />
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
{{/each}}
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
<div class="index-count">{{add @order.payload.middleWaypoints.length 2}}</div>
|
|
42
42
|
</div>
|
|
43
43
|
<div class="order-route-location {{@routeLocationClass}} dark:text-gray-100">
|
|
44
|
-
<DisplayPlace @place={{@order.payload.lastWaypoint}} @eta={{get @eta @order.payload.lastWaypoint.id}} />
|
|
44
|
+
<DisplayPlace @place={{@order.payload.lastWaypoint}} @eta={{get @eta @order.payload.lastWaypoint.id}} @waypointActions={{@waypointActions}} />
|
|
45
45
|
</div>
|
|
46
46
|
</div>
|
|
47
47
|
{{/if}}
|
|
@@ -1047,7 +1047,6 @@ export default class OperationsOrdersIndexController extends BaseController {
|
|
|
1047
1047
|
selected = selected.length > 0 ? selected : this.table.selectedRows;
|
|
1048
1048
|
|
|
1049
1049
|
this.crud.bulkDelete(selected, {
|
|
1050
|
-
modelNamePath: `public_id`,
|
|
1051
1050
|
acceptButtonText: 'Delete Orders',
|
|
1052
1051
|
resolveModelName: (model) => `${model.get('tracking_number.tracking_number')} - ${model.get('public_id')}`,
|
|
1053
1052
|
onSuccess: async () => {
|
|
@@ -1075,7 +1074,6 @@ export default class OperationsOrdersIndexController extends BaseController {
|
|
|
1075
1074
|
acceptButtonText: 'Cancel Orders',
|
|
1076
1075
|
acceptButtonScheme: 'danger',
|
|
1077
1076
|
acceptButtonIcon: 'ban',
|
|
1078
|
-
modelNamePath: `public_id`,
|
|
1079
1077
|
actionPath: `orders/bulk-cancel`,
|
|
1080
1078
|
actionMethod: `PATCH`,
|
|
1081
1079
|
resolveModelName: (model) => `${model.get('tracking_number.tracking_number')} - ${model.get('public_id')}`,
|
|
@@ -1109,7 +1107,6 @@ export default class OperationsOrdersIndexController extends BaseController {
|
|
|
1109
1107
|
acceptButtonText: 'Dispatch Orders',
|
|
1110
1108
|
acceptButtonScheme: 'magic',
|
|
1111
1109
|
acceptButtonIcon: 'rocket',
|
|
1112
|
-
modelNamePath: 'public_id',
|
|
1113
1110
|
actionPath: 'orders/bulk-dispatch',
|
|
1114
1111
|
actionMethod: 'POST',
|
|
1115
1112
|
resolveModelName: (model) => `${model.get('tracking_number.tracking_number')} - ${model.get('public_id')}`,
|
|
@@ -1152,7 +1149,6 @@ export default class OperationsOrdersIndexController extends BaseController {
|
|
|
1152
1149
|
acceptButtonScheme: 'magic',
|
|
1153
1150
|
acceptButtonIcon: 'user-plus',
|
|
1154
1151
|
acceptButtonDisabled: true,
|
|
1155
|
-
modelNamePath: 'public_id',
|
|
1156
1152
|
actionPath: 'orders/bulk-assign-driver',
|
|
1157
1153
|
actionMethod: 'PATCH',
|
|
1158
1154
|
driverAssigned: null,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
3
|
import { action } from '@ember/object';
|
|
4
|
+
import { debug } from '@ember/debug';
|
|
4
5
|
|
|
5
6
|
export default class OperationsOrdersIndexViewRoute extends Route {
|
|
6
7
|
@service currentUser;
|
|
@@ -66,7 +67,23 @@ export default class OperationsOrdersIndexViewRoute extends Route {
|
|
|
66
67
|
// Listen for channel subscription
|
|
67
68
|
(async () => {
|
|
68
69
|
for await (let output of channel) {
|
|
69
|
-
|
|
70
|
+
const { event, data } = output;
|
|
71
|
+
|
|
72
|
+
// debug output
|
|
73
|
+
debug(`Socket Event : ${event} : ${JSON.stringify(output)}`);
|
|
74
|
+
|
|
75
|
+
// Only reload if the order has a status change stemming from an updated event OR
|
|
76
|
+
// if a waypoint has been completed which will trigger `order.completed`
|
|
77
|
+
const statusChanged = event === 'order.updated' && data.status !== model.status;
|
|
78
|
+
const shouldReload = ['order.completed', 'waypoint.activity', 'order.created'].includes(event);
|
|
79
|
+
if (statusChanged || shouldReload) {
|
|
80
|
+
this.refresh();
|
|
81
|
+
|
|
82
|
+
// reload the controller stuff as well
|
|
83
|
+
if (this.controller) {
|
|
84
|
+
this.controller.loadOrderRelations.perform(model);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
70
87
|
|
|
71
88
|
if (typeof this.onOrderEvent === 'function') {
|
|
72
89
|
this.onOrderEvent(output);
|
|
@@ -155,7 +155,7 @@ export default class MovementTrackerService extends Service {
|
|
|
155
155
|
|
|
156
156
|
if (event === `${type}.location_changed` || event === `${type}.simulated_location_changed`) {
|
|
157
157
|
eventBuffer.add(output);
|
|
158
|
-
debug(`
|
|
158
|
+
debug(`Socket Event : ${event} : Added to EventBuffer : ${JSON.stringify(output)}`);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
})();
|
|
@@ -1623,3 +1623,10 @@ body[data-theme='dark']
|
|
|
1623
1623
|
.justify-end-i {
|
|
1624
1624
|
justify-content: end !important;
|
|
1625
1625
|
}
|
|
1626
|
+
|
|
1627
|
+
button.fleetops-btn-xxs.btn,
|
|
1628
|
+
button.fleetops-btn-xxs,
|
|
1629
|
+
.fleetops-btn-xxs {
|
|
1630
|
+
padding-top: 0.2rem !important;
|
|
1631
|
+
padding-bottom: 0.2rem !important;
|
|
1632
|
+
}
|
|
@@ -405,7 +405,7 @@
|
|
|
405
405
|
</div>
|
|
406
406
|
<div>
|
|
407
407
|
<div class="flex flex-row items-center space-x-4 text-sm mt-2">
|
|
408
|
-
<div class={{if (eq waypoint.type "dropoff")
|
|
408
|
+
<div class={{if (eq waypoint.type "dropoff") "is-checked"}}>
|
|
409
409
|
<div class="flex flex-row items-center">
|
|
410
410
|
<RadioButton
|
|
411
411
|
@radioClass="focus:ring-blue-500 h-4 w-4 text-blue-500"
|
|
@@ -418,7 +418,7 @@
|
|
|
418
418
|
<label for={{concat "waypoint_" index "_dropoff"}} class="ml-2">Dropoff</label>
|
|
419
419
|
</div>
|
|
420
420
|
</div>
|
|
421
|
-
<div class={{if (eq waypoint.type "pickup")
|
|
421
|
+
<div class={{if (eq waypoint.type "pickup") "is-checked"}}>
|
|
422
422
|
<div class="flex flex-row items-center">
|
|
423
423
|
<RadioButton
|
|
424
424
|
@radioClass="focus:ring-blue-500 h-4 w-4 text-blue-500"
|
|
@@ -579,7 +579,11 @@
|
|
|
579
579
|
>
|
|
580
580
|
{{#if @model.payload.isMultiDrop}}
|
|
581
581
|
<div>
|
|
582
|
-
<RouteList
|
|
582
|
+
<RouteList
|
|
583
|
+
@order={{@model}}
|
|
584
|
+
@eta={{@model.eta}}
|
|
585
|
+
@waypointActions={{hash viewWaypointLabel=(hash label=(t "fleet-ops.operations.orders.index.view.get-label") fn=this.viewWaypointLabel)}}
|
|
586
|
+
/>
|
|
583
587
|
</div>
|
|
584
588
|
{{else}}
|
|
585
589
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 lg:gap-2">
|
|
@@ -72,7 +72,12 @@
|
|
|
72
72
|
<h4>Bulk Search</h4>
|
|
73
73
|
</div>
|
|
74
74
|
<div class="filters-dropdown-body">
|
|
75
|
-
<Textarea
|
|
75
|
+
<Textarea
|
|
76
|
+
@value={{this.bulkSearchValue}}
|
|
77
|
+
class="form-input w-full"
|
|
78
|
+
rows="8"
|
|
79
|
+
placeholder="Input comma delimited order ID's or tracking numbers to perform a bulk search"
|
|
80
|
+
/>
|
|
76
81
|
</div>
|
|
77
82
|
<div class="filters-dropdown-footer space-x-2">
|
|
78
83
|
<Button @text="Clear" @icon="trash" @size="xs" @onClick={{dropdown-fn dd this.removeBulkQuery}} />
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
<Layout::Section::Header @title={{t "fleet-ops.settings.notifications.fleet-ops-notification-settings"}}>
|
|
2
|
-
|
|
2
|
+
<Button
|
|
3
|
+
@type="primary"
|
|
4
|
+
@size="sm"
|
|
5
|
+
@icon="save"
|
|
6
|
+
@text={{t "common.save-button-text"}}
|
|
7
|
+
@onClick={{perform this.saveSettings}}
|
|
8
|
+
@disabled={{this.saveSettings.isRunning}}
|
|
9
|
+
@isLoading={{or this.saveSettings.isRunning this.getSettings.isRunning}}
|
|
10
|
+
/>
|
|
3
11
|
</Layout::Section::Header>
|
|
4
12
|
|
|
5
13
|
<Layout::Section::Body class="overflow-y-scroll h-full">
|
package/composer.json
CHANGED
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -69,7 +69,7 @@ class TrackOrderDistanceAndTime extends Command
|
|
|
69
69
|
* - Not in 'completed' or 'canceled' status.
|
|
70
70
|
* - Not marked as deleted (`deleted_at` is null).
|
|
71
71
|
* - Associated with a company (`company_uuid` is not null).
|
|
72
|
-
* - The order process has started (`
|
|
72
|
+
* - The order process has started (`started_at` is not null).
|
|
73
73
|
* - Contains a payload (`payload` relationship exists).
|
|
74
74
|
* - Created within the past month.
|
|
75
75
|
*
|
|
@@ -85,7 +85,7 @@ class TrackOrderDistanceAndTime extends Command
|
|
|
85
85
|
return Order::whereNotIn('status', ['completed', 'canceled'])
|
|
86
86
|
->whereNull('deleted_at')
|
|
87
87
|
->whereNotNull('company_uuid')
|
|
88
|
-
->whereNotNull('
|
|
88
|
+
->whereNotNull('started_at')
|
|
89
89
|
->where('created_at', '>=', $oneMonthAgo)
|
|
90
90
|
->whereHas('payload')
|
|
91
91
|
->with(['payload', 'payload.waypoints', 'payload.pickup', 'payload.dropoff'])
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Events;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Events\ResourceLifecycleEvent;
|
|
6
6
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
7
8
|
|
|
8
9
|
class OrderCanceled extends ResourceLifecycleEvent
|
|
9
10
|
{
|
|
@@ -18,4 +19,9 @@ class OrderCanceled extends ResourceLifecycleEvent
|
|
|
18
19
|
* Assosciated activity which triggered the event.
|
|
19
20
|
*/
|
|
20
21
|
public ?Activity $activity;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Assosciated order waypoint which event is for.
|
|
25
|
+
*/
|
|
26
|
+
public ?Waypoint $waypoint;
|
|
21
27
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Events;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Events\ResourceLifecycleEvent;
|
|
6
6
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
7
8
|
|
|
8
9
|
class OrderCompleted extends ResourceLifecycleEvent
|
|
9
10
|
{
|
|
@@ -18,4 +19,9 @@ class OrderCompleted extends ResourceLifecycleEvent
|
|
|
18
19
|
* Assosciated activity which triggered the event.
|
|
19
20
|
*/
|
|
20
21
|
public ?Activity $activity;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Assosciated order waypoint which event is for.
|
|
25
|
+
*/
|
|
26
|
+
public ?Waypoint $waypoint;
|
|
21
27
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Events;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Events\ResourceLifecycleEvent;
|
|
6
6
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
7
8
|
|
|
8
9
|
class OrderDispatched extends ResourceLifecycleEvent
|
|
9
10
|
{
|
|
@@ -18,4 +19,9 @@ class OrderDispatched extends ResourceLifecycleEvent
|
|
|
18
19
|
* Assosciated activity which triggered the event.
|
|
19
20
|
*/
|
|
20
21
|
public ?Activity $activity;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Assosciated order waypoint which event is for.
|
|
25
|
+
*/
|
|
26
|
+
public ?Waypoint $waypoint;
|
|
21
27
|
}
|
|
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Events;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Events\ResourceLifecycleEvent;
|
|
6
6
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
7
8
|
|
|
8
9
|
class OrderFailed extends ResourceLifecycleEvent
|
|
9
10
|
{
|
|
@@ -18,4 +19,9 @@ class OrderFailed extends ResourceLifecycleEvent
|
|
|
18
19
|
* Assosciated activity which triggered the event.
|
|
19
20
|
*/
|
|
20
21
|
public ?Activity $activity;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Assosciated order waypoint which event is for.
|
|
25
|
+
*/
|
|
26
|
+
public ?Waypoint $waypoint;
|
|
21
27
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Flow\Activity;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
8
|
+
use Illuminate\Broadcasting\Channel;
|
|
9
|
+
use Illuminate\Broadcasting\InteractsWithSockets;
|
|
10
|
+
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
11
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
12
|
+
use Illuminate\Queue\SerializesModels;
|
|
13
|
+
use Illuminate\Support\Carbon;
|
|
14
|
+
|
|
15
|
+
class WaypointActivityChanged implements ShouldBroadcast
|
|
16
|
+
{
|
|
17
|
+
use Dispatchable;
|
|
18
|
+
use InteractsWithSockets;
|
|
19
|
+
use SerializesModels;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The waypoint which is completed.
|
|
23
|
+
*/
|
|
24
|
+
public Waypoint $waypoint;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The activity which triggered the waypoint completed.
|
|
28
|
+
*/
|
|
29
|
+
public Activity $activity;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The event id.
|
|
33
|
+
*
|
|
34
|
+
* @var string
|
|
35
|
+
*/
|
|
36
|
+
public $eventId;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The datetime instance the broadcast ws triggered.
|
|
40
|
+
*
|
|
41
|
+
* @var string
|
|
42
|
+
*/
|
|
43
|
+
public $sentAt;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a new event instance.
|
|
47
|
+
*
|
|
48
|
+
* @return void
|
|
49
|
+
*/
|
|
50
|
+
public function __construct(Waypoint $waypoint, Activity $activity)
|
|
51
|
+
{
|
|
52
|
+
$this->waypoint = $waypoint;
|
|
53
|
+
$this->activity = $activity;
|
|
54
|
+
$this->eventId = uniqid('event_');
|
|
55
|
+
$this->sentAt = Carbon::now()->toDateTimeString();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get the channels the event should broadcast on.
|
|
60
|
+
*
|
|
61
|
+
* @return Channel|array
|
|
62
|
+
*/
|
|
63
|
+
public function broadcastOn()
|
|
64
|
+
{
|
|
65
|
+
$channels = [
|
|
66
|
+
new Channel('api.' . session('api_credential')),
|
|
67
|
+
new Channel('waypoint.' . $this->waypoint->public_id),
|
|
68
|
+
new Channel('waypoint.' . $this->waypoint->uuid),
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
$order = $this->getModelRecord();
|
|
72
|
+
if ($order) {
|
|
73
|
+
$channels[] = new Channel('company.' . session('company', data_get($order, 'company.uuid')));
|
|
74
|
+
$channels[] = new Channel('company.' . data_get($order, 'company.public_id'));
|
|
75
|
+
$channels[] = new Channel('order.' . $order->uuid);
|
|
76
|
+
$channels[] = new Channel('order.' . $order->public_id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return $channels;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The event's broadcast name.
|
|
84
|
+
*
|
|
85
|
+
* @return string
|
|
86
|
+
*/
|
|
87
|
+
public function broadcastAs()
|
|
88
|
+
{
|
|
89
|
+
return 'waypoint.activity';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get the data to broadcast.
|
|
94
|
+
*
|
|
95
|
+
* @return array
|
|
96
|
+
*/
|
|
97
|
+
public function broadcastWith()
|
|
98
|
+
{
|
|
99
|
+
return [
|
|
100
|
+
'id' => $this->eventId,
|
|
101
|
+
'api_version' => config('api.version'),
|
|
102
|
+
'event' => $this->broadcastAs(),
|
|
103
|
+
'created_at' => $this->sentAt,
|
|
104
|
+
'data' => [
|
|
105
|
+
'waypoint' => $this->waypoint->public_id,
|
|
106
|
+
'place' => data_get($this->waypoint, 'place.public_id'),
|
|
107
|
+
'activity' => $this->activity->toArray(),
|
|
108
|
+
],
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get the assosciated order model record for this waypoint.
|
|
114
|
+
*/
|
|
115
|
+
public function getModelRecord(): ?Order
|
|
116
|
+
{
|
|
117
|
+
return Order::where('payload_uuid', $this->waypoint->payload_uuid)->first();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Events;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Flow\Activity;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
8
|
+
use Illuminate\Broadcasting\Channel;
|
|
9
|
+
use Illuminate\Broadcasting\InteractsWithSockets;
|
|
10
|
+
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
11
|
+
use Illuminate\Foundation\Events\Dispatchable;
|
|
12
|
+
use Illuminate\Queue\SerializesModels;
|
|
13
|
+
use Illuminate\Support\Carbon;
|
|
14
|
+
|
|
15
|
+
class WaypointCompleted implements ShouldBroadcast
|
|
16
|
+
{
|
|
17
|
+
use Dispatchable;
|
|
18
|
+
use InteractsWithSockets;
|
|
19
|
+
use SerializesModels;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The waypoint which is completed.
|
|
23
|
+
*/
|
|
24
|
+
public Waypoint $waypoint;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The activity which triggered the waypoint completed.
|
|
28
|
+
*/
|
|
29
|
+
public Activity $activity;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The event id.
|
|
33
|
+
*
|
|
34
|
+
* @var string
|
|
35
|
+
*/
|
|
36
|
+
public $eventId;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The datetime instance the broadcast ws triggered.
|
|
40
|
+
*
|
|
41
|
+
* @var string
|
|
42
|
+
*/
|
|
43
|
+
public $sentAt;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a new event instance.
|
|
47
|
+
*
|
|
48
|
+
* @return void
|
|
49
|
+
*/
|
|
50
|
+
public function __construct(Waypoint $waypoint, Activity $activity)
|
|
51
|
+
{
|
|
52
|
+
$this->waypoint = $waypoint;
|
|
53
|
+
$this->activity = $activity;
|
|
54
|
+
$this->eventId = uniqid('event_');
|
|
55
|
+
$this->sentAt = Carbon::now()->toDateTimeString();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get the channels the event should broadcast on.
|
|
60
|
+
*
|
|
61
|
+
* @return Channel|array
|
|
62
|
+
*/
|
|
63
|
+
public function broadcastOn()
|
|
64
|
+
{
|
|
65
|
+
$channels = [
|
|
66
|
+
new Channel('api.' . session('api_credential')),
|
|
67
|
+
new Channel('waypoint.' . $this->waypoint->public_id),
|
|
68
|
+
new Channel('waypoint.' . $this->waypoint->uuid),
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
$order = $this->getModelRecord();
|
|
72
|
+
if ($order) {
|
|
73
|
+
$channels[] = new Channel('company.' . session('company', data_get($order, 'company.uuid')));
|
|
74
|
+
$channels[] = new Channel('company.' . data_get($order, 'company.public_id'));
|
|
75
|
+
$channels[] = new Channel('order.' . $order->uuid);
|
|
76
|
+
$channels[] = new Channel('order.' . $order->public_id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return $channels;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The event's broadcast name.
|
|
84
|
+
*
|
|
85
|
+
* @return string
|
|
86
|
+
*/
|
|
87
|
+
public function broadcastAs()
|
|
88
|
+
{
|
|
89
|
+
return 'waypoint.completed';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get the data to broadcast.
|
|
94
|
+
*
|
|
95
|
+
* @return array
|
|
96
|
+
*/
|
|
97
|
+
public function broadcastWith()
|
|
98
|
+
{
|
|
99
|
+
return [
|
|
100
|
+
'id' => $this->eventId,
|
|
101
|
+
'api_version' => config('api.version'),
|
|
102
|
+
'event' => $this->broadcastAs(),
|
|
103
|
+
'created_at' => $this->sentAt,
|
|
104
|
+
'data' => [
|
|
105
|
+
'waypoint' => $this->waypoint->public_id,
|
|
106
|
+
'place' => data_get($this->waypoint, 'place.public_id'),
|
|
107
|
+
'activity' => $this->activity->toArray(),
|
|
108
|
+
],
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get the assosciated order model record for this waypoint.
|
|
114
|
+
*/
|
|
115
|
+
public function getModelRecord(): ?Order
|
|
116
|
+
{
|
|
117
|
+
return Order::where('payload_uuid', $this->waypoint->payload_uuid)->first();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Flow;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Models\Order;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Waypoint;
|
|
6
7
|
use Fleetbase\FleetOps\Support\Utils;
|
|
7
8
|
|
|
8
9
|
class Activity extends FlowResource
|
|
@@ -100,10 +101,10 @@ class Activity extends FlowResource
|
|
|
100
101
|
*
|
|
101
102
|
* @param Order $order the order object to be passed to each event
|
|
102
103
|
*/
|
|
103
|
-
public function fireEvents(Order $order)
|
|
104
|
+
public function fireEvents(Order $order, ?Waypoint $waypoint = null)
|
|
104
105
|
{
|
|
105
106
|
foreach ($this->events as $event) {
|
|
106
|
-
$event->fire($order, $this);
|
|
107
|
+
$event->fire($order, $this, $waypoint);
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -112,12 +113,22 @@ class Activity extends FlowResource
|
|
|
112
113
|
*
|
|
113
114
|
* @return \Illuminate\Support\Collection a collection of child activities
|
|
114
115
|
*/
|
|
115
|
-
public function getChildActivities()
|
|
116
|
+
public function getChildActivities(Order|Waypoint|null $context = null)
|
|
116
117
|
{
|
|
117
|
-
$children
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
$children = collect();
|
|
119
|
+
$activities = $this->activities;
|
|
120
|
+
|
|
121
|
+
// if waypoint provided
|
|
122
|
+
$waypointContext = $context instanceof Waypoint;
|
|
123
|
+
|
|
124
|
+
if (is_array($activities)) {
|
|
125
|
+
foreach ($activities as $childActivityCode) {
|
|
120
126
|
$childActivity = $this->flow->getActivity($childActivityCode);
|
|
127
|
+
// if waypoint context skip `created` - `started` - `dispatched`
|
|
128
|
+
if ($waypointContext && in_array($childActivity->code, ['created', 'started', 'dispatched'])) {
|
|
129
|
+
return $childActivity->getChildActivities($context);
|
|
130
|
+
}
|
|
131
|
+
|
|
121
132
|
if ($childActivity) {
|
|
122
133
|
$children->push($childActivity);
|
|
123
134
|
}
|
|
@@ -158,15 +169,19 @@ class Activity extends FlowResource
|
|
|
158
169
|
/**
|
|
159
170
|
* Determines the next set of activities based on the provided Order.
|
|
160
171
|
*
|
|
161
|
-
* @param Order $order the order to determine the next activities for
|
|
162
|
-
*
|
|
163
172
|
* @return \Illuminate\Support\Collection a collection of the next activities
|
|
164
173
|
*/
|
|
165
|
-
public function getNext(Order $
|
|
174
|
+
public function getNext(Order|Waypoint $context)
|
|
166
175
|
{
|
|
167
|
-
$children = $this->getChildActivities();
|
|
176
|
+
$children = $this->getChildActivities($context);
|
|
168
177
|
$nextActivities = collect();
|
|
169
178
|
|
|
179
|
+
// if context is a waypoint get the waypoint order
|
|
180
|
+
$order = $context;
|
|
181
|
+
if ($context instanceof Waypoint) {
|
|
182
|
+
$order = Order::where('payload_uuid', $context->payload_uuid)->first();
|
|
183
|
+
}
|
|
184
|
+
|
|
170
185
|
foreach ($children as $childActivity) {
|
|
171
186
|
if ($childActivity->passes($order)) {
|
|
172
187
|
$nextActivities->push($childActivity);
|
|
@@ -237,6 +252,9 @@ class Activity extends FlowResource
|
|
|
237
252
|
return $this->complete();
|
|
238
253
|
}
|
|
239
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Checks if this activiy has been completed within the order already.
|
|
257
|
+
*/
|
|
240
258
|
public function isCompleted(Order $order): bool
|
|
241
259
|
{
|
|
242
260
|
return $order->hasCompletedActivity($this);
|