@fleetbase/fleetops-engine 0.6.44 → 0.6.46
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/admin/map-settings.hbs +26 -0
- package/addon/components/admin/map-settings.js +46 -0
- package/addon/components/admin/routing-settings.hbs +11 -0
- package/addon/components/cell/order-route-type.hbs +46 -0
- package/addon/components/cell/order-route-type.js +90 -0
- package/addon/components/cell/place-address.hbs +1 -0
- package/addon/components/display-place.hbs +45 -56
- package/addon/components/display-place.js +21 -0
- package/addon/components/entity/form.hbs +24 -0
- package/addon/components/entity/form.js +30 -0
- package/addon/components/layout/fleet-ops-sidebar/driver-listing.js +5 -5
- package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +5 -5
- package/addon/components/layout/fleet-ops-sidebar.js +8 -0
- package/addon/components/leaflet-draw-control.js +1 -1
- package/addon/components/maintenance-schedule/form.js +2 -1
- package/addon/components/map/drawer/driver-listing.js +5 -5
- package/addon/components/map/drawer/geofence-event-listing.js +5 -2
- package/addon/components/map/drawer/place-listing.js +5 -5
- package/addon/components/map/drawer/position-listing.js +102 -21
- package/addon/components/map/drawer/vehicle-listing.js +5 -5
- package/addon/components/map/google-live-map.hbs +9 -0
- package/addon/components/map/google-live-map.js +445 -0
- package/addon/components/map/leaflet-live-map.hbs +186 -142
- package/addon/components/map/leaflet-live-map.js +121 -41
- package/addon/components/map/toolbar/visibility-control-panel.js +2 -2
- package/addon/components/map/toolbar/zones-panel.hbs +9 -9
- package/addon/components/map/toolbar.hbs +3 -3
- package/addon/components/map/toolbar.js +9 -1
- package/addon/components/modals/map-layer-form.hbs +132 -63
- package/addon/components/modals/orchestrator-import.hbs +4 -11
- package/addon/components/modals/orchestrator-import.js +17 -1
- package/addon/components/modals/update-order-activity.hbs +1 -1
- package/addon/components/orchestrator/order-pool.js +3 -2
- package/addon/components/orchestrator-workbench.js +29 -41
- package/addon/components/order/details/detail.js +2 -2
- package/addon/components/order/details/payload.hbs +5 -5
- package/addon/components/order/details/payload.js +18 -1
- package/addon/components/order/details/route.hbs +2 -2
- package/addon/components/order/details/route.js +76 -3
- package/addon/components/order/form/payload.hbs +33 -0
- package/addon/components/order/form/payload.js +1 -0
- package/addon/components/order/form/route.hbs +8 -8
- package/addon/components/order/form/route.js +78 -18
- package/addon/components/order/form/service-rate.hbs +1 -1
- package/addon/components/order/form.js +2 -2
- package/addon/components/order/route-editor.hbs +209 -147
- package/addon/components/order/route-editor.js +143 -102
- package/addon/components/place/address.hbs +1 -0
- package/addon/components/place/address.js +12 -0
- package/addon/components/route-list.hbs +43 -55
- package/addon/components/route-list.js +47 -0
- package/addon/components/route-optimization-wizard-panel.js +3 -4
- package/addon/components/service-rate/details.hbs +6 -6
- package/addon/components/service-rate/form.hbs +28 -15
- package/addon/components/vehicle/card.hbs +4 -4
- package/addon/controllers/maintenance/schedules/index.js +2 -1
- package/addon/controllers/operations/orders/index/details/virtual.js +5 -0
- package/addon/controllers/operations/orders/index/details.js +113 -15
- package/addon/controllers/operations/orders/index/new.js +1 -1
- package/addon/controllers/operations/orders/index.js +8 -1
- package/addon/controllers/operations/service-rates/index/edit.js +1 -0
- package/addon/controllers/operations/service-rates/index/new.js +1 -0
- package/addon/controllers/settings/map.js +97 -0
- package/addon/controllers/settings/routing.js +47 -12
- package/addon/extension.js +11 -0
- package/addon/helpers/f-to-int.js +6 -0
- package/addon/helpers/place-address-html.js +6 -0
- package/addon/instance-initializers/register-google-routes.js +17 -0
- package/addon/instance-initializers/register-osrm.js +5 -0
- package/addon/routes/application.js +9 -3
- package/addon/routes/operations/orchestrator.js +13 -0
- package/addon/routes/operations/orders/index/details/virtual.js +1 -0
- package/addon/routes/operations/orders/index/details.js +47 -24
- package/addon/routes/operations/orders/index/new.js +9 -0
- package/addon/routes/operations/orders/index.js +0 -1
- package/addon/routes/settings/map.js +3 -0
- package/addon/routes.js +1 -0
- package/addon/services/entity-actions.js +1 -1
- package/addon/services/equipment-actions.js +4 -6
- package/addon/services/geofence-event-bus.js +2 -1
- package/addon/services/geofence.js +204 -168
- package/addon/services/google-routes.js +300 -0
- package/addon/services/leaflet-draw-restriction.js +2 -1
- package/addon/services/leaflet-map-manager.js +21 -0
- package/addon/services/maintenance-actions.js +4 -6
- package/addon/services/map-adapter/google.js +2205 -0
- package/addon/services/map-adapter/leaflet.js +1042 -0
- package/addon/services/map-adapter-interface.js +551 -0
- package/addon/services/map-manager.js +768 -0
- package/addon/services/map-settings.js +75 -0
- package/addon/services/movement-tracker.js +83 -32
- package/addon/services/order-actions.js +11 -1
- package/addon/services/osrm.js +79 -6
- package/addon/services/part-actions.js +4 -6
- package/addon/services/position-playback.js +135 -62
- package/addon/services/route-engine.js +83 -0
- package/addon/services/service-areas.js +8 -1
- package/addon/services/service-rate-actions.js +8 -3
- package/addon/styles/fleetops-engine.css +555 -0
- package/addon/templates/management/vehicles/index.hbs +0 -1
- package/addon/templates/operations/orders/index/details/virtual.hbs +7 -1
- package/addon/templates/operations/orders/index/details.hbs +0 -1
- package/addon/templates/settings/map.hbs +53 -0
- package/addon/templates/settings/routing.hbs +15 -4
- package/addon/utils/fleet-ops-options.js +34 -0
- package/addon/utils/has-valid-coordinates.js +6 -0
- package/addon/utils/map-provider-options.js +6 -0
- package/addon/utils/order-route-editing.js +86 -0
- package/addon/utils/order-route-summary.js +20 -0
- package/addon/utils/place-address-html.js +41 -0
- package/addon/utils/route-colors.js +43 -12
- package/addon/utils/route-visualization.js +93 -0
- package/addon/utils/serialize-payload.js +1 -1
- package/addon/utils/vendor-integration.js +2 -1
- package/app/components/admin/map-settings.js +1 -0
- package/app/components/admin/routing-settings.js +1 -0
- package/app/components/cell/order-route-type.js +1 -0
- package/app/components/cell/place-address.js +1 -0
- package/app/components/map/google-live-map.js +1 -0
- package/app/components/place/address.js +1 -0
- package/app/controllers/operations/orders/index/details/virtual.js +1 -0
- package/app/controllers/settings/map.js +1 -0
- package/app/helpers/f-to-int.js +1 -0
- package/app/helpers/place-address-html.js +1 -0
- package/app/routes/settings/map.js +1 -0
- package/app/services/map-adapter/google.js +1 -0
- package/app/services/map-adapter/leaflet.js +1 -0
- package/app/services/map-adapter-interface.js +1 -0
- package/app/services/map-manager.js +1 -0
- package/app/services/map-settings.js +1 -0
- package/app/templates/settings/map.js +1 -0
- package/app/utils/has-valid-coordinates.js +1 -0
- package/app/utils/order-route-editing.js +2 -0
- package/app/utils/order-route-summary.js +1 -0
- package/app/utils/place-address-html.js +1 -0
- package/app/utils/route-colors.js +1 -1
- package/app/utils/route-visualization.js +1 -0
- package/assets/images/drawing-controls-spritesheet.svg +156 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +3 -3
- package/server/src/Auth/Schemas/FleetOps.php +5 -0
- package/server/src/Http/Controllers/Api/v1/OrderController.php +36 -8
- package/server/src/Http/Controllers/Api/v1/PayloadController.php +14 -1
- package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +11 -3
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +2 -0
- package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +7 -2
- package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +6 -1
- package/server/src/Http/Controllers/Api/v1/ZoneController.php +2 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +2 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +7 -4
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +61 -34
- package/server/src/Http/Controllers/Internal/v1/ServiceQuoteController.php +3 -2
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +106 -3
- package/server/src/Http/Filter/OrderFilter.php +2 -1
- package/server/src/Http/Requests/CreateServiceRateRequest.php +2 -2
- package/server/src/Http/Resources/v1/Index/Payload.php +9 -7
- package/server/src/Http/Resources/v1/Order.php +20 -2
- package/server/src/Http/Resources/v1/ServiceQuote.php +2 -2
- package/server/src/Models/Entity.php +7 -0
- package/server/src/Models/Order.php +81 -8
- package/server/src/Models/OrderConfig.php +15 -0
- package/server/src/Models/Payload.php +131 -27
- package/server/src/Models/Place.php +182 -48
- package/server/src/Models/ServiceRate.php +125 -32
- package/server/src/Observers/PurchaseRateObserver.php +3 -5
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +59 -23
- package/server/src/Rules/ComputableAlgo.php +1 -3
- package/server/src/Support/Algo.php +87 -1
- package/server/src/Support/Utils.php +69 -0
- package/server/src/routes.php +4 -0
- 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 —
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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
|
|
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
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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, '/')
|
|
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
|
}
|
|
@@ -16,9 +16,7 @@ class ComputableAlgo implements Rule
|
|
|
16
16
|
*/
|
|
17
17
|
public function passes($attribute, $value)
|
|
18
18
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return Algo::exec($value, $distanceAndTime) > 0;
|
|
19
|
+
return Algo::isComputable($value);
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
/**
|
|
@@ -6,6 +6,8 @@ use Webit\Util\EvalMath\EvalMath;
|
|
|
6
6
|
|
|
7
7
|
class Algo
|
|
8
8
|
{
|
|
9
|
+
protected const FUNCTION_PATTERN = '/\b(max|min|ceil|floor|round)\(([^()]*)\)/';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Execute an algorithm strig.
|
|
11
13
|
*
|
|
@@ -16,11 +18,18 @@ class Algo
|
|
|
16
18
|
$m = new EvalMath();
|
|
17
19
|
$m->suppress_errors = true;
|
|
18
20
|
|
|
21
|
+
$variables = static::normalizeVariables($variables);
|
|
22
|
+
|
|
19
23
|
foreach ($variables as $key => $value) {
|
|
20
24
|
$algorithm = str_replace('{' . $key . '}', $value, $algorithm);
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
$
|
|
27
|
+
$algorithm = static::evaluateFunctions($algorithm);
|
|
28
|
+
$result = $m->evaluate($algorithm);
|
|
29
|
+
|
|
30
|
+
if ($result === false || $result === null || !is_numeric($result)) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
24
33
|
|
|
25
34
|
if ($round) {
|
|
26
35
|
return round($result, 2); // precision 2 cuz most likely dealing with $
|
|
@@ -28,4 +37,81 @@ class Algo
|
|
|
28
37
|
|
|
29
38
|
return $result;
|
|
30
39
|
}
|
|
40
|
+
|
|
41
|
+
public static function isComputable($algorithm): bool
|
|
42
|
+
{
|
|
43
|
+
$result = static::exec($algorithm, static::validationFixture(), true);
|
|
44
|
+
|
|
45
|
+
return $result !== null && is_numeric($result);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public static function normalizeVariables($variables = []): array
|
|
49
|
+
{
|
|
50
|
+
$variables = collect($variables)->all();
|
|
51
|
+
|
|
52
|
+
$distanceM = (float) ($variables['distance_m'] ?? $variables['distance'] ?? 0);
|
|
53
|
+
$timeS = (float) ($variables['time_s'] ?? $variables['time'] ?? 0);
|
|
54
|
+
|
|
55
|
+
$normalized = [
|
|
56
|
+
'distance_m' => $distanceM,
|
|
57
|
+
'distance' => $distanceM,
|
|
58
|
+
'distance_km'=> $distanceM / 1000,
|
|
59
|
+
'distance_mi'=> $distanceM / 1609.344,
|
|
60
|
+
'time_s' => $timeS,
|
|
61
|
+
'time' => $timeS,
|
|
62
|
+
'time_min' => $timeS / 60,
|
|
63
|
+
'stops' => (int) ($variables['stops'] ?? 0),
|
|
64
|
+
'waypoints' => (int) ($variables['waypoints'] ?? 0),
|
|
65
|
+
'parcels' => (int) ($variables['parcels'] ?? 0),
|
|
66
|
+
'entities' => (int) ($variables['entities'] ?? 0),
|
|
67
|
+
'base_fee' => (float) ($variables['base_fee'] ?? 0),
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
return array_merge($normalized, $variables);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected static function validationFixture(): array
|
|
74
|
+
{
|
|
75
|
+
return static::normalizeVariables([
|
|
76
|
+
'distance_m' => 25000,
|
|
77
|
+
'time_s' => 5400,
|
|
78
|
+
'stops' => 4,
|
|
79
|
+
'waypoints' => 2,
|
|
80
|
+
'parcels' => 3,
|
|
81
|
+
'entities' => 5,
|
|
82
|
+
'base_fee' => 100,
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected static function evaluateFunctions(string $algorithm): string
|
|
87
|
+
{
|
|
88
|
+
while (preg_match(static::FUNCTION_PATTERN, $algorithm)) {
|
|
89
|
+
$algorithm = preg_replace_callback(static::FUNCTION_PATTERN, function ($matches) {
|
|
90
|
+
$function = $matches[1];
|
|
91
|
+
$args = array_map('trim', explode(',', $matches[2]));
|
|
92
|
+
$m = new EvalMath();
|
|
93
|
+
$m->suppress_errors = true;
|
|
94
|
+
$numbers = array_map(function ($arg) use ($m) {
|
|
95
|
+
$result = $m->evaluate($arg);
|
|
96
|
+
|
|
97
|
+
if ($result === false || $result === null || !is_numeric($result)) {
|
|
98
|
+
return (float) $arg;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (float) $result;
|
|
102
|
+
}, $args);
|
|
103
|
+
|
|
104
|
+
return match ($function) {
|
|
105
|
+
'max' => (string) max($numbers[0] ?? 0, $numbers[1] ?? 0),
|
|
106
|
+
'min' => (string) min($numbers[0] ?? 0, $numbers[1] ?? 0),
|
|
107
|
+
'ceil' => (string) ceil($numbers[0] ?? 0),
|
|
108
|
+
'floor' => (string) floor($numbers[0] ?? 0),
|
|
109
|
+
'round' => (string) round($numbers[0] ?? 0, (int) ($numbers[1] ?? 0)),
|
|
110
|
+
default => $matches[0],
|
|
111
|
+
};
|
|
112
|
+
}, $algorithm);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return $algorithm;
|
|
116
|
+
}
|
|
31
117
|
}
|
|
@@ -4,6 +4,8 @@ namespace Fleetbase\FleetOps\Support;
|
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
6
6
|
use Fleetbase\LaravelMysqlSpatial\Types\Point;
|
|
7
|
+
use Fleetbase\Models\Company;
|
|
8
|
+
use Fleetbase\Models\Setting;
|
|
7
9
|
use Fleetbase\Support\Utils as FleetbaseUtils;
|
|
8
10
|
use Illuminate\Support\Arr;
|
|
9
11
|
use Illuminate\Support\Facades\DB;
|
|
@@ -20,6 +22,39 @@ class Utils extends FleetbaseUtils
|
|
|
20
22
|
*/
|
|
21
23
|
public const DRIVING_TIME_MULTIPLIER = 7.2;
|
|
22
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the preferred transaction currency for a company.
|
|
27
|
+
*
|
|
28
|
+
* Resolution order:
|
|
29
|
+
* 1. Organization/company configured currency
|
|
30
|
+
* 2. Ledger accounting base currency
|
|
31
|
+
* 3. USD
|
|
32
|
+
*/
|
|
33
|
+
public static function getCompanyTransactionCurrency(string|Company|null $company = null): string
|
|
34
|
+
{
|
|
35
|
+
$companyModel = $company instanceof Company
|
|
36
|
+
? $company
|
|
37
|
+
: (filled($company) ? Company::where('uuid', $company)->first() : null);
|
|
38
|
+
|
|
39
|
+
$companyUuid = $companyModel?->uuid ?? (is_string($company) ? $company : null);
|
|
40
|
+
|
|
41
|
+
$companyCurrency = data_get($companyModel, 'currency');
|
|
42
|
+
if (filled($companyCurrency)) {
|
|
43
|
+
return strtoupper($companyCurrency);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (filled($companyUuid)) {
|
|
47
|
+
$accountingSettings = Setting::lookup('company.' . $companyUuid . '.ledger.accounting-settings', []);
|
|
48
|
+
$baseCurrency = data_get($accountingSettings, 'base_currency');
|
|
49
|
+
|
|
50
|
+
if (filled($baseCurrency)) {
|
|
51
|
+
return strtoupper($baseCurrency);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return 'USD';
|
|
56
|
+
}
|
|
57
|
+
|
|
23
58
|
/**
|
|
24
59
|
* Get a formatted string representation of a place's address.
|
|
25
60
|
*
|
|
@@ -209,6 +244,10 @@ class Utils extends FleetbaseUtils
|
|
|
209
244
|
$coordinates = $coordinates->getSpatialValue();
|
|
210
245
|
}
|
|
211
246
|
|
|
247
|
+
if ($coordinates instanceof \Illuminate\Database\Query\Expression) {
|
|
248
|
+
$coordinates = static::extractPointWktFromQueryExpression($coordinates) ?? $coordinates;
|
|
249
|
+
}
|
|
250
|
+
|
|
212
251
|
if ($coordinates instanceof Point) {
|
|
213
252
|
$latitude = $coordinates->getLat();
|
|
214
253
|
$longitude = $coordinates->getLng();
|
|
@@ -334,6 +373,32 @@ class Utils extends FleetbaseUtils
|
|
|
334
373
|
return new Point((float) $latitude, (float) $longitude);
|
|
335
374
|
}
|
|
336
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
|
+
|
|
337
402
|
/**
|
|
338
403
|
* Always return spatial point.
|
|
339
404
|
*
|
|
@@ -379,6 +444,10 @@ class Utils extends FleetbaseUtils
|
|
|
379
444
|
$coordinates = $coordinates->getSpatialValue();
|
|
380
445
|
}
|
|
381
446
|
|
|
447
|
+
if ($coordinates instanceof \Illuminate\Database\Query\Expression) {
|
|
448
|
+
$coordinates = static::extractPointWktFromQueryExpression($coordinates) ?? $coordinates;
|
|
449
|
+
}
|
|
450
|
+
|
|
382
451
|
if ($coordinates instanceof Point) {
|
|
383
452
|
return $coordinates;
|
|
384
453
|
}
|
package/server/src/routes.php
CHANGED
|
@@ -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');
|