@fleetbase/fleetops-engine 0.6.69 → 0.6.70
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/RELEASE.md +41 -8
- package/addon/components/admin/telematics-settings.hbs +143 -0
- package/addon/components/admin/telematics-settings.js +145 -0
- package/addon/components/fuel-integration/hub.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +37 -17
- package/addon/components/map/leaflet-live-map.hbs +4 -242
- package/addon/components/map/leaflet-live-map.js +2 -1
- package/addon/components/map/marker-card/driver.hbs +57 -0
- package/addon/components/map/marker-card/driver.js +3 -0
- package/addon/components/map/marker-card/vehicle.hbs +78 -0
- package/addon/components/map/marker-card/vehicle.js +3 -0
- package/addon/components/telematic/hub.hbs +1 -1
- package/addon/components/widget/live-fleet.hbs +8 -40
- package/addon/controllers/analytics/reports/index.js +5 -0
- package/addon/controllers/connectivity/devices/index.js +4 -0
- package/addon/controllers/connectivity/fuel-providers/index.js +6 -4
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/index.js +4 -0
- package/addon/controllers/maintenance/equipment/index.js +11 -4
- package/addon/controllers/maintenance/inspection-forms/index.js +2 -2
- package/addon/controllers/maintenance/inspection-submissions/index.js +8 -2
- package/addon/controllers/maintenance/maintenances/index.js +4 -0
- package/addon/controllers/maintenance/parts/index.js +11 -4
- package/addon/controllers/maintenance/schedules/index.js +17 -4
- package/addon/controllers/maintenance/work-orders/index.js +11 -4
- package/addon/controllers/management/contacts/index.js +4 -0
- package/addon/controllers/management/drivers/index.js +4 -0
- package/addon/controllers/management/fleets/index.js +4 -0
- package/addon/controllers/management/fuel-reports/index.js +4 -0
- package/addon/controllers/management/fuel-transactions/index.js +9 -7
- package/addon/controllers/management/issues/index.js +4 -0
- package/addon/controllers/management/places/index.js +4 -0
- package/addon/controllers/management/vehicles/index.js +4 -0
- package/addon/controllers/management/vendors/index.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +30 -1
- package/addon/controllers/operations/orders/index.js +7 -0
- package/addon/controllers/operations/service-rates/index.js +3 -0
- package/addon/controllers/settings/index.js +13 -0
- package/addon/controllers/settings/telematics.js +113 -0
- package/addon/extension.js +38 -6
- package/addon/routes/analytics/index.js +14 -1
- package/addon/routes/analytics/reports/index/details.js +1 -1
- package/addon/routes/analytics/reports/index/edit.js +1 -1
- package/addon/routes/analytics/reports/index/new.js +14 -1
- package/addon/routes/analytics/reports.js +14 -1
- package/addon/routes/connectivity/devices/index/new.js +14 -1
- package/addon/routes/connectivity/devices.js +14 -1
- package/addon/routes/connectivity/events.js +14 -1
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +12 -0
- package/addon/routes/connectivity/fuel-providers/details.js +9 -0
- package/addon/routes/connectivity/fuel-providers/edit.js +9 -0
- package/addon/routes/connectivity/fuel-providers/new.js +14 -1
- package/addon/routes/connectivity/fuel-providers.js +14 -1
- package/addon/routes/connectivity/sensors/index/new.js +14 -1
- package/addon/routes/connectivity/sensors.js +14 -1
- package/addon/routes/connectivity/telematics/new.js +14 -1
- package/addon/routes/connectivity/telematics.js +14 -1
- package/addon/routes/connectivity/tracking.js +14 -1
- package/addon/routes/maintenance/equipment/index/details.js +2 -2
- package/addon/routes/maintenance/equipment/index/edit.js +2 -2
- package/addon/routes/maintenance/equipment/index/new.js +14 -1
- package/addon/routes/maintenance/equipment.js +14 -1
- package/addon/routes/maintenance/index.js +14 -1
- package/addon/routes/maintenance/inspection-forms/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-forms.js +14 -1
- package/addon/routes/maintenance/inspection-submissions/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-submissions.js +14 -1
- package/addon/routes/maintenance/maintenances/index/details.js +2 -2
- package/addon/routes/maintenance/maintenances/index/edit.js +2 -2
- package/addon/routes/maintenance/maintenances/index/new.js +14 -1
- package/addon/routes/maintenance/maintenances.js +14 -1
- package/addon/routes/maintenance/parts/index/details.js +2 -2
- package/addon/routes/maintenance/parts/index/edit.js +2 -2
- package/addon/routes/maintenance/parts/index/new.js +14 -1
- package/addon/routes/maintenance/parts.js +14 -1
- package/addon/routes/maintenance/schedules/index/details.js +2 -2
- package/addon/routes/maintenance/schedules/index/edit.js +2 -2
- package/addon/routes/maintenance/schedules/index/new.js +15 -1
- package/addon/routes/maintenance/schedules.js +15 -1
- package/addon/routes/maintenance/work-orders/index/details.js +2 -2
- package/addon/routes/maintenance/work-orders/index/edit.js +2 -2
- package/addon/routes/maintenance/work-orders/index/new.js +14 -1
- package/addon/routes/maintenance/work-orders.js +14 -1
- package/addon/routes/management/fuel-transactions/index/details.js +9 -0
- package/addon/routes/management/fuel-transactions.js +14 -1
- package/addon/routes/management/index.js +13 -0
- package/addon/routes/management/trailers.js +16 -0
- package/addon/routes/management/vendors/integrated/details.js +14 -1
- package/addon/routes/management/vendors/integrated/edit.js +14 -1
- package/addon/routes/management/vendors/integrated/new.js +14 -1
- package/addon/routes/management/vendors/integrated.js +14 -1
- package/addon/routes/operations/orders.js +40 -1
- package/addon/routes/operations/routes/index/details.js +14 -1
- package/addon/routes/operations/routes/index/new.js +13 -0
- package/addon/routes/operations/routes.js +14 -1
- package/addon/routes/operations/service-rates/index/new.js +11 -0
- package/addon/routes/operations/service-rates.js +14 -1
- package/addon/routes/settings/avatars.js +14 -1
- package/addon/routes/settings/custom-fields.js +14 -1
- package/addon/routes/settings/map.js +14 -1
- package/addon/routes/settings/notifications.js +11 -0
- package/addon/routes/settings/orchestrator.js +1 -1
- package/addon/routes/settings/payments/index.js +1 -1
- package/addon/routes/settings/routing.js +14 -1
- package/addon/routes/settings/scheduling.js +14 -1
- package/addon/routes/settings/telematics.js +21 -0
- package/addon/routes/virtual.js +11 -0
- package/addon/routes.js +1 -0
- package/addon/templates/settings/telematics.hbs +70 -0
- package/app/components/admin/telematics-settings.js +1 -0
- package/app/components/map/marker-card/driver.js +1 -0
- package/app/components/map/marker-card/vehicle.js +1 -0
- package/app/controllers/settings/telematics.js +1 -0
- package/app/routes/settings/telematics.js +1 -0
- package/app/templates/settings/telematics.js +1 -0
- package/composer.json +2 -2
- package/docs/AFAQY.md +1 -1
- package/docs/TELEMATICS_QUEUES.md +1 -1
- package/docs/TELEMETRY_ARCHITECTURE.md +72 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/config/telemetry.php +12 -0
- package/server/migrations/2026_09_23_000001_add_retention_index_to_device_events.php +40 -0
- package/server/migrations/2026_09_23_000002_add_retention_index_to_positions.php +40 -0
- package/server/migrations/2026_09_23_000003_add_retention_index_to_telematic_sync_runs.php +40 -0
- package/server/src/Auth/Schemas/FleetOps.php +104 -5
- package/server/src/Console/Commands/DrainTelematicInbox.php +3 -13
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +3 -3
- package/server/src/Console/Commands/PruneTelematicsData.php +318 -0
- package/server/src/Http/Controllers/Api/v1/OrchestrationController.php +9 -0
- package/server/src/Http/Controllers/FleetOpsController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +14 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/InspectionFormController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +42 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +12 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/PaymentController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/RadarController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +465 -14
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +11 -0
- package/server/src/Jobs/DispatchTelematicsRetentionJobs.php +70 -0
- package/server/src/Jobs/PruneTelematicsDataJob.php +74 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +3 -3
- package/server/src/Mail/CustomerCredentialsMail.php +1 -1
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +9 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +3 -0
- package/server/src/Support/Analytics/LiveFleet.php +18 -2
- package/server/src/Support/Authorization.php +103 -0
- package/server/src/Support/Database/TableIndexes.php +66 -0
- package/server/src/Support/OrderTracker.php +2 -2
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +476 -116
- package/server/src/Support/Telematics/Retention/RetentionPolicy.php +300 -0
- package/server/src/Support/Telematics/Retention/TelemetryActivity.php +40 -0
- package/server/src/Support/Telematics/TelematicService.php +12 -2
- package/server/src/Support/Telematics/Telemetry/Ingestor.php +4 -2
- package/server/src/Tracking/TrackingIntelligenceService.php +1 -1
- package/server/src/Tracking/TrackingOptions.php +2 -2
- package/server/src/Traits/AuthorizesMethods.php +37 -0
- package/server/src/routes.php +9 -1
- package/server/tests/AnalyticsRoutesTest.php +29 -2
- package/server/tests/Feature/Http/AfaqyRealtimeIngestionTest.php +16 -1
- package/server/tests/Feature/Http/Api/TelematicsRetentionIndexMigrationTest.php +115 -0
- package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +71 -0
- package/server/tests/Feature/Http/Internal/TelematicsStorageDeadlinesTest.php +119 -0
- package/server/tests/InternalImportExportControllerContractsTest.php +5 -8
- package/server/tests/NavigatorControllerContractsTest.php +36 -4
- package/server/tests/NotificationAndMailContractsTest.php +31 -0
- package/server/tests/ObserverContractsTest.php +1 -1
- package/server/tests/OrchestratorConsumableApiTest.php +42 -0
- package/server/tests/ProviderContractsTest.php +10 -0
- package/server/tests/ReportSchemaContractsTest.php +120 -6
- package/server/tests/SettingControllerContractsTest.php +429 -18
- package/server/tests/SmallControllerContractsTest.php +8 -5
- package/server/tests/Support/PruneTelematicsDataProbe.php +55 -0
- package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +2 -2
- package/server/tests/Unit/Console/PruneTelematicsDataCommandTest.php +353 -0
- package/server/tests/Unit/Jobs/DispatchTelematicsRetentionJobsTest.php +114 -0
- package/server/tests/Unit/Jobs/PruneTelematicsDataJobTest.php +60 -0
- package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +20 -0
- package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +6 -0
- package/server/tests/Unit/Support/AuthorizationTest.php +142 -0
- package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +12 -1
- package/server/tests/Unit/Support/MoreQuerySeamsTest.php +11 -2
- package/server/tests/Unit/Support/Telematics/Retention/RetentionPolicyTest.php +190 -0
- package/server/tests/Unit/Support/Telematics/Retention/TelemetryActivityTest.php +68 -0
- package/server/tests/Unit/Tracking/TrackingOptionsCompanySettingsTest.php +109 -0
- package/translations/en-us.yaml +48 -0
|
@@ -47,12 +47,20 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Create the Orders table definition.
|
|
50
|
+
*
|
|
51
|
+
* Money is stored in the currency's smallest unit (e.g. cents). `meta` has no fixed shape
|
|
52
|
+
* (it holds whatever users, integrations and extensions put there), so no column assumes a
|
|
53
|
+
* key in it; read one with a computed column, e.g.
|
|
54
|
+
* `CAST(JSON_UNQUOTE(JSON_EXTRACT(meta, '$.total')) AS DECIMAL(15,2))`.
|
|
55
|
+
*
|
|
56
|
+
* Selecting line item columns (Payload Items) returns one row per item, so order-level
|
|
57
|
+
* sums over item rows repeat each order; count orders with Total Orders (a distinct count).
|
|
50
58
|
*/
|
|
51
59
|
protected function createOrdersTable(): Table
|
|
52
60
|
{
|
|
53
|
-
return Table::make('orders')
|
|
61
|
+
return $this->softDeletes(Table::make('orders'))
|
|
54
62
|
->label('Orders')
|
|
55
|
-
->description('Delivery and service orders')
|
|
63
|
+
->description('Delivery and service orders, with their payload items, tracking, assignment and payment')
|
|
56
64
|
->category('Operations')
|
|
57
65
|
->extension('fleet-ops')
|
|
58
66
|
->excludeColumns(['uuid', 'deleted_at']) // Hide foreign keys and system columns
|
|
@@ -60,7 +68,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
60
68
|
->cacheTtl(3600)
|
|
61
69
|
->columns([
|
|
62
70
|
Column::make('public_id', 'string')
|
|
63
|
-
->label('
|
|
71
|
+
->label('ID')
|
|
64
72
|
->description('Public order identifier')
|
|
65
73
|
->searchable()
|
|
66
74
|
->filterable()
|
|
@@ -94,8 +102,21 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
94
102
|
}),
|
|
95
103
|
|
|
96
104
|
Column::make('type', 'string')
|
|
97
|
-
->label('
|
|
98
|
-
->description('Type of order service')
|
|
105
|
+
->label('Type')
|
|
106
|
+
->description('Type of order service, e.g. transport or storefront')
|
|
107
|
+
->filterable()
|
|
108
|
+
->sortable()
|
|
109
|
+
->aggregatable(),
|
|
110
|
+
|
|
111
|
+
Column::make('customer_type', 'string')
|
|
112
|
+
->label('Customer Kind')
|
|
113
|
+
->description('Whether the customer is a contact or a vendor')
|
|
114
|
+
->filterable()
|
|
115
|
+
->aggregatable(),
|
|
116
|
+
|
|
117
|
+
Column::make('facilitator_type', 'string')
|
|
118
|
+
->label('Facilitator Kind')
|
|
119
|
+
->description('Whether the facilitator is a vendor or an integrated vendor')
|
|
99
120
|
->filterable()
|
|
100
121
|
->aggregatable(),
|
|
101
122
|
|
|
@@ -106,6 +127,12 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
106
127
|
->sortable()
|
|
107
128
|
->aggregatable(),
|
|
108
129
|
|
|
130
|
+
Column::make('dispatched', 'boolean')
|
|
131
|
+
->label('Dispatched')
|
|
132
|
+
->description('Whether the order has been dispatched')
|
|
133
|
+
->filterable()
|
|
134
|
+
->aggregatable(),
|
|
135
|
+
|
|
109
136
|
Column::make('dispatched_at', 'datetime')
|
|
110
137
|
->label('Dispatched At')
|
|
111
138
|
->description('When the order was dispatched')
|
|
@@ -113,6 +140,12 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
113
140
|
->sortable()
|
|
114
141
|
->aggregatable(),
|
|
115
142
|
|
|
143
|
+
Column::make('started', 'boolean')
|
|
144
|
+
->label('Started')
|
|
145
|
+
->description('Whether the order has been started')
|
|
146
|
+
->filterable()
|
|
147
|
+
->aggregatable(),
|
|
148
|
+
|
|
116
149
|
Column::make('started_at', 'datetime')
|
|
117
150
|
->label('Started At')
|
|
118
151
|
->description('When the order was started')
|
|
@@ -120,18 +153,29 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
120
153
|
->sortable()
|
|
121
154
|
->aggregatable(),
|
|
122
155
|
|
|
156
|
+
Column::make('time_window_start', 'datetime')
|
|
157
|
+
->label('Time Window Start')
|
|
158
|
+
->description('Earliest time the order may be serviced')
|
|
159
|
+
->filterable()
|
|
160
|
+
->sortable(),
|
|
161
|
+
|
|
162
|
+
Column::make('time_window_end', 'datetime')
|
|
163
|
+
->label('Time Window End')
|
|
164
|
+
->description('Latest time the order may be serviced')
|
|
165
|
+
->filterable()
|
|
166
|
+
->sortable(),
|
|
167
|
+
|
|
123
168
|
Column::make('distance', 'integer')
|
|
124
|
-
->label('Distance (
|
|
125
|
-
->description('
|
|
169
|
+
->label('Distance (m)')
|
|
170
|
+
->description('Route distance for the order in meters')
|
|
171
|
+
->filterable()
|
|
126
172
|
->aggregatable()
|
|
127
|
-
->sortable()
|
|
128
|
-
->transformer(function ($value) {
|
|
129
|
-
return round($value * 0.621371, 2); // Convert km to miles
|
|
130
|
-
}),
|
|
173
|
+
->sortable(),
|
|
131
174
|
|
|
132
175
|
Column::make('time', 'integer')
|
|
133
|
-
->label('Duration (
|
|
134
|
-
->description('Estimated duration in
|
|
176
|
+
->label('Duration (s)')
|
|
177
|
+
->description('Estimated route duration in seconds')
|
|
178
|
+
->filterable()
|
|
135
179
|
->aggregatable()
|
|
136
180
|
->sortable(),
|
|
137
181
|
|
|
@@ -144,6 +188,12 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
144
188
|
return $value ? 'Yes' : 'No';
|
|
145
189
|
}),
|
|
146
190
|
|
|
191
|
+
Column::make('adhoc_distance', 'integer')
|
|
192
|
+
->label('Ad Hoc Distance (m)')
|
|
193
|
+
->description('Radius in meters used to offer an ad hoc order to drivers')
|
|
194
|
+
->filterable()
|
|
195
|
+
->sortable(),
|
|
196
|
+
|
|
147
197
|
Column::make('pod_required', 'boolean')
|
|
148
198
|
->label('POD Required')
|
|
149
199
|
->description('Whether proof of delivery is required')
|
|
@@ -153,6 +203,31 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
153
203
|
return $value ? 'Yes' : 'No';
|
|
154
204
|
}),
|
|
155
205
|
|
|
206
|
+
Column::make('pod_method', 'string')
|
|
207
|
+
->label('POD Method')
|
|
208
|
+
->description('Proof of delivery method, e.g. scan, signature or photo')
|
|
209
|
+
->filterable()
|
|
210
|
+
->aggregatable(),
|
|
211
|
+
|
|
212
|
+
Column::make('is_route_optimized', 'boolean')
|
|
213
|
+
->label('Route Optimized')
|
|
214
|
+
->description('Whether the route was optimized')
|
|
215
|
+
->filterable()
|
|
216
|
+
->aggregatable(),
|
|
217
|
+
|
|
218
|
+
Column::make('orchestrator_priority', 'integer')
|
|
219
|
+
->label('Priority')
|
|
220
|
+
->description('Dispatch priority used by the orchestrator')
|
|
221
|
+
->filterable()
|
|
222
|
+
->sortable()
|
|
223
|
+
->aggregatable(),
|
|
224
|
+
|
|
225
|
+
Column::make('notes', 'string')
|
|
226
|
+
->label('Notes')
|
|
227
|
+
->description('Order notes')
|
|
228
|
+
->searchable()
|
|
229
|
+
->filterable(),
|
|
230
|
+
|
|
156
231
|
Column::make('created_at', 'datetime')
|
|
157
232
|
->label('Created At')
|
|
158
233
|
->description('When the order was created')
|
|
@@ -168,76 +243,156 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
168
243
|
|
|
169
244
|
Column::make('meta', 'json')
|
|
170
245
|
->label('Metadata')
|
|
171
|
-
->description('Order metadata and custom fields')
|
|
246
|
+
->description('Order metadata and custom fields; its keys vary by order, so read one with a computed column, e.g. JSON_UNQUOTE(JSON_EXTRACT(meta, \'$.key\'))')
|
|
172
247
|
->searchable()
|
|
173
248
|
->filterable(),
|
|
174
249
|
])
|
|
175
250
|
->computedColumns([
|
|
176
|
-
|
|
251
|
+
// Distinct, so the count stays right when payload items are selected too.
|
|
252
|
+
Column::count('total_orders', 'DISTINCT id')
|
|
177
253
|
->label('Total Orders')
|
|
178
|
-
->description('
|
|
254
|
+
->description('Number of orders'),
|
|
255
|
+
|
|
256
|
+
Column::computed('completed_orders', "COUNT(DISTINCT CASE WHEN status = 'completed' THEN id END)", 'integer')
|
|
257
|
+
->label('Completed Orders')
|
|
258
|
+
->description('Number of completed orders'),
|
|
259
|
+
|
|
260
|
+
Column::computed('canceled_orders', "COUNT(DISTINCT CASE WHEN status = 'canceled' THEN id END)", 'integer')
|
|
261
|
+
->label('Canceled Orders')
|
|
262
|
+
->description('Number of canceled orders'),
|
|
179
263
|
|
|
180
264
|
Column::sum('total_distance', 'distance')
|
|
181
|
-
->label('Total Distance')
|
|
265
|
+
->label('Total Distance (m)')
|
|
182
266
|
->description('Sum of all order distances'),
|
|
183
267
|
|
|
184
268
|
Column::avg('average_distance', 'distance')
|
|
185
|
-
->label('Average Distance')
|
|
269
|
+
->label('Average Distance (m)')
|
|
186
270
|
->description('Average distance per order'),
|
|
187
271
|
|
|
188
272
|
Column::sum('total_time', 'time')
|
|
189
|
-
->label('Total
|
|
273
|
+
->label('Total Duration (s)')
|
|
190
274
|
->description('Sum of all order durations'),
|
|
191
275
|
|
|
192
276
|
Column::avg('average_time', 'time')
|
|
193
|
-
->label('Average
|
|
277
|
+
->label('Average Duration (s)')
|
|
194
278
|
->description('Average duration per order'),
|
|
195
279
|
|
|
196
|
-
Column::sum('total_transaction_amount', 'amount')
|
|
197
|
-
->label('
|
|
198
|
-
->description('Sum of
|
|
280
|
+
Column::sum('total_transaction_amount', 'transaction.amount')
|
|
281
|
+
->label('Transaction Amount Sum (minor units)')
|
|
282
|
+
->description('Sum of the orders\' transaction amounts'),
|
|
199
283
|
|
|
200
|
-
Column::avg('average_transaction_amount', 'amount')
|
|
201
|
-
->label('Average Transaction Amount')
|
|
284
|
+
Column::avg('average_transaction_amount', 'transaction.amount')
|
|
285
|
+
->label('Average Transaction Amount (minor units)')
|
|
202
286
|
->description('Average transaction amount per order'),
|
|
203
287
|
|
|
204
|
-
Column::count('orders_with_transactions', 'transaction_uuid')
|
|
288
|
+
Column::count('orders_with_transactions', 'DISTINCT transaction_uuid')
|
|
205
289
|
->label('Orders with Transactions')
|
|
206
|
-
->description('
|
|
290
|
+
->description('Number of orders that have a transaction'),
|
|
207
291
|
])
|
|
208
292
|
->relationships([
|
|
209
|
-
|
|
293
|
+
Relationship::hasAutoJoin('tracking_number', 'tracking_numbers')
|
|
294
|
+
->label('Tracking')
|
|
295
|
+
->description('The order\'s tracking number and its latest tracking status')
|
|
296
|
+
->localKey('tracking_number_uuid')
|
|
297
|
+
->foreignKey('uuid')
|
|
298
|
+
->columns([
|
|
299
|
+
Column::make('tracking_number', 'string')->label('Number')->description('Tracking number'),
|
|
300
|
+
Column::make('public_id', 'string')->label('ID')->description('Tracking number record identifier'),
|
|
301
|
+
Column::make('region', 'string')->label('Region'),
|
|
302
|
+
])
|
|
303
|
+
->with([
|
|
304
|
+
Relationship::hasAutoJoin('status', 'tracking_statuses')
|
|
305
|
+
->label('Tracking Status')
|
|
306
|
+
->localKey('status_uuid')
|
|
307
|
+
->foreignKey('uuid')
|
|
308
|
+
->columns([
|
|
309
|
+
Column::make('status', 'string')->label('Tracking Status'),
|
|
310
|
+
Column::make('code', 'string')->label('Code'),
|
|
311
|
+
Column::make('details', 'string')->label('Details'),
|
|
312
|
+
Column::make('complete', 'boolean')->label('Complete'),
|
|
313
|
+
Column::make('city', 'string')->label('City'),
|
|
314
|
+
Column::make('province', 'string')->label('Province'),
|
|
315
|
+
Column::make('country', 'string')->label('Country'),
|
|
316
|
+
Column::make('created_at', 'datetime')->label('Updated At'),
|
|
317
|
+
]),
|
|
318
|
+
]),
|
|
319
|
+
|
|
320
|
+
Relationship::hasAutoJoin('order_config', 'order_configs')
|
|
321
|
+
->label('Order Config')
|
|
322
|
+
->description('The order configuration (order type) the order follows')
|
|
323
|
+
->localKey('order_config_uuid')
|
|
324
|
+
->foreignKey('uuid')
|
|
325
|
+
->columns([
|
|
326
|
+
Column::make('name', 'string')->label('Name'),
|
|
327
|
+
Column::make('key', 'string')->label('Key'),
|
|
328
|
+
Column::make('namespace', 'string')->label('Namespace'),
|
|
329
|
+
]),
|
|
330
|
+
|
|
210
331
|
Relationship::hasAutoJoin('payload', 'payloads')
|
|
211
332
|
->label('Payload')
|
|
212
333
|
->localKey('payload_uuid')
|
|
213
334
|
->foreignKey('uuid')
|
|
335
|
+
->columns([
|
|
336
|
+
Column::make('public_id', 'string')->label('ID')->description('Payload identifier'),
|
|
337
|
+
Column::make('type', 'string')->label('Type'),
|
|
338
|
+
Column::make('payment_method', 'string')->label('Payment Method'),
|
|
339
|
+
Column::make('cod_amount', 'integer')->label('COD Amount (minor units)')->description('Cash on delivery amount in the currency\'s smallest unit'),
|
|
340
|
+
Column::make('cod_currency', 'string')->label('COD Currency'),
|
|
341
|
+
Column::make('cod_payment_method', 'string')->label('COD Payment Method'),
|
|
342
|
+
Column::make('provider', 'string')->label('Provider'),
|
|
343
|
+
])
|
|
214
344
|
->with([
|
|
215
345
|
Relationship::hasAutoJoin('pickup', 'places')
|
|
216
346
|
->label('Pickup')
|
|
217
347
|
->localKey('pickup_uuid')
|
|
218
348
|
->foreignKey('uuid')
|
|
219
|
-
->columns(
|
|
220
|
-
Column::make('name', 'string')->label('Name'),
|
|
221
|
-
Column::make('street1', 'string')->label('Street'),
|
|
222
|
-
Column::make('street2', 'string')->label('Street 2'),
|
|
223
|
-
Column::make('city', 'string')->label('City'),
|
|
224
|
-
Column::make('province', 'string')->label('Province'),
|
|
225
|
-
Column::make('postal_code', 'string')->label('Postal Code'),
|
|
226
|
-
Column::make('country', 'string')->label('Country'),
|
|
227
|
-
]),
|
|
349
|
+
->columns($this->placeColumns()),
|
|
228
350
|
|
|
229
351
|
Relationship::hasAutoJoin('dropoff', 'places')
|
|
230
352
|
->label('Dropoff')
|
|
231
353
|
->localKey('dropoff_uuid')
|
|
232
354
|
->foreignKey('uuid')
|
|
355
|
+
->columns($this->placeColumns()),
|
|
356
|
+
|
|
357
|
+
Relationship::hasAutoJoin('return', 'places')
|
|
358
|
+
->label('Return')
|
|
359
|
+
->localKey('return_uuid')
|
|
360
|
+
->foreignKey('uuid')
|
|
361
|
+
->columns($this->placeColumns()),
|
|
362
|
+
|
|
363
|
+
// One row per item: the goods, parcels or storefront products in the order.
|
|
364
|
+
$this->softDeletes(Relationship::hasAutoJoin('entities', 'entities'))
|
|
365
|
+
->label('Item')
|
|
366
|
+
->description('Items carried by the order (storefront products, parcels, goods); one row per item')
|
|
367
|
+
->localKey('uuid')
|
|
368
|
+
->foreignKey('payload_uuid')
|
|
233
369
|
->columns([
|
|
234
|
-
Column::make('
|
|
235
|
-
Column::make('
|
|
236
|
-
Column::make('
|
|
237
|
-
Column::make('
|
|
238
|
-
Column::make('
|
|
239
|
-
Column::make('
|
|
240
|
-
Column::make('
|
|
370
|
+
Column::make('public_id', 'string')->label('ID')->description('Item identifier'),
|
|
371
|
+
Column::make('internal_id', 'string')->label('Internal ID')->description('Internal reference; the product ID for storefront items'),
|
|
372
|
+
Column::make('name', 'string')->label('Name')->aggregatable(),
|
|
373
|
+
Column::make('type', 'string')->label('Type')->aggregatable(),
|
|
374
|
+
Column::make('description', 'string')->label('Description'),
|
|
375
|
+
Column::make('sku', 'string')->label('SKU')->aggregatable(),
|
|
376
|
+
Column::make('currency', 'string')->label('Currency'),
|
|
377
|
+
Column::make('price', 'decimal')->label('Price (minor units)')->description('Unit price in the currency\'s smallest unit'),
|
|
378
|
+
Column::make('sale_price', 'decimal')->label('Sale Price (minor units)')->description('Unit sale price in the currency\'s smallest unit'),
|
|
379
|
+
Column::make('declared_value', 'integer')->label('Declared Value (minor units)'),
|
|
380
|
+
Column::make('weight', 'decimal')->label('Weight'),
|
|
381
|
+
Column::make('weight_unit', 'string')->label('Weight Unit'),
|
|
382
|
+
Column::make('length', 'decimal')->label('Length'),
|
|
383
|
+
Column::make('width', 'decimal')->label('Width'),
|
|
384
|
+
Column::make('height', 'decimal')->label('Height'),
|
|
385
|
+
Column::make('dimensions_unit', 'string')->label('Dimensions Unit'),
|
|
386
|
+
Column::make('barcode', 'string')->label('Barcode'),
|
|
387
|
+
Column::make('meta', 'json')->label('Metadata')->description('Item metadata; read a key with a computed column, e.g. JSON_EXTRACT(payload.entities.meta, \'$.quantity\')'),
|
|
388
|
+
Column::make('created_at', 'datetime')->label('Created At'),
|
|
389
|
+
])
|
|
390
|
+
->with([
|
|
391
|
+
Relationship::hasAutoJoin('destination', 'places')
|
|
392
|
+
->label('Destination')
|
|
393
|
+
->localKey('destination_uuid')
|
|
394
|
+
->foreignKey('uuid')
|
|
395
|
+
->columns($this->placeColumns()),
|
|
241
396
|
]),
|
|
242
397
|
]),
|
|
243
398
|
|
|
@@ -246,6 +401,8 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
246
401
|
->localKey('driver_assigned_uuid')
|
|
247
402
|
->foreignKey('uuid')
|
|
248
403
|
->columns([
|
|
404
|
+
Column::make('public_id', 'string')->label('ID')->description('Driver identifier'),
|
|
405
|
+
Column::make('internal_id', 'string')->label('Internal ID'),
|
|
249
406
|
Column::make('drivers_license_number', 'string')->label('License Number'),
|
|
250
407
|
Column::make('country', 'string')->label('Country'),
|
|
251
408
|
Column::make('city', 'string')->label('City'),
|
|
@@ -268,6 +425,9 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
268
425
|
->localKey('vehicle_assigned_uuid')
|
|
269
426
|
->foreignKey('uuid')
|
|
270
427
|
->columns([
|
|
428
|
+
Column::make('public_id', 'string')->label('ID')->description('Vehicle identifier'),
|
|
429
|
+
Column::make('internal_id', 'string')->label('Internal ID'),
|
|
430
|
+
Column::make('name', 'string')->label('Name'),
|
|
271
431
|
Column::make('make', 'string')->label('Make'),
|
|
272
432
|
Column::make('model', 'string')->label('Model'),
|
|
273
433
|
Column::make('year', 'integer')->label('Year'),
|
|
@@ -279,9 +439,27 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
279
439
|
|
|
280
440
|
Relationship::hasAutoJoin('customer', 'contacts')
|
|
281
441
|
->label('Customer')
|
|
442
|
+
->description('The customer when it is a contact')
|
|
443
|
+
->localKey('customer_uuid')
|
|
444
|
+
->foreignKey('uuid')
|
|
445
|
+
->columns([
|
|
446
|
+
Column::make('public_id', 'string')->label('ID')->description('Customer identifier'),
|
|
447
|
+
Column::make('internal_id', 'string')->label('Internal ID'),
|
|
448
|
+
Column::make('name', 'string')->label('Name'),
|
|
449
|
+
Column::make('title', 'string')->label('Title'),
|
|
450
|
+
Column::make('email', 'string')->label('Email'),
|
|
451
|
+
Column::make('phone', 'string')->label('Phone'),
|
|
452
|
+
Column::make('type', 'string')->label('Type'),
|
|
453
|
+
]),
|
|
454
|
+
|
|
455
|
+
Relationship::hasAutoJoin('customer_vendor', 'vendors')
|
|
456
|
+
->label('Customer Vendor')
|
|
457
|
+
->description('The customer when it is a vendor')
|
|
282
458
|
->localKey('customer_uuid')
|
|
283
459
|
->foreignKey('uuid')
|
|
284
460
|
->columns([
|
|
461
|
+
Column::make('public_id', 'string')->label('ID')->description('Vendor identifier'),
|
|
462
|
+
Column::make('internal_id', 'string')->label('Internal ID'),
|
|
285
463
|
Column::make('name', 'string')->label('Name'),
|
|
286
464
|
Column::make('email', 'string')->label('Email'),
|
|
287
465
|
Column::make('phone', 'string')->label('Phone'),
|
|
@@ -289,16 +467,48 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
289
467
|
]),
|
|
290
468
|
|
|
291
469
|
Relationship::hasAutoJoin('facilitator', 'vendors')
|
|
292
|
-
->label('
|
|
470
|
+
->label('Facilitator')
|
|
293
471
|
->localKey('facilitator_uuid')
|
|
294
472
|
->foreignKey('uuid')
|
|
295
473
|
->columns([
|
|
474
|
+
Column::make('public_id', 'string')->label('ID')->description('Facilitator identifier'),
|
|
475
|
+
Column::make('internal_id', 'string')->label('Internal ID'),
|
|
296
476
|
Column::make('name', 'string')->label('Name'),
|
|
297
477
|
Column::make('email', 'string')->label('Email'),
|
|
298
478
|
Column::make('phone', 'string')->label('Phone'),
|
|
299
479
|
Column::make('type', 'string')->label('Type'),
|
|
300
480
|
]),
|
|
301
481
|
|
|
482
|
+
Relationship::hasAutoJoin('created_by', 'users')
|
|
483
|
+
->label('Created By')
|
|
484
|
+
->localKey('created_by_uuid')
|
|
485
|
+
->foreignKey('uuid')
|
|
486
|
+
->columns([
|
|
487
|
+
Column::make('name', 'string')->label('Name'),
|
|
488
|
+
Column::make('email', 'string')->label('Email'),
|
|
489
|
+
]),
|
|
490
|
+
|
|
491
|
+
Relationship::hasAutoJoin('purchase_rate', 'purchase_rates')
|
|
492
|
+
->label('Purchase Rate')
|
|
493
|
+
->description('The service quote purchased for the order')
|
|
494
|
+
->localKey('purchase_rate_uuid')
|
|
495
|
+
->foreignKey('uuid')
|
|
496
|
+
->columns([
|
|
497
|
+
Column::make('public_id', 'string')->label('ID')->description('Purchase rate identifier'),
|
|
498
|
+
Column::make('status', 'string')->label('Status'),
|
|
499
|
+
])
|
|
500
|
+
->with([
|
|
501
|
+
Relationship::hasAutoJoin('service_quote', 'service_quotes')
|
|
502
|
+
->label('Service Quote')
|
|
503
|
+
->localKey('service_quote_uuid')
|
|
504
|
+
->foreignKey('uuid')
|
|
505
|
+
->columns([
|
|
506
|
+
Column::make('public_id', 'string')->label('ID')->description('Service quote identifier'),
|
|
507
|
+
Column::make('amount', 'integer')->label('Amount (minor units)')->description('Quoted delivery price in the currency\'s smallest unit'),
|
|
508
|
+
Column::make('currency', 'string')->label('Currency'),
|
|
509
|
+
]),
|
|
510
|
+
]),
|
|
511
|
+
|
|
302
512
|
Relationship::hasAutoJoin('transaction', 'transactions')
|
|
303
513
|
->label('Transaction')
|
|
304
514
|
->localKey('transaction_uuid')
|
|
@@ -312,7 +522,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
312
522
|
->sortable(),
|
|
313
523
|
|
|
314
524
|
Column::make('gateway_transaction_id', 'string')
|
|
315
|
-
->label('Gateway
|
|
525
|
+
->label('Gateway ID')
|
|
316
526
|
->description('Transaction ID from payment gateway')
|
|
317
527
|
->searchable()
|
|
318
528
|
->filterable()
|
|
@@ -324,15 +534,35 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
324
534
|
->filterable()
|
|
325
535
|
->aggregatable(),
|
|
326
536
|
|
|
537
|
+
Column::make('payment_method', 'string')
|
|
538
|
+
->label('Payment Method')
|
|
539
|
+
->description('Payment method used, e.g. card or cash')
|
|
540
|
+
->filterable()
|
|
541
|
+
->aggregatable(),
|
|
542
|
+
|
|
327
543
|
Column::make('amount', 'integer')
|
|
328
|
-
->label('Amount')
|
|
329
|
-
->description('Transaction amount
|
|
544
|
+
->label('Amount (minor units)')
|
|
545
|
+
->description('Transaction amount in the currency\'s smallest unit (e.g. cents)')
|
|
330
546
|
->aggregatable()
|
|
331
|
-
->sortable()
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
547
|
+
->sortable(),
|
|
548
|
+
|
|
549
|
+
Column::make('fee_amount', 'integer')
|
|
550
|
+
->label('Fee Amount (minor units)')
|
|
551
|
+
->description('Gateway fee in the currency\'s smallest unit')
|
|
552
|
+
->aggregatable()
|
|
553
|
+
->sortable(),
|
|
554
|
+
|
|
555
|
+
Column::make('tax_amount', 'integer')
|
|
556
|
+
->label('Tax Amount (minor units)')
|
|
557
|
+
->description('Tax in the currency\'s smallest unit')
|
|
558
|
+
->aggregatable()
|
|
559
|
+
->sortable(),
|
|
560
|
+
|
|
561
|
+
Column::make('net_amount', 'integer')
|
|
562
|
+
->label('Net Amount (minor units)')
|
|
563
|
+
->description('Amount after fees in the currency\'s smallest unit')
|
|
564
|
+
->aggregatable()
|
|
565
|
+
->sortable(),
|
|
336
566
|
|
|
337
567
|
Column::make('currency', 'string')
|
|
338
568
|
->label('Currency')
|
|
@@ -369,6 +599,12 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
369
599
|
return $labels[$value] ?? ucfirst($value);
|
|
370
600
|
}),
|
|
371
601
|
|
|
602
|
+
Column::make('settlement_status', 'string')
|
|
603
|
+
->label('Settlement Status')
|
|
604
|
+
->description('Whether the transaction has settled')
|
|
605
|
+
->filterable()
|
|
606
|
+
->aggregatable(),
|
|
607
|
+
|
|
372
608
|
Column::make('created_at', 'datetime')
|
|
373
609
|
->label('Transaction Date')
|
|
374
610
|
->description('When the transaction was created')
|
|
@@ -378,30 +614,48 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
378
614
|
])
|
|
379
615
|
->with([
|
|
380
616
|
// Nested relationship for transaction items
|
|
381
|
-
Relationship::hasAutoJoin('items', 'transaction_items')
|
|
382
|
-
->label('Transaction
|
|
617
|
+
$this->softDeletes(Relationship::hasAutoJoin('items', 'transaction_items'))
|
|
618
|
+
->label('Transaction Item')
|
|
383
619
|
->localKey('uuid')
|
|
384
620
|
->foreignKey('transaction_uuid')
|
|
385
621
|
->columns([
|
|
386
|
-
Column::make('
|
|
387
|
-
->label('
|
|
622
|
+
Column::make('description', 'string')
|
|
623
|
+
->label('Description')
|
|
624
|
+
->description('Line item description')
|
|
625
|
+
->searchable()
|
|
626
|
+
->filterable(),
|
|
627
|
+
|
|
628
|
+
Column::make('quantity', 'integer')
|
|
629
|
+
->label('Quantity')
|
|
630
|
+
->description('Line item quantity')
|
|
631
|
+
->aggregatable()
|
|
632
|
+
->sortable(),
|
|
633
|
+
|
|
634
|
+
Column::make('unit_price', 'integer')
|
|
635
|
+
->label('Unit Price (minor units)')
|
|
636
|
+
->description('Line item unit price')
|
|
637
|
+
->aggregatable()
|
|
638
|
+
->sortable(),
|
|
639
|
+
|
|
640
|
+
Column::make('amount', 'integer')
|
|
641
|
+
->label('Amount (minor units)')
|
|
388
642
|
->description('Line item amount')
|
|
389
643
|
->aggregatable()
|
|
390
644
|
->sortable(),
|
|
391
645
|
|
|
392
646
|
Column::make('currency', 'string')
|
|
393
|
-
->label('
|
|
647
|
+
->label('Currency')
|
|
394
648
|
->description('Line item currency code')
|
|
395
649
|
->filterable(),
|
|
396
650
|
|
|
397
651
|
Column::make('details', 'string')
|
|
398
|
-
->label('
|
|
652
|
+
->label('Details')
|
|
399
653
|
->description('Detailed description of the line item')
|
|
400
654
|
->searchable()
|
|
401
655
|
->filterable(),
|
|
402
656
|
|
|
403
657
|
Column::make('code', 'string')
|
|
404
|
-
->label('
|
|
658
|
+
->label('Code')
|
|
405
659
|
->description('Item or SKU code')
|
|
406
660
|
->searchable()
|
|
407
661
|
->filterable()
|
|
@@ -416,7 +670,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
416
670
|
*/
|
|
417
671
|
protected function createDriversTable(): Table
|
|
418
672
|
{
|
|
419
|
-
return Table::make('drivers')
|
|
673
|
+
return $this->softDeletes(Table::make('drivers'))
|
|
420
674
|
->label('Drivers')
|
|
421
675
|
->description('Fleet drivers and personnel')
|
|
422
676
|
->category('Personnel')
|
|
@@ -425,30 +679,28 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
425
679
|
->maxRows(10000)
|
|
426
680
|
->columns([
|
|
427
681
|
Column::make('public_id', 'string')
|
|
428
|
-
->label('
|
|
682
|
+
->label('ID')
|
|
429
683
|
->description('Public driver identifier')
|
|
430
684
|
->searchable()
|
|
431
685
|
->filterable()
|
|
432
686
|
->sortable(),
|
|
433
687
|
|
|
434
|
-
Column::make('
|
|
435
|
-
->label('
|
|
436
|
-
->description('
|
|
688
|
+
Column::make('internal_id', 'string')
|
|
689
|
+
->label('Internal ID')
|
|
690
|
+
->description('Internal driver reference')
|
|
437
691
|
->searchable()
|
|
438
692
|
->filterable()
|
|
439
693
|
->sortable(),
|
|
440
694
|
|
|
441
|
-
Column::make('
|
|
442
|
-
->label('
|
|
443
|
-
->description('Driver
|
|
695
|
+
Column::make('drivers_license_number', 'string')
|
|
696
|
+
->label('License Number')
|
|
697
|
+
->description('Driver license number')
|
|
444
698
|
->searchable()
|
|
445
|
-
->filterable()
|
|
446
|
-
->sortable(),
|
|
699
|
+
->filterable(),
|
|
447
700
|
|
|
448
|
-
Column::make('
|
|
449
|
-
->label('
|
|
450
|
-
->description('
|
|
451
|
-
->searchable()
|
|
701
|
+
Column::make('license_expiry', 'date')
|
|
702
|
+
->label('License Expiry')
|
|
703
|
+
->description('When the driver license expires')
|
|
452
704
|
->filterable()
|
|
453
705
|
->sortable(),
|
|
454
706
|
|
|
@@ -477,24 +729,45 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
477
729
|
return $value ? 'Yes' : 'No';
|
|
478
730
|
}),
|
|
479
731
|
|
|
732
|
+
Column::make('city', 'string')
|
|
733
|
+
->label('City')
|
|
734
|
+
->filterable()
|
|
735
|
+
->aggregatable(),
|
|
736
|
+
|
|
737
|
+
Column::make('country', 'string')
|
|
738
|
+
->label('Country')
|
|
739
|
+
->filterable()
|
|
740
|
+
->aggregatable(),
|
|
741
|
+
|
|
480
742
|
Column::make('created_at', 'datetime')
|
|
481
743
|
->label('Hired Date')
|
|
482
|
-
->description('When the driver was
|
|
744
|
+
->description('When the driver was added')
|
|
483
745
|
->filterable()
|
|
484
746
|
->sortable()
|
|
485
747
|
->aggregatable(),
|
|
486
748
|
])
|
|
487
749
|
->computedColumns([
|
|
488
|
-
Column::count('total_drivers', 'id')
|
|
750
|
+
Column::count('total_drivers', 'DISTINCT id')
|
|
489
751
|
->label('Total Drivers')
|
|
490
752
|
->description('Count of drivers'),
|
|
491
753
|
])
|
|
492
754
|
->relationships([
|
|
493
|
-
Relationship::hasAutoJoin('
|
|
755
|
+
Relationship::hasAutoJoin('user', 'users')
|
|
756
|
+
->label('Driver')
|
|
757
|
+
->localKey('user_uuid')
|
|
758
|
+
->foreignKey('uuid')
|
|
759
|
+
->columns([
|
|
760
|
+
Column::make('name', 'string')->label('Name'),
|
|
761
|
+
Column::make('email', 'string')->label('Email'),
|
|
762
|
+
Column::make('phone', 'string')->label('Phone'),
|
|
763
|
+
]),
|
|
764
|
+
|
|
765
|
+
Relationship::hasAutoJoin('vehicle', 'vehicles')
|
|
494
766
|
->label('Vehicle')
|
|
495
|
-
->localKey('
|
|
767
|
+
->localKey('vehicle_uuid')
|
|
496
768
|
->foreignKey('uuid')
|
|
497
769
|
->columns([
|
|
770
|
+
Column::make('public_id', 'string')->label('Vehicle ID'),
|
|
498
771
|
Column::make('make', 'string')->label('Vehicle Make'),
|
|
499
772
|
Column::make('model', 'string')->label('Vehicle Model'),
|
|
500
773
|
Column::make('plate_number', 'string')->label('Plate Number'),
|
|
@@ -507,7 +780,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
507
780
|
*/
|
|
508
781
|
protected function createVehiclesTable(): Table
|
|
509
782
|
{
|
|
510
|
-
return Table::make('vehicles')
|
|
783
|
+
return $this->softDeletes(Table::make('vehicles'))
|
|
511
784
|
->label('Vehicles')
|
|
512
785
|
->description('Fleet vehicles and assets')
|
|
513
786
|
->category('Fleet')
|
|
@@ -516,12 +789,26 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
516
789
|
->maxRows(10000)
|
|
517
790
|
->columns([
|
|
518
791
|
Column::make('public_id', 'string')
|
|
519
|
-
->label('
|
|
792
|
+
->label('ID')
|
|
520
793
|
->description('Public vehicle identifier')
|
|
521
794
|
->searchable()
|
|
522
795
|
->filterable()
|
|
523
796
|
->sortable(),
|
|
524
797
|
|
|
798
|
+
Column::make('internal_id', 'string')
|
|
799
|
+
->label('Internal ID')
|
|
800
|
+
->description('Internal vehicle reference')
|
|
801
|
+
->searchable()
|
|
802
|
+
->filterable()
|
|
803
|
+
->sortable(),
|
|
804
|
+
|
|
805
|
+
Column::make('name', 'string')
|
|
806
|
+
->label('Name')
|
|
807
|
+
->description('Vehicle name')
|
|
808
|
+
->searchable()
|
|
809
|
+
->filterable()
|
|
810
|
+
->sortable(),
|
|
811
|
+
|
|
525
812
|
Column::make('make', 'string')
|
|
526
813
|
->label('Make')
|
|
527
814
|
->description('Vehicle manufacturer')
|
|
@@ -583,19 +870,30 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
583
870
|
->aggregatable(),
|
|
584
871
|
])
|
|
585
872
|
->computedColumns([
|
|
586
|
-
Column::count('total_vehicles', 'id')
|
|
873
|
+
Column::count('total_vehicles', 'DISTINCT id')
|
|
587
874
|
->label('Total Vehicles')
|
|
588
875
|
->description('Count of vehicles'),
|
|
589
876
|
])
|
|
590
877
|
->relationships([
|
|
591
|
-
|
|
878
|
+
// A driver points at the vehicle they drive (drivers.vehicle_uuid).
|
|
879
|
+
$this->softDeletes(Relationship::hasAutoJoin('driver', 'drivers'))
|
|
592
880
|
->label('Driver')
|
|
593
|
-
->localKey('
|
|
594
|
-
->foreignKey('
|
|
881
|
+
->localKey('uuid')
|
|
882
|
+
->foreignKey('vehicle_uuid')
|
|
595
883
|
->columns([
|
|
596
|
-
Column::make('
|
|
597
|
-
Column::make('
|
|
598
|
-
|
|
884
|
+
Column::make('public_id', 'string')->label('Driver ID'),
|
|
885
|
+
Column::make('status', 'string')->label('Driver Status'),
|
|
886
|
+
])
|
|
887
|
+
->with([
|
|
888
|
+
Relationship::hasAutoJoin('user', 'users')
|
|
889
|
+
->label('Driver')
|
|
890
|
+
->localKey('user_uuid')
|
|
891
|
+
->foreignKey('uuid')
|
|
892
|
+
->columns([
|
|
893
|
+
Column::make('name', 'string')->label('Name'),
|
|
894
|
+
Column::make('email', 'string')->label('Email'),
|
|
895
|
+
Column::make('phone', 'string')->label('Phone'),
|
|
896
|
+
]),
|
|
599
897
|
]),
|
|
600
898
|
]);
|
|
601
899
|
}
|
|
@@ -605,7 +903,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
605
903
|
*/
|
|
606
904
|
protected function createAssetsTable(): Table
|
|
607
905
|
{
|
|
608
|
-
return Table::make('assets')
|
|
906
|
+
return $this->softDeletes(Table::make('assets'))
|
|
609
907
|
->label('Trailers and Assets')
|
|
610
908
|
->description('Independently managed fleet assets; Trailer rows use asset_class trailer')
|
|
611
909
|
->category('Fleet')
|
|
@@ -613,7 +911,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
613
911
|
->excludeColumns(['uuid', 'company_uuid', 'deleted_at', 'meta', 'attributes'])
|
|
614
912
|
->maxRows(10000)
|
|
615
913
|
->columns([
|
|
616
|
-
Column::make('public_id', 'string')->label('
|
|
914
|
+
Column::make('public_id', 'string')->label('ID')->searchable()->filterable()->sortable(),
|
|
617
915
|
Column::make('asset_class', 'string')->label('Asset Class')->filterable()->aggregatable(),
|
|
618
916
|
Column::make('name', 'string')->label('Name')->searchable()->filterable()->sortable(),
|
|
619
917
|
Column::make('code', 'string')->label('Code')->searchable()->filterable()->sortable(),
|
|
@@ -640,7 +938,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
640
938
|
*/
|
|
641
939
|
protected function createPlacesTable(): Table
|
|
642
940
|
{
|
|
643
|
-
return Table::make('places')
|
|
941
|
+
return $this->softDeletes(Table::make('places'))
|
|
644
942
|
->label('Places')
|
|
645
943
|
->description('Locations and addresses')
|
|
646
944
|
->category('Geography')
|
|
@@ -649,7 +947,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
649
947
|
->maxRows(100000)
|
|
650
948
|
->columns([
|
|
651
949
|
Column::make('public_id', 'string')
|
|
652
|
-
->label('
|
|
950
|
+
->label('ID')
|
|
653
951
|
->description('Public place identifier')
|
|
654
952
|
->searchable()
|
|
655
953
|
->filterable()
|
|
@@ -706,7 +1004,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
706
1004
|
*/
|
|
707
1005
|
protected function createContactsTable(): Table
|
|
708
1006
|
{
|
|
709
|
-
return Table::make('contacts')
|
|
1007
|
+
return $this->softDeletes(Table::make('contacts'))
|
|
710
1008
|
->label('Contacts')
|
|
711
1009
|
->description('Customer and vendor contacts')
|
|
712
1010
|
->category('CRM')
|
|
@@ -715,7 +1013,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
715
1013
|
->maxRows(50000)
|
|
716
1014
|
->columns([
|
|
717
1015
|
Column::make('public_id', 'string')
|
|
718
|
-
->label('
|
|
1016
|
+
->label('ID')
|
|
719
1017
|
->description('Public contact identifier')
|
|
720
1018
|
->searchable()
|
|
721
1019
|
->filterable()
|
|
@@ -762,7 +1060,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
762
1060
|
*/
|
|
763
1061
|
protected function createVendorsTable(): Table
|
|
764
1062
|
{
|
|
765
|
-
return Table::make('vendors')
|
|
1063
|
+
return $this->softDeletes(Table::make('vendors'))
|
|
766
1064
|
->label('Vendors')
|
|
767
1065
|
->description('Service providers and vendors')
|
|
768
1066
|
->category('CRM')
|
|
@@ -771,7 +1069,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
771
1069
|
->maxRows(10000)
|
|
772
1070
|
->columns([
|
|
773
1071
|
Column::make('public_id', 'string')
|
|
774
|
-
->label('
|
|
1072
|
+
->label('ID')
|
|
775
1073
|
->description('Public vendor identifier')
|
|
776
1074
|
->searchable()
|
|
777
1075
|
->filterable()
|
|
@@ -818,7 +1116,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
818
1116
|
*/
|
|
819
1117
|
protected function createFuelReportsTable(): Table
|
|
820
1118
|
{
|
|
821
|
-
return Table::make('fuel_reports')
|
|
1119
|
+
return $this->softDeletes(Table::make('fuel_reports'))
|
|
822
1120
|
->label('Fuel Reports')
|
|
823
1121
|
->description('Vehicle fuel consumption reports')
|
|
824
1122
|
->category('Operations')
|
|
@@ -827,24 +1125,30 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
827
1125
|
->maxRows(100000)
|
|
828
1126
|
->columns([
|
|
829
1127
|
Column::make('public_id', 'string')
|
|
830
|
-
->label('
|
|
1128
|
+
->label('ID')
|
|
831
1129
|
->description('Public fuel report identifier')
|
|
832
1130
|
->searchable()
|
|
833
1131
|
->filterable()
|
|
834
1132
|
->sortable(),
|
|
835
1133
|
|
|
836
1134
|
Column::make('volume', 'decimal')
|
|
837
|
-
->label('Volume
|
|
838
|
-
->description('Fuel volume in
|
|
1135
|
+
->label('Volume')
|
|
1136
|
+
->description('Fuel volume, in the report\'s metric unit')
|
|
839
1137
|
->aggregatable()
|
|
840
1138
|
->sortable(),
|
|
841
1139
|
|
|
842
|
-
Column::make('
|
|
1140
|
+
Column::make('metric_unit', 'string')
|
|
1141
|
+
->label('Volume Unit')
|
|
1142
|
+
->description('Unit of the fuel volume')
|
|
1143
|
+
->filterable()
|
|
1144
|
+
->aggregatable(),
|
|
1145
|
+
|
|
1146
|
+
Column::make('odometer', 'integer')
|
|
843
1147
|
->label('Odometer Reading')
|
|
844
1148
|
->description('Vehicle odometer reading')
|
|
845
1149
|
->sortable(),
|
|
846
1150
|
|
|
847
|
-
Column::make('
|
|
1151
|
+
Column::make('amount', 'decimal')
|
|
848
1152
|
->label('Cost')
|
|
849
1153
|
->description('Fuel cost amount')
|
|
850
1154
|
->aggregatable()
|
|
@@ -856,15 +1160,26 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
856
1160
|
->filterable()
|
|
857
1161
|
->aggregatable(),
|
|
858
1162
|
|
|
859
|
-
Column::make('
|
|
1163
|
+
Column::make('status', 'string')
|
|
1164
|
+
->label('Status')
|
|
1165
|
+
->filterable()
|
|
1166
|
+
->aggregatable(),
|
|
1167
|
+
|
|
1168
|
+
Column::make('report', 'string')
|
|
1169
|
+
->label('Report')
|
|
1170
|
+
->description('Report notes')
|
|
1171
|
+
->searchable()
|
|
1172
|
+
->filterable(),
|
|
1173
|
+
|
|
1174
|
+
Column::make('created_at', 'datetime')
|
|
860
1175
|
->label('Report Date')
|
|
861
|
-
->description('
|
|
1176
|
+
->description('When the fuel report was recorded')
|
|
862
1177
|
->filterable()
|
|
863
1178
|
->sortable()
|
|
864
1179
|
->aggregatable(),
|
|
865
1180
|
])
|
|
866
1181
|
->computedColumns([
|
|
867
|
-
Column::sum('total_fuel_cost', '
|
|
1182
|
+
Column::sum('total_fuel_cost', 'amount')
|
|
868
1183
|
->label('Total Fuel Cost')
|
|
869
1184
|
->description('Sum of all fuel costs'),
|
|
870
1185
|
|
|
@@ -872,7 +1187,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
872
1187
|
->label('Total Fuel Volume')
|
|
873
1188
|
->description('Sum of all fuel volumes'),
|
|
874
1189
|
|
|
875
|
-
Column::avg('average_fuel_cost', '
|
|
1190
|
+
Column::avg('average_fuel_cost', 'amount')
|
|
876
1191
|
->label('Average Fuel Cost')
|
|
877
1192
|
->description('Average fuel cost per report'),
|
|
878
1193
|
])
|
|
@@ -882,6 +1197,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
882
1197
|
->localKey('vehicle_uuid')
|
|
883
1198
|
->foreignKey('uuid')
|
|
884
1199
|
->columns([
|
|
1200
|
+
Column::make('public_id', 'string')->label('Vehicle ID'),
|
|
885
1201
|
Column::make('make', 'string')->label('Vehicle Make'),
|
|
886
1202
|
Column::make('model', 'string')->label('Vehicle Model'),
|
|
887
1203
|
Column::make('plate_number', 'string')->label('Plate Number'),
|
|
@@ -892,8 +1208,17 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
892
1208
|
->localKey('driver_uuid')
|
|
893
1209
|
->foreignKey('uuid')
|
|
894
1210
|
->columns([
|
|
895
|
-
Column::make('
|
|
896
|
-
|
|
1211
|
+
Column::make('public_id', 'string')->label('Driver ID'),
|
|
1212
|
+
])
|
|
1213
|
+
->with([
|
|
1214
|
+
Relationship::hasAutoJoin('user', 'users')
|
|
1215
|
+
->label('Driver')
|
|
1216
|
+
->localKey('user_uuid')
|
|
1217
|
+
->foreignKey('uuid')
|
|
1218
|
+
->columns([
|
|
1219
|
+
Column::make('name', 'string')->label('Name'),
|
|
1220
|
+
Column::make('email', 'string')->label('Email'),
|
|
1221
|
+
]),
|
|
897
1222
|
]),
|
|
898
1223
|
]);
|
|
899
1224
|
}
|
|
@@ -903,7 +1228,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
903
1228
|
*/
|
|
904
1229
|
protected function createWorkOrdersTable(): Table
|
|
905
1230
|
{
|
|
906
|
-
return Table::make('work_orders')
|
|
1231
|
+
return $this->softDeletes(Table::make('work_orders'))
|
|
907
1232
|
->label('Work Orders')
|
|
908
1233
|
->description('Maintenance work orders, assignments, budgets, and lifecycle status')
|
|
909
1234
|
->category('Maintenance')
|
|
@@ -911,7 +1236,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
911
1236
|
->excludeColumns(['uuid', 'deleted_at', 'meta', 'checklist', 'cost_breakdown'])
|
|
912
1237
|
->maxRows(100000)
|
|
913
1238
|
->columns([
|
|
914
|
-
Column::make('public_id', 'string')->label('
|
|
1239
|
+
Column::make('public_id', 'string')->label('ID')->searchable()->filterable()->sortable(),
|
|
915
1240
|
Column::make('code', 'string')->label('Code')->searchable()->filterable()->sortable(),
|
|
916
1241
|
Column::make('subject', 'string')->label('Subject')->searchable()->filterable()->sortable(),
|
|
917
1242
|
Column::make('status', 'string')->label('Status')->filterable()->sortable()->aggregatable(),
|
|
@@ -938,7 +1263,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
938
1263
|
->localKey('target_uuid')
|
|
939
1264
|
->foreignKey('uuid')
|
|
940
1265
|
->columns([
|
|
941
|
-
Column::make('public_id', 'string')->label('
|
|
1266
|
+
Column::make('public_id', 'string')->label('ID'),
|
|
942
1267
|
Column::make('plate_number', 'string')->label('Plate Number'),
|
|
943
1268
|
Column::make('make', 'string')->label('Make'),
|
|
944
1269
|
Column::make('model', 'string')->label('Model'),
|
|
@@ -952,7 +1277,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
952
1277
|
*/
|
|
953
1278
|
protected function createMaintenancesTable(): Table
|
|
954
1279
|
{
|
|
955
|
-
return Table::make('maintenances')
|
|
1280
|
+
return $this->softDeletes(Table::make('maintenances'))
|
|
956
1281
|
->label('Maintenance History')
|
|
957
1282
|
->description('Completed and scheduled maintenance records with labor, parts, tax, and total cost')
|
|
958
1283
|
->category('Maintenance')
|
|
@@ -960,7 +1285,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
960
1285
|
->excludeColumns(['uuid', 'deleted_at', 'meta', 'line_items', 'attachments'])
|
|
961
1286
|
->maxRows(100000)
|
|
962
1287
|
->columns([
|
|
963
|
-
Column::make('public_id', 'string')->label('
|
|
1288
|
+
Column::make('public_id', 'string')->label('ID')->searchable()->filterable()->sortable(),
|
|
964
1289
|
Column::make('type', 'string')->label('Type')->filterable()->sortable()->aggregatable(),
|
|
965
1290
|
Column::make('status', 'string')->label('Status')->filterable()->sortable()->aggregatable(),
|
|
966
1291
|
Column::make('priority', 'string')->label('Priority')->filterable()->sortable()->aggregatable(),
|
|
@@ -1013,7 +1338,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
1013
1338
|
*/
|
|
1014
1339
|
protected function createInspectionSubmissionsTable(): Table
|
|
1015
1340
|
{
|
|
1016
|
-
return Table::make('inspection_submissions')
|
|
1341
|
+
return $this->softDeletes(Table::make('inspection_submissions'))
|
|
1017
1342
|
->label('Inspections')
|
|
1018
1343
|
->description('DVIR and inspection submissions, pass/fail status, and linked maintenance follow-up')
|
|
1019
1344
|
->category('Maintenance')
|
|
@@ -1021,7 +1346,7 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
1021
1346
|
->excludeColumns(['uuid', 'deleted_at', 'meta', 'location', 'signature', 'attachments'])
|
|
1022
1347
|
->maxRows(100000)
|
|
1023
1348
|
->columns([
|
|
1024
|
-
Column::make('public_id', 'string')->label('
|
|
1349
|
+
Column::make('public_id', 'string')->label('ID')->searchable()->filterable()->sortable(),
|
|
1025
1350
|
Column::make('type', 'string')->label('Type')->filterable()->sortable()->aggregatable(),
|
|
1026
1351
|
Column::make('status', 'string')->label('Status')->filterable()->sortable()->aggregatable(),
|
|
1027
1352
|
Column::make('result', 'string')->label('Result')->filterable()->sortable()->aggregatable(),
|
|
@@ -1046,8 +1371,8 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
1046
1371
|
->localKey('inspection_form_uuid')
|
|
1047
1372
|
->foreignKey('uuid')
|
|
1048
1373
|
->columns([
|
|
1049
|
-
Column::make('name', 'string')->label('
|
|
1050
|
-
Column::make('type', 'string')->label('
|
|
1374
|
+
Column::make('name', 'string')->label('Name'),
|
|
1375
|
+
Column::make('type', 'string')->label('Type'),
|
|
1051
1376
|
]),
|
|
1052
1377
|
Relationship::hasAutoJoin('vehicle', 'vehicles')
|
|
1053
1378
|
->label('Vehicle')
|
|
@@ -1070,4 +1395,39 @@ class FleetOpsReportSchema implements ReportSchema
|
|
|
1070
1395
|
]),
|
|
1071
1396
|
]);
|
|
1072
1397
|
}
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* Columns reported for a place (pickup, dropoff, return or item destination).
|
|
1401
|
+
*/
|
|
1402
|
+
protected function placeColumns(): array
|
|
1403
|
+
{
|
|
1404
|
+
return [
|
|
1405
|
+
Column::make('public_id', 'string')->label('ID'),
|
|
1406
|
+
Column::make('name', 'string')->label('Name'),
|
|
1407
|
+
Column::make('street1', 'string')->label('Street'),
|
|
1408
|
+
Column::make('street2', 'string')->label('Street 2'),
|
|
1409
|
+
Column::make('neighborhood', 'string')->label('Neighborhood'),
|
|
1410
|
+
Column::make('district', 'string')->label('District'),
|
|
1411
|
+
Column::make('city', 'string')->label('City'),
|
|
1412
|
+
Column::make('province', 'string')->label('Province'),
|
|
1413
|
+
Column::make('postal_code', 'string')->label('Postal Code'),
|
|
1414
|
+
Column::make('country', 'string')->label('Country'),
|
|
1415
|
+
Column::make('latitude', 'decimal')->label('Latitude'),
|
|
1416
|
+
Column::make('longitude', 'decimal')->label('Longitude'),
|
|
1417
|
+
];
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Leave soft-deleted rows out of a table or joined relationship, on Core API releases that support it.
|
|
1422
|
+
*
|
|
1423
|
+
* @template T of Table|Relationship
|
|
1424
|
+
*
|
|
1425
|
+
* @param T $schema
|
|
1426
|
+
*
|
|
1427
|
+
* @return T
|
|
1428
|
+
*/
|
|
1429
|
+
protected function softDeletes(Table|Relationship $schema): Table|Relationship
|
|
1430
|
+
{
|
|
1431
|
+
return method_exists($schema, 'softDeletes') ? $schema->softDeletes() : $schema;
|
|
1432
|
+
}
|
|
1073
1433
|
}
|