@fleetbase/fleetops-engine 0.6.55 → 0.6.57
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 +1 -1
- package/addon/components/ai/create-order-preview.hbs +297 -0
- package/addon/components/ai/create-order-preview.js +362 -0
- package/addon/components/ai/route-preview-map.hbs +79 -0
- package/addon/components/ai/route-preview-map.js +527 -0
- package/addon/components/device/details.js +1 -1
- package/addon/components/device-event/details.hbs +192 -0
- package/addon/components/device-event/details.js +151 -0
- package/addon/components/driver/schedule.js +1 -1
- package/addon/components/fleet/details.hbs +21 -8
- package/addon/components/fleet/details.js +55 -1
- package/addon/components/fleet/hierarchy-tree.hbs +137 -0
- package/addon/components/fleet/hierarchy-tree.js +528 -0
- package/addon/components/layout/fleet-ops-sidebar.js +15 -9
- package/addon/components/map/drawer/device-event-listing.js +1 -0
- package/addon/components/map/drawer/driver-listing.js +1 -0
- package/addon/components/map/drawer/place-listing.js +1 -0
- package/addon/components/map/drawer/vehicle-listing.js +1 -0
- package/addon/components/order/details.hbs +34 -1
- package/addon/components/order/form/details.hbs +4 -0
- package/addon/components/order/form.hbs +9 -1
- package/addon/components/telematic/details.hbs +1 -1
- package/addon/components/telematic/form.hbs +2 -2
- package/addon/components/telematic/settings.hbs +1 -1
- package/addon/components/vehicle/card.hbs +14 -2
- package/addon/components/vehicle/form.hbs +13 -1
- package/addon/controllers/connectivity/devices/index/details/events.js +1 -1
- package/addon/controllers/connectivity/devices/index/details/vehicle.js +2 -2
- package/addon/controllers/connectivity/events/details.js +68 -1
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/details/events.js +1 -1
- package/addon/controllers/connectivity/telematics/details/sensors.js +4 -0
- package/addon/controllers/settings/map.js +19 -0
- package/addon/extension.js +14 -0
- package/addon/instance-initializers/register-vroom-allocation.js +1 -1
- package/addon/routes/connectivity/events/details.js +26 -1
- package/addon/routes/management/fleets/index/details.js +1 -1
- package/addon/routes/management/vehicles/index/details.js +3 -1
- package/addon/services/map-adapter/google.js +66 -1
- package/addon/services/map-adapter/leaflet.js +1 -1
- package/addon/services/map-adapter-interface.js +1 -1
- package/addon/services/map-manager.js +16 -1
- package/addon/services/map-settings.js +15 -0
- package/addon/styles/fleetops-engine.css +487 -1
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +2 -1
- package/addon/templates/connectivity/events/details.hbs +40 -1
- package/addon/templates/settings/map.hbs +38 -9
- package/addon/utils/leaflet-plugin-loader.js +5 -5
- package/addon/utils/map-drawer-dropdown-position.js +11 -13
- package/addon/utils/route-colors.js +1 -1
- package/app/components/ai/create-order-preview.js +1 -0
- package/app/components/ai/route-preview-map.js +1 -0
- package/app/components/device-event/details.hbs +192 -0
- package/app/components/device-event/details.js +1 -0
- package/app/components/fleet/hierarchy-tree.js +1 -0
- package/app/services/route-engine.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +6 -4
- package/scripts/normalize-rgba-alpha.js +90 -0
- package/server/migrations/2026_06_23_000001_delete_bad_afaqy_telematics_sensors.php +34 -0
- package/server/src/Exports/ContactExport.php +12 -5
- package/server/src/Exports/DeviceExport.php +92 -0
- package/server/src/Exports/DriverExport.php +28 -3
- package/server/src/Exports/EquipmentExport.php +94 -0
- package/server/src/Exports/FleetExport.php +22 -7
- package/server/src/Exports/FuelReportExport.php +16 -1
- package/server/src/Exports/IssueExport.php +25 -3
- package/server/src/Exports/MaintenanceExport.php +106 -0
- package/server/src/Exports/MaintenanceScheduleExport.php +99 -0
- package/server/src/Exports/OrderExport.php +24 -5
- package/server/src/Exports/PartExport.php +99 -0
- package/server/src/Exports/PlaceExport.php +33 -7
- package/server/src/Exports/SensorExport.php +94 -0
- package/server/src/Exports/ServiceAreaExport.php +31 -7
- package/server/src/Exports/ServiceRateExport.php +41 -1
- package/server/src/Exports/TelematicExport.php +90 -0
- package/server/src/Exports/VehicleExport.php +274 -8
- package/server/src/Exports/VendorExport.php +15 -2
- package/server/src/Exports/WorkOrderExport.php +92 -0
- package/server/src/Http/Controllers/Api/v1/Concerns/ResolvesFleetOpsApiResources.php +176 -0
- package/server/src/Http/Controllers/Api/v1/DeviceController.php +225 -0
- package/server/src/Http/Controllers/Api/v1/EquipmentController.php +114 -0
- package/server/src/Http/Controllers/Api/v1/FuelTransactionController.php +185 -0
- package/server/src/Http/Controllers/Api/v1/PartController.php +120 -0
- package/server/src/Http/Controllers/Api/v1/SensorController.php +132 -0
- package/server/src/Http/Controllers/Api/v1/WorkOrderController.php +161 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/EquipmentController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/PartController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/SensorController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +29 -5
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +18 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +17 -0
- package/server/src/Http/Filter/DeviceFilter.php +33 -10
- package/server/src/Http/Filter/EquipmentFilter.php +23 -0
- package/server/src/Http/Filter/FuelProviderTransactionFilter.php +57 -2
- package/server/src/Http/Filter/PartFilter.php +47 -0
- package/server/src/Http/Filter/SensorFilter.php +34 -6
- package/server/src/Http/Filter/WorkOrderFilter.php +23 -0
- package/server/src/Http/Requests/CreateDeviceRequest.php +51 -0
- package/server/src/Http/Requests/CreateEquipmentRequest.php +35 -0
- package/server/src/Http/Requests/CreateFuelTransactionRequest.php +50 -0
- package/server/src/Http/Requests/CreatePartRequest.php +40 -0
- package/server/src/Http/Requests/CreateSensorRequest.php +47 -0
- package/server/src/Http/Requests/CreateWorkOrderRequest.php +42 -0
- package/server/src/Http/Requests/UpdateDeviceRequest.php +7 -0
- package/server/src/Http/Requests/UpdateEquipmentRequest.php +7 -0
- package/server/src/Http/Requests/UpdateFuelTransactionRequest.php +7 -0
- package/server/src/Http/Requests/UpdatePartRequest.php +7 -0
- package/server/src/Http/Requests/UpdateSensorRequest.php +7 -0
- package/server/src/Http/Requests/UpdateWorkOrderRequest.php +7 -0
- package/server/src/Http/Resources/v1/Device.php +72 -0
- package/server/src/Http/Resources/v1/Equipment.php +57 -0
- package/server/src/Http/Resources/v1/Fleet.php +8 -2
- package/server/src/Http/Resources/v1/FuelTransaction.php +69 -0
- package/server/src/Http/Resources/v1/Part.php +64 -0
- package/server/src/Http/Resources/v1/Sensor.php +68 -0
- package/server/src/Jobs/SyncTelematicDevicesJob.php +194 -38
- package/server/src/Models/Driver.php +6 -0
- package/server/src/Models/Order.php +20 -7
- package/server/src/Models/Place.php +11 -3
- package/server/src/Observers/PurchaseRateObserver.php +2 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +26 -0
- package/server/src/Support/Ai/Capabilities/AbstractFleetOpsAICapability.php +88 -0
- package/server/src/Support/Ai/Capabilities/AssetStatusCapability.php +108 -0
- package/server/src/Support/Ai/Capabilities/ConsoleNavigationCapability.php +55 -0
- package/server/src/Support/Ai/Capabilities/CreateOrderPreviewCapability.php +508 -0
- package/server/src/Support/Ai/Capabilities/DocsHelpCapability.php +49 -0
- package/server/src/Support/Ai/Capabilities/ImportOrdersPreviewCapability.php +66 -0
- package/server/src/Support/Ai/Capabilities/OperationalQueryCapability.php +319 -0
- package/server/src/Support/Ai/Capabilities/OptimizeOrderRouteCapability.php +240 -0
- package/server/src/Support/Ai/Capabilities/OrderInsightsCapability.php +95 -0
- package/server/src/Support/Ai/Capabilities/SearchResourcesCapability.php +195 -0
- package/server/src/Support/Ai/FleetOpsAiQueryResources.php +150 -0
- package/server/src/Support/Analytics/RevenueTrend.php +3 -8
- package/server/src/Support/Metrics/ActiveRevenueQuery.php +121 -0
- package/server/src/Support/Metrics/AvgOrderValueMetric.php +1 -7
- package/server/src/Support/Metrics/EarningsMetric.php +1 -10
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +104 -5
- package/server/src/Support/Telematics/Providers/SafeeProvider.php +550 -54
- package/server/src/Support/Telematics/TelematicService.php +28 -9
- package/server/src/Support/Utils.php +52 -0
- package/server/src/routes.php +67 -14
- package/server/tests/AiCreateOrderPreviewCapabilityTest.php +131 -0
- package/server/tests/AiOperationalQueryCapabilityTest.php +75 -0
- package/server/tests/ExportCoverageTest.php +79 -0
- package/server/tests/FleetHierarchyResourceTest.php +12 -0
- package/server/tests/MetricsRegistryTest.php +45 -5
- package/server/tests/OrderPayloadPlaceResolutionTest.php +53 -0
- package/server/tests/PointResolutionTest.php +63 -0
- package/server/tests/PublicFleetOpsRestEndpointsTest.php +191 -0
- package/server/tests/TelematicsHardeningTest.php +636 -1
- package/addon/components/table/cell/dropdown/action-item.hbs +0 -31
- package/addon/components/table/cell/dropdown/action-item.js +0 -62
- package/addon/components/table/cell/dropdown.hbs +0 -28
- package/addon/components/table/cell/dropdown.js +0 -91
- package/app/components/table/cell/dropdown/action-item.js +0 -1
- package/app/components/table/cell/dropdown.js +0 -1
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Exports;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
5
6
|
use Fleetbase\FleetOps\Models\Vehicle;
|
|
7
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
6
8
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
7
9
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
|
8
10
|
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
|
@@ -14,6 +16,14 @@ class VehicleExport implements FromCollection, WithHeadings, WithMapping, WithCo
|
|
|
14
16
|
{
|
|
15
17
|
protected array $selections = [];
|
|
16
18
|
|
|
19
|
+
protected array $dateHeadings = [
|
|
20
|
+
'Purchased At',
|
|
21
|
+
'Lease Expires At',
|
|
22
|
+
'Loan First Payment',
|
|
23
|
+
'Created At',
|
|
24
|
+
'Updated At',
|
|
25
|
+
];
|
|
26
|
+
|
|
17
27
|
public function __construct(array $selections = [])
|
|
18
28
|
{
|
|
19
29
|
$this->selections = $selections;
|
|
@@ -21,15 +31,103 @@ class VehicleExport implements FromCollection, WithHeadings, WithMapping, WithCo
|
|
|
21
31
|
|
|
22
32
|
public function map($vehicle): array
|
|
23
33
|
{
|
|
34
|
+
$currency = $vehicle->currency ?: 'USD';
|
|
35
|
+
|
|
24
36
|
return [
|
|
25
37
|
$vehicle->public_id,
|
|
26
38
|
$vehicle->internal_id,
|
|
27
39
|
$vehicle->display_name,
|
|
28
|
-
$vehicle->
|
|
40
|
+
$vehicle->description,
|
|
41
|
+
$vehicle->plate_number,
|
|
42
|
+
$vehicle->vin,
|
|
29
43
|
$vehicle->make,
|
|
30
44
|
$vehicle->model,
|
|
31
45
|
$vehicle->year,
|
|
46
|
+
$vehicle->trim,
|
|
47
|
+
$vehicle->color,
|
|
48
|
+
$vehicle->serial_number,
|
|
49
|
+
$vehicle->fuel_card_number,
|
|
50
|
+
$vehicle->class,
|
|
51
|
+
$vehicle->type,
|
|
52
|
+
$vehicle->driver_name,
|
|
53
|
+
$vehicle->vendor_name,
|
|
54
|
+
$vehicle->status,
|
|
55
|
+
$this->yesNo($vehicle->online),
|
|
56
|
+
$vehicle->call_sign,
|
|
57
|
+
$this->locationPart($vehicle->location, 'lat'),
|
|
58
|
+
$this->locationPart($vehicle->location, 'lng'),
|
|
59
|
+
$vehicle->heading,
|
|
60
|
+
$vehicle->altitude,
|
|
61
|
+
$vehicle->speed,
|
|
62
|
+
$vehicle->measurement_system,
|
|
63
|
+
$vehicle->fuel_volume_unit,
|
|
64
|
+
$vehicle->odometer,
|
|
65
|
+
$vehicle->odometer_unit,
|
|
66
|
+
$vehicle->odometer_at_purchase,
|
|
67
|
+
$vehicle->body_type,
|
|
68
|
+
$vehicle->body_sub_type,
|
|
69
|
+
$vehicle->usage_type,
|
|
70
|
+
$vehicle->ownership_type,
|
|
71
|
+
$vehicle->fuel_type,
|
|
72
|
+
$vehicle->transmission,
|
|
73
|
+
$vehicle->engine_number,
|
|
74
|
+
$vehicle->engine_make,
|
|
75
|
+
$vehicle->engine_model,
|
|
76
|
+
$vehicle->engine_family,
|
|
77
|
+
$vehicle->engine_configuration,
|
|
78
|
+
$vehicle->cylinder_arrangement,
|
|
79
|
+
$vehicle->number_of_cylinders,
|
|
80
|
+
$vehicle->engine_size,
|
|
81
|
+
$vehicle->engine_displacement,
|
|
82
|
+
$vehicle->horsepower,
|
|
83
|
+
$vehicle->horsepower_rpm,
|
|
84
|
+
$vehicle->torque,
|
|
85
|
+
$vehicle->torque_rpm,
|
|
86
|
+
$vehicle->fuel_capacity,
|
|
87
|
+
$vehicle->payload_capacity,
|
|
88
|
+
$vehicle->towing_capacity,
|
|
89
|
+
$vehicle->seating_capacity,
|
|
90
|
+
$vehicle->weight,
|
|
91
|
+
$vehicle->length,
|
|
92
|
+
$vehicle->width,
|
|
93
|
+
$vehicle->height,
|
|
94
|
+
$vehicle->cargo_volume,
|
|
95
|
+
$vehicle->payload_capacity_volume,
|
|
96
|
+
$vehicle->payload_capacity_pallets,
|
|
97
|
+
$vehicle->payload_capacity_parcels,
|
|
98
|
+
$vehicle->passenger_volume,
|
|
99
|
+
$vehicle->interior_volume,
|
|
100
|
+
$vehicle->ground_clearance,
|
|
101
|
+
$vehicle->bed_length,
|
|
102
|
+
$vehicle->emission_standard,
|
|
103
|
+
$this->yesNo($vehicle->dpf_equipped),
|
|
104
|
+
$this->yesNo($vehicle->scr_equipped),
|
|
105
|
+
$vehicle->gvwr,
|
|
106
|
+
$vehicle->gcwr,
|
|
107
|
+
$vehicle->currency,
|
|
108
|
+
$this->money($vehicle->acquisition_cost, $currency),
|
|
109
|
+
$this->money($vehicle->current_value, $currency),
|
|
110
|
+
$this->money($vehicle->insurance_value, $currency),
|
|
111
|
+
$vehicle->depreciation_rate,
|
|
112
|
+
$vehicle->estimated_service_life_distance,
|
|
113
|
+
$vehicle->estimated_service_life_distance_unit,
|
|
114
|
+
$vehicle->estimated_service_life_months,
|
|
115
|
+
$vehicle->purchased_at,
|
|
116
|
+
$vehicle->lease_expires_at,
|
|
117
|
+
$vehicle->financing_status,
|
|
118
|
+
$this->money($vehicle->loan_amount, $currency),
|
|
119
|
+
$vehicle->loan_number_of_payments,
|
|
120
|
+
$vehicle->loan_first_payment,
|
|
121
|
+
$this->joinSkills($vehicle->skills),
|
|
122
|
+
$vehicle->time_window_start,
|
|
123
|
+
$vehicle->time_window_end,
|
|
124
|
+
$vehicle->max_tasks,
|
|
125
|
+
$this->yesNo($vehicle->return_to_depot),
|
|
126
|
+
$this->assignedOrdersCount($vehicle),
|
|
127
|
+
$this->currentOrderReference($vehicle),
|
|
128
|
+
$vehicle->notes,
|
|
32
129
|
$vehicle->created_at,
|
|
130
|
+
$vehicle->updated_at,
|
|
33
131
|
];
|
|
34
132
|
}
|
|
35
133
|
|
|
@@ -39,19 +137,111 @@ class VehicleExport implements FromCollection, WithHeadings, WithMapping, WithCo
|
|
|
39
137
|
'ID',
|
|
40
138
|
'Internal ID',
|
|
41
139
|
'Name',
|
|
42
|
-
'
|
|
140
|
+
'Description',
|
|
141
|
+
'Plate Number',
|
|
142
|
+
'VIN',
|
|
43
143
|
'Make',
|
|
44
144
|
'Model',
|
|
45
145
|
'Year',
|
|
46
|
-
'
|
|
146
|
+
'Trim',
|
|
147
|
+
'Color',
|
|
148
|
+
'Serial Number',
|
|
149
|
+
'Fuel Card Number',
|
|
150
|
+
'Class',
|
|
151
|
+
'Type',
|
|
152
|
+
'Driver',
|
|
153
|
+
'Vendor',
|
|
154
|
+
'Status',
|
|
155
|
+
'Online',
|
|
156
|
+
'Call Sign',
|
|
157
|
+
'Latitude',
|
|
158
|
+
'Longitude',
|
|
159
|
+
'Heading',
|
|
160
|
+
'Altitude',
|
|
161
|
+
'Speed',
|
|
162
|
+
'Measurement System',
|
|
163
|
+
'Fuel Volume Unit',
|
|
164
|
+
'Odometer',
|
|
165
|
+
'Odometer Unit',
|
|
166
|
+
'Odometer At Purchase',
|
|
167
|
+
'Body Type',
|
|
168
|
+
'Body Sub Type',
|
|
169
|
+
'Usage Type',
|
|
170
|
+
'Ownership Type',
|
|
171
|
+
'Fuel Type',
|
|
172
|
+
'Transmission',
|
|
173
|
+
'Engine Number',
|
|
174
|
+
'Engine Make',
|
|
175
|
+
'Engine Model',
|
|
176
|
+
'Engine Family',
|
|
177
|
+
'Engine Configuration',
|
|
178
|
+
'Cylinder Arrangement',
|
|
179
|
+
'Number Of Cylinders',
|
|
180
|
+
'Engine Size (L)',
|
|
181
|
+
'Engine Displacement (cc)',
|
|
182
|
+
'Horsepower (hp)',
|
|
183
|
+
'Horsepower RPM',
|
|
184
|
+
'Torque (Nm)',
|
|
185
|
+
'Torque RPM',
|
|
186
|
+
'Fuel Capacity (L)',
|
|
187
|
+
'Payload Capacity (kg)',
|
|
188
|
+
'Towing Capacity (kg)',
|
|
189
|
+
'Seating Capacity',
|
|
190
|
+
'Weight (kg)',
|
|
191
|
+
'Length (cm)',
|
|
192
|
+
'Width (cm)',
|
|
193
|
+
'Height (cm)',
|
|
194
|
+
'Cargo Volume (L)',
|
|
195
|
+
'Payload Volume (m3)',
|
|
196
|
+
'Payload Pallets',
|
|
197
|
+
'Payload Parcels',
|
|
198
|
+
'Passenger Volume (L)',
|
|
199
|
+
'Interior Volume (L)',
|
|
200
|
+
'Ground Clearance (cm)',
|
|
201
|
+
'Bed Length (cm)',
|
|
202
|
+
'Emission Standard',
|
|
203
|
+
'DPF Equipped',
|
|
204
|
+
'SCR Equipped',
|
|
205
|
+
'GVWR (kg)',
|
|
206
|
+
'GCWR (kg)',
|
|
207
|
+
'Currency',
|
|
208
|
+
'Acquisition Cost',
|
|
209
|
+
'Current Value',
|
|
210
|
+
'Insurance Value',
|
|
211
|
+
'Depreciation Rate',
|
|
212
|
+
'Estimated Service Life Distance',
|
|
213
|
+
'Estimated Service Life Distance Unit',
|
|
214
|
+
'Estimated Service Life Months',
|
|
215
|
+
'Purchased At',
|
|
216
|
+
'Lease Expires At',
|
|
217
|
+
'Financing Status',
|
|
218
|
+
'Loan Amount',
|
|
219
|
+
'Loan Number Of Payments',
|
|
220
|
+
'Loan First Payment',
|
|
221
|
+
'Vehicle Skills',
|
|
222
|
+
'Time Window Start',
|
|
223
|
+
'Time Window End',
|
|
224
|
+
'Max Tasks',
|
|
225
|
+
'Return To Depot',
|
|
226
|
+
'Assigned Order Count',
|
|
227
|
+
'Current Order Reference',
|
|
228
|
+
'Notes',
|
|
229
|
+
'Created At',
|
|
230
|
+
'Updated At',
|
|
47
231
|
];
|
|
48
232
|
}
|
|
49
233
|
|
|
50
234
|
public function columnFormats(): array
|
|
51
235
|
{
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
236
|
+
return collect($this->headings())
|
|
237
|
+
->mapWithKeys(function ($heading, $index) {
|
|
238
|
+
if (!in_array($heading, $this->dateHeadings, true)) {
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return [$this->columnLetter($index + 1) => NumberFormat::FORMAT_DATE_DDMMYYYY];
|
|
243
|
+
})
|
|
244
|
+
->all();
|
|
55
245
|
}
|
|
56
246
|
|
|
57
247
|
/**
|
|
@@ -59,10 +249,86 @@ class VehicleExport implements FromCollection, WithHeadings, WithMapping, WithCo
|
|
|
59
249
|
*/
|
|
60
250
|
public function collection()
|
|
61
251
|
{
|
|
252
|
+
$query = Vehicle::where('company_uuid', session('company'))->with(['driver.currentOrder', 'vendor']);
|
|
253
|
+
|
|
62
254
|
if ($this->selections) {
|
|
63
|
-
|
|
255
|
+
$query->whereIn('uuid', $this->selections);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return $query->get();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
protected function yesNo($value): ?string
|
|
262
|
+
{
|
|
263
|
+
if ($value === null) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return filter_var($value, FILTER_VALIDATE_BOOLEAN) ? 'Yes' : 'No';
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
protected function joinSkills($skills): ?string
|
|
271
|
+
{
|
|
272
|
+
if (empty($skills)) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (is_string($skills)) {
|
|
277
|
+
return $skills;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return collect($skills)->filter()->values()->join(', ');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
protected function locationPart($location, string $part)
|
|
284
|
+
{
|
|
285
|
+
$location = Utils::castPoint($location);
|
|
286
|
+
|
|
287
|
+
if (!$location) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if ($part === 'lat') {
|
|
292
|
+
return method_exists($location, 'getLat') ? $location->getLat() : data_get($location, 'latitude', data_get($location, 'lat'));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return method_exists($location, 'getLng') ? $location->getLng() : data_get($location, 'longitude', data_get($location, 'lng'));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
protected function money($amount, ?string $currency = 'USD'): ?string
|
|
299
|
+
{
|
|
300
|
+
if ($amount === null || $amount === '') {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return Utils::moneyFormat($amount, $currency ?: 'USD');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
protected function assignedOrdersCount(Vehicle $vehicle): int
|
|
308
|
+
{
|
|
309
|
+
return Order::where('vehicle_assigned_uuid', $vehicle->uuid)->count();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
protected function currentOrderReference(Vehicle $vehicle): ?string
|
|
313
|
+
{
|
|
314
|
+
$order = data_get($vehicle, 'driver.currentOrder') ?? Order::where('vehicle_assigned_uuid', $vehicle->uuid)
|
|
315
|
+
->whereNotIn('status', ['completed', 'canceled', 'cancelled'])
|
|
316
|
+
->latest()
|
|
317
|
+
->first();
|
|
318
|
+
|
|
319
|
+
return data_get($order, 'tracking') ?? data_get($order, 'public_id');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
protected function columnLetter(int $index): string
|
|
323
|
+
{
|
|
324
|
+
$letter = '';
|
|
325
|
+
|
|
326
|
+
while ($index > 0) {
|
|
327
|
+
$index--;
|
|
328
|
+
$letter = chr(65 + ($index % 26)) . $letter;
|
|
329
|
+
$index = intdiv($index, 26);
|
|
64
330
|
}
|
|
65
331
|
|
|
66
|
-
return
|
|
332
|
+
return $letter;
|
|
67
333
|
}
|
|
68
334
|
}
|
|
@@ -25,10 +25,16 @@ class VendorExport implements FromCollection, WithHeadings, WithMapping, WithCol
|
|
|
25
25
|
$vendor->public_id,
|
|
26
26
|
$vendor->internal_id,
|
|
27
27
|
$vendor->name,
|
|
28
|
+
$vendor->business_id,
|
|
28
29
|
$vendor->address,
|
|
29
30
|
$vendor->email,
|
|
31
|
+
$vendor->website_url,
|
|
30
32
|
$vendor->phone,
|
|
33
|
+
$vendor->type,
|
|
34
|
+
$vendor->country,
|
|
35
|
+
$vendor->status,
|
|
31
36
|
$vendor->created_at,
|
|
37
|
+
$vendor->updated_at,
|
|
32
38
|
];
|
|
33
39
|
}
|
|
34
40
|
|
|
@@ -38,18 +44,25 @@ class VendorExport implements FromCollection, WithHeadings, WithMapping, WithCol
|
|
|
38
44
|
'ID',
|
|
39
45
|
'Internal ID',
|
|
40
46
|
'Name',
|
|
47
|
+
'Business ID',
|
|
41
48
|
'Address',
|
|
42
49
|
'Email',
|
|
50
|
+
'Website URL',
|
|
43
51
|
'Phone',
|
|
52
|
+
'Type',
|
|
53
|
+
'Country',
|
|
54
|
+
'Status',
|
|
44
55
|
'Date Created',
|
|
56
|
+
'Date Updated',
|
|
45
57
|
];
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
public function columnFormats(): array
|
|
49
61
|
{
|
|
50
62
|
return [
|
|
51
|
-
'
|
|
52
|
-
'
|
|
63
|
+
'H' => '+#',
|
|
64
|
+
'L' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
65
|
+
'M' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
53
66
|
];
|
|
54
67
|
}
|
|
55
68
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Exports;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\WorkOrder;
|
|
6
|
+
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
7
|
+
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
|
8
|
+
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
|
9
|
+
use Maatwebsite\Excel\Concerns\WithHeadings;
|
|
10
|
+
use Maatwebsite\Excel\Concerns\WithMapping;
|
|
11
|
+
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
|
12
|
+
|
|
13
|
+
class WorkOrderExport implements FromCollection, WithHeadings, WithMapping, WithColumnFormatting, ShouldAutoSize
|
|
14
|
+
{
|
|
15
|
+
protected array $selections = [];
|
|
16
|
+
|
|
17
|
+
public function __construct(array $selections = [])
|
|
18
|
+
{
|
|
19
|
+
$this->selections = $selections;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public function map($workOrder): array
|
|
23
|
+
{
|
|
24
|
+
return [
|
|
25
|
+
$workOrder->public_id,
|
|
26
|
+
$workOrder->code,
|
|
27
|
+
$workOrder->subject,
|
|
28
|
+
$workOrder->category,
|
|
29
|
+
$workOrder->status,
|
|
30
|
+
$workOrder->priority,
|
|
31
|
+
$workOrder->target_name,
|
|
32
|
+
$workOrder->assignee_name,
|
|
33
|
+
$workOrder->opened_at,
|
|
34
|
+
$workOrder->due_at,
|
|
35
|
+
$workOrder->closed_at,
|
|
36
|
+
$workOrder->completion_percentage,
|
|
37
|
+
$this->yesNo($workOrder->is_overdue),
|
|
38
|
+
$workOrder->days_until_due,
|
|
39
|
+
$workOrder->created_at,
|
|
40
|
+
$workOrder->updated_at,
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public function headings(): array
|
|
45
|
+
{
|
|
46
|
+
return [
|
|
47
|
+
'ID',
|
|
48
|
+
'Code',
|
|
49
|
+
'Subject',
|
|
50
|
+
'Category',
|
|
51
|
+
'Status',
|
|
52
|
+
'Priority',
|
|
53
|
+
'Target',
|
|
54
|
+
'Assignee',
|
|
55
|
+
'Opened At',
|
|
56
|
+
'Due At',
|
|
57
|
+
'Closed At',
|
|
58
|
+
'Completion Percentage',
|
|
59
|
+
'Overdue',
|
|
60
|
+
'Days Until Due',
|
|
61
|
+
'Date Created',
|
|
62
|
+
'Date Updated',
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public function columnFormats(): array
|
|
67
|
+
{
|
|
68
|
+
return [
|
|
69
|
+
'I' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
70
|
+
'J' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
71
|
+
'K' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
72
|
+
'O' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
73
|
+
'P' => NumberFormat::FORMAT_DATE_DDMMYYYY,
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public function collection()
|
|
78
|
+
{
|
|
79
|
+
$query = WorkOrder::where('company_uuid', session('company'))->with(['target', 'assignee']);
|
|
80
|
+
|
|
81
|
+
if ($this->selections) {
|
|
82
|
+
$query->whereIn('uuid', $this->selections);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return $query->get();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected function yesNo($value): string
|
|
89
|
+
{
|
|
90
|
+
return $value ? 'Yes' : 'No';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Http\Controllers\Api\v1\Concerns;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\Contact;
|
|
6
|
+
use Fleetbase\FleetOps\Models\Device;
|
|
7
|
+
use Fleetbase\FleetOps\Models\Driver;
|
|
8
|
+
use Fleetbase\FleetOps\Models\Equipment;
|
|
9
|
+
use Fleetbase\FleetOps\Models\FuelProviderConnection;
|
|
10
|
+
use Fleetbase\FleetOps\Models\FuelReport;
|
|
11
|
+
use Fleetbase\FleetOps\Models\Order;
|
|
12
|
+
use Fleetbase\FleetOps\Models\Part;
|
|
13
|
+
use Fleetbase\FleetOps\Models\Telematic;
|
|
14
|
+
use Fleetbase\FleetOps\Models\Vehicle;
|
|
15
|
+
use Fleetbase\FleetOps\Models\Vendor;
|
|
16
|
+
use Fleetbase\FleetOps\Models\Warranty;
|
|
17
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
18
|
+
use Fleetbase\Models\File;
|
|
19
|
+
use Illuminate\Database\Eloquent\Model;
|
|
20
|
+
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
21
|
+
use Illuminate\Http\Request;
|
|
22
|
+
use Illuminate\Validation\ValidationException;
|
|
23
|
+
|
|
24
|
+
trait ResolvesFleetOpsApiResources
|
|
25
|
+
{
|
|
26
|
+
protected function resolveUuid(string $modelClass, ?string $id): ?string
|
|
27
|
+
{
|
|
28
|
+
if (empty($id)) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return $this->resolveModel($modelClass, $id)->uuid;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected function resolveModel(string $modelClass, string $id): Model
|
|
36
|
+
{
|
|
37
|
+
$instance = new $modelClass();
|
|
38
|
+
$query = $modelClass::query()->where(function ($query) use ($id, $instance) {
|
|
39
|
+
$query->whereRaw('0 = 1');
|
|
40
|
+
|
|
41
|
+
if (in_array('public_id', $instance->getFillable()) || method_exists($instance, 'getPublicIdType')) {
|
|
42
|
+
$query->orWhere('public_id', $id);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (in_array('internal_id', $instance->getFillable())) {
|
|
46
|
+
$query->orWhere('internal_id', $id);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (session('company') && $this->modelHasColumn($instance, 'company_uuid')) {
|
|
51
|
+
$query->where($instance->qualifyColumn('company_uuid'), session('company'));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
$model = $query->first();
|
|
55
|
+
if ($model) {
|
|
56
|
+
return $model;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw (new ModelNotFoundException())->setModel($modelClass, $id);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected function resolveMorph(?string $type, ?string $id): array
|
|
63
|
+
{
|
|
64
|
+
if (empty($type) || empty($id)) {
|
|
65
|
+
return [null, null];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
$modelClass = Utils::getMutationType($type);
|
|
69
|
+
$model = $this->resolveModel($modelClass, $id);
|
|
70
|
+
|
|
71
|
+
return [$modelClass, $model->uuid];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected function rejectUuidIdentifiers(Request $request): void
|
|
75
|
+
{
|
|
76
|
+
$invalidKeys = array_unique(array_merge(
|
|
77
|
+
$this->collectUuidIdentifierKeys($request->query->all()),
|
|
78
|
+
$this->collectUuidIdentifierKeys($request->request->all())
|
|
79
|
+
));
|
|
80
|
+
|
|
81
|
+
if (empty($invalidKeys)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
$messages = [];
|
|
86
|
+
foreach ($invalidKeys as $key) {
|
|
87
|
+
$messages[$key] = ['UUID identifiers are not accepted by the public API. Use public_id or internal_id values instead.'];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw ValidationException::withMessages($messages);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected function collectUuidIdentifierKeys(array $input, string $prefix = ''): array
|
|
94
|
+
{
|
|
95
|
+
$keys = [];
|
|
96
|
+
|
|
97
|
+
foreach ($input as $key => $value) {
|
|
98
|
+
$path = $prefix ? $prefix . '.' . $key : (string) $key;
|
|
99
|
+
|
|
100
|
+
if ($this->isUuidIdentifierKey((string) $key)) {
|
|
101
|
+
$keys[] = $path;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (is_array($value)) {
|
|
105
|
+
$keys = array_merge($keys, $this->collectUuidIdentifierKeys($value, $path));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return $keys;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected function isUuidIdentifierKey(string $key): bool
|
|
113
|
+
{
|
|
114
|
+
return preg_match('/(^uuid$|_uuid$|Uuid$|UUID$)/', $key) === 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
protected function applyPublicIdRelation(array &$input, string $requestKey, string $column, string $modelClass, $request): void
|
|
118
|
+
{
|
|
119
|
+
if (!$request->exists($requestKey)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
$input[$column] = filled($request->input($requestKey))
|
|
124
|
+
? $this->resolveUuid($modelClass, $request->input($requestKey))
|
|
125
|
+
: null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
protected function allowedMorphTypes(): array
|
|
129
|
+
{
|
|
130
|
+
return [
|
|
131
|
+
'fleet-ops:vehicle' => Vehicle::class,
|
|
132
|
+
'vehicle' => Vehicle::class,
|
|
133
|
+
Vehicle::class => Vehicle::class,
|
|
134
|
+
'fleet-ops:driver' => Driver::class,
|
|
135
|
+
'driver' => Driver::class,
|
|
136
|
+
Driver::class => Driver::class,
|
|
137
|
+
'fleet-ops:equipment' => Equipment::class,
|
|
138
|
+
'equipment' => Equipment::class,
|
|
139
|
+
Equipment::class => Equipment::class,
|
|
140
|
+
'fleet-ops:part' => Part::class,
|
|
141
|
+
'part' => Part::class,
|
|
142
|
+
Part::class => Part::class,
|
|
143
|
+
'fleet-ops:vendor' => Vendor::class,
|
|
144
|
+
'vendor' => Vendor::class,
|
|
145
|
+
Vendor::class => Vendor::class,
|
|
146
|
+
'fleet-ops:contact' => Contact::class,
|
|
147
|
+
'contact' => Contact::class,
|
|
148
|
+
Contact::class => Contact::class,
|
|
149
|
+
'fleet-ops:device' => Device::class,
|
|
150
|
+
'device' => Device::class,
|
|
151
|
+
Device::class => Device::class,
|
|
152
|
+
'fleet-ops:telematic' => Telematic::class,
|
|
153
|
+
'telematic' => Telematic::class,
|
|
154
|
+
Telematic::class => Telematic::class,
|
|
155
|
+
'fleet-ops:warranty' => Warranty::class,
|
|
156
|
+
'warranty' => Warranty::class,
|
|
157
|
+
Warranty::class => Warranty::class,
|
|
158
|
+
'fleet-ops:fuel-report' => FuelReport::class,
|
|
159
|
+
'fuel-report' => FuelReport::class,
|
|
160
|
+
FuelReport::class => FuelReport::class,
|
|
161
|
+
'fleet-ops:fuel-provider-connection' => FuelProviderConnection::class,
|
|
162
|
+
'fuel-provider-connection' => FuelProviderConnection::class,
|
|
163
|
+
FuelProviderConnection::class => FuelProviderConnection::class,
|
|
164
|
+
'fleet-ops:order' => Order::class,
|
|
165
|
+
'order' => Order::class,
|
|
166
|
+
Order::class => Order::class,
|
|
167
|
+
'file' => File::class,
|
|
168
|
+
File::class => File::class,
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
protected function modelHasColumn(Model $model, string $column): bool
|
|
173
|
+
{
|
|
174
|
+
return in_array($column, $model->getFillable()) || $column === $model->getKeyName();
|
|
175
|
+
}
|
|
176
|
+
}
|