@fleetbase/fleetops-engine 0.6.65 → 0.6.66
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 +11 -6
- package/addon/components/ai/create-order-preview.hbs +10 -5
- package/addon/components/asset/pill.hbs +24 -0
- package/addon/components/asset/summary.hbs +1 -0
- package/addon/components/asset-connection/pill.hbs +24 -0
- package/addon/components/asset-connection/summary.hbs +1 -0
- package/addon/components/attachable/pill.hbs +24 -0
- package/addon/components/attachable/summary.hbs +1 -0
- package/addon/components/cell/asset-connection-identity.hbs +1 -0
- package/addon/components/cell/asset-identity.hbs +1 -0
- package/addon/components/cell/attachable-identity.hbs +1 -0
- package/addon/components/cell/contact-identity.hbs +1 -0
- package/addon/components/cell/customer-identity.hbs +1 -0
- package/addon/components/cell/device-event-identity.hbs +1 -0
- package/addon/components/cell/device-identity.hbs +1 -24
- package/addon/components/cell/driver-identity.hbs +1 -33
- package/addon/components/cell/entity-identity.hbs +1 -0
- package/addon/components/cell/equipment-identity.hbs +1 -5
- package/addon/components/cell/facilitator-identity.hbs +1 -0
- package/addon/components/cell/fleet-driver-identity.hbs +1 -0
- package/addon/components/cell/fleet-identity.hbs +1 -0
- package/addon/components/cell/fuel-provider-connection-identity.hbs +1 -0
- package/addon/components/cell/fuel-provider-transaction-identity.hbs +1 -0
- package/addon/components/cell/fuel-report-identity.hbs +1 -0
- package/addon/components/cell/inspection-form-identity.hbs +1 -0
- package/addon/components/cell/inspection-item-result-identity.hbs +1 -0
- package/addon/components/cell/inspection-submission-identity.hbs +1 -0
- package/addon/components/cell/integrated-vendor-identity.hbs +1 -0
- package/addon/components/cell/issue-identity.hbs +1 -0
- package/addon/components/cell/maintenance-identity.hbs +1 -0
- package/addon/components/cell/maintenance-schedule-identity.hbs +1 -0
- package/addon/components/cell/maintenance-subject-identity.hbs +1 -0
- package/addon/components/cell/manifest-identity.hbs +1 -0
- package/addon/components/cell/manifest-stop-identity.hbs +1 -0
- package/addon/components/cell/order-config-identity.hbs +1 -0
- package/addon/components/cell/order-identity.hbs +1 -0
- package/addon/components/cell/part-identity.hbs +1 -5
- package/addon/components/cell/payload-identity.hbs +1 -0
- package/addon/components/cell/place-identity.hbs +1 -0
- package/addon/components/cell/position-identity.hbs +1 -0
- package/addon/components/cell/purchase-rate-identity.hbs +1 -0
- package/addon/components/cell/recurring-order-schedule-identity.hbs +1 -0
- package/addon/components/cell/resource-list.hbs +10 -0
- package/addon/components/cell/resource-list.js +28 -0
- package/addon/components/cell/route-identity.hbs +1 -0
- package/addon/components/cell/sensor-identity.hbs +1 -0
- package/addon/components/cell/service-area-identity.hbs +1 -0
- package/addon/components/cell/service-quote-identity.hbs +1 -0
- package/addon/components/cell/service-quote-item-identity.hbs +1 -0
- package/addon/components/cell/service-rate-fee-identity.hbs +1 -0
- package/addon/components/cell/service-rate-identity.hbs +1 -0
- package/addon/components/cell/service-rate-parcel-fee-identity.hbs +1 -0
- package/addon/components/cell/telematic-identity.hbs +1 -0
- package/addon/components/cell/tracking-number-identity.hbs +1 -0
- package/addon/components/cell/tracking-status-identity.hbs +1 -0
- package/addon/components/cell/trailer-identity.hbs +1 -0
- package/addon/components/cell/vehicle-device-identity.hbs +1 -0
- package/addon/components/cell/vehicle-identity.hbs +1 -33
- package/addon/components/cell/vendor-identity.hbs +1 -0
- package/addon/components/cell/warranty-identity.hbs +1 -0
- package/addon/components/cell/waypoint-identity.hbs +1 -0
- package/addon/components/cell/work-order-identity.hbs +1 -0
- package/addon/components/cell/zone-identity.hbs +1 -0
- package/addon/components/contact/form.hbs +2 -4
- package/addon/components/contact/pill.hbs +24 -0
- package/addon/components/contact/summary.hbs +1 -0
- package/addon/components/customer/create-order-form.hbs +8 -4
- package/addon/components/customer/form.hbs +2 -4
- package/addon/components/customer/order-form.hbs +10 -8
- package/addon/components/customer/pill.hbs +24 -0
- package/addon/components/customer/summary.hbs +1 -0
- package/addon/components/device/details.hbs +3 -1
- package/addon/components/device/form.hbs +4 -13
- package/addon/components/device/panel-header.hbs +3 -2
- package/addon/components/device/panel-header.js +1 -5
- package/addon/components/device/panel-tabs/vehicle.hbs +2 -2
- package/addon/components/device/pill.hbs +24 -16
- package/addon/components/device/summary.hbs +1 -0
- package/addon/components/device/telemetry.hbs +17 -0
- package/addon/components/device/telemetry.js +117 -0
- package/addon/components/device-event/details.hbs +6 -24
- package/addon/components/device-event/pill.hbs +24 -0
- package/addon/components/device-event/summary.hbs +1 -0
- package/addon/components/driver/details.hbs +9 -1
- package/addon/components/driver/form.hbs +6 -18
- package/addon/components/driver/panel-header.hbs +3 -4
- package/addon/components/driver/panel-header.js +8 -1
- package/addon/components/driver/pill.hbs +16 -8
- package/addon/components/driver/summary.hbs +1 -0
- package/addon/components/entity/pill.hbs +24 -0
- package/addon/components/entity/summary.hbs +1 -0
- package/addon/components/equipment/details.hbs +6 -2
- package/addon/components/equipment/form.hbs +10 -4
- package/addon/components/equipment/pill.hbs +24 -20
- package/addon/components/equipment/summary.hbs +1 -0
- package/addon/components/facilitator/pill.hbs +24 -0
- package/addon/components/facilitator/summary.hbs +1 -0
- package/addon/components/fleet/details.hbs +6 -2
- package/addon/components/fleet/driver-listing.hbs +3 -12
- package/addon/components/fleet/form.hbs +8 -4
- package/addon/components/fleet/pill.hbs +24 -0
- package/addon/components/fleet/summary.hbs +1 -0
- package/addon/components/fleet/vehicle-listing.hbs +3 -12
- package/addon/components/fleet-driver/pill.hbs +24 -0
- package/addon/components/fleet-driver/summary.hbs +1 -0
- package/addon/components/fleet-driver-listing.hbs +2 -1
- package/addon/components/fleet-panel/details.hbs +6 -2
- package/addon/components/fleet-panel/driver-listing.hbs +2 -1
- package/addon/components/fleet-panel/vehicle-listing.hbs +2 -1
- package/addon/components/fleet-vehicle-listing.hbs +2 -1
- package/addon/components/fuel-integration/form.hbs +125 -25
- package/addon/components/fuel-integration/form.js +74 -19
- package/addon/components/fuel-integration/hub.hbs +68 -65
- package/addon/components/fuel-integration/hub.js +15 -19
- package/addon/components/fuel-provider-connection/pill.hbs +24 -0
- package/addon/components/fuel-provider-connection/summary.hbs +1 -0
- package/addon/components/fuel-provider-transaction/pill.hbs +24 -0
- package/addon/components/fuel-provider-transaction/summary.hbs +1 -0
- package/addon/components/fuel-report/details.hbs +9 -3
- package/addon/components/fuel-report/form.hbs +6 -3
- package/addon/components/fuel-report/pill.hbs +24 -0
- package/addon/components/fuel-report/summary.hbs +1 -0
- package/addon/components/fuel-transaction-status.hbs +1 -0
- package/addon/components/fuel-transaction-status.js +8 -0
- package/addon/components/geofence-map.hbs +19 -0
- package/addon/components/geofence-map.js +83 -0
- package/addon/components/inspection-field/form.hbs +103 -0
- package/addon/components/inspection-field/form.js +211 -0
- package/addon/components/inspection-field/input.hbs +270 -0
- package/addon/components/inspection-field/input.js +472 -0
- package/addon/components/inspection-field/value.hbs +90 -0
- package/addon/components/inspection-field/value.js +158 -0
- package/addon/components/inspection-flyout.hbs +34 -0
- package/addon/components/inspection-flyout.js +66 -0
- package/addon/components/inspection-form/builder.hbs +88 -0
- package/addon/components/inspection-form/builder.js +211 -0
- package/addon/components/inspection-form/details/submissions.hbs +48 -0
- package/addon/components/inspection-form/details/submissions.js +42 -0
- package/addon/components/inspection-form/details.hbs +97 -0
- package/addon/components/inspection-form/details.js +57 -0
- package/addon/components/inspection-form/form.hbs +93 -0
- package/addon/components/inspection-form/form.js +79 -0
- package/addon/components/inspection-form/pill.hbs +24 -0
- package/addon/components/inspection-form/summary.hbs +1 -0
- package/addon/components/inspection-item-result/pill.hbs +24 -0
- package/addon/components/inspection-item-result/summary.hbs +1 -0
- package/addon/components/inspection-link/list.hbs +94 -0
- package/addon/components/inspection-link/list.js +129 -0
- package/addon/components/inspection-sheet/group.hbs +45 -0
- package/addon/components/inspection-sheet/group.js +75 -0
- package/addon/components/inspection-sheet.hbs +77 -0
- package/addon/components/inspection-sheet.js +152 -0
- package/addon/components/inspection-submission/details.hbs +149 -0
- package/addon/components/inspection-submission/details.js +130 -0
- package/addon/components/inspection-submission/form.hbs +114 -0
- package/addon/components/inspection-submission/form.js +129 -0
- package/addon/components/inspection-submission/photos.hbs +20 -0
- package/addon/components/inspection-submission/photos.js +57 -0
- package/addon/components/inspection-submission/pill.hbs +24 -0
- package/addon/components/inspection-submission/summary.hbs +1 -0
- package/addon/components/integrated-vendor/pill.hbs +24 -0
- package/addon/components/integrated-vendor/summary.hbs +1 -0
- package/addon/components/issue/details.hbs +12 -0
- package/addon/components/issue/details.js +36 -0
- package/addon/components/issue/form.hbs +10 -5
- package/addon/components/issue/pill.hbs +24 -0
- package/addon/components/issue/summary.hbs +1 -0
- package/addon/components/layout/fleet-ops-sidebar.js +14 -3
- package/addon/components/maintenance/details.hbs +9 -3
- package/addon/components/maintenance/form.hbs +22 -3
- package/addon/components/maintenance/form.js +4 -4
- package/addon/components/maintenance/panel-header.hbs +14 -12
- package/addon/components/maintenance/pill.hbs +24 -0
- package/addon/components/maintenance/summary.hbs +1 -0
- package/addon/components/maintenance-schedule/details.hbs +7 -3
- package/addon/components/maintenance-schedule/form.hbs +20 -2
- package/addon/components/maintenance-schedule/form.js +6 -6
- package/addon/components/maintenance-schedule/pill.hbs +24 -0
- package/addon/components/maintenance-schedule/summary.hbs +1 -0
- package/addon/components/maintenance-schedule/work-orders.hbs +39 -0
- package/addon/components/maintenance-schedule/work-orders.js +37 -0
- package/addon/components/maintenance-subject/pill.hbs +24 -0
- package/addon/components/maintenance-subject/summary.hbs +1 -0
- package/addon/components/manifest/pill.hbs +24 -0
- package/addon/components/manifest/summary.hbs +1 -0
- package/addon/components/manifest-stop/pill.hbs +24 -0
- package/addon/components/manifest-stop/summary.hbs +1 -0
- package/addon/components/map/drawer/device-event-listing.hbs +4 -14
- package/addon/components/map/drawer/device-event-listing.js +3 -1
- package/addon/components/map/drawer/driver-listing.js +6 -2
- package/addon/components/map/drawer/position-listing.hbs +2 -16
- package/addon/components/map/drawer/vehicle-listing.js +1 -2
- package/addon/components/modals/add-driver-shift.hbs +2 -1
- package/addon/components/modals/assign-driver.hbs +2 -16
- package/addon/components/modals/attach-device.hbs +2 -1
- package/addon/components/modals/attach-equipment.hbs +2 -4
- package/addon/components/modals/attach-telematic-device.hbs +8 -1
- package/addon/components/modals/attach-trailer.hbs +2 -1
- package/addon/components/modals/bulk-assign-driver.hbs +2 -9
- package/addon/components/modals/bulk-assign-orders.hbs +2 -9
- package/addon/components/modals/driver-assign-order.hbs +2 -6
- package/addon/components/modals/driver-assign-vehicle.hbs +4 -12
- package/addon/components/modals/driver-assign-vehicle.js +30 -0
- package/addon/components/modals/driver-assign-vendor.hbs +2 -1
- package/addon/components/modals/driver-form.hbs +4 -2
- package/addon/components/modals/fleet-assign-driver.hbs +2 -1
- package/addon/components/modals/fleet-assign-vehicle.hbs +2 -1
- package/addon/components/modals/fleet-form.hbs +4 -2
- package/addon/components/modals/fuel-connection-diagnostics.hbs +35 -0
- package/addon/components/modals/fuel-connection-diagnostics.js +87 -0
- package/addon/components/modals/fuel-report-form.hbs +4 -2
- package/addon/components/modals/fuel-transaction-action.hbs +48 -0
- package/addon/components/modals/fuel-transaction-action.js +98 -0
- package/addon/components/modals/group-form.hbs +2 -1
- package/addon/components/modals/inspection-follow-up.hbs +31 -0
- package/addon/components/modals/inspection-follow-up.js +39 -0
- package/addon/components/modals/inspection-link.hbs +100 -0
- package/addon/components/modals/inspection-link.js +83 -0
- package/addon/components/modals/issue-assign.hbs +2 -1
- package/addon/components/modals/issue-from.hbs +8 -4
- package/addon/components/modals/map-layer-form.hbs +2 -1
- package/addon/components/modals/order-assign-driver.hbs +2 -16
- package/addon/components/modals/order-form.hbs +8 -46
- package/addon/components/modals/order-route-form.hbs +8 -4
- package/addon/components/modals/place-assign-vendor.hbs +3 -2
- package/addon/components/modals/place-details.hbs +1 -1
- package/addon/components/modals/point-map.hbs +1 -1
- package/addon/components/modals/radar-notice.hbs +24 -0
- package/addon/components/modals/radar-notice.js +8 -0
- package/addon/components/modals/radar-save-view.hbs +7 -0
- package/addon/components/modals/radar-select-resource.hbs +35 -0
- package/addon/components/modals/radar-send-pin.hbs +20 -0
- package/addon/components/modals/radar-send-pin.js +8 -0
- package/addon/components/modals/select-trailer.hbs +2 -4
- package/addon/components/modals/vehicle-form.hbs +2 -1
- package/addon/components/modals/vendor-form.hbs +2 -3
- package/addon/components/order/details/activity.js +9 -0
- package/addon/components/order/details/detail.hbs +2 -32
- package/addon/components/order/form/details.hbs +10 -48
- package/addon/components/order/form/route.hbs +10 -12
- package/addon/components/order/form/service-rate.hbs +2 -3
- package/addon/components/order/pill.hbs +24 -34
- package/addon/components/order/route-editor.hbs +8 -4
- package/addon/components/order/schedule-card.hbs +2 -1
- package/addon/components/order/summary.hbs +1 -0
- package/addon/components/order-config/pill.hbs +24 -0
- package/addon/components/order-config/summary.hbs +1 -0
- package/addon/components/part/details.hbs +15 -3
- package/addon/components/part/details.js +37 -1
- package/addon/components/part/form.hbs +12 -5
- package/addon/components/part/pill.hbs +24 -0
- package/addon/components/part/summary.hbs +1 -0
- package/addon/components/payload/pill.hbs +24 -0
- package/addon/components/payload/summary.hbs +1 -0
- package/addon/components/place/details.hbs +1 -1
- package/addon/components/place/pill.hbs +24 -0
- package/addon/components/place/summary.hbs +1 -0
- package/addon/components/position/pill.hbs +24 -0
- package/addon/components/position/summary.hbs +1 -0
- package/addon/components/positions-replay.hbs +2 -4
- package/addon/components/public-inspection.hbs +174 -0
- package/addon/components/public-inspection.js +279 -0
- package/addon/components/purchase-rate/pill.hbs +24 -0
- package/addon/components/purchase-rate/summary.hbs +1 -0
- package/addon/components/radar/agenda/entry.hbs +17 -0
- package/addon/components/radar/agenda/entry.js +26 -0
- package/addon/components/radar/agenda/lane.hbs +33 -0
- package/addon/components/radar/agenda/lane.js +80 -0
- package/addon/components/radar/agenda.hbs +69 -0
- package/addon/components/radar/agenda.js +29 -0
- package/addon/components/radar/briefing.hbs +108 -0
- package/addon/components/radar/briefing.js +43 -0
- package/addon/components/radar/bulk-bar.hbs +41 -0
- package/addon/components/radar/bulk-bar.js +32 -0
- package/addon/components/radar/decision-card.hbs +28 -0
- package/addon/components/radar/decision-card.js +7 -0
- package/addon/components/radar/empty-state.hbs +30 -0
- package/addon/components/radar/empty-state.js +27 -0
- package/addon/components/radar/filter-pills.hbs +22 -0
- package/addon/components/radar/filter-pills.js +3 -0
- package/addon/components/radar/handover-card.hbs +62 -0
- package/addon/components/radar/handover-card.js +14 -0
- package/addon/components/radar/header.hbs +28 -0
- package/addon/components/radar/header.js +12 -0
- package/addon/components/radar/item-drawer.hbs +92 -0
- package/addon/components/radar/item-drawer.js +37 -0
- package/addon/components/radar/item-list.hbs +20 -0
- package/addon/components/radar/item-list.js +3 -0
- package/addon/components/radar/item-row.hbs +90 -0
- package/addon/components/radar/item-row.js +43 -0
- package/addon/components/radar/keyboard-hints.hbs +8 -0
- package/addon/components/radar/keyboard-hints.js +3 -0
- package/addon/components/radar/subject.hbs +14 -0
- package/addon/components/radar/subject.js +26 -0
- package/addon/components/radar/view-bar.hbs +27 -0
- package/addon/components/radar/view-bar.js +16 -0
- package/addon/components/recurring-order-schedule/pill.hbs +24 -0
- package/addon/components/recurring-order-schedule/summary.hbs +1 -0
- package/addon/components/resource-activity.hbs +1 -0
- package/addon/components/resource-activity.js +4 -0
- package/addon/components/route/pill.hbs +24 -0
- package/addon/components/route/summary.hbs +1 -0
- package/addon/components/select-option/asset-connection.hbs +12 -0
- package/addon/components/select-option/asset.hbs +12 -0
- package/addon/components/select-option/attachable.hbs +12 -0
- package/addon/components/select-option/contact.hbs +12 -0
- package/addon/components/select-option/customer.hbs +12 -0
- package/addon/components/select-option/device-event.hbs +12 -0
- package/addon/components/select-option/device.hbs +12 -0
- package/addon/components/select-option/driver.hbs +12 -0
- package/addon/components/select-option/entity.hbs +12 -0
- package/addon/components/select-option/equipment.hbs +12 -0
- package/addon/components/select-option/facilitator.hbs +12 -0
- package/addon/components/select-option/fleet-driver.hbs +12 -0
- package/addon/components/select-option/fleet.hbs +12 -0
- package/addon/components/select-option/fuel-provider-connection.hbs +12 -0
- package/addon/components/select-option/fuel-provider-transaction.hbs +12 -0
- package/addon/components/select-option/fuel-report.hbs +12 -0
- package/addon/components/select-option/inspection-form.hbs +12 -0
- package/addon/components/select-option/inspection-item-result.hbs +12 -0
- package/addon/components/select-option/inspection-submission.hbs +12 -0
- package/addon/components/select-option/integrated-vendor.hbs +12 -0
- package/addon/components/select-option/issue.hbs +12 -0
- package/addon/components/select-option/maintenance-schedule.hbs +12 -0
- package/addon/components/select-option/maintenance-subject.hbs +12 -0
- package/addon/components/select-option/maintenance.hbs +12 -0
- package/addon/components/select-option/manifest-stop.hbs +12 -0
- package/addon/components/select-option/manifest.hbs +12 -0
- package/addon/components/select-option/order-config.hbs +12 -0
- package/addon/components/select-option/order.hbs +12 -0
- package/addon/components/select-option/part.hbs +12 -0
- package/addon/components/select-option/payload.hbs +12 -0
- package/addon/components/select-option/place.hbs +12 -0
- package/addon/components/select-option/position.hbs +12 -0
- package/addon/components/select-option/purchase-rate.hbs +12 -0
- package/addon/components/select-option/recurring-order-schedule.hbs +12 -0
- package/addon/components/select-option/route.hbs +12 -0
- package/addon/components/select-option/sensor.hbs +12 -0
- package/addon/components/select-option/service-area.hbs +12 -0
- package/addon/components/select-option/service-quote-item.hbs +12 -0
- package/addon/components/select-option/service-quote.hbs +12 -0
- package/addon/components/select-option/service-rate-fee.hbs +12 -0
- package/addon/components/select-option/service-rate-parcel-fee.hbs +12 -0
- package/addon/components/select-option/service-rate.hbs +12 -0
- package/addon/components/select-option/telematic.hbs +12 -0
- package/addon/components/select-option/trackable.hbs +8 -0
- package/addon/components/select-option/tracking-number.hbs +12 -0
- package/addon/components/select-option/tracking-status.hbs +12 -0
- package/addon/components/select-option/trailer.hbs +12 -0
- package/addon/components/select-option/vehicle-device.hbs +12 -0
- package/addon/components/select-option/vehicle.hbs +12 -0
- package/addon/components/select-option/vendor.hbs +12 -0
- package/addon/components/select-option/warranty.hbs +12 -0
- package/addon/components/select-option/waypoint.hbs +12 -0
- package/addon/components/select-option/work-order.hbs +12 -0
- package/addon/components/select-option/zone.hbs +12 -0
- package/addon/components/sensor/details.hbs +6 -2
- package/addon/components/sensor/form.hbs +6 -17
- package/addon/components/sensor/panel-header.hbs +1 -1
- package/addon/components/sensor/pill.hbs +24 -0
- package/addon/components/sensor/summary.hbs +1 -0
- package/addon/components/service-area/details.hbs +1 -20
- package/addon/components/service-area/pill.hbs +24 -0
- package/addon/components/service-area/summary.hbs +1 -0
- package/addon/components/service-quote/pill.hbs +24 -0
- package/addon/components/service-quote/summary.hbs +1 -0
- package/addon/components/service-quote-item/pill.hbs +24 -0
- package/addon/components/service-quote-item/summary.hbs +1 -0
- package/addon/components/service-rate/details.hbs +12 -6
- package/addon/components/service-rate/form.hbs +10 -8
- package/addon/components/service-rate/pill.hbs +24 -0
- package/addon/components/service-rate/summary.hbs +1 -0
- package/addon/components/service-rate-fee/pill.hbs +24 -0
- package/addon/components/service-rate-fee/summary.hbs +1 -0
- package/addon/components/service-rate-parcel-fee/pill.hbs +24 -0
- package/addon/components/service-rate-parcel-fee/summary.hbs +1 -0
- package/addon/components/table/cell/fleet-ops-option.hbs +20 -0
- package/addon/components/telematic/details.hbs +4 -1
- package/addon/components/telematic/details.js +1 -0
- package/addon/components/telematic/form.hbs +6 -1
- package/addon/components/telematic/form.js +1 -0
- package/addon/components/telematic/pill.hbs +24 -0
- package/addon/components/telematic/settings.hbs +6 -1
- package/addon/components/telematic/settings.js +1 -0
- package/addon/components/telematic/summary.hbs +1 -0
- package/addon/components/telematic/telemetry-status.hbs +43 -0
- package/addon/components/telematic/telemetry-status.js +95 -0
- package/addon/components/tracking-number/pill.hbs +24 -0
- package/addon/components/tracking-number/summary.hbs +1 -0
- package/addon/components/tracking-status/pill.hbs +24 -0
- package/addon/components/tracking-status/summary.hbs +1 -0
- package/addon/components/trailer/card.hbs +2 -5
- package/addon/components/trailer/details.hbs +11 -5
- package/addon/components/trailer/details.js +4 -0
- package/addon/components/trailer/form.hbs +6 -3
- package/addon/components/trailer/pill.hbs +24 -21
- package/addon/components/trailer/summary.hbs +1 -0
- package/addon/components/vehicle/card.hbs +4 -8
- package/addon/components/vehicle/details/inspections.hbs +49 -0
- package/addon/components/vehicle/details/inspections.js +44 -0
- package/addon/components/vehicle/details/maintenance-history.hbs +1 -1
- package/addon/components/vehicle/details/schedules.hbs +2 -2
- package/addon/components/vehicle/details/work-orders.hbs +1 -1
- package/addon/components/vehicle/details.hbs +18 -1
- package/addon/components/vehicle/form.hbs +2 -1
- package/addon/components/vehicle/panel-header.hbs +3 -4
- package/addon/components/vehicle/panel-header.js +8 -1
- package/addon/components/vehicle/pill.hbs +15 -24
- package/addon/components/vehicle/summary.hbs +1 -0
- package/addon/components/vehicle-device/pill.hbs +24 -0
- package/addon/components/vehicle-device/summary.hbs +1 -0
- package/addon/components/vendor/form.hbs +2 -4
- package/addon/components/vendor/personnel-manager.hbs +2 -9
- package/addon/components/vendor/personnel-tab.hbs +1 -0
- package/addon/components/vendor/personnel-tab.js +4 -0
- package/addon/components/vendor/pill.hbs +24 -0
- package/addon/components/vendor/summary.hbs +1 -0
- package/addon/components/warranty/details.hbs +3 -1
- package/addon/components/warranty/form.hbs +2 -1
- package/addon/components/warranty/pill.hbs +24 -0
- package/addon/components/warranty/summary.hbs +1 -0
- package/addon/components/waypoint/pill.hbs +24 -0
- package/addon/components/waypoint/summary.hbs +1 -0
- package/addon/components/widget/radar.hbs +28 -0
- package/addon/components/widget/radar.js +44 -0
- package/addon/components/work-order/details.hbs +20 -4
- package/addon/components/work-order/details.js +64 -1
- package/addon/components/work-order/form.hbs +20 -2
- package/addon/components/work-order/form.js +10 -10
- package/addon/components/work-order/panel-header.hbs +15 -13
- package/addon/components/work-order/pill.hbs +24 -0
- package/addon/components/work-order/summary.hbs +1 -0
- package/addon/components/zone/details.hbs +2 -21
- package/addon/components/zone/pill.hbs +24 -0
- package/addon/components/zone/summary.hbs +1 -0
- package/addon/controllers/connectivity/devices/index/details/sensors.js +4 -0
- package/addon/controllers/connectivity/devices/index/details.js +1 -18
- package/addon/controllers/connectivity/events/index.js +1 -4
- package/addon/controllers/connectivity/fuel-providers/details/index.js +6 -0
- package/addon/controllers/connectivity/fuel-providers/details/matching.js +13 -0
- package/addon/controllers/connectivity/fuel-providers/details/sync.js +21 -10
- package/addon/controllers/connectivity/fuel-providers/details/transactions.js +5 -16
- package/addon/controllers/connectivity/fuel-providers/details.js +76 -13
- package/addon/controllers/connectivity/fuel-providers/index.js +22 -17
- package/addon/controllers/connectivity/sensors/index.js +1 -3
- package/addon/controllers/connectivity/telematics/details/events.js +8 -0
- package/addon/controllers/connectivity/telematics/details/sensors.js +3 -2
- package/addon/controllers/connectivity/telematics/index.js +3 -1
- package/addon/controllers/maintenance/inspection-forms/index/details.js +29 -0
- package/addon/controllers/maintenance/inspection-forms/index/edit.js +39 -0
- package/addon/controllers/maintenance/inspection-forms/index/new.js +48 -0
- package/addon/controllers/maintenance/inspection-forms/index.js +90 -0
- package/addon/controllers/maintenance/inspection-submissions/index/details.js +53 -0
- package/addon/controllers/maintenance/inspection-submissions/index/edit.js +39 -0
- package/addon/controllers/maintenance/inspection-submissions/index/new.js +48 -0
- package/addon/controllers/maintenance/inspection-submissions/index.js +142 -0
- package/addon/controllers/maintenance/maintenances/index.js +6 -2
- package/addon/controllers/maintenance/schedules/index/details.js +4 -86
- package/addon/controllers/maintenance/schedules/index.js +15 -0
- package/addon/controllers/maintenance/work-orders/index.js +19 -1
- package/addon/controllers/management/contacts/customers.js +6 -4
- package/addon/controllers/management/contacts/index.js +6 -3
- package/addon/controllers/management/drivers/index/details.js +1 -66
- package/addon/controllers/management/drivers/index.js +9 -34
- package/addon/controllers/management/fleets/index/details.js +2 -15
- package/addon/controllers/management/fleets/index.js +12 -20
- package/addon/controllers/management/fuel-reports/index.js +9 -59
- package/addon/controllers/management/fuel-transactions/index/details.js +51 -48
- package/addon/controllers/management/fuel-transactions/index.js +32 -32
- package/addon/controllers/management/index.js +1367 -49
- package/addon/controllers/management/issues/index/details.js +1 -33
- package/addon/controllers/management/issues/index.js +10 -59
- package/addon/controllers/management/trailers/index/details.js +4 -78
- package/addon/controllers/management/trailers/index.js +20 -22
- package/addon/controllers/management/vehicles/index/details.js +9 -77
- package/addon/controllers/management/vehicles/index.js +50 -72
- package/addon/controllers/management/vendors/index.js +6 -3
- package/addon/controllers/operations/orders/index.js +38 -11
- package/addon/controllers/operations/service-rates/index.js +10 -2
- package/addon/controllers/settings/payments/index.js +11 -2
- package/addon/extension.js +36 -0
- package/addon/helpers/initials.js +6 -0
- package/addon/helpers/leaflet-tile-url.js +6 -1
- package/addon/instance-initializers/register-fleetops-resource-descriptors.js +29 -0
- package/addon/modifiers/inspection-flyout.js +237 -0
- package/addon/modifiers/radar-keyboard.js +78 -0
- package/addon/modifiers/sync-value.js +26 -0
- package/addon/modifiers/when-changed.js +25 -0
- package/addon/routes/connectivity/fuel-providers/details/settings.js +5 -2
- package/addon/routes/connectivity/fuel-providers/details/sync.js +6 -13
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +8 -7
- package/addon/routes/connectivity/fuel-providers/details.js +15 -2
- package/addon/routes/connectivity/fuel-providers/edit.js +2 -1
- package/addon/routes/connectivity/fuel-providers/index.js +5 -0
- package/addon/routes/maintenance/inspection-forms/index/details/index.js +3 -0
- package/addon/routes/maintenance/inspection-forms/index/details/submissions.js +3 -0
- package/addon/routes/maintenance/inspection-forms/index/details.js +18 -0
- package/addon/routes/maintenance/inspection-forms/index/edit.js +18 -0
- package/addon/routes/maintenance/inspection-forms/index/new.js +3 -0
- package/addon/routes/maintenance/inspection-forms/index.js +22 -0
- package/addon/routes/maintenance/inspection-forms.js +3 -0
- package/addon/routes/maintenance/inspection-submissions/index/details/audit.js +8 -0
- package/addon/routes/maintenance/inspection-submissions/index/details/index.js +3 -0
- package/addon/routes/maintenance/inspection-submissions/index/details/photos.js +8 -0
- package/addon/routes/maintenance/inspection-submissions/index/details.js +18 -0
- package/addon/routes/maintenance/inspection-submissions/index/edit.js +18 -0
- package/addon/routes/maintenance/inspection-submissions/index/new.js +3 -0
- package/addon/routes/maintenance/inspection-submissions/index.js +25 -0
- package/addon/routes/maintenance/inspection-submissions.js +3 -0
- package/addon/routes/management/fuel-transactions/index/details.js +12 -2
- package/addon/routes/management/fuel-transactions/index.js +6 -0
- package/addon/routes/management/index.js +17 -1
- package/addon/routes/management/vehicles/index/details/inspections.js +3 -0
- package/addon/routes/management/vehicles/index.js +2 -2
- package/addon/routes.js +24 -0
- package/addon/services/contact-actions.js +22 -4
- package/addon/services/customer-actions.js +7 -4
- package/addon/services/device-actions.js +28 -0
- package/addon/services/driver-actions.js +79 -16
- package/addon/services/equipment-actions.js +15 -6
- package/addon/services/fleet-actions.js +20 -4
- package/addon/services/fuel-report-actions.js +7 -7
- package/addon/services/inspection-form-actions.js +236 -0
- package/addon/services/inspection-submission-actions.js +273 -0
- package/addon/services/issue-actions.js +58 -7
- package/addon/services/maintenance-actions.js +22 -3
- package/addon/services/maintenance-schedule-actions.js +70 -5
- package/addon/services/movement-tracker.js +52 -1
- package/addon/services/part-actions.js +13 -7
- package/addon/services/place-actions.js +8 -7
- package/addon/services/service-area-actions.js +27 -4
- package/addon/services/trailer-actions.js +60 -7
- package/addon/services/vehicle-actions.js +58 -3
- package/addon/services/vendor-actions.js +8 -7
- package/addon/services/work-order-actions.js +14 -5
- package/addon/services/zone-actions.js +27 -4
- package/addon/styles/fleetops-engine.css +3621 -75
- package/addon/templates/connectivity/devices/index/details/vehicle.hbs +2 -2
- package/addon/templates/connectivity/events/details.hbs +2 -2
- package/addon/templates/connectivity/fuel-providers/details/index.hbs +65 -35
- package/addon/templates/connectivity/fuel-providers/details/matching.hbs +2 -2
- package/addon/templates/connectivity/fuel-providers/details/sync.hbs +54 -43
- package/addon/templates/connectivity/fuel-providers/details/transactions.hbs +10 -5
- package/addon/templates/connectivity/fuel-providers/details.hbs +38 -13
- package/addon/templates/connectivity/fuel-providers/edit.hbs +1 -0
- package/addon/templates/connectivity/fuel-providers/index.hbs +2 -1
- package/addon/templates/connectivity/fuel-providers/new.hbs +1 -1
- package/addon/templates/connectivity/telematics/details/attachments.hbs +2 -1
- package/addon/templates/maintenance/inspection-forms/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/inspection-forms/index/details/submissions.hbs +2 -0
- package/addon/templates/maintenance/inspection-forms/index/details.hbs +14 -0
- package/addon/templates/maintenance/inspection-forms/index/edit.hbs +11 -0
- package/addon/templates/maintenance/inspection-forms/index/new.hbs +11 -0
- package/addon/templates/maintenance/inspection-forms/index.hbs +28 -0
- package/addon/templates/maintenance/inspection-forms.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details/audit.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details/index.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details/photos.hbs +1 -0
- package/addon/templates/maintenance/inspection-submissions/index/details.hbs +14 -0
- package/addon/templates/maintenance/inspection-submissions/index/edit.hbs +11 -0
- package/addon/templates/maintenance/inspection-submissions/index/new.hbs +11 -0
- package/addon/templates/maintenance/inspection-submissions/index.hbs +28 -0
- package/addon/templates/maintenance/inspection-submissions.hbs +1 -0
- package/addon/templates/management/fuel-transactions/index/details.hbs +64 -62
- package/addon/templates/management/fuel-transactions/index.hbs +9 -31
- package/addon/templates/management/index.hbs +110 -102
- package/addon/templates/management/vehicles/index/details/inspections.hbs +2 -0
- package/addon/templates/operations/orders/index.hbs +2 -4
- package/addon/utils/context-panel.js +34 -0
- package/addon/utils/device-table-columns.js +18 -27
- package/addon/utils/fleet-ops-options.js +40 -0
- package/addon/utils/fuel-integration-format.js +43 -0
- package/addon/utils/fuel-transaction.js +115 -0
- package/addon/utils/identity-cell-resource.js +56 -0
- package/addon/utils/inspection-answers.js +283 -0
- package/addon/utils/inspection-field-types.js +74 -0
- package/addon/utils/inspection-form-structure.js +161 -0
- package/addon/utils/radar.js +212 -0
- package/addon/utils/relation-value.js +37 -0
- package/addon/utils/resource-descriptors/assets.js +246 -0
- package/addon/utils/resource-descriptors/connectivity.js +146 -0
- package/addon/utils/resource-descriptors/fuel.js +75 -0
- package/addon/utils/resource-descriptors/helpers.js +191 -0
- package/addon/utils/resource-descriptors/index.js +35 -0
- package/addon/utils/resource-descriptors/maintenance.js +175 -0
- package/addon/utils/resource-descriptors/operations.js +215 -0
- package/addon/utils/resource-descriptors/people.js +173 -0
- package/addon/utils/resource-descriptors/polymorphic.js +123 -0
- package/addon/utils/resource-descriptors/sub-records.js +297 -0
- package/addon/utils/telemetry-timestamp.js +6 -0
- package/app/components/asset/pill.js +1 -0
- package/app/components/asset/summary.js +1 -0
- package/app/components/asset-connection/pill.js +1 -0
- package/app/components/asset-connection/summary.js +1 -0
- package/app/components/attachable/pill.js +1 -0
- package/app/components/attachable/summary.js +1 -0
- package/app/components/cell/asset-connection-identity.js +1 -0
- package/app/components/cell/{attached-vehicle.js → asset-identity.js} +1 -1
- package/app/components/cell/attachable-identity.js +1 -0
- package/app/components/cell/{telematic-device.js → contact-identity.js} +1 -1
- package/app/components/cell/customer-identity.js +1 -0
- package/app/components/cell/device-event-identity.js +1 -0
- package/app/components/cell/entity-identity.js +1 -0
- package/app/components/cell/facilitator-identity.js +1 -0
- package/app/components/cell/fleet-driver-identity.js +1 -0
- package/app/components/cell/fleet-identity.js +1 -0
- package/app/components/cell/fuel-provider-connection-identity.js +1 -0
- package/app/components/cell/fuel-provider-transaction-identity.js +1 -0
- package/app/components/cell/fuel-report-identity.js +1 -0
- package/app/components/cell/inspection-form-identity.js +1 -0
- package/app/components/cell/inspection-item-result-identity.js +1 -0
- package/app/components/cell/inspection-submission-identity.js +1 -0
- package/app/components/cell/integrated-vendor-identity.js +1 -0
- package/app/components/cell/issue-identity.js +1 -0
- package/app/components/cell/maintenance-identity.js +1 -0
- package/app/components/cell/maintenance-schedule-identity.js +1 -0
- package/app/components/cell/maintenance-subject-identity.js +1 -0
- package/app/components/cell/manifest-identity.js +1 -0
- package/app/components/cell/manifest-stop-identity.js +1 -0
- package/app/components/cell/order-config-identity.js +1 -0
- package/app/components/cell/order-identity.js +1 -0
- package/app/components/cell/payload-identity.js +1 -0
- package/app/components/cell/place-identity.js +1 -0
- package/app/components/cell/position-identity.js +1 -0
- package/app/components/cell/purchase-rate-identity.js +1 -0
- package/app/components/cell/recurring-order-schedule-identity.js +1 -0
- package/app/components/cell/resource-list.js +1 -0
- package/app/components/cell/route-identity.js +1 -0
- package/app/components/cell/sensor-identity.js +1 -0
- package/app/components/cell/service-area-identity.js +1 -0
- package/app/components/cell/service-quote-identity.js +1 -0
- package/app/components/cell/service-quote-item-identity.js +1 -0
- package/app/components/cell/service-rate-fee-identity.js +1 -0
- package/app/components/cell/service-rate-identity.js +1 -0
- package/app/components/cell/service-rate-parcel-fee-identity.js +1 -0
- package/app/components/cell/{telematic-provider.js → telematic-identity.js} +1 -1
- package/app/components/cell/tracking-number-identity.js +1 -0
- package/app/components/cell/tracking-status-identity.js +1 -0
- package/app/components/cell/trailer-identity.js +1 -0
- package/app/components/cell/vehicle-device-identity.js +1 -0
- package/app/components/cell/vendor-identity.js +1 -0
- package/app/components/cell/warranty-identity.js +1 -0
- package/app/components/cell/waypoint-identity.js +1 -0
- package/app/components/cell/work-order-identity.js +1 -0
- package/app/components/cell/zone-identity.js +1 -0
- package/app/components/{cell/driver-name.js → contact/pill.js} +1 -1
- package/app/components/{cell/vehicle-name.js → contact/summary.js} +1 -1
- package/app/components/customer/pill.js +1 -0
- package/app/components/customer/summary.js +1 -0
- package/app/components/device/summary.js +1 -0
- package/app/components/device/telemetry.js +1 -0
- package/app/components/device-event/pill.js +1 -0
- package/app/components/device-event/summary.js +1 -0
- package/app/components/driver/summary.js +1 -0
- package/app/components/entity/pill.js +1 -0
- package/app/components/entity/summary.js +1 -0
- package/app/components/equipment/card.js +1 -0
- package/app/components/equipment/panel-header.js +1 -0
- package/app/components/equipment/summary.js +1 -0
- package/app/components/{filter/multi-model.js → facilitator/pill.js} +1 -1
- package/app/components/facilitator/summary.js +1 -0
- package/app/components/fleet/pill.js +1 -0
- package/app/components/fleet/summary.js +1 -0
- package/app/components/fleet-driver/pill.js +1 -0
- package/app/components/fleet-driver/summary.js +1 -0
- package/app/components/fuel-provider-connection/pill.js +1 -0
- package/app/components/fuel-provider-connection/summary.js +1 -0
- package/app/components/fuel-provider-transaction/pill.js +1 -0
- package/app/components/fuel-provider-transaction/summary.js +1 -0
- package/app/components/fuel-report/pill.js +1 -0
- package/app/components/fuel-report/summary.js +1 -0
- package/app/components/fuel-transaction-status.js +1 -0
- package/app/components/geofence-map.js +1 -0
- package/app/components/inspection-field/form.js +1 -0
- package/app/components/inspection-field/input.js +1 -0
- package/app/components/inspection-field/value.js +1 -0
- package/app/components/inspection-flyout.js +1 -0
- package/app/components/inspection-form/builder.js +1 -0
- package/app/components/inspection-form/details/submissions.js +1 -0
- package/app/components/inspection-form/details.js +1 -0
- package/app/components/inspection-form/form.js +1 -0
- package/app/components/inspection-form/pill.js +1 -0
- package/app/components/inspection-form/summary.js +1 -0
- package/app/components/inspection-item-result/pill.js +1 -0
- package/app/components/inspection-item-result/summary.js +1 -0
- package/app/components/inspection-link/list.js +1 -0
- package/app/components/inspection-sheet/group.js +1 -0
- package/app/components/inspection-sheet.js +1 -0
- package/app/components/inspection-submission/details.js +1 -0
- package/app/components/inspection-submission/form.js +1 -0
- package/app/components/inspection-submission/photos.js +1 -0
- package/app/components/inspection-submission/pill.js +1 -0
- package/app/components/inspection-submission/summary.js +1 -0
- package/app/components/integrated-vendor/pill.js +1 -0
- package/app/components/integrated-vendor/summary.js +1 -0
- package/app/components/issue/pill.js +1 -0
- package/app/components/issue/summary.js +1 -0
- package/app/components/issue/timeline.js +1 -0
- package/app/components/layout/fleet-ops-sidebar/operations-monitor.js +1 -0
- package/app/components/maintenance/pill.js +1 -0
- package/app/components/maintenance/summary.js +1 -0
- package/app/components/maintenance-schedule/pill.js +1 -0
- package/app/components/maintenance-schedule/summary.js +1 -0
- package/app/components/maintenance-schedule/work-orders.js +1 -0
- package/app/components/maintenance-subject/pill.js +1 -0
- package/app/components/maintenance-subject/summary.js +1 -0
- package/app/components/manifest/pill.js +1 -0
- package/app/components/manifest/summary.js +1 -0
- package/app/components/manifest-stop/pill.js +1 -0
- package/app/components/manifest-stop/summary.js +1 -0
- package/app/components/modals/fuel-connection-diagnostics.js +1 -0
- package/app/components/modals/fuel-transaction-action.js +1 -0
- package/app/components/modals/inspection-follow-up.js +1 -0
- package/app/components/modals/inspection-link.js +1 -0
- package/app/components/modals/radar-notice.js +1 -0
- package/app/components/modals/radar-save-view.js +1 -0
- package/app/components/modals/radar-select-resource.js +1 -0
- package/app/components/modals/radar-send-pin.js +1 -0
- package/app/components/order/summary.js +1 -0
- package/app/components/order-config/pill.js +1 -0
- package/app/components/order-config/summary.js +1 -0
- package/app/components/part/card.js +1 -0
- package/app/components/part/panel-header.js +1 -0
- package/app/components/part/pill.js +1 -0
- package/app/components/part/summary.js +1 -0
- package/app/components/payload/pill.js +1 -0
- package/app/components/payload/summary.js +1 -0
- package/app/components/place/pill.js +1 -0
- package/app/components/place/summary.js +1 -0
- package/app/components/position/pill.js +1 -0
- package/app/components/position/summary.js +1 -0
- package/app/components/public-inspection.js +1 -0
- package/app/components/purchase-rate/pill.js +1 -0
- package/app/components/purchase-rate/summary.js +1 -0
- package/app/components/radar/agenda/entry.js +1 -0
- package/app/components/radar/agenda/lane.js +1 -0
- package/app/components/radar/agenda.js +1 -0
- package/app/components/radar/briefing.js +1 -0
- package/app/components/radar/bulk-bar.js +1 -0
- package/app/components/radar/decision-card.js +1 -0
- package/app/components/radar/empty-state.js +1 -0
- package/app/components/radar/filter-pills.js +1 -0
- package/app/components/radar/handover-card.js +1 -0
- package/app/components/radar/header.js +1 -0
- package/app/components/radar/item-drawer.js +1 -0
- package/app/components/radar/item-list.js +1 -0
- package/app/components/radar/item-row.js +1 -0
- package/app/components/radar/keyboard-hints.js +1 -0
- package/app/components/radar/subject.js +1 -0
- package/app/components/radar/view-bar.js +1 -0
- package/app/components/recurring-order-schedule/pill.js +1 -0
- package/app/components/recurring-order-schedule/summary.js +1 -0
- package/app/components/resource-activity.js +1 -0
- package/app/components/route/pill.js +1 -0
- package/app/components/route/summary.js +1 -0
- package/app/components/select-option/asset-connection.js +1 -0
- package/app/components/select-option/asset.js +1 -0
- package/app/components/select-option/attachable.js +1 -0
- package/app/components/select-option/contact.js +1 -0
- package/app/components/select-option/customer.js +1 -0
- package/app/components/select-option/device-event.js +1 -0
- package/app/components/select-option/device.js +1 -0
- package/app/components/select-option/driver.js +1 -0
- package/app/components/select-option/entity.js +1 -0
- package/app/components/select-option/equipment.js +1 -0
- package/app/components/select-option/facilitator.js +1 -0
- package/app/components/select-option/fleet-driver.js +1 -0
- package/app/components/select-option/fleet.js +1 -0
- package/app/components/select-option/fuel-provider-connection.js +1 -0
- package/app/components/select-option/fuel-provider-transaction.js +1 -0
- package/app/components/select-option/fuel-report.js +1 -0
- package/app/components/select-option/inspection-form.js +1 -0
- package/app/components/select-option/inspection-item-result.js +1 -0
- package/app/components/select-option/inspection-submission.js +1 -0
- package/app/components/select-option/integrated-vendor.js +1 -0
- package/app/components/select-option/issue.js +1 -0
- package/app/components/select-option/maintenance-schedule.js +1 -0
- package/app/components/select-option/maintenance-subject.js +1 -0
- package/app/components/select-option/maintenance.js +1 -0
- package/app/components/select-option/manifest-stop.js +1 -0
- package/app/components/select-option/manifest.js +1 -0
- package/app/components/select-option/order-config.js +1 -0
- package/app/components/select-option/order.js +1 -0
- package/app/components/select-option/part.js +1 -0
- package/app/components/select-option/payload.js +1 -0
- package/app/components/select-option/place.js +1 -0
- package/app/components/select-option/position.js +1 -0
- package/app/components/select-option/purchase-rate.js +1 -0
- package/app/components/select-option/recurring-order-schedule.js +1 -0
- package/app/components/select-option/route.js +1 -0
- package/app/components/select-option/sensor.js +1 -0
- package/app/components/select-option/service-area.js +1 -0
- package/app/components/select-option/service-quote-item.js +1 -0
- package/app/components/select-option/service-quote.js +1 -0
- package/app/components/select-option/service-rate-fee.js +1 -0
- package/app/components/select-option/service-rate-parcel-fee.js +1 -0
- package/app/components/select-option/service-rate.js +1 -0
- package/app/components/select-option/telematic.js +1 -0
- package/app/components/select-option/trackable.js +1 -0
- package/app/components/select-option/tracking-number.js +1 -0
- package/app/components/select-option/tracking-status.js +1 -0
- package/app/components/select-option/trailer.js +1 -0
- package/app/components/select-option/vehicle-device.js +1 -0
- package/app/components/select-option/vehicle.js +1 -0
- package/app/components/select-option/vendor.js +1 -0
- package/app/components/select-option/warranty.js +1 -0
- package/app/components/select-option/waypoint.js +1 -0
- package/app/components/select-option/work-order.js +1 -0
- package/app/components/select-option/zone.js +1 -0
- package/app/components/sensor/pill.js +1 -0
- package/app/components/sensor/summary.js +1 -0
- package/app/components/service-area/pill.js +1 -0
- package/app/components/service-area/summary.js +1 -0
- package/app/components/service-quote/pill.js +1 -0
- package/app/components/service-quote/summary.js +1 -0
- package/app/components/service-quote-item/pill.js +1 -0
- package/app/components/service-quote-item/summary.js +1 -0
- package/app/components/service-rate/pill.js +1 -0
- package/app/components/service-rate/summary.js +1 -0
- package/app/components/service-rate-fee/pill.js +1 -0
- package/app/components/service-rate-fee/summary.js +1 -0
- package/app/components/service-rate-parcel-fee/pill.js +1 -0
- package/app/components/service-rate-parcel-fee/summary.js +1 -0
- package/app/components/table/cell/fleet-ops-option.js +1 -0
- package/app/components/telematic/pill.js +1 -0
- package/app/components/telematic/summary.js +1 -0
- package/app/components/telematic/telemetry-status.js +1 -0
- package/app/components/tracking-number/pill.js +1 -0
- package/app/components/tracking-number/summary.js +1 -0
- package/app/components/tracking-status/pill.js +1 -0
- package/app/components/tracking-status/summary.js +1 -0
- package/app/components/trailer/summary.js +1 -0
- package/app/components/vehicle/details/inspections.js +1 -0
- package/app/components/vehicle/summary.js +1 -0
- package/app/components/vehicle-device/pill.js +1 -0
- package/app/components/vehicle-device/summary.js +1 -0
- package/app/components/vendor/personnel-tab.js +1 -0
- package/app/components/vendor/pill.js +1 -0
- package/app/components/vendor/summary.js +1 -0
- package/app/components/warranty/pill.js +1 -0
- package/app/components/warranty/summary.js +1 -0
- package/app/components/waypoint/pill.js +1 -0
- package/app/components/waypoint/summary.js +1 -0
- package/app/components/widget/radar.js +1 -0
- package/app/components/work-order/panel-header.js +1 -0
- package/app/components/work-order/pill.js +1 -0
- package/app/components/work-order/summary.js +1 -0
- package/app/components/zone/pill.js +1 -0
- package/app/components/zone/summary.js +1 -0
- package/app/controllers/maintenance/inspection-forms/index/details.js +1 -0
- package/app/controllers/maintenance/inspection-forms/index/edit.js +1 -0
- package/app/controllers/maintenance/inspection-forms/index/new.js +1 -0
- package/app/controllers/maintenance/inspection-forms/index.js +1 -0
- package/app/controllers/maintenance/inspection-submissions/index/details.js +1 -0
- package/app/controllers/maintenance/inspection-submissions/index/edit.js +1 -0
- package/app/controllers/maintenance/inspection-submissions/index/new.js +1 -0
- package/app/controllers/maintenance/inspection-submissions/index.js +1 -0
- package/app/helpers/initials.js +1 -0
- package/app/modifiers/inspection-flyout.js +1 -0
- package/app/modifiers/radar-keyboard.js +1 -0
- package/app/modifiers/sync-value.js +1 -0
- package/app/modifiers/when-changed.js +1 -0
- package/app/routes/maintenance/inspection-forms/index/details/index.js +1 -0
- package/app/routes/maintenance/inspection-forms/index/details/submissions.js +1 -0
- package/app/routes/maintenance/inspection-forms/index/details.js +1 -0
- package/app/routes/maintenance/inspection-forms/index/edit.js +1 -0
- package/app/routes/maintenance/inspection-forms/index/new.js +1 -0
- package/app/routes/maintenance/inspection-forms/index.js +1 -0
- package/app/routes/maintenance/inspection-forms.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/details/audit.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/details/index.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/details/photos.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/details.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/edit.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index/new.js +1 -0
- package/app/routes/maintenance/inspection-submissions/index.js +1 -0
- package/app/routes/maintenance/inspection-submissions.js +1 -0
- package/app/routes/management/vehicles/index/details/inspections.js +1 -0
- package/app/services/inspection-form-actions.js +1 -0
- package/app/services/inspection-submission-actions.js +1 -0
- package/app/templates/maintenance/inspection-forms/index/details/index.js +1 -0
- package/app/templates/maintenance/inspection-forms/index/details/submissions.js +1 -0
- package/app/templates/maintenance/inspection-forms/index/details.js +1 -0
- package/app/templates/maintenance/inspection-forms/index/edit.js +1 -0
- package/app/templates/maintenance/inspection-forms/index/new.js +1 -0
- package/app/templates/maintenance/inspection-forms/index.js +1 -0
- package/app/templates/maintenance/inspection-forms.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/details/audit.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/details/index.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/details/photos.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/details.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/edit.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index/new.js +1 -0
- package/app/templates/maintenance/inspection-submissions/index.js +1 -0
- package/app/templates/maintenance/inspection-submissions.js +1 -0
- package/app/templates/management/vehicles/index/details/inspections.js +1 -0
- package/app/utils/inspection-field-types.js +2 -0
- package/app/utils/inspection-form-structure.js +1 -0
- package/app/utils/radar.js +1 -0
- package/composer.json +1 -1
- package/docs/AFAQY.md +91 -0
- package/docs/TELEMETRY_ARCHITECTURE.md +115 -0
- package/extension.json +1 -1
- package/package.json +3 -3
- package/scripts/coverage-summary.php +11 -0
- package/scripts/pest-bootstrap.php +1 -1
- package/server/config/afaqy.php +8 -0
- package/server/config/fuel-providers.php +28 -7
- package/server/config/telematics.php +8 -1
- package/server/config/telemetry.php +17 -0
- package/server/migrations/2026_09_09_000001_create_inspection_tables.php +152 -0
- package/server/migrations/2026_09_10_000001_convert_inspection_form_items_to_field_groups.php +44 -0
- package/server/migrations/2026_09_10_000002_add_token_to_inspection_links.php +39 -0
- package/server/migrations/2026_09_11_000001_add_assignee_and_pin_to_inspection_links.php +39 -0
- package/server/migrations/2026_09_15_000001_create_telematic_telemetry_tables.php +62 -0
- package/server/migrations/2026_09_15_000002_scope_fuel_transactions_to_connection.php +25 -0
- package/server/migrations/2026_09_16_000001_add_public_id_to_alerts_table.php +45 -0
- package/server/resources/views/mail/inspection-link-pin.blade.php +34 -0
- package/server/src/Auth/Schemas/FleetOps.php +12 -0
- package/server/src/Console/Commands/DrainTelematicInbox.php +82 -0
- package/server/src/Console/Commands/ProcessMaintenanceTriggers.php +4 -1
- package/server/src/Console/Commands/SyncTelematics.php +32 -2
- package/server/src/Contracts/TelemetryProviderInterface.php +27 -0
- package/server/src/Events/DeviceTelemetryUpdated.php +37 -0
- package/server/src/Events/VehicleLocationChanged.php +8 -4
- package/server/src/Exports/InspectionExport.php +125 -0
- package/server/src/Http/Controllers/Api/v1/GeofenceController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/InspectionController.php +300 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +40 -8
- package/server/src/Http/Controllers/Internal/v1/HubController.php +36 -11
- package/server/src/Http/Controllers/Internal/v1/InspectionFormController.php +326 -0
- package/server/src/Http/Controllers/Internal/v1/InspectionSubmissionController.php +229 -0
- package/server/src/Http/Controllers/Internal/v1/RadarController.php +1117 -0
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +67 -0
- package/server/src/Http/Controllers/Public/PublicInspectionController.php +243 -0
- package/server/src/Http/Controllers/TelematicPositionWebhookController.php +60 -0
- package/server/src/Http/Controllers/TelematicWebhookController.php +3 -0
- package/server/src/Http/Filter/FuelProviderConnectionFilter.php +1 -1
- package/server/src/Http/Middleware/ForceJsonResponse.php +25 -0
- package/server/src/Http/Resources/v1/InspectionForm.php +153 -0
- package/server/src/Http/Resources/v1/InspectionItemResult.php +77 -0
- package/server/src/Http/Resources/v1/InspectionLink.php +84 -0
- package/server/src/Http/Resources/v1/InspectionSubmission.php +173 -0
- package/server/src/Jobs/PollTelematicTelemetry.php +118 -0
- package/server/src/Jobs/ProcessTelematicDelivery.php +122 -0
- package/server/src/Jobs/SyncFuelProviderTransactionsJob.php +21 -4
- package/server/src/Mail/InspectionLinkPinMail.php +57 -0
- package/server/src/Models/Driver.php +8 -2
- package/server/src/Models/FuelProviderTransaction.php +1 -0
- package/server/src/Models/InspectionForm.php +240 -0
- package/server/src/Models/InspectionItemResult.php +90 -0
- package/server/src/Models/InspectionLink.php +284 -0
- package/server/src/Models/InspectionSubmission.php +440 -0
- package/server/src/Models/Part.php +9 -2
- package/server/src/Models/WorkOrder.php +3 -0
- package/server/src/Observers/WorkOrderObserver.php +1 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +9 -0
- package/server/src/Rules/Base64OrUrl.php +54 -0
- package/server/src/Support/FuelProviders/FuelProviderService.php +64 -27
- package/server/src/Support/FuelProviders/Providers/PetroAppFuelProvider.php +81 -15
- package/server/src/Support/InspectionFileStore.php +268 -0
- package/server/src/Support/InspectionFormSync.php +231 -0
- package/server/src/Support/InspectionLinkPin.php +150 -0
- package/server/src/Support/InspectionSubmitter.php +297 -0
- package/server/src/Support/Radar/RadarAgenda.php +375 -0
- package/server/src/Support/Radar/RadarBriefing.php +504 -0
- package/server/src/Support/Radar/RadarItemState.php +435 -0
- package/server/src/Support/Radar/RadarRules.php +1424 -0
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +178 -0
- package/server/src/Support/Telematics/Afaqy/Payload.php +49 -0
- package/server/src/Support/Telematics/Providers/AfaqyProvider.php +179 -61
- package/server/src/Support/Telematics/TelematicService.php +37 -6
- package/server/src/Support/Telematics/Telemetry/Configuration.php +30 -0
- package/server/src/Support/Telematics/Telemetry/Inbox.php +61 -0
- package/server/src/Support/Telematics/Telemetry/Ingestor.php +112 -0
- package/server/src/Support/Telematics/Telemetry/Queue.php +28 -0
- package/server/src/Support/Telematics/Telemetry/Sample.php +54 -0
- package/server/src/routes.php +76 -0
- package/server/tests/ApiManifestControllerContractsTest.php +9 -9
- package/server/tests/ControllerFilterContractsTest.php +1 -1
- package/server/tests/EventContractsTest.php +2 -1
- package/server/tests/Feature/Http/AfaqyRealtimeIngestionTest.php +792 -0
- package/server/tests/Feature/Http/Api/GeofenceControllerContractsTest.php +4 -4
- package/server/tests/Feature/Http/Api/TrailerControllerLifecycleTest.php +1 -1
- package/server/tests/Feature/Http/Internal/DriverControllerCreateRecordTest.php +1 -1
- package/server/tests/Feature/Http/Internal/DriverControllerExistingUserAdoptionTest.php +1 -1
- package/server/tests/Feature/Http/Internal/HubControllerTest.php +28 -2
- package/server/tests/Feature/Http/Internal/OrderControllerCreateRecordTest.php +1 -1
- package/server/tests/Feature/Http/Internal/RadarControllerDatabaseTest.php +415 -0
- package/server/tests/Feature/Http/Internal/RadarControllerTest.php +594 -0
- package/server/tests/FuelProviderConnectionControllerContractsTest.php +83 -3
- package/server/tests/FuelProviderImplementationTest.php +10 -2
- package/server/tests/HubAndGettingStartedContractsTest.php +26 -3
- package/server/tests/InspectionControllerContractsTest.php +1329 -0
- package/server/tests/InspectionFieldContractsTest.php +1019 -0
- package/server/tests/InspectionModelContractsTest.php +728 -0
- package/server/tests/InspectionSubmitterRulesTest.php +47 -0
- package/server/tests/ObserverContractsTest.php +1 -1
- package/server/tests/QueueJobContractsTest.php +3 -4
- package/server/tests/RadarRoutesTest.php +35 -0
- package/server/tests/ReportSchemaContractsTest.php +15 -1
- package/server/tests/RouteRegistrationExecutionTest.php +109 -18
- package/server/tests/Support/AfaqyTestCrypto.php +27 -0
- package/server/tests/Support/ExampleTelemetryProvider.php +82 -0
- package/server/tests/Support/TelemetryTestEnvironment.php +53 -0
- package/server/tests/TelematicsHardeningTest.php +17 -17
- package/server/tests/TrailerSupportCoverageTest.php +1 -1
- package/server/tests/Unit/Http/Resources/ManifestResourceTest.php +3 -3
- package/server/tests/Unit/Support/FuelProviderServiceMatchingTest.php +127 -0
- package/server/tests/Unit/Support/PetroAppFuelProviderTest.php +126 -1
- package/server/tests/Unit/Support/RadarAgendaTest.php +200 -0
- package/server/tests/Unit/Support/RadarBriefingTest.php +214 -0
- package/server/tests/Unit/Support/RadarItemStateTest.php +260 -0
- package/server/tests/Unit/Support/RadarRulesTest.php +523 -0
- package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTest.php +9 -1
- package/server/tests/Unit/Support/Telematics/Providers/AfaqyProviderTransportTest.php +8 -0
- package/server/tests/Unit/Support/Telematics/Providers/AfaqyRealtimeContractTest.php +188 -0
- package/server/tests/Unit/Support/Telematics/TelematicServiceTelemetryTest.php +1 -0
- package/translations/ar-ae.yml +3 -1
- package/translations/bg-bg.yaml +3 -1
- package/translations/en-us.yaml +738 -15
- package/translations/es-pa.yaml +3 -1
- package/translations/fr-fr.yaml +3 -1
- package/translations/mn-mn.yaml +3 -1
- package/translations/pt-br.yaml +3 -1
- package/translations/ru-ru.yaml +3 -1
- package/translations/vi-vn.yaml +3 -1
- package/addon/components/cell/attached-vehicle.hbs +0 -10
- package/addon/components/cell/attached-vehicle.js +0 -58
- package/addon/components/cell/device-identity.js +0 -129
- package/addon/components/cell/driver-identity.js +0 -143
- package/addon/components/cell/driver-name.hbs +0 -26
- package/addon/components/cell/driver-name.js +0 -30
- package/addon/components/cell/equipment-identity.js +0 -48
- package/addon/components/cell/part-identity.js +0 -63
- package/addon/components/cell/telematic-device.hbs +0 -38
- package/addon/components/cell/telematic-device.js +0 -44
- package/addon/components/cell/telematic-provider.hbs +0 -33
- package/addon/components/cell/telematic-provider.js +0 -78
- package/addon/components/cell/vehicle-identity.js +0 -138
- package/addon/components/cell/vehicle-name.hbs +0 -23
- package/addon/components/cell/vehicle-name.js +0 -3
- package/addon/components/device/pill.js +0 -3
- package/addon/components/driver/pill.js +0 -7
- package/addon/components/equipment/pill.js +0 -3
- package/addon/components/filter/multi-model.hbs +0 -19
- package/addon/components/filter/multi-model.js +0 -90
- package/addon/components/order/pill.js +0 -3
- package/addon/components/trailer/pill.js +0 -3
- package/addon/components/vehicle/pill.js +0 -7
- package/addon/templates/connectivity/fuel-providers/details/settings.hbs +0 -11
|
@@ -87,14 +87,14 @@ class FuelProviderService
|
|
|
87
87
|
|
|
88
88
|
public function syncTransactions(FuelProviderConnection $connection, ?Carbon $from = null, ?Carbon $to = null, array $options = [], ?FuelProviderSyncRun $syncRun = null): array
|
|
89
89
|
{
|
|
90
|
-
$
|
|
91
|
-
$from ??= Carbon::parse(data_get($settings, 'from', $connection->last_synced_at?->copy()->subDay() ?? now()->subDays((int) data_get($settings, 'window_days', 7))));
|
|
92
|
-
$to ??= Carbon::parse(data_get($settings, 'to', now()));
|
|
90
|
+
[$from, $to] = $this->syncWindow($connection, $from ?? $syncRun?->from, $to ?? $syncRun?->to);
|
|
93
91
|
|
|
94
92
|
$syncRun ??= $this->createSyncRun($connection, $from, $to, 'running');
|
|
95
|
-
$syncRun->update(['status' => 'running', 'started_at' => now(), 'error' => null]);
|
|
93
|
+
$syncRun->update(['status' => 'running', 'from' => $from, 'to' => $to, 'started_at' => now(), 'error' => null]);
|
|
96
94
|
|
|
97
95
|
$summary = [
|
|
96
|
+
'received' => 0,
|
|
97
|
+
'updated' => 0,
|
|
98
98
|
'imported' => 0,
|
|
99
99
|
'matched' => 0,
|
|
100
100
|
'unmatched' => 0,
|
|
@@ -109,22 +109,23 @@ class FuelProviderService
|
|
|
109
109
|
|
|
110
110
|
foreach ($payloads as $payload) {
|
|
111
111
|
$transaction = $this->ingestTransaction($connection, $payload);
|
|
112
|
-
$summary['
|
|
112
|
+
$summary['received']++;
|
|
113
|
+
$summary[$transaction->wasRecentlyCreated ? 'imported' : 'updated']++;
|
|
113
114
|
$summary['liters'] += (float) $transaction->volume;
|
|
114
115
|
$summary['amount'] += (int) $transaction->amount;
|
|
115
116
|
|
|
116
117
|
if ($transaction->sync_status === 'matched') {
|
|
117
118
|
$summary['matched']++;
|
|
118
|
-
}
|
|
119
|
+
} elseif ($transaction->sync_status === 'unmatched') {
|
|
119
120
|
$summary['unmatched']++;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
if ($transaction->fuel_report_uuid) {
|
|
123
|
+
if ($transaction->fuel_report_uuid && $transaction->createdFuelReport) {
|
|
123
124
|
$summary['fuel_reports_created']++;
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
} catch (\Throwable $e) {
|
|
127
|
-
$syncRun->update(['status' => 'error', 'finished_at' => now(), 'error' => $e->getMessage(), 'summary' => $summary]);
|
|
128
|
+
$syncRun->update(array_merge(collect($summary)->only(['imported', 'matched', 'unmatched', 'fuel_reports_created', 'liters', 'amount'])->all(), ['status' => 'error', 'finished_at' => now(), 'error' => $e->getMessage(), 'summary' => $summary]));
|
|
128
129
|
$connection->update(['status' => 'error', 'last_error' => $e->getMessage()]);
|
|
129
130
|
throw $e;
|
|
130
131
|
}
|
|
@@ -158,6 +159,8 @@ class FuelProviderService
|
|
|
158
159
|
|
|
159
160
|
public function createSyncRun(FuelProviderConnection $connection, ?Carbon $from = null, ?Carbon $to = null, string $status = 'queued'): FuelProviderSyncRun
|
|
160
161
|
{
|
|
162
|
+
[$from, $to] = $this->syncWindow($connection, $from, $to);
|
|
163
|
+
|
|
161
164
|
return FuelProviderSyncRun::create([
|
|
162
165
|
'company_uuid' => $connection->company_uuid,
|
|
163
166
|
'fuel_provider_connection_uuid' => $connection->uuid,
|
|
@@ -168,29 +171,42 @@ class FuelProviderService
|
|
|
168
171
|
]);
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
public function syncWindow(FuelProviderConnection $connection, ?Carbon $from = null, ?Carbon $to = null): array
|
|
175
|
+
{
|
|
176
|
+
$settings = (array) $connection->sync_settings;
|
|
177
|
+
$from ??= Carbon::parse(data_get($settings, 'from') ?: now()->subDays(max(1, (int) data_get($settings, 'window_days', 7))))->startOfDay();
|
|
178
|
+
$to ??= Carbon::parse(data_get($settings, 'to') ?: now())->endOfDay();
|
|
179
|
+
if ($from->gt($to)) {
|
|
180
|
+
throw new \InvalidArgumentException('The sync start date must be on or before the end date.');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return [$from, $to];
|
|
184
|
+
}
|
|
185
|
+
|
|
171
186
|
public function ingestTransaction(FuelProviderConnection $connection, array $payload): FuelProviderTransaction
|
|
172
187
|
{
|
|
173
188
|
return DB::transaction(function () use ($connection, $payload) {
|
|
174
189
|
$provider = $payload['provider'] ?? $connection->provider;
|
|
175
190
|
$providerTransactionId = $payload['provider_transaction_id'];
|
|
176
|
-
//
|
|
177
|
-
// unique within the account they were issued for, so keying on
|
|
178
|
-
// (provider, provider_transaction_id) alone let one company's sync find
|
|
179
|
-
// and overwrite another company's transaction — reassigning its
|
|
180
|
-
// company_uuid. Mirrors fuel_provider_txn_company_provider_unique.
|
|
191
|
+
// Provider IDs are scoped to the connected account/environment.
|
|
181
192
|
$transaction = FuelProviderTransaction::updateOrCreate(
|
|
182
193
|
[
|
|
183
|
-
'company_uuid'
|
|
184
|
-
'
|
|
185
|
-
'
|
|
194
|
+
'company_uuid' => $connection->company_uuid,
|
|
195
|
+
'fuel_provider_connection_uuid' => $connection->uuid,
|
|
196
|
+
'provider' => $provider,
|
|
197
|
+
'provider_transaction_id' => $providerTransactionId,
|
|
186
198
|
],
|
|
187
199
|
array_merge($payload, [
|
|
188
200
|
'company_uuid' => $connection->company_uuid,
|
|
189
201
|
'fuel_provider_connection_uuid' => $connection->uuid,
|
|
190
|
-
'sync_status' => 'imported',
|
|
191
202
|
])
|
|
192
203
|
);
|
|
193
204
|
|
|
205
|
+
$created = $transaction->wasRecentlyCreated;
|
|
206
|
+
$hadReport = (bool) $transaction->fuel_report_uuid;
|
|
207
|
+
if (!$created && in_array($transaction->sync_status, ['reviewed', 'ignored'], true)) {
|
|
208
|
+
return $transaction;
|
|
209
|
+
}
|
|
194
210
|
event(new FuelProviderTransactionImported($transaction));
|
|
195
211
|
|
|
196
212
|
$this->matchTransaction($transaction, $connection);
|
|
@@ -211,7 +227,11 @@ class FuelProviderService
|
|
|
211
227
|
event(new FuelProviderTransactionUnmatched($transaction));
|
|
212
228
|
}
|
|
213
229
|
|
|
214
|
-
|
|
230
|
+
$result = $transaction->fresh(['vehicle', 'driver', 'fuelReport']);
|
|
231
|
+
$result->wasRecentlyCreated = $created;
|
|
232
|
+
$result->createdFuelReport = !$hadReport && (bool) $result->fuel_report_uuid;
|
|
233
|
+
|
|
234
|
+
return $result;
|
|
215
235
|
});
|
|
216
236
|
}
|
|
217
237
|
|
|
@@ -228,7 +248,9 @@ class FuelProviderService
|
|
|
228
248
|
$transaction->sync_status = 'matched';
|
|
229
249
|
$transaction->matched_at ??= now();
|
|
230
250
|
$transaction->save();
|
|
231
|
-
$this->
|
|
251
|
+
if (!$transaction->connection || $this->shouldCreateFuelReport($transaction->connection)) {
|
|
252
|
+
$this->ensureFuelReport($transaction);
|
|
253
|
+
}
|
|
232
254
|
|
|
233
255
|
event(new FuelProviderTransactionMatched($transaction));
|
|
234
256
|
|
|
@@ -257,7 +279,9 @@ class FuelProviderService
|
|
|
257
279
|
|
|
258
280
|
$this->matchTransaction($transaction, $transaction->connection);
|
|
259
281
|
if ($transaction->vehicle_uuid) {
|
|
260
|
-
$this->
|
|
282
|
+
if (!$transaction->connection || $this->shouldCreateFuelReport($transaction->connection)) {
|
|
283
|
+
$this->ensureFuelReport($transaction);
|
|
284
|
+
}
|
|
261
285
|
$transaction->sync_status = 'matched';
|
|
262
286
|
$transaction->matched_at ??= now();
|
|
263
287
|
event(new FuelProviderTransactionMatched($transaction));
|
|
@@ -313,7 +337,11 @@ class FuelProviderService
|
|
|
313
337
|
|
|
314
338
|
protected function matchingOrder(?FuelProviderConnection $connection = null): Collection
|
|
315
339
|
{
|
|
316
|
-
$
|
|
340
|
+
$settings = (array) $connection?->sync_settings;
|
|
341
|
+
if (array_key_exists('matching_order', $settings) && $settings['matching_order'] === []) {
|
|
342
|
+
return collect();
|
|
343
|
+
}
|
|
344
|
+
$configuredFields = collect(data_get($settings, 'matching_order', []))->filter()->values();
|
|
317
345
|
|
|
318
346
|
if ($configuredFields->all() === self::LEGACY_DEFAULT_MATCHING_ORDER) {
|
|
319
347
|
return collect(self::DEFAULT_MATCHING_ORDER);
|
|
@@ -334,14 +362,16 @@ class FuelProviderService
|
|
|
334
362
|
|
|
335
363
|
protected function resolveOrder(FuelProviderTransaction $transaction): ?Order
|
|
336
364
|
{
|
|
337
|
-
|
|
365
|
+
$matches = Order::where('company_uuid', $transaction->company_uuid)
|
|
338
366
|
->where(function ($query) use ($transaction) {
|
|
339
367
|
$query->where('public_id', $transaction->trip_number)
|
|
340
368
|
->orWhere('internal_id', $transaction->trip_number)
|
|
341
369
|
->orWhereHas('trackingNumber', function ($trackingNumberQuery) use ($transaction) {
|
|
342
370
|
$trackingNumberQuery->where('tracking_number', $transaction->trip_number);
|
|
343
371
|
});
|
|
344
|
-
})->
|
|
372
|
+
})->limit(2)->get();
|
|
373
|
+
|
|
374
|
+
return $matches->count() === 1 ? $matches->first() : null;
|
|
345
375
|
}
|
|
346
376
|
|
|
347
377
|
protected function resolveVehicle(FuelProviderTransaction $transaction, string $field): ?Vehicle
|
|
@@ -373,14 +403,16 @@ class FuelProviderService
|
|
|
373
403
|
|
|
374
404
|
$normalized = $this->normalizeIdentifier($identifier);
|
|
375
405
|
|
|
376
|
-
|
|
406
|
+
$matches = Vehicle::where('company_uuid', $transaction->company_uuid)
|
|
377
407
|
->where(function ($query) use ($identifier, $normalized, $vehicleFields) {
|
|
378
408
|
foreach ($vehicleFields as $vehicleField) {
|
|
379
409
|
$query->orWhere($vehicleField, $identifier)
|
|
380
410
|
->orWhereRaw("REPLACE(REPLACE(UPPER({$vehicleField}), ' ', ''), '-', '') = ?", [$normalized]);
|
|
381
411
|
}
|
|
382
412
|
})
|
|
383
|
-
->
|
|
413
|
+
->limit(2)->get();
|
|
414
|
+
|
|
415
|
+
return $matches->count() === 1 ? $matches->first() : null;
|
|
384
416
|
}
|
|
385
417
|
|
|
386
418
|
protected function resolveVehicleByProviderId(FuelProviderTransaction $transaction): ?Vehicle
|
|
@@ -389,12 +421,14 @@ class FuelProviderService
|
|
|
389
421
|
return null;
|
|
390
422
|
}
|
|
391
423
|
|
|
392
|
-
|
|
424
|
+
$matches = Vehicle::where('company_uuid', $transaction->company_uuid)
|
|
393
425
|
->where(function ($query) use ($transaction) {
|
|
394
426
|
$query->where('meta->fuel_provider_vehicle_id', $transaction->provider_vehicle_id)
|
|
395
427
|
->orWhere("meta->fuel_provider_ids->{$transaction->provider}", $transaction->provider_vehicle_id);
|
|
396
428
|
})
|
|
397
|
-
->
|
|
429
|
+
->limit(2)->get();
|
|
430
|
+
|
|
431
|
+
return $matches->count() === 1 ? $matches->first() : null;
|
|
398
432
|
}
|
|
399
433
|
|
|
400
434
|
protected function normalizeMatchingField(string $field): string
|
|
@@ -433,12 +467,15 @@ class FuelProviderService
|
|
|
433
467
|
'source' => 'fuel_provider',
|
|
434
468
|
'provider' => $transaction->provider,
|
|
435
469
|
'fuel_provider_transaction_uuid' => $transaction->uuid,
|
|
470
|
+
'fuel_provider_connection_uuid' => $transaction->fuel_provider_connection_uuid,
|
|
471
|
+
'transaction_at' => $transaction->transaction_at?->toIso8601String(),
|
|
436
472
|
'station_name' => $transaction->station_name,
|
|
437
473
|
'trip_number' => $transaction->trip_number,
|
|
438
474
|
],
|
|
439
475
|
]);
|
|
440
476
|
|
|
441
477
|
$transaction->fuel_report_uuid = $fuelReport->uuid;
|
|
478
|
+
$transaction->save();
|
|
442
479
|
event(new FuelReportCreatedFromProvider($transaction, $fuelReport));
|
|
443
480
|
|
|
444
481
|
return $fuelReport;
|
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Support\FuelProviders\Providers;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Models\FuelProviderConnection;
|
|
6
|
+
use Illuminate\Http\Client\Response;
|
|
6
7
|
use Illuminate\Support\Carbon;
|
|
7
8
|
use Illuminate\Support\Collection;
|
|
8
9
|
|
|
9
10
|
class PetroAppFuelProvider extends AbstractFuelProvider
|
|
10
11
|
{
|
|
12
|
+
public const BASE_URLS = [
|
|
13
|
+
'sandbox' => 'https://app-public.staging.petroapp.app/webservice',
|
|
14
|
+
'production' => 'https://app.petroapp.com.sa/webservice',
|
|
15
|
+
];
|
|
16
|
+
|
|
11
17
|
public function key(): string
|
|
12
18
|
{
|
|
13
19
|
return 'petroapp';
|
|
@@ -21,22 +27,28 @@ class PetroAppFuelProvider extends AbstractFuelProvider
|
|
|
21
27
|
public function testConnection(FuelProviderConnection $connection): array
|
|
22
28
|
{
|
|
23
29
|
try {
|
|
24
|
-
$response = $this->
|
|
30
|
+
[$response, $authType] = $this->getResponse($connection, 'vehicles', ['page' => 1]);
|
|
31
|
+
$metadata = [
|
|
32
|
+
'environment' => $connection->environment ?? 'production',
|
|
33
|
+
'host' => parse_url($this->baseUrl($connection), PHP_URL_HOST),
|
|
34
|
+
'auth_type' => $authType,
|
|
35
|
+
'status' => $response->status(),
|
|
36
|
+
];
|
|
25
37
|
|
|
26
|
-
if (!$response->
|
|
38
|
+
if (!$this->successfulResponse($response) || !is_array($response->json('data.data'))) {
|
|
27
39
|
return [
|
|
28
40
|
'success' => false,
|
|
29
41
|
'message' => $response->json('message') ?? 'Unable to connect to PetroApp.',
|
|
30
|
-
'metadata' =>
|
|
42
|
+
'metadata' => $metadata,
|
|
31
43
|
];
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
return [
|
|
35
47
|
'success' => true,
|
|
36
48
|
'message' => 'PetroApp connection successful.',
|
|
37
|
-
'metadata' => [
|
|
38
|
-
'total_vehicles' => $response->json('data.total'),
|
|
39
|
-
],
|
|
49
|
+
'metadata' => array_merge($metadata, [
|
|
50
|
+
'total_vehicles' => $response->json('data.total') ?? $response->json('data.meta.total'),
|
|
51
|
+
]),
|
|
40
52
|
];
|
|
41
53
|
} catch (\Throwable $e) {
|
|
42
54
|
return ['success' => false, 'message' => $e->getMessage(), 'metadata' => []];
|
|
@@ -69,13 +81,15 @@ class PetroAppFuelProvider extends AbstractFuelProvider
|
|
|
69
81
|
{
|
|
70
82
|
$credentials = (array) $connection->credentials;
|
|
71
83
|
|
|
72
|
-
|
|
84
|
+
$override = trim((string) data_get($credentials, 'base_url', ''));
|
|
85
|
+
|
|
86
|
+
return rtrim($override ?: self::BASE_URLS[$connection->environment ?? 'production'], '/');
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
protected function headers(FuelProviderConnection $connection): array
|
|
76
90
|
{
|
|
77
91
|
$credentials = (array) $connection->credentials;
|
|
78
|
-
$token = data_get($credentials, 'api_token') ?? data_get($credentials, 'api_key');
|
|
92
|
+
$token = trim((string) (data_get($credentials, 'api_token') ?? data_get($credentials, 'api_key')));
|
|
79
93
|
|
|
80
94
|
if (data_get($credentials, 'auth_type') === 'ws_sk_header') {
|
|
81
95
|
return [
|
|
@@ -99,28 +113,80 @@ class PetroAppFuelProvider extends AbstractFuelProvider
|
|
|
99
113
|
$items = collect();
|
|
100
114
|
|
|
101
115
|
do {
|
|
102
|
-
$response = $this->
|
|
116
|
+
[$response] = $this->getResponse($connection, $endpoint, array_merge($params, ['page' => $page]));
|
|
103
117
|
|
|
104
|
-
if (!$
|
|
118
|
+
if (!$this->successfulResponse($response)) {
|
|
105
119
|
throw new \RuntimeException($response->json('message') ?? "PetroApp {$endpoint} request failed.");
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
$payload = $response->json();
|
|
109
|
-
$data = $dataKey ? data_get($payload, $dataKey
|
|
123
|
+
$data = $dataKey ? data_get($payload, $dataKey) : data_get($payload, 'data.data');
|
|
124
|
+
if (!is_array($data)) {
|
|
125
|
+
throw new \RuntimeException("PetroApp {$endpoint} returned an invalid response.");
|
|
126
|
+
}
|
|
110
127
|
$items = $items->merge($data);
|
|
111
128
|
|
|
112
|
-
$lastPage = (int) data_get($payload, 'data.last_page', $page);
|
|
113
|
-
$hasMore = data_get($payload, 'data.next_page_url') || $page < $lastPage;
|
|
129
|
+
$lastPage = (int) data_get($payload, 'data.last_page', data_get($payload, 'data.meta.last_page', $page));
|
|
130
|
+
$hasMore = data_get($payload, 'data.next_page_url') || data_get($payload, 'data.links.next') || $page < $lastPage;
|
|
114
131
|
$page++;
|
|
115
132
|
} while ($hasMore && $page <= $maxPages);
|
|
116
133
|
|
|
134
|
+
if ($hasMore) {
|
|
135
|
+
throw new \RuntimeException('PetroApp returned more pages than the sync limit. Choose a shorter date range and retry; the import was not marked complete.');
|
|
136
|
+
}
|
|
137
|
+
|
|
117
138
|
return $items;
|
|
118
139
|
}
|
|
119
140
|
|
|
141
|
+
protected function getResponse(FuelProviderConnection $connection, string $endpoint, array $params): array
|
|
142
|
+
{
|
|
143
|
+
$credentials = (array) $connection->credentials;
|
|
144
|
+
$authType = data_get($credentials, 'auth_type') ?: 'bearer_token';
|
|
145
|
+
$response = $this->client($connection)->get($endpoint, $params);
|
|
146
|
+
|
|
147
|
+
// Older forms supplied only api_token. Preserve working Bearer tokens,
|
|
148
|
+
// but support WS-SK tokens when PetroApp explicitly requests a secret key.
|
|
149
|
+
if (blank(data_get($credentials, 'auth_type')) && $response->json('message') === 'Secret key is not found') {
|
|
150
|
+
$retryConnection = clone $connection;
|
|
151
|
+
$retryConnection->credentials = array_merge($credentials, ['auth_type' => 'ws_sk_header']);
|
|
152
|
+
$response = $this->client($retryConnection)->get($endpoint, $params);
|
|
153
|
+
$authType = 'ws_sk_header';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return [$response, $authType];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected function successfulResponse(Response $response): bool
|
|
160
|
+
{
|
|
161
|
+
$payload = $response->json();
|
|
162
|
+
if (!$response->successful() || !is_array($payload)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
foreach (['success', 'status'] as $key) {
|
|
167
|
+
if (array_key_exists($key, $payload) && in_array($payload[$key], [false, 0, '0', 'false', 'error'], true)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected function billPlate(array $bill): ?string
|
|
176
|
+
{
|
|
177
|
+
$number = $this->compactIdentifier($bill['plate_snum'] ?? null);
|
|
178
|
+
$letters = $this->compactIdentifier($bill['plate_letter'] ?? null);
|
|
179
|
+
if (!$letters || !$number || str_contains($number, $letters)) {
|
|
180
|
+
return $number;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return $this->compactIdentifier($letters . ' ' . $number);
|
|
184
|
+
}
|
|
185
|
+
|
|
120
186
|
protected function normalizeBill(array $bill): array
|
|
121
187
|
{
|
|
122
188
|
$transactionAt = $this->dateFrom($bill['bill_date'] ?? $bill['billDate'] ?? null);
|
|
123
|
-
$providerId = $bill['id'] ?? $bill['bill_id'] ?? null;
|
|
189
|
+
$providerId = $bill['id'] ?? $bill['bill_id'] ?? $bill['bill_number'] ?? null;
|
|
124
190
|
$fallbackId = $this->transactionHash([
|
|
125
191
|
$bill['bill_date'] ?? $bill['billDate'] ?? null,
|
|
126
192
|
$bill['trip_number'] ?? null,
|
|
@@ -139,7 +205,7 @@ class PetroAppFuelProvider extends AbstractFuelProvider
|
|
|
139
205
|
'vehicle_card_id' => $this->compactIdentifier($bill['vehicle_card_id'] ?? $bill['fuel_card_number'] ?? $bill['card_number'] ?? null),
|
|
140
206
|
'internal_number' => $this->compactIdentifier($bill['internal_number'] ?? null),
|
|
141
207
|
'structure_number' => $this->compactIdentifier($bill['structure_number'] ?? null),
|
|
142
|
-
'plate_number' => $this->
|
|
208
|
+
'plate_number' => $this->billPlate($bill),
|
|
143
209
|
'vin' => $this->compactIdentifier($bill['vin'] ?? $bill['vin_number'] ?? null),
|
|
144
210
|
'serial_number' => $this->compactIdentifier($bill['serial_number'] ?? null),
|
|
145
211
|
'call_sign' => $this->compactIdentifier($bill['call_sign'] ?? null),
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Support;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Models\InspectionSubmission;
|
|
6
|
+
use Fleetbase\Models\File;
|
|
7
|
+
use Illuminate\Support\Str;
|
|
8
|
+
use Illuminate\Validation\ValidationException;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Turns what a driver sends for a photo or a signature into a platform file.
|
|
12
|
+
*
|
|
13
|
+
* The app is offline-first: it cannot upload a photo and then reference it,
|
|
14
|
+
* so a photo arrives inside the submit body as base64. The platform's own
|
|
15
|
+
* convention for a file held in a custom-field value is `file:<uuid>`, which
|
|
16
|
+
* is what every value leaves here as — a URL, or a reference to a file that
|
|
17
|
+
* already exists, is kept as it came.
|
|
18
|
+
*
|
|
19
|
+
* A reference is only ever kept for a file the submission may use: one that
|
|
20
|
+
* belongs to the submission's own company. A submission through a public
|
|
21
|
+
* link may go further than that only in one direction — it may reference
|
|
22
|
+
* nothing but files uploaded through that same link, and it may not use an
|
|
23
|
+
* outside URL as a photo at all.
|
|
24
|
+
*/
|
|
25
|
+
class InspectionFileStore
|
|
26
|
+
{
|
|
27
|
+
public const TYPE_PHOTO = 'inspection_photo';
|
|
28
|
+
public const TYPE_SIGNATURE = 'inspection_signature';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Normalizes one file value. Returns the value unchanged when it is not a
|
|
32
|
+
* string, is empty, or is something other than base64 or a file reference.
|
|
33
|
+
*/
|
|
34
|
+
public static function normalize(mixed $value, InspectionSubmission $submission, string $type = self::TYPE_PHOTO, ?string $uploaderUuid = null): mixed
|
|
35
|
+
{
|
|
36
|
+
if (!is_string($value) || trim($value) === '') {
|
|
37
|
+
return $value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
$value = trim($value);
|
|
41
|
+
|
|
42
|
+
$linkUuid = static::linkUuidOf($submission);
|
|
43
|
+
|
|
44
|
+
// A reference to a file that already exists — `file:<uuid>`, a bare
|
|
45
|
+
// uuid, or the public id an upload answers with — is kept only for a
|
|
46
|
+
// file the submission may use.
|
|
47
|
+
if (Str::startsWith($value, 'file:') || Str::isUuid($value) || Str::startsWith($value, 'file_')) {
|
|
48
|
+
return static::ownedReference($value, $submission, $linkUuid);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (static::isUrl($value)) {
|
|
52
|
+
if ($linkUuid) {
|
|
53
|
+
throw ValidationException::withMessages(['photos' => 'A photo on an inspection link must be uploaded through the link.']);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return $value;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (static::isBase64($value)) {
|
|
60
|
+
$file = static::store($value, $submission, $type, $uploaderUuid);
|
|
61
|
+
|
|
62
|
+
return $file ? 'file:' . $file->uuid : $value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return $value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Stores a base64 payload — bare or as a data URI — as a file that belongs
|
|
70
|
+
* to the submission, under `inspections/<submission uuid>/`.
|
|
71
|
+
*/
|
|
72
|
+
public static function store(string $base64, InspectionSubmission $submission, string $type = self::TYPE_PHOTO, ?string $uploaderUuid = null): ?File
|
|
73
|
+
{
|
|
74
|
+
$contentType = null;
|
|
75
|
+
$data = $base64;
|
|
76
|
+
|
|
77
|
+
if (preg_match('/^data:(?<content_type>[^;]+);base64,(?<data>.+)$/s', $base64, $matches)) {
|
|
78
|
+
$contentType = $matches['content_type'];
|
|
79
|
+
$data = $matches['data'];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
$data = preg_replace('/\s+/', '', $data);
|
|
83
|
+
$contentType = $contentType ?? static::sniffContentType($data);
|
|
84
|
+
$extension = static::extensionFor($contentType);
|
|
85
|
+
$fileName = Str::lower(Str::random(20)) . '.' . $extension;
|
|
86
|
+
|
|
87
|
+
$file = File::createFromBase64($data, $fileName, 'inspections/' . $submission->uuid, $type, $contentType);
|
|
88
|
+
if (!$file instanceof File) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
$file->company_uuid = $submission->company_uuid;
|
|
93
|
+
$file->uploader_uuid = $uploaderUuid ?? $submission->submitted_by_uuid ?? $file->uploader_uuid;
|
|
94
|
+
$file->setSubject($submission, $type);
|
|
95
|
+
|
|
96
|
+
return $file;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Files referenced by `file:<uuid>` values that were uploaded before the
|
|
101
|
+
* submission existed — the console uploads a photo as soon as it is picked
|
|
102
|
+
* — are claimed by the submission so its Photos panel lists them.
|
|
103
|
+
*
|
|
104
|
+
* @param string[] $uuids
|
|
105
|
+
*/
|
|
106
|
+
public static function attachReferenced(InspectionSubmission $submission, array $uuids): int
|
|
107
|
+
{
|
|
108
|
+
$uuids = array_values(array_unique(array_filter($uuids, 'is_string')));
|
|
109
|
+
if (empty($uuids)) {
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Only the submission's own company's files, and — for a submission
|
|
114
|
+
// through a public link — only files uploaded through that link. This
|
|
115
|
+
// claim was unscoped: any unattached file anywhere whose uuid appeared
|
|
116
|
+
// in an answer was taken.
|
|
117
|
+
$query = File::query()
|
|
118
|
+
->whereIn('uuid', $uuids)
|
|
119
|
+
->where('company_uuid', $submission->company_uuid)
|
|
120
|
+
->whereNull('subject_uuid');
|
|
121
|
+
|
|
122
|
+
if ($linkUuid = static::linkUuidOf($submission)) {
|
|
123
|
+
$query->where('meta->inspection_link_uuid', $linkUuid);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return $query->update(['subject_uuid' => $submission->uuid, 'subject_type' => $submission->getMorphClass()]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The inspection link a submission came through, or null when it came
|
|
131
|
+
* through the console or the driver app.
|
|
132
|
+
*/
|
|
133
|
+
protected static function linkUuidOf(InspectionSubmission $submission): ?string
|
|
134
|
+
{
|
|
135
|
+
if ($submission->source !== 'public_link') {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
$uuid = data_get($submission->meta, 'inspection_link_uuid');
|
|
140
|
+
|
|
141
|
+
return is_string($uuid) && $uuid !== '' ? $uuid : null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* A reference to an existing file, as `file:<uuid>`, kept only when the
|
|
146
|
+
* file is the submission's to use.
|
|
147
|
+
*
|
|
148
|
+
* The lookup used to be unscoped, so a submission that named another
|
|
149
|
+
* company's file — by uuid or public id — kept the reference, the file was
|
|
150
|
+
* attached to it, and the submission resource then handed out that file's
|
|
151
|
+
* URL. It is now scoped to the submission's company; a submission through
|
|
152
|
+
* a public link must also have uploaded the file through that link, and is
|
|
153
|
+
* refused outright rather than silently losing a photo it named.
|
|
154
|
+
*/
|
|
155
|
+
protected static function ownedReference(string $value, InspectionSubmission $submission, ?string $linkUuid): ?string
|
|
156
|
+
{
|
|
157
|
+
$reference = Str::startsWith($value, 'file:') ? substr($value, 5) : $value;
|
|
158
|
+
|
|
159
|
+
$file = File::query()
|
|
160
|
+
->where('company_uuid', $submission->company_uuid)
|
|
161
|
+
->where(Str::isUuid($reference) ? 'uuid' : 'public_id', $reference)
|
|
162
|
+
->first();
|
|
163
|
+
|
|
164
|
+
if ($file && (!$linkUuid || data_get($file->meta, 'inspection_link_uuid') === $linkUuid)) {
|
|
165
|
+
return 'file:' . $file->uuid;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if ($linkUuid) {
|
|
169
|
+
throw ValidationException::withMessages(['photos' => 'A photo on an inspection link must be uploaded through the link.']);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The uuid a `file:<uuid>` value points at, or null for anything else. */
|
|
176
|
+
public static function referencedUuid(mixed $value): ?string
|
|
177
|
+
{
|
|
178
|
+
if (!is_string($value) || !Str::startsWith($value, 'file:')) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
$uuid = substr($value, 5);
|
|
183
|
+
|
|
184
|
+
return Str::isUuid($uuid) ? $uuid : null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Resolves a `file:<uuid>` value to its file, or null. */
|
|
188
|
+
public static function resolve(mixed $value): ?File
|
|
189
|
+
{
|
|
190
|
+
$uuid = static::referencedUuid($value);
|
|
191
|
+
|
|
192
|
+
return $uuid ? File::query()->where('uuid', $uuid)->first() : null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* What the driver API answers for a file value: the file's id and where to
|
|
197
|
+
* fetch it, or the value as it was stored when it is a URL.
|
|
198
|
+
*/
|
|
199
|
+
public static function project(mixed $value): mixed
|
|
200
|
+
{
|
|
201
|
+
$file = static::resolve($value);
|
|
202
|
+
if (!$file) {
|
|
203
|
+
return $value;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return [
|
|
207
|
+
'id' => $file->public_id,
|
|
208
|
+
'url' => $file->url,
|
|
209
|
+
'filename' => $file->original_filename,
|
|
210
|
+
'content_type' => $file->content_type,
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public static function isUrl(string $value): bool
|
|
215
|
+
{
|
|
216
|
+
return (bool) preg_match('#^https?://#i', $value);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Bare base64 of at least a few bytes: long enough not to be a word, and only base64 characters. */
|
|
220
|
+
public static function isBase64(string $value): bool
|
|
221
|
+
{
|
|
222
|
+
if (Str::startsWith($value, 'data:')) {
|
|
223
|
+
return (bool) preg_match('/^data:[^;]+;base64,[A-Za-z0-9+\/=\s]+$/s', $value);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
$stripped = preg_replace('/\s+/', '', $value);
|
|
227
|
+
|
|
228
|
+
return strlen($stripped) >= 16
|
|
229
|
+
&& strlen($stripped) % 4 === 0
|
|
230
|
+
&& (bool) preg_match('/^[A-Za-z0-9+\/]+={0,2}$/', $stripped);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** The image type from the decoded bytes' signature; PNG when it is not a known image. */
|
|
234
|
+
public static function sniffContentType(string $base64): string
|
|
235
|
+
{
|
|
236
|
+
$bytes = (string) base64_decode(substr($base64, 0, 32), true);
|
|
237
|
+
|
|
238
|
+
if (str_starts_with($bytes, "\xFF\xD8\xFF")) {
|
|
239
|
+
return 'image/jpeg';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (str_starts_with($bytes, 'GIF8')) {
|
|
243
|
+
return 'image/gif';
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (str_starts_with($bytes, 'RIFF') && substr($bytes, 8, 4) === 'WEBP') {
|
|
247
|
+
return 'image/webp';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (str_starts_with($bytes, '%PDF')) {
|
|
251
|
+
return 'application/pdf';
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return 'image/png';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public static function extensionFor(string $contentType): string
|
|
258
|
+
{
|
|
259
|
+
return match (strtolower($contentType)) {
|
|
260
|
+
'image/jpeg', 'image/jpg' => 'jpg',
|
|
261
|
+
'image/gif' => 'gif',
|
|
262
|
+
'image/webp' => 'webp',
|
|
263
|
+
'application/pdf' => 'pdf',
|
|
264
|
+
'image/svg+xml' => 'svg',
|
|
265
|
+
default => 'png',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|