@fleetbase/fleetops-engine 0.6.44 → 0.6.45

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 (42) hide show
  1. package/addon/components/entity/form.hbs +24 -0
  2. package/addon/components/entity/form.js +30 -0
  3. package/addon/components/leaflet-draw-control.js +1 -1
  4. package/addon/components/map/drawer/geofence-event-listing.js +5 -2
  5. package/addon/components/order/form/service-rate.hbs +1 -1
  6. package/addon/components/service-rate/details.hbs +6 -6
  7. package/addon/components/service-rate/form.hbs +28 -15
  8. package/addon/controllers/operations/orders/index/details/virtual.js +5 -0
  9. package/addon/controllers/operations/orders/index/details.js +27 -2
  10. package/addon/controllers/operations/service-rates/index/edit.js +1 -0
  11. package/addon/controllers/operations/service-rates/index/new.js +1 -0
  12. package/addon/helpers/f-to-int.js +6 -0
  13. package/addon/routes/application.js +3 -3
  14. package/addon/routes/operations/orders/index/details/virtual.js +1 -0
  15. package/addon/routes/operations/orders/index/details.js +19 -3
  16. package/addon/services/equipment-actions.js +4 -6
  17. package/addon/services/leaflet-map-manager.js +4 -0
  18. package/addon/services/maintenance-actions.js +4 -6
  19. package/addon/services/part-actions.js +4 -6
  20. package/addon/services/service-rate-actions.js +8 -3
  21. package/addon/templates/operations/orders/index/details/virtual.hbs +7 -1
  22. package/addon/utils/fleet-ops-options.js +33 -0
  23. package/addon/utils/serialize-payload.js +1 -1
  24. package/app/controllers/operations/orders/index/details/virtual.js +1 -0
  25. package/app/helpers/f-to-int.js +1 -0
  26. package/composer.json +1 -1
  27. package/extension.json +1 -1
  28. package/package.json +2 -2
  29. package/server/src/Http/Controllers/Api/v1/OrderController.php +5 -5
  30. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +11 -3
  31. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +4 -0
  32. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +6 -1
  33. package/server/src/Http/Requests/CreateServiceRateRequest.php +2 -2
  34. package/server/src/Http/Resources/v1/Order.php +0 -1
  35. package/server/src/Http/Resources/v1/ServiceQuote.php +2 -2
  36. package/server/src/Models/Entity.php +7 -0
  37. package/server/src/Models/Order.php +39 -7
  38. package/server/src/Models/ServiceRate.php +122 -30
  39. package/server/src/Observers/PurchaseRateObserver.php +3 -5
  40. package/server/src/Rules/ComputableAlgo.php +1 -3
  41. package/server/src/Support/Algo.php +87 -1
  42. package/server/src/Support/Utils.php +35 -0
@@ -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
- $result = $m->evaluate($algorithm);
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
  }
@@ -3,6 +3,8 @@
3
3
  namespace Fleetbase\FleetOps\Support;
4
4
 
5
5
  use Fleetbase\FleetOps\Flow\Activity;
6
+ use Fleetbase\Models\Company;
7
+ use Fleetbase\Models\Setting;
6
8
  use Fleetbase\LaravelMysqlSpatial\Types\Point;
7
9
  use Fleetbase\Support\Utils as FleetbaseUtils;
8
10
  use Illuminate\Support\Arr;
@@ -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
  *