@fleetbase/fleetops-engine 0.6.14 → 0.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/addon/components/customer/orders.js +2 -2
  2. package/addon/components/live-map.hbs +1 -1
  3. package/addon/components/live-map.js +2 -2
  4. package/addon/components/order-config-manager/activity-flow.js +1 -1
  5. package/addon/components/order-config-manager/details.js +18 -2
  6. package/addon/components/order-config-manager.hbs +3 -0
  7. package/addon/components/order-config-manager.js +28 -15
  8. package/addon/components/route-optimization-engine-select-button.hbs +2 -1
  9. package/addon/components/route-optimization-wizard-panel.hbs +24 -0
  10. package/addon/components/route-optimization-wizard-panel.js +46 -0
  11. package/addon/controllers/operations/orders/index/new.js +6 -5
  12. package/addon/controllers/operations/orders/index/view.js +2 -2
  13. package/addon/controllers/operations/orders/index.js +26 -1
  14. package/addon/controllers/operations/routes/index/new.js +36 -0
  15. package/addon/controllers/operations/routes/index/view.js +3 -0
  16. package/addon/controllers/operations/routes/index.js +13 -0
  17. package/addon/controllers/settings/routing.js +25 -3
  18. package/addon/engine.js +6 -5
  19. package/addon/routes/operations/routes/index/new.js +9 -0
  20. package/addon/routes/operations/routes/index/view.js +3 -0
  21. package/addon/routes/operations/routes/index.js +3 -0
  22. package/addon/routes/operations/routes.js +3 -0
  23. package/addon/routes.js +6 -0
  24. package/addon/services/leaflet-routing-control.js +64 -0
  25. package/addon/services/osrm.js +1 -1
  26. package/addon/templates/operations/order-config.hbs +2 -1
  27. package/addon/templates/operations/routes/index/new.hbs +2 -0
  28. package/addon/templates/operations/routes/index/view.hbs +1 -0
  29. package/addon/templates/operations/routes/index.hbs +13 -0
  30. package/addon/templates/operations/routes.hbs +1 -0
  31. package/addon/templates/settings/routing.hbs +15 -1
  32. package/app/components/route-optimization-wizard-panel.js +1 -0
  33. package/app/controllers/operations/routes/index/new.js +1 -0
  34. package/app/controllers/operations/routes/index/view.js +1 -0
  35. package/app/routes/operations/routes/index/new.js +1 -0
  36. package/app/routes/operations/routes/index/view.js +1 -0
  37. package/app/routes/operations/routes/index.js +1 -0
  38. package/app/routes/operations/routes.js +1 -0
  39. package/app/services/leaflet-routing-control.js +1 -0
  40. package/app/templates/operations/routes/index/new.js +1 -0
  41. package/app/templates/operations/routes/index/view.js +1 -0
  42. package/app/templates/operations/routes/index.js +1 -0
  43. package/app/templates/operations/routes.js +1 -0
  44. package/composer.json +1 -1
  45. package/extension.json +1 -1
  46. package/package.json +1 -1
  47. package/server/src/Http/Controllers/Internal/v1/OrderConfigController.php +3 -1
  48. package/server/src/Http/Controllers/Internal/v1/SettingController.php +8 -2
  49. package/server/src/Http/Filter/OrderFilter.php +5 -0
  50. package/server/src/Http/Requests/CreateDriverRequest.php +1 -1
  51. package/server/src/Listeners/NotifyOrderEvent.php +1 -1
  52. package/server/src/routes.php +40 -40
  53. package/translations/en-us.yaml +1 -0
@@ -25,7 +25,7 @@ export default class CustomerOrdersComponent extends Component {
25
25
  @service modalsManager;
26
26
  @service customerSession;
27
27
  @service hostRouter;
28
- @service leafletRouterControl;
28
+ @service leafletRoutingControl;
29
29
  @engineService('@fleetbase/fleetops-engine') movementTracker;
30
30
  @engineService('@fleetbase/fleetops-engine') location;
31
31
  @tracked orders = [];
@@ -240,7 +240,7 @@ export default class CustomerOrdersComponent extends Component {
240
240
  }
241
241
 
242
242
  const routingService = this.currentUser.getOption('routing', { router: 'osrm' }).router;
243
- const { router, formatter } = this.leafletRouterControl.get(routingService);
243
+ const { router, formatter } = this.leafletRoutingControl.get(routingService);
244
244
 
245
245
  this.routeControl = new RoutingControl({
246
246
  router,
@@ -243,7 +243,7 @@
243
243
  {{/if}}
244
244
  </div>
245
245
 
246
- {{#if this.isDataLoaded}}
246
+ {{#if (and this.isDataLoaded (not-eq @drawerTab false))}}
247
247
  <LiveMapDrawer
248
248
  @tab={{@drawerTab}}
249
249
  @onTabChanged={{@onDrawerTabChanged}}
@@ -36,7 +36,7 @@ export default class LiveMapComponent extends Component {
36
36
  @service contextPanel;
37
37
  @service leafletMapManager;
38
38
  @service leafletContextmenuManager;
39
- @service leafletRouterControl;
39
+ @service leafletRoutingControl;
40
40
  @service theme;
41
41
 
42
42
  /**
@@ -1140,7 +1140,7 @@ export default class LiveMapComponent extends Component {
1140
1140
  }
1141
1141
 
1142
1142
  const routingService = this.currentUser.getOption('routing', { router: 'osrm' }).router;
1143
- const { router, formatter } = this.leafletRouterControl.get(routingService);
1143
+ const { router, formatter } = this.leafletRoutingControl.get(routingService);
1144
1144
 
1145
1145
  this.routeControl = new RoutingControl({
1146
1146
  router,
@@ -435,7 +435,7 @@ export default class OrderConfigManagerActivityFlowComponent extends Component {
435
435
  * Initializes the activity flow by either loading from configuration or creating a default flow.
436
436
  */
437
437
  initializeActivityFlow() {
438
- const hasFlow = Object.keys(this.config.flow).length > 0;
438
+ const hasFlow = this.config && Object.keys(this.config.flow).length > 0;
439
439
  if (hasFlow) {
440
440
  this.deserializeFlow(this.config.flow);
441
441
  this.initializeContext();
@@ -29,9 +29,13 @@ export default class OrderConfigManagerDetailsComponent extends Component {
29
29
  * @param {Object} owner - The owner of the component.
30
30
  * @param {Object} args - The arguments passed to the component, including the configuration.
31
31
  */
32
- constructor(owner, { config }) {
32
+ constructor(owner, { config, configManagerContext }) {
33
33
  super(...arguments);
34
34
  this.config = config;
35
+
36
+ configManagerContext.on('onConfigChanged', (newConfig) => {
37
+ this.changeConfig(newConfig);
38
+ });
35
39
  }
36
40
 
37
41
  /**
@@ -87,11 +91,23 @@ export default class OrderConfigManagerDetailsComponent extends Component {
87
91
  @task *deleteConfig() {
88
92
  try {
89
93
  yield this.config.destroyRecord();
94
+ this.notifications.success(`Order config ${this.config.name} was deleted.`);
95
+
90
96
  if (typeof this.args.onConfigDeleted === 'function') {
91
- this.args.onConfigDeleted(this.config);
97
+ this.args.onConfigDeleted();
92
98
  }
93
99
  } catch (error) {
94
100
  this.notifications.serverError(error);
95
101
  }
96
102
  }
103
+
104
+ /**
105
+ * Handle change of config.
106
+ *
107
+ * @param {OrderConfigModel} newConfig
108
+ * @memberof OrderConfigManagerDetailsComponent
109
+ */
110
+ changeConfig(newConfig) {
111
+ this.config = newConfig;
112
+ }
97
113
  }
@@ -20,6 +20,7 @@
20
20
  this.tab.component
21
21
  configManagerContext=this.configManagerContext
22
22
  config=this.currentConfig
23
+ allConfigs=this.configs
23
24
  context=this.context
24
25
  contextModel=this.contextModel
25
26
  tabOptions=this.tab
@@ -31,5 +32,7 @@
31
32
  )
32
33
  onTabChanged=this.onTabChanged
33
34
  onClickCreateOrderConfig=this.createNewOrderConfig
35
+ childTaskRunning=this.childTaskRunning
36
+ configManagerContext=this.configManagerContext
34
37
  )
35
38
  }}
@@ -31,6 +31,7 @@ export default class OrderConfigManagerComponent extends Component {
31
31
  @tracked context;
32
32
  @tracked contextModel;
33
33
  @tracked ready = false;
34
+ @tracked childTaskRunning = false;
34
35
 
35
36
  /**
36
37
  * Returns the array of tabs available for the panel.
@@ -62,11 +63,36 @@ export default class OrderConfigManagerComponent extends Component {
62
63
 
63
64
  this.context = context;
64
65
  this.contextModel = contextModel;
65
- this.configManagerContext = configManagerContext.create();
66
+ this.configManagerContext = this.#createManagerContext();
66
67
  this.tab = findActiveTab(this.tabs, tab);
67
68
  this.loadOrderConfigs.perform();
68
69
  }
69
70
 
71
+ /**
72
+ * Creates a contextual object for the order config manager.
73
+ */
74
+ #createManagerContext() {
75
+ const component = this;
76
+ const ctxmc = configManagerContext.create();
77
+ ctxmc.loadOrderConfigs = component.loadOrderConfigs;
78
+ ctxmc.createNewOrderConfig = component.createNewOrderConfig;
79
+ ctxmc.selectConfig = component.selectConfig;
80
+ ctxmc.unready = function () {
81
+ component.ready = false;
82
+ };
83
+ ctxmc.ready = function () {
84
+ component.ready = true;
85
+ };
86
+ ctxmc.childTaskStarted = function () {
87
+ component.childTaskRunning = true;
88
+ };
89
+ ctxmc.childTaskEnded = function () {
90
+ component.childTaskRunning = false;
91
+ };
92
+
93
+ return ctxmc;
94
+ }
95
+
70
96
  /**
71
97
  * Loads all available order configs asynchronously.
72
98
  *
@@ -81,20 +107,8 @@ export default class OrderConfigManagerComponent extends Component {
81
107
  this.configs = yield this.store.findAll('order-config').then(Array.from);
82
108
 
83
109
  let currentConfig;
84
- let initialOrderConfig = this.args.orderConfig;
85
110
  if (isArray(this.configs) && this.configs.length > 0) {
86
- if (initialOrderConfig) {
87
- currentConfig = this.configs.find((config) => {
88
- if (isModel(initialOrderConfig)) {
89
- return config.id === initialOrderConfig.id;
90
- }
91
-
92
- if (typeof initialOrderConfig === 'string') {
93
- return config.id === initialOrderConfig;
94
- }
95
- });
96
- }
97
-
111
+ currentConfig = this.configs.find((_) => _.key === 'transport');
98
112
  if (!currentConfig) {
99
113
  currentConfig = this.configs[0];
100
114
  }
@@ -208,7 +222,6 @@ export default class OrderConfigManagerComponent extends Component {
208
222
  * in 'contextComponentCallback'.
209
223
  */
210
224
  @action onConfigDeleting() {
211
- this.selectConfig(null);
212
225
  this.configManagerContext.trigger('onConfigDeleting');
213
226
  contextComponentCallback(this, 'onConfigDeleting', ...arguments);
214
227
  }
@@ -15,7 +15,8 @@
15
15
  <div class="px-1">
16
16
  {{#each this.routeOptimization.availableServices as |service|}}
17
17
  <a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.handleClick service)}}>
18
- <div >
18
+ <div class="flex flex-row items-center">
19
+ <div class="mr-2"><FaIcon @icon="arrow-right" /></div>
19
20
  <div class="text-sm">{{service.name}}</div>
20
21
  </div>
21
22
  </a>
@@ -0,0 +1,24 @@
1
+ <Overlay
2
+ @isOpen={{true}}
3
+ @onLoad={{this.setOverlayContext}}
4
+ @position="right"
5
+ @noBackdrop={{true}}
6
+ @fullHeight={{true}}
7
+ @isResizeble={{true}}
8
+ @width="450px"
9
+ @overlayClass="route-optimization-wizard-panel"
10
+ >
11
+ <Overlay::Header @title="New Route Optimization">
12
+ <div class="flex flex-1 justify-end">
13
+ <Button @icon="play" @type="primary" @text="Run" @wrapperClass="mr-2" />
14
+ <Button @type="default" @icon="times" />
15
+ </div>
16
+ </Overlay::Header>
17
+
18
+ <Overlay::Body @wrapperClass="px-4 space-y-4 pt-4">
19
+ {{#each @waypoints as |waypoint|}}
20
+ <div class="border rounded p-4 flex items-center mb-3">{{waypoint.address}}</div>
21
+ {{/each}}
22
+ <Spacer @height="300px" />
23
+ </Overlay::Body>
24
+ </Overlay>
@@ -0,0 +1,46 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+ import { inject as service } from '@ember/service';
5
+ import contextComponentCallback from '@fleetbase/ember-core/utils/context-component-callback';
6
+ import applyContextComponentArguments from '@fleetbase/ember-core/utils/apply-context-component-arguments';
7
+
8
+ export default class RouteOptimizationWizardPanelComponent extends Component {
9
+ @service universe;
10
+ @tracked context;
11
+
12
+ /**
13
+ * Constructs the component and applies initial state.
14
+ */
15
+ constructor(owner, { controller }) {
16
+ super(...arguments);
17
+ this.controller = controller;
18
+ applyContextComponentArguments(this);
19
+ }
20
+
21
+ /**
22
+ * Sets the overlay context.
23
+ *
24
+ * @action
25
+ * @param {OverlayContextObject} overlayContext
26
+ */
27
+ @action setOverlayContext(overlayContext) {
28
+ this.context = overlayContext;
29
+ // hide sidebar
30
+ if (this.universe.sidebarContext) {
31
+ this.universe.sidebarContext.hide();
32
+ }
33
+ contextComponentCallback(this, 'onLoad', ...arguments);
34
+ }
35
+
36
+ /**
37
+ * Handles the cancel action.
38
+ *
39
+ * @method
40
+ * @action
41
+ * @returns {Boolean} Indicates whether the cancel action was overridden.
42
+ */
43
+ @action onPressCancel() {
44
+ return contextComponentCallback(this, 'onPressCancel');
45
+ }
46
+ }
@@ -41,7 +41,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
41
41
  @service contextPanel;
42
42
  @service universe;
43
43
  @service routeOptimization;
44
- @service leafletRouterControl;
44
+ @service leafletRoutingControl;
45
45
  @service osrm;
46
46
 
47
47
  @tracked order = this.store.createRecord('order', { meta: [] });
@@ -613,7 +613,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
613
613
  return route;
614
614
  }
615
615
 
616
- @action setOptimizedRoute(route, trip, waypoints) {
616
+ @action setOptimizedRoute(route, trip, waypoints, engine = 'osrm') {
617
617
  let summary = { totalDistance: trip.distance, totalTime: trip.duration };
618
618
  let payload = {
619
619
  optimized: true,
@@ -621,6 +621,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
621
621
  waypoints,
622
622
  trip,
623
623
  summary,
624
+ engine,
624
625
  };
625
626
 
626
627
  this.leafletOptimizedRoute = payload;
@@ -792,7 +793,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
792
793
 
793
794
  if (canPreviewRoute) {
794
795
  const routingService = this.currentUser.getOption('routing', { router: 'osrm' }).router;
795
- const { router, formatter } = this.leafletRouterControl.get(routingService);
796
+ const { router, formatter } = this.leafletRoutingControl.get(routingService);
796
797
 
797
798
  this.previewRouteControl = new RoutingControl({
798
799
  router,
@@ -886,7 +887,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
886
887
  }
887
888
  }
888
889
 
889
- handleRouteOptimization({ sortedWaypoints, route, trip, result }) {
890
+ handleRouteOptimization({ sortedWaypoints, route, trip, result, engine = 'osrm' }) {
890
891
  // Update map layers & UI
891
892
  this.removeRoutingControlPreview();
892
893
  this.removeOptimizedRoute(this.leafletMap);
@@ -895,7 +896,7 @@ export default class OperationsOrdersIndexNewController extends BaseController {
895
896
  // Update controller state
896
897
  this.waypoints = sortedWaypoints;
897
898
  if (route) {
898
- this.setOptimizedRoute(route, trip, result.waypoints);
899
+ this.setOptimizedRoute(route, trip, result.waypoints, engine);
899
900
  }
900
901
  this.previewDraftOrderRoute(this.payload, this.waypoints, this.isMultipleDropoffOrder);
901
902
  this.updatePayloadCoordinates();
@@ -23,7 +23,7 @@ export default class OperationsOrdersIndexViewController extends BaseController
23
23
  @service socket;
24
24
  @service universe;
25
25
  @service contextPanel;
26
- @service leafletRouterControl;
26
+ @service leafletRoutingControl;
27
27
 
28
28
  @tracked isLoadingAdditionalData = false;
29
29
  @tracked isWaypointsCollapsed;
@@ -383,7 +383,7 @@ export default class OperationsOrdersIndexViewController extends BaseController
383
383
  leafletMap.flyTo(waypoints.firstObject);
384
384
 
385
385
  const routingService = this.currentUser.getOption('routing', { router: 'osrm' }).router;
386
- const { router, formatter } = this.leafletRouterControl.get(routingService);
386
+ const { router, formatter } = this.leafletRoutingControl.get(routingService);
387
387
 
388
388
  this.routeControl = new RoutingControl({
389
389
  router,
@@ -22,6 +22,7 @@ export default class OperationsOrdersIndexController extends BaseController {
22
22
  @service socket;
23
23
  @service abilities;
24
24
  @service theme;
25
+ @service routeOptimization;
25
26
 
26
27
  /**
27
28
  * Queryable parameters for this controller's model
@@ -1130,7 +1131,6 @@ export default class OperationsOrdersIndexController extends BaseController {
1130
1131
  */
1131
1132
  @action bulkAssignDriver(selected = []) {
1132
1133
  selected = selected.length > 0 ? selected : this.table.selectedRows;
1133
-
1134
1134
  if (!isArray(selected) || selected.length === 0) {
1135
1135
  return;
1136
1136
  }
@@ -1199,12 +1199,37 @@ export default class OperationsOrdersIndexController extends BaseController {
1199
1199
  });
1200
1200
  }
1201
1201
 
1202
+ /**
1203
+ * Commits the bulk query to the server for results.
1204
+ * @action
1205
+ * @memberof OperationsOrdersIndexController
1206
+ */
1202
1207
  @action commitBulkQuery() {
1203
1208
  this.bulk_query = this.bulkSearchValue;
1204
1209
  }
1205
1210
 
1211
+ /**
1212
+ * Resets/clear the bulk query search.
1213
+ * @action
1214
+ * @memberof OperationsOrdersIndexController
1215
+ */
1206
1216
  @action removeBulkQuery() {
1207
1217
  this.bulkSearchValue = '';
1208
1218
  this.bulk_query = null;
1209
1219
  }
1220
+
1221
+ /**
1222
+ * Run route optimization wizard.
1223
+ * @action
1224
+ * @memberof OperationsOrdersIndexController
1225
+ */
1226
+ @action optimizeOrderRoutes(selected = []) {
1227
+ selected = selected.length > 0 ? selected : this.table.selectedRows;
1228
+
1229
+ return this.hostRouter.transitionTo('console.fleet-ops.operations.routes.index.new', {
1230
+ queryParams: {
1231
+ selectedOrders: selected.map((_) => _.public_id).join(','),
1232
+ },
1233
+ });
1234
+ }
1210
1235
  }
@@ -0,0 +1,36 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { inject as service } from '@ember/service';
4
+ import { action } from '@ember/object';
5
+ import { task } from 'ember-concurrency';
6
+
7
+ export default class OperationsRoutesIndexNewController extends Controller {
8
+ @service store;
9
+ @tracked panel;
10
+ @tracked selectedOrders = '';
11
+ @tracked waypoints = [];
12
+
13
+ @action setOverlayPanelContext(overlayPanelContext) {
14
+ this.panel = overlayPanelContext;
15
+ this.loadSelectedOrders.perform(this.selectedOrders.split(','));
16
+ }
17
+
18
+ @task *loadSelectedOrders(selectedOrders) {
19
+ const orders = yield this.store.query('order', { only: selectedOrders });
20
+ console.log('[orders]', orders);
21
+ this.extractWaypoints(orders);
22
+ }
23
+
24
+ extractWaypoints(orders = []) {
25
+ const extracted = [];
26
+
27
+ orders.forEach((order) => {
28
+ const pickup = order.get('payload.pickup');
29
+ const dropoff = order.get('payload.dropoff');
30
+ const waypoints = order.get('payload.waypoints')?.toArray() ?? [];
31
+ extracted.push(pickup, dropoff, ...waypoints);
32
+ });
33
+
34
+ this.waypoints = extracted.filter(Boolean);
35
+ }
36
+ }
@@ -0,0 +1,3 @@
1
+ import Controller from '@ember/controller';
2
+
3
+ export default class OperationsRoutesIndexViewController extends Controller {}
@@ -0,0 +1,13 @@
1
+ import Controller from '@ember/controller';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+
5
+ export default class OperationsRoutesIndexController extends Controller {
6
+ @tracked leafletMap;
7
+ @tracked liveMap;
8
+
9
+ @action setMapReference({ target }) {
10
+ this.leafletMap = target;
11
+ this.liveMap = target.liveMap;
12
+ }
13
+ }
@@ -7,8 +7,14 @@ export default class SettingsRoutingController extends Controller {
7
7
  @service fetch;
8
8
  @service notifications;
9
9
  @service currentUser;
10
- @service leafletRouterControl;
10
+ @service leafletRoutingControl;
11
11
  @tracked routerService = 'osrm';
12
+ @tracked routingUnit = 'km';
13
+ @tracked routingUnitOptions = [
14
+ { label: 'Kilometers', value: 'km' },
15
+ { label: 'Miles', value: 'mi' },
16
+ ];
17
+ @tracked saveTasks = [];
12
18
 
13
19
  constructor() {
14
20
  super(...arguments);
@@ -23,8 +29,9 @@ export default class SettingsRoutingController extends Controller {
23
29
  @task *saveSettings() {
24
30
  try {
25
31
  yield this.fetch.post('fleet-ops/settings/routing-settings', { router: this.routerService });
32
+ yield this.performAdditionalSaveTasks();
26
33
  // Save in local memory too
27
- this.currentUser.setOption('routing', { router: this.routerService });
34
+ this.currentUser.setOption('routing', { router: this.routerService, unit: this.routingUnit });
28
35
  this.notifications.success('Routing setting saved.');
29
36
  } catch (error) {
30
37
  this.notifications.serverError(error);
@@ -38,10 +45,25 @@ export default class SettingsRoutingController extends Controller {
38
45
  */
39
46
  @task *getSettings() {
40
47
  try {
41
- const { router } = yield this.fetch.get('fleet-ops/settings/routing-settings');
48
+ const { router, unit } = yield this.fetch.get('fleet-ops/settings/routing-settings');
42
49
  this.routerService = router;
50
+ this.routingUnit = unit;
43
51
  } catch (error) {
44
52
  this.notifications.serverError(error);
45
53
  }
46
54
  }
55
+
56
+ registerSaveTask(task) {
57
+ this.saveTasks.push(task);
58
+ }
59
+
60
+ async performAdditionalSaveTasks() {
61
+ for (let i = 0; i < this.saveTasks.length; i++) {
62
+ const task = this.saveTasks[i];
63
+ if (typeof task.perform === 'function') {
64
+ await task.perform();
65
+ }
66
+ }
67
+ return true;
68
+ }
47
69
  }
package/addon/engine.js CHANGED
@@ -9,7 +9,7 @@ import AdminAvatarManagementComponent from './components/admin/avatar-management
9
9
  import CustomerOrdersComponent from './components/customer/orders';
10
10
  import CustomerAdminSettingsComponent from './components/customer/admin-settings';
11
11
  import OrderTrackingLookupComponent from './components/order-tracking-lookup';
12
- import { RouterControl } from './services/leaflet-router-control';
12
+ import { RoutingControl } from './services/leaflet-routing-control';
13
13
  import { OSRMv1 } from '@fleetbase/leaflet-routing-machine';
14
14
  import getRoutingHost from '@fleetbase/ember-core/utils/get-routing-host';
15
15
 
@@ -68,12 +68,12 @@ export default class FleetOpsEngine extends Engine {
68
68
  }
69
69
 
70
70
  // Register OSRM as Routing Controler
71
- const leafletRouterControl = app.lookup('service:leaflet-router-control');
72
- if (leafletRouterControl) {
71
+ const leafletRoutingControl = app.lookup('service:leaflet-routing-control');
72
+ if (leafletRoutingControl) {
73
73
  const routingHost = getRoutingHost();
74
- leafletRouterControl.register(
74
+ leafletRoutingControl.register(
75
75
  'osrm',
76
- new RouterControl({
76
+ new RoutingControl({
77
77
  name: 'OSRM',
78
78
  router: new OSRMv1({
79
79
  serviceUrl: `${routingHost}/route/v1`,
@@ -133,6 +133,7 @@ export default class FleetOpsEngine extends Engine {
133
133
  'fleet-ops:template:operations:orders:new',
134
134
  'fleet-ops:template:operations:orders:new:entities-input',
135
135
  'fleet-ops:template:operations:orders:new:entities-input:entity',
136
+ 'fleet-ops:template:settings:routing',
136
137
  ]);
137
138
 
138
139
  universe.afterBoot(function (universe) {
@@ -0,0 +1,9 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class OperationsRoutesIndexNewRoute extends Route {
4
+ queryParams = {
5
+ selectedOrders: {
6
+ refreshModel: false,
7
+ },
8
+ };
9
+ }
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class OperationsRoutesIndexViewRoute extends Route {}
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class OperationsRoutesIndexRoute extends Route {}
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class OperationsRoutesRoute extends Route {}
package/addon/routes.js CHANGED
@@ -31,6 +31,12 @@ export default buildRoutes(function () {
31
31
  });
32
32
  });
33
33
  });
34
+ this.route('routes', function () {
35
+ this.route('index', { path: '/' }, function () {
36
+ this.route('new');
37
+ this.route('view', { path: '/:public_id' });
38
+ });
39
+ });
34
40
  });
35
41
  this.route('management', { path: '/manage' }, function () {
36
42
  this.route('fleets', function () {
@@ -0,0 +1,64 @@
1
+ import Service, { inject as service } from '@ember/service';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { underscore } from '@ember/string';
4
+
5
+ export class RoutingControlRegistry {
6
+ @tracked routers = {};
7
+ }
8
+
9
+ export class RoutingControl {
10
+ @tracked name;
11
+ @tracked router;
12
+ @tracked formatter;
13
+
14
+ constructor(init) {
15
+ const { name, router, formatter } = typeof init === 'function' ? init() : init;
16
+ this.name = name;
17
+ this.router = router;
18
+ this.formatter = formatter;
19
+ }
20
+ }
21
+
22
+ export default class LeafletRoutingControlService extends Service {
23
+ @service universe;
24
+ registry = this.#initializeRegistry();
25
+
26
+ get availableEngines() {
27
+ return Object.keys(this.registry.routers).map(underscore);
28
+ }
29
+
30
+ get availableServices() {
31
+ return Object.entries(this.registry.routers).map(([key, control]) => ({
32
+ key,
33
+ name: control.name ?? key,
34
+ }));
35
+ }
36
+
37
+ register(name, getter) {
38
+ this.registry.routers = {
39
+ ...this.registry.routers,
40
+ [underscore(name)]: getter,
41
+ };
42
+ }
43
+
44
+ /* eslint-disable no-unused-vars */
45
+ unregister(name) {
46
+ let key = underscore(name);
47
+ let { [key]: _, ...rest } = this.registry.routers;
48
+ this.registry.routers = rest;
49
+ }
50
+
51
+ get(name) {
52
+ return this.registry.routers[underscore(name)];
53
+ }
54
+
55
+ #initializeRegistry() {
56
+ const registry = 'registry:routing-controls';
57
+ const application = this.universe.getApplicationInstance();
58
+ if (!application.hasRegistration(registry)) {
59
+ application.register(registry, new RoutingControlRegistry(), { instantiate: false });
60
+ }
61
+
62
+ return application.resolveRegistration(registry);
63
+ }
64
+ }
@@ -37,7 +37,7 @@ export default class OsrmService extends RouteOptimizationInterfaceService {
37
37
  const trip = result.trips?.[0];
38
38
  const route = polyline.decode(trip.geometry);
39
39
 
40
- return { sortedWaypoints, trip, route, result };
40
+ return { sortedWaypoints, trip, route, result, engine: 'osrm' };
41
41
  } catch (err) {
42
42
  debug(`[OSRM] Error routing trip : ${err.message}`);
43
43
  throw err;
@@ -82,10 +82,11 @@
82
82
  <div class="flex flex-col items-center justify-center h-40">
83
83
  <h4 class="text-lg text-gray-400 mb-4">{{t "fleet-ops.component.order-config-manager.select-order-config-to-start"}}</h4>
84
84
  <Button
85
- @type="link"
85
+ @type="primary"
86
86
  @text={{t "fleet-ops.component.order-config-manager.new-order-config"}}
87
87
  @onClick={{Context.onClickCreateOrderConfig}}
88
88
  @permission="fleet-ops create order-config"
89
+ @icon="plus"
89
90
  class="text-blue-400"
90
91
  />
91
92
  </div>
@@ -0,0 +1,2 @@
1
+ <RouteOptimizationWizardPanel @waypoints={{this.waypoints}} @controller={{this}} @onLoad={{this.setOverlayPanelContext}} />
2
+ {{outlet}}
@@ -0,0 +1 @@
1
+ {{outlet}}
@@ -0,0 +1,13 @@
1
+ <LiveMap
2
+ id="leafletMap"
3
+ class="next-leaflet-container-map"
4
+ @lat={{1.3521}}
5
+ @lng={{103.8198}}
6
+ @zoom={{12}}
7
+ @zoomControl={{false}}
8
+ @drawerTab={{false}}
9
+ @onLoad={{this.setMapReference}}
10
+ @darkMode={{eq this.theme.activeTheme "dark"}}
11
+ {{set-container-dimensions}}
12
+ />
13
+ {{outlet}}
@@ -0,0 +1 @@
1
+ {{outlet}}
@@ -17,7 +17,7 @@
17
17
  <InputGroup @name="Routing Service" @helpText="Select the service which is responsible for calculating and plotting routes on the map.">
18
18
  <Select
19
19
  @value={{this.routerService}}
20
- @options={{this.leafletRouterControl.availableServices}}
20
+ @options={{this.leafletRoutingControl.availableServices}}
21
21
  @optionLabel="name"
22
22
  @optionValue="key"
23
23
  @onSelect={{fn (mut this.routerService)}}
@@ -25,7 +25,21 @@
25
25
  class="w-full"
26
26
  />
27
27
  </InputGroup>
28
+ <InputGroup @name="Routing Distance Unit" @helpText="The unit used for calculating distance and routes.">
29
+ <Select
30
+ @value={{this.routingUnit}}
31
+ @options={{this.routingUnitOptions}}
32
+ @optionLabel="label"
33
+ @optionValue="value"
34
+ @onSelect={{fn (mut this.routingUnit)}}
35
+ @placeholder="Select routing unit..."
36
+ class="w-full"
37
+ />
38
+ </InputGroup>
28
39
  </ContentPanel>
40
+ <RegistryYield @registry="fleet-ops:template:settings:routing" as |RegistryComponent|>
41
+ <RegistryComponent @controller={{this}} />
42
+ </RegistryYield>
29
43
  </div>
30
44
  </div>
31
45
  <Spacer @height="600px" />
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/components/route-optimization-wizard-panel';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/operations/routes/index/new';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/controllers/operations/routes/index/view';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/routes/index/new';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/routes/index/view';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/routes/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/routes/operations/routes';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/services/leaflet-routing-control';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/operations/routes/index/new';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/operations/routes/index/view';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/operations/routes/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/fleetops-engine/templates/operations/routes';
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/fleetops-api",
3
- "version": "0.6.14",
3
+ "version": "0.6.16",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Fleet-Ops",
3
- "version": "0.6.14",
3
+ "version": "0.6.16",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/fleetops",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/fleetops-engine",
3
- "version": "0.6.14",
3
+ "version": "0.6.16",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "fleet-ops"
@@ -61,7 +61,7 @@ class OrderConfigController extends FleetOpsController
61
61
  }
62
62
 
63
63
  // `core_service` order configs cannot be deleted
64
- if ($orderConfig->core_service) {
64
+ if ($orderConfig->core_service === 1) {
65
65
  return response()->error('Core service order config\'s cannot be deleted.');
66
66
  }
67
67
 
@@ -72,5 +72,7 @@ class OrderConfigController extends FleetOpsController
72
72
 
73
73
  return new $this->resource($orderConfig);
74
74
  }
75
+
76
+ return response()->error('Unable to delete order config.');
75
77
  }
76
78
  }
@@ -185,7 +185,8 @@ class SettingController extends Controller
185
185
  public function saveRoutingSettings(Request $request)
186
186
  {
187
187
  $router = $request->input('router');
188
- Setting::configureCompany('routing', ['router' => $router]);
188
+ $unit = $request->input('unit', 'km');
189
+ Setting::configureCompany('routing', ['router' => $router, 'unit' => $unit]);
189
190
 
190
191
  return response()->json([
191
192
  'status' => 'ok',
@@ -200,7 +201,12 @@ class SettingController extends Controller
200
201
  */
201
202
  public function getRoutingSettings()
202
203
  {
203
- $routingSettings = Setting::lookupCompany('routing', ['router' => 'osrm']);
204
+ $routingSettings = Setting::lookupCompany('routing', ['router' => 'osrm', 'unit' => 'km']);
205
+
206
+ // always default to km if no unit is set
207
+ if (!isset($routingSettings['unit'])) {
208
+ $routingSettings['unit'] = 'km';
209
+ }
204
210
 
205
211
  return response()->json($routingSettings);
206
212
  }
@@ -173,6 +173,11 @@ class OrderFilter extends Filter
173
173
  }
174
174
  }
175
175
 
176
+ public function only($ids)
177
+ {
178
+ $this->builder->whereIn('public_id', $ids);
179
+ }
180
+
176
181
  public function pickup(string $pickup)
177
182
  {
178
183
  $this->builder->whereHas(
@@ -34,7 +34,7 @@ class CreateDriverRequest extends FleetbaseRequest
34
34
  'password' => 'nullable|string',
35
35
  'country' => 'nullable|size:2',
36
36
  'city' => 'nullable|string',
37
- 'vehicle' => 'nullable|string|starts_with:vehicle_|exists:drivers,public_id',
37
+ 'vehicle' => 'nullable|string|starts_with:vehicle_|exists:vehicles,public_id',
38
38
  'status' => 'nullable|string|in:active,inactive',
39
39
  'vendor' => 'nullable|exists:vendors,public_id',
40
40
  'job' => 'nullable|exists:orders,public_id',
@@ -34,7 +34,7 @@ class NotifyOrderEvent implements ShouldQueue
34
34
  $reason = $event->activity ? $event->activity->get('details') : '';
35
35
  NotificationRegistry::notify(OrderCanceled::class, $order, $reason, $event->waypoint);
36
36
  }
37
-
37
+
38
38
  if ($event instanceof \Fleetbase\FleetOps\Events\OrderCompleted) {
39
39
  NotificationRegistry::notify(OrderCompleted::class, $order, $event->waypoint);
40
40
  }
@@ -23,7 +23,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
23
23
  */
24
24
  $router->group(['prefix' => 'v1', 'middleware' => ['fleetbase.api', Fleetbase\FleetOps\Http\Middleware\TransformLocationMiddleware::class], 'namespace' => 'Api\v1'], function ($router) {
25
25
  // drivers routes
26
- $router->group(['prefix' => 'drivers', 'middleware' => [Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]], function () use ($router) {
26
+ $router->group(['prefix' => 'drivers', 'middleware' => []], function () use ($router) {
27
27
  $router->post('register-device', 'DriverController@registerDevice');
28
28
  $router->post('login-with-sms', 'DriverController@loginWithPhone');
29
29
  $router->post('verify-code', 'DriverController@verifyCode');
@@ -74,7 +74,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
74
74
  $router->delete('{id}', 'FuelReportController@delete');
75
75
  });
76
76
  // orders routes
77
- $router->group(['prefix' => 'orders', 'middleware' => [Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]], function () use ($router) {
77
+ $router->group(['prefix' => 'orders', 'middleware' => []], function () use ($router) {
78
78
  $router->post('/', 'OrderController@create');
79
79
  $router->get('/', 'OrderController@query');
80
80
  $router->get('{id}', 'OrderController@find');
@@ -251,8 +251,8 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
251
251
  $router->fleetbaseRoutes(
252
252
  'contacts',
253
253
  function ($router, $controller) {
254
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
255
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
254
+ $router->match(['get', 'post'], 'export', $controller('export'));
255
+ $router->post('import', $controller('import'));
256
256
  $router->get('facilitators/{id}', $controller('getAsFacilitator'));
257
257
  $router->get('customers/{id}', $controller('getAsCustomer'));
258
258
  $router->delete('bulk-delete', $controller('bulkDelete'));
@@ -261,11 +261,11 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
261
261
  $router->fleetbaseRoutes(
262
262
  'drivers',
263
263
  function ($router, $controller) {
264
- $router->get('statuses', $controller('statuses'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
265
- $router->get('avatars', $controller('avatars'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
266
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
264
+ $router->get('statuses', $controller('statuses'));
265
+ $router->get('avatars', $controller('avatars'));
266
+ $router->match(['get', 'post'], 'export', $controller('export'));
267
267
  $router->delete('bulk-delete', $controller('bulkDelete'));
268
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
268
+ $router->post('import', $controller('import'));
269
269
  }
270
270
  );
271
271
  $router->fleetbaseRoutes('entities');
@@ -276,31 +276,31 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
276
276
  $router->post('remove-driver', $controller('removeDriver'));
277
277
  $router->post('assign-vehicle', $controller('assignVehicle'));
278
278
  $router->post('remove-vehicle', $controller('removeVehicle'));
279
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
280
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
279
+ $router->match(['get', 'post'], 'export', $controller('export'));
280
+ $router->post('import', $controller('import'));
281
281
  $router->delete('bulk-delete', $controller('bulkDelete'));
282
282
  }
283
283
  );
284
284
  $router->fleetbaseRoutes(
285
285
  'fuel-reports',
286
286
  function ($router, $controller) {
287
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
288
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
287
+ $router->match(['get', 'post'], 'export', $controller('export'));
288
+ $router->post('import', $controller('import'));
289
289
  $router->delete('bulk-delete', $controller('bulkDelete'));
290
290
  }
291
291
  );
292
292
  $router->fleetbaseRoutes(
293
293
  'issues',
294
294
  function ($router, $controller) {
295
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
296
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
295
+ $router->match(['get', 'post'], 'export', $controller('export'));
296
+ $router->post('import', $controller('import'));
297
297
  $router->delete('bulk-delete', $controller('bulkDelete'));
298
298
  }
299
299
  );
300
300
  $router->fleetbaseRoutes(
301
301
  'integrated-vendors',
302
302
  function ($router, $controller) {
303
- $router->get('supported', $controller('getSupported'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
303
+ $router->get('supported', $controller('getSupported'));
304
304
  $router->delete('bulk-delete', $controller('bulkDelete'));
305
305
  }
306
306
  );
@@ -309,12 +309,12 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
309
309
  function ($router, $controller) {
310
310
  $router->get('default-config', $controller('getDefaultOrderConfig'));
311
311
  $router->get('search', $controller('search'));
312
- $router->get('statuses', $controller('statuses'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
312
+ $router->get('statuses', $controller('statuses'));
313
313
  $router->get('types', $controller('types'));
314
314
  $router->get('label/{id}', $controller('label'));
315
- $router->get('next-activity/{id}', $controller('nextActivity'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
316
- $router->get('{id}/tracker', 'OrderController@trackerInfo')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
317
- $router->get('{id}/eta', 'OrderController@waypointEtas')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
315
+ $router->get('next-activity/{id}', $controller('nextActivity'));
316
+ $router->get('{id}/tracker', 'OrderController@trackerInfo');
317
+ $router->get('{id}/eta', 'OrderController@waypointEtas');
318
318
  $router->post('process-imports', $controller('importFromFiles'));
319
319
  $router->patch('route/{id}', $controller('editOrderRoute'));
320
320
  $router->patch('update-activity/{id}', $controller('updateActivity'));
@@ -326,7 +326,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
326
326
  $router->patch('dispatch', $controller('dispatchOrder'));
327
327
  $router->patch('start', $controller('start'));
328
328
  $router->delete('bulk-delete', $controller('bulkDelete'));
329
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
329
+ $router->match(['get', 'post'], 'export', $controller('export'));
330
330
  }
331
331
  );
332
332
  $router->fleetbaseRoutes('order-configs');
@@ -334,12 +334,12 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
334
334
  $router->fleetbaseRoutes(
335
335
  'places',
336
336
  function ($router, $controller) {
337
- $router->get('search', $controller('search'))->middleware(['cache.headers:private;max_age=3600', Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
338
- $router->get('lookup', $controller('geocode'))->middleware(['cache.headers:private;max_age=3600', Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
337
+ $router->get('search', $controller('search'))->middleware(['cache.headers:private;max_age=3600']);
338
+ $router->get('lookup', $controller('geocode'))->middleware(['cache.headers:private;max_age=3600']);
339
339
  $router->get('avatars', $controller('avatars'));
340
340
  $router->match(['get', 'post'], 'export', $controller('export'));
341
341
  $router->delete('bulk-delete', $controller('bulkDelete'));
342
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
342
+ $router->post('import', $controller('import'));
343
343
  }
344
344
  );
345
345
  $router->fleetbaseRoutes('proofs');
@@ -348,7 +348,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
348
348
  $router->fleetbaseRoutes(
349
349
  'service-areas',
350
350
  function ($router, $controller) {
351
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
351
+ $router->match(['get', 'post'], 'export', $controller('export'));
352
352
  $router->delete('bulk-delete', $controller('bulkDelete'));
353
353
  }
354
354
  );
@@ -366,8 +366,8 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
366
366
  function ($router, $controller) {
367
367
  $router->delete('bulk-delete', $controller('bulkDelete'));
368
368
  $router->get('for-route', $controller('getServicesForRoute'));
369
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
370
- $router->get('for-route', $controller('getServicesForRoute'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
369
+ $router->match(['get', 'post'], 'export', $controller('export'));
370
+ $router->get('for-route', $controller('getServicesForRoute'));
371
371
  }
372
372
  );
373
373
  $router->fleetbaseRoutes('tracking-numbers');
@@ -375,10 +375,10 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
375
375
  $router->fleetbaseRoutes(
376
376
  'vehicles',
377
377
  function ($router, $controller) {
378
- $router->get('statuses', $controller('statuses'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
379
- $router->get('avatars', $controller('avatars'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
380
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
381
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
378
+ $router->get('statuses', $controller('statuses'));
379
+ $router->get('avatars', $controller('avatars'));
380
+ $router->match(['get', 'post'], 'export', $controller('export'));
381
+ $router->post('import', $controller('import'));
382
382
  $router->delete('bulk-delete', $controller('bulkDelete'));
383
383
  }
384
384
  );
@@ -386,14 +386,14 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
386
386
  $router->fleetbaseRoutes(
387
387
  'vendors',
388
388
  function ($router, $controller) {
389
- $router->get('statuses', $controller('statuses'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
390
- $router->match(['get', 'post'], 'export', $controller('export'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
389
+ $router->get('statuses', $controller('statuses'));
390
+ $router->match(['get', 'post'], 'export', $controller('export'));
391
391
  $router->get('facilitators/{id}', $controller('getAsFacilitator'));
392
392
  $router->get('customers/{id}', $controller('getAsCustomer'));
393
393
  $router->post('{id}/assign-driver', $controller('assignDriver'));
394
394
  $router->post('{id}/remove-driver', $controller('removeDriver'));
395
395
  $router->delete('bulk-delete', $controller('bulkDelete'));
396
- $router->post('import', $controller('import'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
396
+ $router->post('import', $controller('import'));
397
397
  }
398
398
  );
399
399
  $router->group(
@@ -417,7 +417,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
417
417
  }
418
418
  );
419
419
  $router->group(
420
- ['prefix' => 'geocoder', ['middleware' => [Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]]],
420
+ ['prefix' => 'geocoder', ['middleware' => []]],
421
421
  function ($router) {
422
422
  $router->get('reverse', 'GeocoderController@reverse');
423
423
  $router->get('query', 'GeocoderController@geocode');
@@ -427,12 +427,12 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
427
427
  ['prefix' => 'fleet-ops'],
428
428
  function ($router) {
429
429
  $router->group(
430
- ['prefix' => 'payments', ['middleware' => [Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]]],
430
+ ['prefix' => 'payments', ['middleware' => []]],
431
431
  function () use ($router) {
432
- $router->post('stripe-account', 'PaymentController@getStripeAccount')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
433
- $router->post('stripe-account-session', 'PaymentController@getStripeAccountSession')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
434
- $router->get('has-stripe-connect-account', 'PaymentController@hasStripeConnectAccount')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
435
- $router->get('payments-received', 'PaymentController@getCompanyReceivedPayments')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
432
+ $router->post('stripe-account', 'PaymentController@getStripeAccount');
433
+ $router->post('stripe-account-session', 'PaymentController@getStripeAccountSession');
434
+ $router->get('has-stripe-connect-account', 'PaymentController@hasStripeConnectAccount');
435
+ $router->get('payments-received', 'PaymentController@getCompanyReceivedPayments');
436
436
  }
437
437
  );
438
438
 
@@ -455,7 +455,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
455
455
  }
456
456
  );
457
457
  $router->group(
458
- ['prefix' => 'settings', 'middleware' => [Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]],
458
+ ['prefix' => 'settings', 'middleware' => []],
459
459
  function ($router) {
460
460
  $router->get('customer-payments-config', 'SettingController@getCustomerPortalPaymentConfig');
461
461
  $router->post('customer-payments-config', 'SettingController@saveCustomerPortalPaymentConfig');
@@ -1332,6 +1332,7 @@ fleet-ops:
1332
1332
  delete-orders: Delete Orders
1333
1333
  dispatch-orders: Dispatch Orders
1334
1334
  assign-driver: Assign Driver
1335
+ route-optimization: Route Optimization
1335
1336
  bulk-assign-driver-helptext: Select a driver to assign to multiple orders.
1336
1337
  new:
1337
1338
  create-new-customer: Create new customer