@fleetbase/fleetops-engine 0.6.54 → 0.6.56

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 (220) hide show
  1. package/addon/components/admin/map-settings.hbs +1 -1
  2. package/addon/components/admin/routing-settings.hbs +2 -1
  3. package/addon/components/cell/attached-vehicle.hbs +10 -0
  4. package/addon/components/cell/attached-vehicle.js +58 -0
  5. package/addon/components/cell/device-identity.hbs +24 -0
  6. package/addon/components/cell/device-identity.js +129 -0
  7. package/addon/components/cell/driver-identity.hbs +33 -0
  8. package/addon/components/cell/driver-identity.js +143 -0
  9. package/addon/components/cell/equipment-identity.hbs +5 -0
  10. package/addon/components/cell/equipment-identity.js +48 -0
  11. package/addon/components/cell/part-identity.hbs +5 -0
  12. package/addon/components/cell/part-identity.js +63 -0
  13. package/addon/components/cell/telematic-device.hbs +38 -0
  14. package/addon/components/cell/telematic-device.js +44 -0
  15. package/addon/components/cell/telematic-provider.hbs +33 -16
  16. package/addon/components/cell/telematic-provider.js +50 -8
  17. package/addon/components/cell/vehicle-identity.hbs +33 -0
  18. package/addon/components/cell/vehicle-identity.js +138 -0
  19. package/addon/components/device/details.js +1 -1
  20. package/addon/components/device/form.hbs +2 -2
  21. package/addon/components/device/form.js +7 -0
  22. package/addon/components/device/panel-header.hbs +45 -20
  23. package/addon/components/device/panel-header.js +49 -1
  24. package/addon/components/device/panel-tabs/events.hbs +30 -0
  25. package/addon/components/device/panel-tabs/events.js +128 -0
  26. package/addon/components/device/panel-tabs/sensors.hbs +30 -0
  27. package/addon/components/device/panel-tabs/sensors.js +93 -0
  28. package/addon/components/device/panel-tabs/vehicle.hbs +68 -0
  29. package/addon/components/device/panel-tabs/vehicle.js +90 -0
  30. package/addon/components/device-event/details.hbs +192 -0
  31. package/addon/components/device-event/details.js +151 -0
  32. package/addon/components/driver/schedule.js +1 -1
  33. package/addon/components/equipment/form.js +8 -1
  34. package/addon/components/layout/fleet-ops-sidebar.hbs +1 -1
  35. package/addon/components/layout/fleet-ops-sidebar.js +20 -6
  36. package/addon/components/map/drawer/device-event-listing.js +2 -0
  37. package/addon/components/map/drawer/driver-listing.js +2 -0
  38. package/addon/components/map/drawer/place-listing.js +2 -0
  39. package/addon/components/map/drawer/position-listing.hbs +11 -6
  40. package/addon/components/map/drawer/position-listing.js +17 -4
  41. package/addon/components/map/drawer/vehicle-listing.js +2 -0
  42. package/addon/components/sensor/panel-header.hbs +47 -15
  43. package/addon/components/sensor/panel-header.js +59 -1
  44. package/addon/components/table/cell/dropdown/action-item.hbs +31 -0
  45. package/addon/components/table/cell/dropdown/action-item.js +62 -0
  46. package/addon/components/table/cell/dropdown.hbs +28 -0
  47. package/addon/components/table/cell/dropdown.js +91 -0
  48. package/addon/components/telematic/details.hbs +1 -1
  49. package/addon/components/telematic/form.hbs +2 -2
  50. package/addon/components/telematic/settings.hbs +1 -1
  51. package/addon/components/vendor/panel-header.hbs +82 -0
  52. package/addon/components/vendor/panel-header.js +48 -0
  53. package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
  54. package/addon/controllers/connectivity/devices/index/details/vehicle.js +50 -2
  55. package/addon/controllers/connectivity/devices/index.js +144 -129
  56. package/addon/controllers/connectivity/events/details.js +70 -0
  57. package/addon/controllers/connectivity/events/index.js +187 -11
  58. package/addon/controllers/connectivity/sensors/index.js +160 -14
  59. package/addon/controllers/connectivity/telematics/details/devices.js +126 -134
  60. package/addon/controllers/connectivity/telematics/details/events.js +1 -1
  61. package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
  62. package/addon/controllers/maintenance/equipment/index.js +1 -2
  63. package/addon/controllers/maintenance/parts/index.js +1 -2
  64. package/addon/controllers/management/drivers/index.js +82 -42
  65. package/addon/controllers/management/fuel-reports/index.js +63 -4
  66. package/addon/controllers/management/issues/index.js +63 -4
  67. package/addon/controllers/management/vehicles/index.js +33 -6
  68. package/addon/controllers/settings/map.js +15 -0
  69. package/addon/instance-initializers/register-vroom-allocation.js +1 -1
  70. package/addon/routes/connectivity/devices/index/details/vehicle.js +24 -2
  71. package/addon/routes/connectivity/devices/index.js +7 -0
  72. package/addon/routes/connectivity/events/details.js +28 -0
  73. package/addon/routes/connectivity/events/index.js +6 -2
  74. package/addon/routes/connectivity/sensors/index.js +7 -2
  75. package/addon/routes/connectivity/telematics/details/devices.js +2 -0
  76. package/addon/routes/management/vehicles/index/details.js +3 -1
  77. package/addon/services/device-actions.js +30 -0
  78. package/addon/services/device-event-actions.js +1 -1
  79. package/addon/services/equipment-actions.js +1 -0
  80. package/addon/services/map-adapter/google.js +25 -0
  81. package/addon/services/map-adapter/leaflet.js +1 -1
  82. package/addon/services/map-adapter-interface.js +1 -1
  83. package/addon/services/map-manager.js +4 -1
  84. package/addon/services/map-settings.js +15 -0
  85. package/addon/services/sensor-actions.js +3 -0
  86. package/addon/services/service-rate-actions.js +39 -1
  87. package/addon/services/vehicle-actions.js +24 -12
  88. package/addon/services/vendor-actions.js +3 -0
  89. package/addon/styles/fleetops-engine.css +9 -1
  90. package/addon/templates/connectivity/devices/index/details/vehicle.hbs +66 -2
  91. package/addon/templates/connectivity/events/details.hbs +40 -0
  92. package/addon/templates/management/vendors/index/details.hbs +2 -2
  93. package/addon/templates/settings/map.hbs +38 -9
  94. package/addon/templates/settings/notifications.hbs +2 -1
  95. package/addon/templates/settings/routing.hbs +1 -0
  96. package/addon/utils/device-table-columns.js +288 -0
  97. package/addon/utils/identity-cell-resource.js +20 -0
  98. package/addon/utils/leaflet-plugin-loader.js +5 -5
  99. package/addon/utils/map-drawer-dropdown-position.js +47 -0
  100. package/addon/utils/route-colors.js +1 -1
  101. package/addon/utils/trackable-option.js +93 -0
  102. package/app/components/cell/attached-vehicle.js +1 -0
  103. package/app/components/cell/device-identity.js +1 -0
  104. package/app/components/cell/driver-identity.js +1 -0
  105. package/app/components/cell/equipment-identity.js +1 -0
  106. package/app/components/cell/part-identity.js +1 -0
  107. package/app/components/cell/telematic-device.js +1 -0
  108. package/app/components/cell/vehicle-identity.js +1 -0
  109. package/app/components/device/panel-tabs/events.hbs +30 -0
  110. package/app/components/device/panel-tabs/events.js +128 -0
  111. package/app/components/device/panel-tabs/sensors.hbs +30 -0
  112. package/app/components/device/panel-tabs/sensors.js +93 -0
  113. package/app/components/device/panel-tabs/vehicle.hbs +68 -0
  114. package/app/components/device/panel-tabs/vehicle.js +90 -0
  115. package/app/components/device-event/details.hbs +192 -0
  116. package/app/components/device-event/details.js +1 -0
  117. package/app/components/table/cell/dropdown/action-item.js +1 -0
  118. package/app/components/table/cell/dropdown.js +1 -0
  119. package/app/components/vendor/panel-header.js +1 -0
  120. package/app/controllers/connectivity/events/{index/details.js → details.js} +1 -1
  121. package/app/routes/connectivity/events/{index/details.js → details.js} +1 -1
  122. package/app/templates/connectivity/events/{index/details.js → details.js} +1 -1
  123. package/app/utils/map-drawer-dropdown-position.js +1 -0
  124. package/app/utils/trackable-option.js +1 -0
  125. package/composer.json +1 -1
  126. package/extension.json +1 -1
  127. package/package.json +4 -4
  128. package/server/migrations/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
  129. package/server/src/Console/Commands/SyncTelematics.php +4 -4
  130. package/server/src/Exports/ContactExport.php +12 -5
  131. package/server/src/Exports/DeviceExport.php +92 -0
  132. package/server/src/Exports/DriverExport.php +28 -3
  133. package/server/src/Exports/EquipmentExport.php +94 -0
  134. package/server/src/Exports/FleetExport.php +22 -7
  135. package/server/src/Exports/FuelReportExport.php +16 -1
  136. package/server/src/Exports/IssueExport.php +25 -3
  137. package/server/src/Exports/MaintenanceExport.php +106 -0
  138. package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
  139. package/server/src/Exports/OrderExport.php +24 -5
  140. package/server/src/Exports/PartExport.php +99 -0
  141. package/server/src/Exports/PlaceExport.php +33 -7
  142. package/server/src/Exports/SensorExport.php +94 -0
  143. package/server/src/Exports/ServiceAreaExport.php +31 -7
  144. package/server/src/Exports/ServiceRateExport.php +41 -1
  145. package/server/src/Exports/TelematicExport.php +90 -0
  146. package/server/src/Exports/VehicleExport.php +274 -8
  147. package/server/src/Exports/VendorExport.php +15 -2
  148. package/server/src/Exports/WorkOrderExport.php +92 -0
  149. package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
  150. package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
  151. package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
  152. package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
  153. package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
  154. package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
  155. package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
  156. package/server/src/Http/Controllers/Internal/v1/DeviceController.php +36 -1
  157. package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +1 -1
  158. package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
  159. package/server/src/Http/Controllers/Internal/v1/LiveController.php +1 -1
  160. package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
  161. package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
  162. package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
  163. package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
  164. package/server/src/Http/Controllers/Internal/v1/ServiceRateController.php +82 -13
  165. package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
  166. package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
  167. package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
  168. package/server/src/Http/Filter/DeviceEventFilter.php +21 -0
  169. package/server/src/Http/Filter/DeviceFilter.php +50 -4
  170. package/server/src/Http/Filter/EquipmentFilter.php +23 -0
  171. package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
  172. package/server/src/Http/Filter/PartFilter.php +47 -0
  173. package/server/src/Http/Filter/SensorFilter.php +34 -6
  174. package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
  175. package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
  176. package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
  177. package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
  178. package/server/src/Http/Requests/CreatePartRequest.php +40 -0
  179. package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
  180. package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
  181. package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
  182. package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
  183. package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
  184. package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
  185. package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
  186. package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
  187. package/server/src/Http/Resources/v1/Device.php +72 -0
  188. package/server/src/Http/Resources/v1/Equipment.php +57 -0
  189. package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
  190. package/server/src/Http/Resources/v1/Index/Vehicle.php +19 -0
  191. package/server/src/Http/Resources/v1/Part.php +64 -0
  192. package/server/src/Http/Resources/v1/Sensor.php +68 -0
  193. package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
  194. package/server/src/Models/Device.php +2 -0
  195. package/server/src/Models/DeviceEvent.php +81 -0
  196. package/server/src/Models/Equipment.php +55 -0
  197. package/server/src/Models/Order.php +2 -1
  198. package/server/src/Observers/PurchaseRateObserver.php +2 -1
  199. package/server/src/Support/Analytics/RevenueTrend.php +3 -8
  200. package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
  201. package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
  202. package/server/src/Support/Metrics/EarningsMetric.php +1 -10
  203. package/server/src/Support/Telematics/Providers/AfaqyProvider.php +105 -5
  204. package/server/src/Support/Telematics/Providers/FlespiProvider.php +89 -15
  205. package/server/src/Support/Telematics/Providers/GeotabProvider.php +123 -35
  206. package/server/src/Support/Telematics/Providers/SafeeProvider.php +567 -47
  207. package/server/src/Support/Telematics/Providers/SamsaraProvider.php +122 -14
  208. package/server/src/Support/Telematics/TelematicService.php +28 -9
  209. package/server/src/routes.php +67 -15
  210. package/server/tests/DeviceFilterTest.php +9 -0
  211. package/server/tests/DriverVehicleStatusDefaultTest.php +19 -2
  212. package/server/tests/EquipmentAssignmentMorphTypeTest.php +35 -0
  213. package/server/tests/ExportCoverageTest.php +79 -0
  214. package/server/tests/MetricsRegistryTest.php +45 -5
  215. package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
  216. package/server/tests/ServiceRateRouteValidationTest.php +101 -0
  217. package/server/tests/TelematicsHardeningTest.php +873 -7
  218. package/addon/controllers/connectivity/events/index/details.js +0 -3
  219. package/addon/routes/connectivity/events/index/details.js +0 -3
  220. package/addon/templates/connectivity/events/index/details.hbs +0 -1
@@ -24,7 +24,7 @@ class DeviceEventController extends FleetOpsController
24
24
  */
25
25
  public static function onQueryRecord($query, $request): void
26
26
  {
27
- $query->with(['device']);
27
+ $query->with(['device.telematic']);
28
28
 
29
29
  if ($request->filled('telematic')) {
30
30
  $query->whereHas('device', function ($deviceQuery) use ($request) {
@@ -2,9 +2,12 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\EquipmentExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Imports\EquipmentImport;
8
+ use Fleetbase\Http\Requests\ExportRequest;
7
9
  use Fleetbase\Http\Requests\ImportRequest;
10
+ use Illuminate\Support\Str;
8
11
  use Maatwebsite\Excel\Facades\Excel;
9
12
 
10
13
  class EquipmentController extends FleetOpsController
@@ -16,6 +19,20 @@ class EquipmentController extends FleetOpsController
16
19
  */
17
20
  public $resource = 'equipment';
18
21
 
22
+ /**
23
+ * Export equipment to excel or csv.
24
+ *
25
+ * @return \Illuminate\Http\Response
26
+ */
27
+ public function export(ExportRequest $request)
28
+ {
29
+ $format = $request->input('format', 'xlsx');
30
+ $selections = $request->array('selections');
31
+ $fileName = trim(Str::slug('equipment-' . date('Y-m-d-H:i')) . '.' . $format);
32
+
33
+ return Excel::download(new EquipmentExport($selections), $fileName);
34
+ }
35
+
19
36
  /**
20
37
  * Process import files (excel, csv) into Equipment records.
21
38
  *
@@ -148,7 +148,7 @@ class LiveController extends Controller
148
148
 
149
149
  return LiveCacheService::remember('drivers', $cacheParams, function () use ($bounds, $limit) {
150
150
  $query = Driver::where(['company_uuid' => session('company')])
151
- ->with(['user', 'vehicle'])
151
+ ->with(['user', 'vehicle.devices'])
152
152
  ->applyDirectivesForPermissions('fleet-ops list driver');
153
153
 
154
154
  $this->applyLiveLocationGuards($query);
@@ -2,12 +2,15 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\MaintenanceExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Imports\MaintenanceImport;
7
8
  use Fleetbase\FleetOps\Models\Maintenance;
9
+ use Fleetbase\Http\Requests\ExportRequest;
8
10
  use Fleetbase\Http\Requests\ImportRequest;
9
11
  use Illuminate\Http\JsonResponse;
10
12
  use Illuminate\Http\Request;
13
+ use Illuminate\Support\Str;
11
14
  use Maatwebsite\Excel\Facades\Excel;
12
15
 
13
16
  class MaintenanceController extends FleetOpsController
@@ -19,6 +22,20 @@ class MaintenanceController extends FleetOpsController
19
22
  */
20
23
  public $resource = 'maintenance';
21
24
 
25
+ /**
26
+ * Export maintenances to excel or csv.
27
+ *
28
+ * @return \Illuminate\Http\Response
29
+ */
30
+ public function export(ExportRequest $request)
31
+ {
32
+ $format = $request->input('format', 'xlsx');
33
+ $selections = $request->array('selections');
34
+ $fileName = trim(Str::slug('maintenances-' . date('Y-m-d-H:i')) . '.' . $format);
35
+
36
+ return Excel::download(new MaintenanceExport($selections), $fileName);
37
+ }
38
+
22
39
  /**
23
40
  * Eager-load polymorphic relationships after create so they appear in the API response.
24
41
  * Called automatically by HasApiControllerBehavior::createRecord() via getControllerCallback.
@@ -2,15 +2,18 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\MaintenanceScheduleExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Imports\MaintenanceScheduleImport;
7
8
  use Fleetbase\FleetOps\Models\MaintenanceSchedule;
8
9
  use Fleetbase\FleetOps\Models\WorkOrder;
10
+ use Fleetbase\Http\Requests\ExportRequest;
9
11
  use Fleetbase\Http\Requests\ImportRequest;
10
12
  use Illuminate\Http\JsonResponse;
11
13
  use Illuminate\Http\Request;
12
14
  use Illuminate\Http\Response;
13
15
  use Illuminate\Support\Carbon;
16
+ use Illuminate\Support\Str;
14
17
  use Maatwebsite\Excel\Facades\Excel;
15
18
  use Spatie\IcalendarGenerator\Components\Calendar;
16
19
  use Spatie\IcalendarGenerator\Components\Event;
@@ -26,6 +29,20 @@ class MaintenanceScheduleController extends FleetOpsController
26
29
  */
27
30
  public $resource = 'maintenance-schedule';
28
31
 
32
+ /**
33
+ * Export maintenance schedules to excel or csv.
34
+ *
35
+ * @return Response
36
+ */
37
+ public function export(ExportRequest $request)
38
+ {
39
+ $format = $request->input('format', 'xlsx');
40
+ $selections = $request->array('selections');
41
+ $fileName = trim(Str::slug('maintenance-schedules-' . date('Y-m-d-H:i')) . '.' . $format);
42
+
43
+ return Excel::download(new MaintenanceScheduleExport($selections), $fileName);
44
+ }
45
+
29
46
  /**
30
47
  * Process import files (excel, csv) into MaintenanceSchedule records.
31
48
  *
@@ -2,9 +2,12 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\PartExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Imports\PartImport;
8
+ use Fleetbase\Http\Requests\ExportRequest;
7
9
  use Fleetbase\Http\Requests\ImportRequest;
10
+ use Illuminate\Support\Str;
8
11
  use Maatwebsite\Excel\Facades\Excel;
9
12
 
10
13
  class PartController extends FleetOpsController
@@ -16,6 +19,20 @@ class PartController extends FleetOpsController
16
19
  */
17
20
  public $resource = 'part';
18
21
 
22
+ /**
23
+ * Export parts to excel or csv.
24
+ *
25
+ * @return \Illuminate\Http\Response
26
+ */
27
+ public function export(ExportRequest $request)
28
+ {
29
+ $format = $request->input('format', 'xlsx');
30
+ $selections = $request->array('selections');
31
+ $fileName = trim(Str::slug('parts-' . date('Y-m-d-H:i')) . '.' . $format);
32
+
33
+ return Excel::download(new PartExport($selections), $fileName);
34
+ }
35
+
19
36
  /**
20
37
  * Process import files (excel, csv) into Part records.
21
38
  *
@@ -2,7 +2,11 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\SensorExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
7
+ use Fleetbase\Http\Requests\ExportRequest;
8
+ use Illuminate\Support\Str;
9
+ use Maatwebsite\Excel\Facades\Excel;
6
10
 
7
11
  class SensorController extends FleetOpsController
8
12
  {
@@ -13,6 +17,20 @@ class SensorController extends FleetOpsController
13
17
  */
14
18
  public $resource = 'sensor';
15
19
 
20
+ /**
21
+ * Export sensors to excel or csv.
22
+ *
23
+ * @return \Illuminate\Http\Response
24
+ */
25
+ public function export(ExportRequest $request)
26
+ {
27
+ $format = $request->input('format', 'xlsx');
28
+ $selections = $request->array('selections');
29
+ $fileName = trim(Str::slug('sensors-' . date('Y-m-d-H:i')) . '.' . $format);
30
+
31
+ return Excel::download(new SensorExport($selections), $fileName);
32
+ }
33
+
16
34
  /**
17
35
  * Query callback when querying record.
18
36
  *
@@ -8,6 +8,7 @@ use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
8
8
  use Fleetbase\FleetOps\Models\ServiceRate;
9
9
  use Fleetbase\Http\Requests\ExportRequest;
10
10
  use Illuminate\Http\Request;
11
+ use Illuminate\Support\Collection;
11
12
  use Illuminate\Support\Str;
12
13
  use Maatwebsite\Excel\Facades\Excel;
13
14
 
@@ -27,24 +28,30 @@ class ServiceRateController extends FleetOpsController
27
28
  */
28
29
  public function getServicesForRoute(Request $request)
29
30
  {
30
- $coordinates = explode(';', $request->input('coordinates')); // ex. 1.3621663,103.8845049;1.353151,103.86458
31
+ $coordinates = $request->input('coordinates');
31
32
 
32
- // convert coordinates to points
33
- $waypoints = collect($coordinates)->map(
34
- function ($coord) {
35
- $coord = explode(',', $coord);
36
- [$latitude, $longitude] = $coord;
33
+ if (!is_string($coordinates) || trim($coordinates) === '') {
34
+ return response()->error('Route coordinates are required to query service rates.', 422);
35
+ }
37
36
 
38
- return Point::fromText("POINT($longitude $latitude)", 4326);
39
- }
40
- );
37
+ $waypoints = $this->parseRouteCoordinates($coordinates);
38
+
39
+ if ($waypoints === null) {
40
+ return response()->error('Invalid route coordinates provided.', 422);
41
+ }
42
+
43
+ if ($waypoints->count() < 2) {
44
+ return response()->error('At least two route coordinates are required to query service rates.', 422);
45
+ }
41
46
 
42
- $applicableServiceRates = ServiceRate::getServicableForWaypoints(
47
+ $serviceType = $this->normalizeOptionalQueryValue($request->input('service_type'));
48
+
49
+ $applicableServiceRates = $this->getServicableForWaypoints(
43
50
  $waypoints,
44
- function ($query) use ($request) {
51
+ function ($query) use ($request, $serviceType) {
45
52
  $query->where('company_uuid', $request->session()->get('company'));
46
- if ($request->filled('service_type')) {
47
- $query->where('service_type', $request->input('service_type'));
53
+ if ($serviceType) {
54
+ $query->where('service_type', $serviceType);
48
55
  }
49
56
  }
50
57
  );
@@ -52,6 +59,68 @@ class ServiceRateController extends FleetOpsController
52
59
  return response()->json($applicableServiceRates);
53
60
  }
54
61
 
62
+ /**
63
+ * Parse semicolon-delimited latitude,longitude coordinate pairs.
64
+ */
65
+ protected function parseRouteCoordinates(string $coordinates): ?Collection
66
+ {
67
+ $coordinates = collect(explode(';', $coordinates))
68
+ ->map(fn ($coordinate) => trim($coordinate));
69
+
70
+ if ($coordinates->contains('')) {
71
+ return null;
72
+ }
73
+
74
+ $waypoints = $coordinates
75
+ ->map(function ($coordinate) {
76
+ $parts = array_map('trim', explode(',', $coordinate));
77
+
78
+ if (count($parts) !== 2) {
79
+ return null;
80
+ }
81
+
82
+ [$latitude, $longitude] = $parts;
83
+
84
+ if (!is_numeric($latitude) || !is_numeric($longitude)) {
85
+ return null;
86
+ }
87
+
88
+ return Point::fromText("POINT($longitude $latitude)", 4326);
89
+ });
90
+
91
+ if ($waypoints->contains(null)) {
92
+ return null;
93
+ }
94
+
95
+ return $waypoints->values();
96
+ }
97
+
98
+ /**
99
+ * Treat placeholder query-string values from the UI as absent.
100
+ */
101
+ protected function normalizeOptionalQueryValue($value): ?string
102
+ {
103
+ if (!is_string($value)) {
104
+ return null;
105
+ }
106
+
107
+ $value = trim($value);
108
+
109
+ if ($value === '' || in_array(strtolower($value), ['null', 'undefined'], true)) {
110
+ return null;
111
+ }
112
+
113
+ return $value;
114
+ }
115
+
116
+ /**
117
+ * Resolve applicable service rates for route waypoints.
118
+ */
119
+ protected function getServicableForWaypoints(Collection $waypoints, \Closure $queryCallback): array
120
+ {
121
+ return ServiceRate::getServicableForWaypoints($waypoints, $queryCallback);
122
+ }
123
+
55
124
  /**
56
125
  * Export the service rate to excel or csv.
57
126
  *
@@ -327,12 +327,16 @@ class SettingController extends Controller
327
327
  public function getMapSettings()
328
328
  {
329
329
  $defaults = [
330
- 'mapProvider' => 'leaflet',
330
+ 'mapProvider' => 'leaflet',
331
+ 'googleMapsMapType' => 'roadmap',
332
+ 'showGoogleMapsTrafficLayer' => false,
333
+ 'showGoogleMapsTransitLayer' => false,
331
334
  ];
332
335
 
333
336
  $systemMapSettings = Setting::lookup('fleet-ops.map-settings', []);
334
337
  $mapSettings = Setting::lookupFromCompany('fleet-ops.map-settings', $defaults);
335
338
  $mapSettings['mapProvider'] = data_get($mapSettings, 'mapProvider') ?: data_get($systemMapSettings, 'mapProvider', 'leaflet');
339
+ $mapSettings = $this->normalizeCompanyMapSettings($mapSettings);
336
340
 
337
341
  // Source the Google Maps API key from the system-level services config
338
342
  // that is managed by the core-api admin settings panel. This ensures a
@@ -362,10 +366,7 @@ class SettingController extends Controller
362
366
  unset($settings['googleMapsApiKey']);
363
367
 
364
368
  // Validate provider value
365
- $allowedProviders = ['leaflet', 'google'];
366
- if (isset($settings['mapProvider']) && !in_array($settings['mapProvider'], $allowedProviders)) {
367
- $settings['mapProvider'] = 'leaflet';
368
- }
369
+ $settings = $this->normalizeCompanyMapSettings($settings);
369
370
 
370
371
  Setting::configureCompany('fleet-ops.map-settings', $settings);
371
372
 
@@ -400,6 +401,29 @@ class SettingController extends Controller
400
401
  return response()->json($this->getAdminMapSettings()->getData(true));
401
402
  }
402
403
 
404
+ protected function normalizeCompanyMapSettings(array $settings): array
405
+ {
406
+ $allowedProviders = ['leaflet', 'google'];
407
+ $mapProvider = data_get($settings, 'mapProvider', 'leaflet');
408
+ if (!in_array($mapProvider, $allowedProviders)) {
409
+ $mapProvider = 'leaflet';
410
+ }
411
+
412
+ $allowedGoogleMapTypes = ['roadmap', 'satellite', 'hybrid', 'terrain'];
413
+ $googleMapsMapType = data_get($settings, 'googleMapsMapType', 'roadmap');
414
+ if (!in_array($googleMapsMapType, $allowedGoogleMapTypes)) {
415
+ $googleMapsMapType = 'roadmap';
416
+ }
417
+
418
+ return [
419
+ ...$settings,
420
+ 'mapProvider' => $mapProvider,
421
+ 'googleMapsMapType' => $googleMapsMapType,
422
+ 'showGoogleMapsTrafficLayer' => filter_var(data_get($settings, 'showGoogleMapsTrafficLayer', false), FILTER_VALIDATE_BOOLEAN),
423
+ 'showGoogleMapsTransitLayer' => filter_var(data_get($settings, 'showGoogleMapsTransitLayer', false), FILTER_VALIDATE_BOOLEAN),
424
+ ];
425
+ }
426
+
403
427
  /**
404
428
  * Retrieve driver scheduling settings for the current company.
405
429
  *
@@ -2,13 +2,17 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\TelematicExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Models\Telematic;
7
8
  use Fleetbase\FleetOps\Support\Telematics\TelematicProviderRegistry;
8
9
  use Fleetbase\FleetOps\Support\Telematics\TelematicService;
10
+ use Fleetbase\Http\Requests\ExportRequest;
9
11
  use Fleetbase\Models\Activity;
10
12
  use Illuminate\Http\JsonResponse;
11
13
  use Illuminate\Http\Request;
14
+ use Illuminate\Support\Str;
15
+ use Maatwebsite\Excel\Facades\Excel;
12
16
 
13
17
  class TelematicController extends FleetOpsController
14
18
  {
@@ -29,6 +33,20 @@ class TelematicController extends FleetOpsController
29
33
  $this->registry = $registry;
30
34
  }
31
35
 
36
+ /**
37
+ * Export telematics to excel or csv.
38
+ *
39
+ * @return \Illuminate\Http\Response
40
+ */
41
+ public function export(ExportRequest $request)
42
+ {
43
+ $format = $request->input('format', 'xlsx');
44
+ $selections = $request->array('selections');
45
+ $fileName = trim(Str::slug('telematics-' . date('Y-m-d-H:i')) . '.' . $format);
46
+
47
+ return Excel::download(new TelematicExport($selections), $fileName);
48
+ }
49
+
32
50
  /**
33
51
  * Query callback when querying record.
34
52
  *
@@ -2,13 +2,16 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Exports\WorkOrderExport;
5
6
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
6
7
  use Fleetbase\FleetOps\Imports\WorkOrderImport;
7
8
  use Fleetbase\FleetOps\Mail\WorkOrderDispatched;
8
9
  use Fleetbase\FleetOps\Models\WorkOrder;
10
+ use Fleetbase\Http\Requests\ExportRequest;
9
11
  use Fleetbase\Http\Requests\ImportRequest;
10
12
  use Illuminate\Http\JsonResponse;
11
13
  use Illuminate\Support\Facades\Mail;
14
+ use Illuminate\Support\Str;
12
15
  use Maatwebsite\Excel\Facades\Excel;
13
16
 
14
17
  class WorkOrderController extends FleetOpsController
@@ -20,6 +23,20 @@ class WorkOrderController extends FleetOpsController
20
23
  */
21
24
  public $resource = 'work-order';
22
25
 
26
+ /**
27
+ * Export work orders to excel or csv.
28
+ *
29
+ * @return \Illuminate\Http\Response
30
+ */
31
+ public function export(ExportRequest $request)
32
+ {
33
+ $format = $request->input('format', 'xlsx');
34
+ $selections = $request->array('selections');
35
+ $fileName = trim(Str::slug('work-orders-' . date('Y-m-d-H:i')) . '.' . $format);
36
+
37
+ return Excel::download(new WorkOrderExport($selections), $fileName);
38
+ }
39
+
23
40
  /**
24
41
  * Process import files (excel, csv) into WorkOrder records.
25
42
  *
@@ -26,6 +26,27 @@ class DeviceEventFilter extends Filter
26
26
  $this->builder->search($searchQuery);
27
27
  }
28
28
 
29
+ public function eventType(?string $eventType)
30
+ {
31
+ if ($eventType) {
32
+ $this->builder->where('event_type', 'like', '%' . $eventType . '%');
33
+ }
34
+ }
35
+
36
+ public function provider(?string $provider)
37
+ {
38
+ if ($provider) {
39
+ $this->builder->where('provider', 'like', '%' . $provider . '%');
40
+ }
41
+ }
42
+
43
+ public function code(?string $code)
44
+ {
45
+ if ($code) {
46
+ $this->builder->where('code', 'like', '%' . $code . '%');
47
+ }
48
+ }
49
+
29
50
  public function telematic(?string $telematic)
30
51
  {
31
52
  $this->builder->whereHas('device', function ($query) use ($telematic) {
@@ -2,8 +2,11 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Filter;
4
4
 
5
+ use Fleetbase\FleetOps\Models\Telematic;
6
+ use Fleetbase\FleetOps\Models\Vehicle;
5
7
  use Fleetbase\FleetOps\Support\Utils;
6
8
  use Fleetbase\Http\Filter\Filter;
9
+ use Fleetbase\Support\Http;
7
10
 
8
11
  class DeviceFilter extends Filter
9
12
  {
@@ -38,9 +41,25 @@ class DeviceFilter extends Filter
38
41
  }
39
42
  }
40
43
 
44
+ public function type(string|array|null $type)
45
+ {
46
+ $type = Utils::arrayFrom($type);
47
+
48
+ if ($type) {
49
+ $this->builder->whereIn('type', $type);
50
+ }
51
+ }
52
+
53
+ public function serialNumber(?string $serialNumber)
54
+ {
55
+ if ($serialNumber) {
56
+ $this->builder->where('serial_number', 'like', '%' . $serialNumber . '%');
57
+ }
58
+ }
59
+
41
60
  public function telematic(?string $telematic)
42
61
  {
43
- $this->builder->where('telematic_uuid', $telematic);
62
+ $this->wherePublicRelation('telematic_uuid', Telematic::class, $telematic);
44
63
  }
45
64
 
46
65
  public function telematicUuid(?string $telematic)
@@ -70,9 +89,7 @@ class DeviceFilter extends Filter
70
89
 
71
90
  public function vehicle(?string $vehicle)
72
91
  {
73
- if ($vehicle) {
74
- $this->builder->where('attachable_uuid', $vehicle);
75
- }
92
+ $this->wherePublicRelation('attachable_uuid', Vehicle::class, $vehicle);
76
93
  }
77
94
 
78
95
  public function connectionStatus(string|array $connectionStatus)
@@ -128,4 +145,33 @@ class DeviceFilter extends Filter
128
145
  $this->builder->whereDate($column, $dates);
129
146
  }
130
147
  }
148
+
149
+ protected function wherePublicRelation(string $column, string $modelClass, ?string $identifier): void
150
+ {
151
+ if (!$identifier) {
152
+ return;
153
+ }
154
+
155
+ $this->builder->whereIn($column, $this->resolvePublicRelationUuids($modelClass, $identifier, Http::isInternalRequest($this->request)));
156
+ }
157
+
158
+ protected function resolvePublicRelationUuids(string $modelClass, string $identifier, bool $allowUuid = false)
159
+ {
160
+ $instance = new $modelClass();
161
+
162
+ return $modelClass::query()
163
+ ->where('company_uuid', $this->session->get('company'))
164
+ ->where(function ($query) use ($identifier, $instance, $allowUuid) {
165
+ $query->where('public_id', $identifier);
166
+
167
+ if (in_array('internal_id', $instance->getFillable())) {
168
+ $query->orWhere('internal_id', $identifier);
169
+ }
170
+
171
+ if ($allowUuid) {
172
+ $query->orWhere('uuid', $identifier);
173
+ }
174
+ })
175
+ ->pluck('uuid');
176
+ }
131
177
  }
@@ -0,0 +1,23 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\FleetOps\Http\Filter;
4
+
5
+ use Fleetbase\Http\Filter\Filter;
6
+
7
+ class EquipmentFilter extends Filter
8
+ {
9
+ public function queryForInternal()
10
+ {
11
+ $this->builder->where('company_uuid', $this->session->get('company'));
12
+ }
13
+
14
+ public function queryForPublic()
15
+ {
16
+ $this->queryForInternal();
17
+ }
18
+
19
+ public function query(?string $searchQuery)
20
+ {
21
+ $this->builder->search($searchQuery);
22
+ }
23
+ }
@@ -2,8 +2,14 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Filter;
4
4
 
5
+ use Fleetbase\FleetOps\Models\Driver;
6
+ use Fleetbase\FleetOps\Models\FuelProviderConnection;
7
+ use Fleetbase\FleetOps\Models\FuelReport;
8
+ use Fleetbase\FleetOps\Models\Order;
9
+ use Fleetbase\FleetOps\Models\Vehicle;
5
10
  use Fleetbase\FleetOps\Support\Utils;
6
11
  use Fleetbase\Http\Filter\Filter;
12
+ use Fleetbase\Support\Http;
7
13
  use Illuminate\Support\Str;
8
14
 
9
15
  class FuelProviderTransactionFilter extends Filter
@@ -13,6 +19,11 @@ class FuelProviderTransactionFilter extends Filter
13
19
  $this->builder->where('company_uuid', $this->session->get('company'));
14
20
  }
15
21
 
22
+ public function queryForPublic()
23
+ {
24
+ $this->queryForInternal();
25
+ }
26
+
16
27
  public function query(?string $searchQuery)
17
28
  {
18
29
  $this->builder->search($searchQuery);
@@ -38,12 +49,27 @@ class FuelProviderTransactionFilter extends Filter
38
49
 
39
50
  public function vehicle(?string $vehicle)
40
51
  {
41
- $this->builder->where('vehicle_uuid', $vehicle);
52
+ $this->wherePublicRelation('vehicle_uuid', Vehicle::class, $vehicle);
42
53
  }
43
54
 
44
55
  public function connection(?string $connection)
45
56
  {
46
- $this->builder->where('fuel_provider_connection_uuid', $connection);
57
+ $this->wherePublicRelation('fuel_provider_connection_uuid', FuelProviderConnection::class, $connection);
58
+ }
59
+
60
+ public function driver(?string $driver)
61
+ {
62
+ $this->wherePublicRelation('driver_uuid', Driver::class, $driver);
63
+ }
64
+
65
+ public function order(?string $order)
66
+ {
67
+ $this->wherePublicRelation('order_uuid', Order::class, $order);
68
+ }
69
+
70
+ public function fuelReport(?string $fuelReport)
71
+ {
72
+ $this->wherePublicRelation('fuel_report_uuid', FuelReport::class, $fuelReport);
47
73
  }
48
74
 
49
75
  public function transactionAt($transactionAt)
@@ -56,4 +82,33 @@ class FuelProviderTransactionFilter extends Filter
56
82
  $this->builder->whereDate('transaction_at', $transactionAt);
57
83
  }
58
84
  }
85
+
86
+ protected function wherePublicRelation(string $column, string $modelClass, ?string $identifier): void
87
+ {
88
+ if (!$identifier) {
89
+ return;
90
+ }
91
+
92
+ $this->builder->whereIn($column, $this->resolvePublicRelationUuids($modelClass, $identifier, Http::isInternalRequest($this->request)));
93
+ }
94
+
95
+ protected function resolvePublicRelationUuids(string $modelClass, string $identifier, bool $allowUuid = false)
96
+ {
97
+ $instance = new $modelClass();
98
+
99
+ return $modelClass::query()
100
+ ->where('company_uuid', $this->session->get('company'))
101
+ ->where(function ($query) use ($identifier, $instance, $allowUuid) {
102
+ $query->where('public_id', $identifier);
103
+
104
+ if (in_array('internal_id', $instance->getFillable())) {
105
+ $query->orWhere('internal_id', $identifier);
106
+ }
107
+
108
+ if ($allowUuid) {
109
+ $query->orWhere('uuid', $identifier);
110
+ }
111
+ })
112
+ ->pluck('uuid');
113
+ }
59
114
  }