@fleetbase/fleetops-engine 0.6.45 → 0.6.47

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 (148) hide show
  1. package/addon/components/admin/map-settings.hbs +26 -0
  2. package/addon/components/admin/map-settings.js +46 -0
  3. package/addon/components/admin/routing-settings.hbs +11 -0
  4. package/addon/components/cell/order-route-type.hbs +46 -0
  5. package/addon/components/cell/order-route-type.js +90 -0
  6. package/addon/components/cell/place-address.hbs +1 -0
  7. package/addon/components/display-place.hbs +45 -56
  8. package/addon/components/display-place.js +21 -0
  9. package/addon/components/layout/fleet-ops-sidebar/driver-listing.js +5 -5
  10. package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +5 -5
  11. package/addon/components/layout/fleet-ops-sidebar.js +8 -0
  12. package/addon/components/maintenance-schedule/form.js +2 -1
  13. package/addon/components/map/drawer/driver-listing.js +5 -5
  14. package/addon/components/map/drawer/place-listing.js +5 -5
  15. package/addon/components/map/drawer/position-listing.js +102 -21
  16. package/addon/components/map/drawer/vehicle-listing.js +5 -5
  17. package/addon/components/map/google-live-map.hbs +9 -0
  18. package/addon/components/map/google-live-map.js +445 -0
  19. package/addon/components/map/leaflet-live-map.hbs +186 -142
  20. package/addon/components/map/leaflet-live-map.js +121 -41
  21. package/addon/components/map/toolbar/visibility-control-panel.js +2 -2
  22. package/addon/components/map/toolbar/zones-panel.hbs +9 -9
  23. package/addon/components/map/toolbar.hbs +3 -3
  24. package/addon/components/map/toolbar.js +9 -1
  25. package/addon/components/modals/map-layer-form.hbs +132 -63
  26. package/addon/components/modals/orchestrator-import.hbs +4 -11
  27. package/addon/components/modals/orchestrator-import.js +17 -1
  28. package/addon/components/modals/update-order-activity.hbs +1 -1
  29. package/addon/components/orchestrator/order-pool.js +3 -2
  30. package/addon/components/orchestrator-workbench.js +29 -41
  31. package/addon/components/order/details/detail.js +2 -2
  32. package/addon/components/order/details/payload.hbs +5 -5
  33. package/addon/components/order/details/payload.js +18 -1
  34. package/addon/components/order/details/route.hbs +2 -2
  35. package/addon/components/order/details/route.js +76 -3
  36. package/addon/components/order/form/details.hbs +1 -2
  37. package/addon/components/order/form/details.js +6 -0
  38. package/addon/components/order/form/payload.hbs +33 -0
  39. package/addon/components/order/form/payload.js +1 -0
  40. package/addon/components/order/form/route.hbs +8 -8
  41. package/addon/components/order/form/route.js +86 -18
  42. package/addon/components/order/form.js +2 -2
  43. package/addon/components/order/route-editor.hbs +209 -147
  44. package/addon/components/order/route-editor.js +143 -102
  45. package/addon/components/place/address.hbs +1 -0
  46. package/addon/components/place/address.js +12 -0
  47. package/addon/components/route-list.hbs +43 -55
  48. package/addon/components/route-list.js +47 -0
  49. package/addon/components/route-optimization-wizard-panel.js +3 -4
  50. package/addon/components/vehicle/card.hbs +4 -4
  51. package/addon/controllers/maintenance/schedules/index.js +2 -1
  52. package/addon/controllers/operations/orders/index/details.js +110 -37
  53. package/addon/controllers/operations/orders/index/new.js +1 -1
  54. package/addon/controllers/operations/orders/index.js +8 -1
  55. package/addon/controllers/settings/map.js +97 -0
  56. package/addon/controllers/settings/payments/index.js +1 -1
  57. package/addon/controllers/settings/routing.js +47 -12
  58. package/addon/extension.js +11 -0
  59. package/addon/helpers/place-address-html.js +6 -0
  60. package/addon/instance-initializers/register-google-routes.js +17 -0
  61. package/addon/instance-initializers/register-osrm.js +5 -0
  62. package/addon/routes/application.js +6 -0
  63. package/addon/routes/operations/orchestrator.js +13 -0
  64. package/addon/routes/operations/orders/index/details.js +29 -22
  65. package/addon/routes/operations/orders/index/new.js +9 -0
  66. package/addon/routes/operations/orders/index.js +0 -1
  67. package/addon/routes/settings/map.js +3 -0
  68. package/addon/routes.js +1 -0
  69. package/addon/services/entity-actions.js +1 -1
  70. package/addon/services/geofence-event-bus.js +2 -1
  71. package/addon/services/geofence.js +204 -168
  72. package/addon/services/google-routes.js +300 -0
  73. package/addon/services/leaflet-draw-restriction.js +2 -1
  74. package/addon/services/leaflet-map-manager.js +17 -0
  75. package/addon/services/map-adapter/google.js +2205 -0
  76. package/addon/services/map-adapter/leaflet.js +1042 -0
  77. package/addon/services/map-adapter-interface.js +551 -0
  78. package/addon/services/map-manager.js +768 -0
  79. package/addon/services/map-settings.js +75 -0
  80. package/addon/services/movement-tracker.js +83 -32
  81. package/addon/services/order-actions.js +11 -1
  82. package/addon/services/osrm.js +79 -6
  83. package/addon/services/position-playback.js +135 -62
  84. package/addon/services/route-engine.js +83 -0
  85. package/addon/services/service-areas.js +8 -1
  86. package/addon/styles/fleetops-engine.css +555 -0
  87. package/addon/templates/management/vehicles/index.hbs +0 -1
  88. package/addon/templates/operations/orders/index/details.hbs +0 -1
  89. package/addon/templates/settings/map.hbs +53 -0
  90. package/addon/templates/settings/routing.hbs +15 -4
  91. package/addon/utils/fleet-ops-options.js +1 -0
  92. package/addon/utils/has-valid-coordinates.js +6 -0
  93. package/addon/utils/map-provider-options.js +6 -0
  94. package/addon/utils/order-route-editing.js +86 -0
  95. package/addon/utils/order-route-summary.js +20 -0
  96. package/addon/utils/place-address-html.js +41 -0
  97. package/addon/utils/route-colors.js +43 -12
  98. package/addon/utils/route-visualization.js +93 -0
  99. package/addon/utils/vendor-integration.js +2 -1
  100. package/app/components/admin/map-settings.js +1 -0
  101. package/app/components/admin/routing-settings.js +1 -0
  102. package/app/components/cell/order-route-type.js +1 -0
  103. package/app/components/cell/place-address.js +1 -0
  104. package/app/components/map/google-live-map.js +1 -0
  105. package/app/components/place/address.js +1 -0
  106. package/app/controllers/settings/map.js +1 -0
  107. package/app/helpers/place-address-html.js +1 -0
  108. package/app/routes/settings/map.js +1 -0
  109. package/app/services/map-adapter/google.js +1 -0
  110. package/app/services/map-adapter/leaflet.js +1 -0
  111. package/app/services/map-adapter-interface.js +1 -0
  112. package/app/services/map-manager.js +1 -0
  113. package/app/services/map-settings.js +1 -0
  114. package/app/templates/settings/map.js +1 -0
  115. package/app/utils/has-valid-coordinates.js +1 -0
  116. package/app/utils/order-route-editing.js +2 -0
  117. package/app/utils/order-route-summary.js +1 -0
  118. package/app/utils/place-address-html.js +1 -0
  119. package/app/utils/route-colors.js +1 -1
  120. package/app/utils/route-visualization.js +1 -0
  121. package/assets/images/drawing-controls-spritesheet.svg +156 -0
  122. package/composer.json +1 -1
  123. package/extension.json +1 -1
  124. package/package.json +4 -4
  125. package/pnpm-workspace.yaml +7 -0
  126. package/server/src/Auth/Schemas/FleetOps.php +5 -0
  127. package/server/src/Http/Controllers/Api/v1/OrderController.php +31 -3
  128. package/server/src/Http/Controllers/Api/v1/PayloadController.php +14 -1
  129. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -0
  130. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +3 -2
  131. package/server/src/Http/Controllers/Api/v1/ZoneController.php +2 -0
  132. package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
  133. package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +7 -4
  134. package/server/src/Http/Controllers/Internal/v1/OrderController.php +90 -34
  135. package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +3 -2
  136. package/server/src/Http/Controllers/Internal/v1/SettingController.php +106 -3
  137. package/server/src/Http/Filter/OrderFilter.php +2 -1
  138. package/server/src/Http/Resources/v1/Index/Payload.php +9 -7
  139. package/server/src/Http/Resources/v1/Order.php +20 -1
  140. package/server/src/Models/Order.php +42 -1
  141. package/server/src/Models/OrderConfig.php +15 -0
  142. package/server/src/Models/Payload.php +131 -27
  143. package/server/src/Models/Place.php +182 -48
  144. package/server/src/Models/ServiceRate.php +4 -3
  145. package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +59 -23
  146. package/server/src/Support/Utils.php +36 -2
  147. package/server/src/routes.php +4 -0
  148. package/translations/en-us.yaml +1937 -1916
@@ -20,13 +20,16 @@ use Illuminate\Support\Facades\Log;
20
20
  *
21
21
  * Resolution order for configuration:
22
22
  *
23
- * 1. Company-level setting — `Setting::lookupCompany('vroom', 'api_key')`
24
- * (written by the fleetbase/vroom extension settings page, if installed)
25
- * 2. Environment variable — `VROOM_API_KEY`
26
- * 3. No key — requests are sent without an api_key parameter
23
+ * 1. Company-level setting — organization override
24
+ * 2. System-level setting — admin default
25
+ * 3. Environment/config fallback
26
+ * 4. No key — requests are sent without an api_key parameter
27
27
  * (works for self-hosted VROOM instances that do not require auth)
28
28
  *
29
- * Base URI: `config('vroom.base_uri')` → `VROOM_HOST` env → default production URL
29
+ * Base URI and endpoint mode follow the same precedence, with endpoint mode
30
+ * controlling whether requests are posted to `/solve` or directly to the
31
+ * configured binary host.
32
+ *
30
33
  * Timeout: `VROOM_TIMEOUT` env (default 30 s)
31
34
  *
32
35
  * The VROOM HTTP API endpoint used is `POST {base_uri}/solve`, matching the
@@ -101,27 +104,17 @@ class VroomOrchestrationEngine implements OrchestrationEngineInterface
101
104
  unset($job);
102
105
 
103
106
  // ── Resolve connection config ─────────────────────────────────────────
104
- // Base URI: prefer the vroom extension config, then VROOM_HOST env, then
105
- // the production verso-optim.com hosted service.
106
- $baseUri = config('vroom.base_uri', env('VROOM_HOST', 'https://api.verso-optim.com/vrp/v1'));
107
+ $baseUri = $this->resolveVroomBaseUri();
108
+ $endpointMode = $this->resolveVroomEndpointMode();
107
109
  $timeout = (int) env('VROOM_TIMEOUT', 30);
108
110
 
109
- // ── Resolve API key ───────────────────────────────────────────────────
110
- // 1. Company-level setting (written by fleetbase/vroom extension UI)
111
- // 2. VROOM_API_KEY env var
112
- // 3. null — no key appended (for self-hosted instances)
113
- $apiKey = null;
114
- try {
115
- $apiKey = Setting::lookupCompany('vroom', ['api_key' => null])['api_key'] ?? null;
116
- } catch (\Throwable) {
117
- // Setting table may not exist in minimal installs — ignore
118
- }
119
- if (!$apiKey) {
120
- $apiKey = env('VROOM_API_KEY');
121
- }
111
+ $apiKey = $this->resolveVroomApiKey();
122
112
 
123
- // Build the solve URL — append api_key as query param when present
124
- $solveUrl = rtrim($baseUri, '/') . '/solve';
113
+ // Build the solve URL — append api_key as query param when present.
114
+ $solveUrl = rtrim($baseUri, '/');
115
+ if ($endpointMode !== 'binary') {
116
+ $solveUrl .= '/solve';
117
+ }
125
118
  if ($apiKey) {
126
119
  $solveUrl .= '?api_key=' . urlencode($apiKey);
127
120
  }
@@ -189,4 +182,47 @@ class VroomOrchestrationEngine implements OrchestrationEngineInterface
189
182
  'summary' => $vroomResult['summary'] ?? [],
190
183
  ];
191
184
  }
185
+
186
+ protected function resolveVroomBaseUri(): string
187
+ {
188
+ return $this->resolveVroomSetting('api_host', config('vroom.base_uri', env('VROOM_HOST', 'https://api.verso-optim.com/vrp/v1')));
189
+ }
190
+
191
+ protected function resolveVroomApiKey(): ?string
192
+ {
193
+ return $this->resolveVroomSetting('api_key', env('VROOM_API_KEY'));
194
+ }
195
+
196
+ protected function resolveVroomEndpointMode(): string
197
+ {
198
+ return $this->resolveVroomSetting('endpoint_mode', config('vroom.endpoint_mode', env('VROOM_ENDPOINT_MODE', 'saas')));
199
+ }
200
+
201
+ protected function resolveVroomSetting(string $key, $default = null)
202
+ {
203
+ try {
204
+ $organizationValue = data_get(Setting::lookupCompany('vroom', []), $key);
205
+ if ($this->hasConfiguredValue($organizationValue)) {
206
+ return $organizationValue;
207
+ }
208
+
209
+ $systemValue = data_get(Setting::lookup('vroom', []), $key);
210
+ if ($this->hasConfiguredValue($systemValue)) {
211
+ return $systemValue;
212
+ }
213
+ } catch (\Throwable) {
214
+ // Setting table may not exist in minimal installs — ignore
215
+ }
216
+
217
+ return $default;
218
+ }
219
+
220
+ protected function hasConfiguredValue($value): bool
221
+ {
222
+ if (is_string($value)) {
223
+ return trim($value) !== '';
224
+ }
225
+
226
+ return $value !== null;
227
+ }
192
228
  }
@@ -3,9 +3,9 @@
3
3
  namespace Fleetbase\FleetOps\Support;
4
4
 
5
5
  use Fleetbase\FleetOps\Flow\Activity;
6
+ use Fleetbase\LaravelMysqlSpatial\Types\Point;
6
7
  use Fleetbase\Models\Company;
7
8
  use Fleetbase\Models\Setting;
8
- use Fleetbase\LaravelMysqlSpatial\Types\Point;
9
9
  use Fleetbase\Support\Utils as FleetbaseUtils;
10
10
  use Illuminate\Support\Arr;
11
11
  use Illuminate\Support\Facades\DB;
@@ -45,7 +45,7 @@ class Utils extends FleetbaseUtils
45
45
 
46
46
  if (filled($companyUuid)) {
47
47
  $accountingSettings = Setting::lookup('company.' . $companyUuid . '.ledger.accounting-settings', []);
48
- $baseCurrency = data_get($accountingSettings, 'base_currency');
48
+ $baseCurrency = data_get($accountingSettings, 'base_currency');
49
49
 
50
50
  if (filled($baseCurrency)) {
51
51
  return strtoupper($baseCurrency);
@@ -244,6 +244,10 @@ class Utils extends FleetbaseUtils
244
244
  $coordinates = $coordinates->getSpatialValue();
245
245
  }
246
246
 
247
+ if ($coordinates instanceof \Illuminate\Database\Query\Expression) {
248
+ $coordinates = static::extractPointWktFromQueryExpression($coordinates) ?? $coordinates;
249
+ }
250
+
247
251
  if ($coordinates instanceof Point) {
248
252
  $latitude = $coordinates->getLat();
249
253
  $longitude = $coordinates->getLng();
@@ -369,6 +373,32 @@ class Utils extends FleetbaseUtils
369
373
  return new Point((float) $latitude, (float) $longitude);
370
374
  }
371
375
 
376
+ /**
377
+ * Attempts to extract a WKT POINT string from a query expression.
378
+ */
379
+ protected static function extractPointWktFromQueryExpression(\Illuminate\Database\Query\Expression $expression): ?string
380
+ {
381
+ $expressionValue = null;
382
+
383
+ if (method_exists($expression, 'getValue')) {
384
+ try {
385
+ $expressionValue = $expression->getValue(DB::connection()->getQueryGrammar());
386
+ } catch (\Throwable $e) {
387
+ $expressionValue = null;
388
+ }
389
+ }
390
+
391
+ if (!is_string($expressionValue) || blank($expressionValue)) {
392
+ return null;
393
+ }
394
+
395
+ if (preg_match("/POINT\\(\\s*([-+]?\\d*\\.?\\d+)\\s+([-+]?\\d*\\.?\\d+)\\s*\\)/i", $expressionValue, $matches)) {
396
+ return sprintf('POINT(%s %s)', $matches[1], $matches[2]);
397
+ }
398
+
399
+ return null;
400
+ }
401
+
372
402
  /**
373
403
  * Always return spatial point.
374
404
  *
@@ -414,6 +444,10 @@ class Utils extends FleetbaseUtils
414
444
  $coordinates = $coordinates->getSpatialValue();
415
445
  }
416
446
 
447
+ if ($coordinates instanceof \Illuminate\Database\Query\Expression) {
448
+ $coordinates = static::extractPointWktFromQueryExpression($coordinates) ?? $coordinates;
449
+ }
450
+
417
451
  if ($coordinates instanceof Point) {
418
452
  return $coordinates;
419
453
  }
@@ -546,6 +546,10 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
546
546
  $router->post('notification-settings', 'SettingController@saveNotificationSettings');
547
547
  $router->get('routing-settings', 'SettingController@getRoutingSettings');
548
548
  $router->post('routing-settings', 'SettingController@saveRoutingSettings');
549
+ $router->get('map', 'SettingController@getMapSettings');
550
+ $router->post('map', 'SettingController@saveMapSettings');
551
+ $router->get('admin-map', 'SettingController@getAdminMapSettings');
552
+ $router->post('admin-map', 'SettingController@saveAdminMapSettings');
549
553
  $router->get('scheduling-settings', 'SettingController@getSchedulingSettings');
550
554
  $router->post('scheduling-settings', 'SettingController@saveSchedulingSettings');
551
555
  $router->get('orchestrator-settings', 'SettingController@getOrchestratorSettings');