@fleetbase/fleetops-engine 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/components/admin/navigator-app.hbs +6 -3
- package/addon/components/layout/fleet-ops-sidebar/fleet-listing.hbs +5 -1
- package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +98 -1
- package/addon/components/layout/fleet-ops-sidebar.hbs +5 -1
- package/addon/components/layout/fleet-ops-sidebar.js +1 -0
- package/addon/controllers/management/drivers/index/edit.js +0 -26
- package/addon/engine.js +4 -4
- package/addon/styles/fleetops-engine.css +17 -0
- package/addon/templates/operations/service-rates/index/new.hbs +1 -1
- package/composer.json +2 -2
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/config/fleetops.php +4 -1
- package/server/src/Casts/MultiPolygon.php +14 -3
- package/server/src/Casts/Point.php +12 -2
- package/server/src/Casts/Polygon.php +19 -4
- package/server/src/Http/Controllers/Api/v1/DriverController.php +34 -18
- package/server/src/Http/Controllers/Api/v1/EntityController.php +36 -1
- package/server/src/Http/Controllers/Api/v1/LabelController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/OrderController.php +139 -59
- package/server/src/Http/Controllers/Api/v1/PayloadController.php +20 -12
- package/server/src/Http/Controllers/Api/v1/PlaceController.php +25 -3
- package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +71 -3
- package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +1 -1
- package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +3 -2
- package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +2 -2
- package/server/src/Http/Controllers/Api/v1/VehicleController.php +22 -2
- package/server/src/Http/Controllers/Api/v1/ZoneController.php +59 -3
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +148 -0
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +38 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +11 -1
- package/server/src/Http/Filter/TrackingStatusFilter.php +10 -0
- package/server/src/Http/Requests/CancelOrderRequest.php +1 -2
- package/server/src/Http/Requests/CreateContactRequest.php +5 -4
- package/server/src/Http/Requests/CreateDriverRequest.php +13 -11
- package/server/src/Http/Requests/CreateEntityRequest.php +7 -4
- package/server/src/Http/Requests/CreateOrderRequest.php +2 -2
- package/server/src/Http/Requests/CreatePayloadRequest.php +1 -1
- package/server/src/Http/Requests/CreatePlaceRequest.php +46 -4
- package/server/src/Http/Requests/CreatePurchaseRateRequest.php +3 -2
- package/server/src/Http/Requests/CreateServiceAreaRequest.php +24 -4
- package/server/src/Http/Requests/CreateServiceRateRequest.php +22 -21
- package/server/src/Http/Requests/CreateTrackingStatusRequest.php +9 -8
- package/server/src/Http/Requests/CreateVehicleRequest.php +6 -4
- package/server/src/Http/Requests/CreateZoneRequest.php +24 -5
- package/server/src/Http/Requests/QueryServiceQuotesRequest.php +11 -10
- package/server/src/Http/Requests/ScheduleOrderRequest.php +32 -0
- package/server/src/Http/Requests/UpdateContactRequest.php +0 -13
- package/server/src/Http/Requests/UpdateServiceAreaRequest.php +1 -23
- package/server/src/Http/Requests/UpdateServiceQuoteRequest.php +1 -23
- package/server/src/Http/Requests/UpdateServiceRateRequest.php +1 -23
- package/server/src/Http/Requests/UpdateTrackingStatusRequest.php +1 -26
- package/server/src/Http/Resources/v1/DeletedResource.php +2 -9
- package/server/src/Http/Resources/v1/Entity.php +47 -44
- package/server/src/Http/Resources/v1/Order.php +1 -1
- package/server/src/Http/Resources/v1/ServiceArea.php +2 -2
- package/server/src/Http/Resources/v1/Vehicle.php +1 -3
- package/server/src/Http/Resources/v1/Zone.php +2 -4
- package/server/src/Models/Entity.php +99 -3
- package/server/src/Models/Order.php +75 -7
- package/server/src/Models/Payload.php +104 -33
- package/server/src/Models/Place.php +56 -17
- package/server/src/Models/ServiceArea.php +285 -18
- package/server/src/Models/ServiceRate.php +10 -6
- package/server/src/Models/TrackingNumber.php +18 -24
- package/server/src/Models/TrackingStatus.php +2 -6
- package/server/src/Models/Vehicle.php +2 -2
- package/server/src/Models/Waypoint.php +0 -10
- package/server/src/Models/Zone.php +132 -5
- package/server/src/Support/Flow.php +17 -3
- package/server/src/Support/Utils.php +143 -9
- package/server/src/routes.php +58 -3
|
@@ -6,6 +6,7 @@ use Fleetbase\FleetOps\Events\OrderDispatchFailed;
|
|
|
6
6
|
use Fleetbase\FleetOps\Events\OrderReady;
|
|
7
7
|
use Fleetbase\FleetOps\Events\OrderStarted;
|
|
8
8
|
use Fleetbase\FleetOps\Http\Requests\CreateOrderRequest;
|
|
9
|
+
use Fleetbase\FleetOps\Http\Requests\ScheduleOrderRequest;
|
|
9
10
|
use Fleetbase\FleetOps\Http\Requests\UpdateOrderRequest;
|
|
10
11
|
use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
11
12
|
use Fleetbase\FleetOps\Http\Resources\v1\Order as OrderResource;
|
|
@@ -23,6 +24,7 @@ use Fleetbase\FleetOps\Support\Utils;
|
|
|
23
24
|
use Fleetbase\Http\Controllers\Controller;
|
|
24
25
|
use Fleetbase\Models\Company;
|
|
25
26
|
use Fleetbase\Models\File;
|
|
27
|
+
use Fleetbase\Support\Auth;
|
|
26
28
|
use Illuminate\Http\Request;
|
|
27
29
|
use Illuminate\Support\Carbon;
|
|
28
30
|
use Illuminate\Support\Facades\Storage;
|
|
@@ -55,7 +57,7 @@ class OrderController extends Controller
|
|
|
55
57
|
try {
|
|
56
58
|
$integratedVendorOrder = $serviceQuote->integratedVendor->api()->createOrderFromServiceQuote($serviceQuote, $request);
|
|
57
59
|
} catch (\Exception $e) {
|
|
58
|
-
return response()->
|
|
60
|
+
return response()->apiError($e->getMessage());
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -69,18 +71,18 @@ class OrderController extends Controller
|
|
|
69
71
|
$dropoff = data_get($payloadInput, 'dropoff');
|
|
70
72
|
$return = data_get($payloadInput, 'return');
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
if ($pickup) {
|
|
75
|
+
$payload->setPickup($pickup, [
|
|
76
|
+
'callback' => function ($pickup, $payload) {
|
|
77
|
+
$payload->setCurrentWaypoint($pickup);
|
|
78
|
+
},
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if ($dropoff) {
|
|
83
|
+
$payload->setDropoff($dropoff);
|
|
76
84
|
}
|
|
77
85
|
|
|
78
|
-
$payload->setPickup($pickup, [
|
|
79
|
-
'callback' => function ($pickup, $payload) {
|
|
80
|
-
$payload->setCurrentWaypoint($pickup);
|
|
81
|
-
},
|
|
82
|
-
]);
|
|
83
|
-
$payload->setDropoff($dropoff);
|
|
84
86
|
if ($return) {
|
|
85
87
|
$payload->setReturn($return);
|
|
86
88
|
}
|
|
@@ -91,6 +93,12 @@ class OrderController extends Controller
|
|
|
91
93
|
$payload->setWaypoints($waypoints);
|
|
92
94
|
$payload->setEntities($entities);
|
|
93
95
|
|
|
96
|
+
// set the first / current waypoint
|
|
97
|
+
$firstWaypoint = $payload->getPickupOrFirstWaypoint();
|
|
98
|
+
if ($firstWaypoint instanceof Place) {
|
|
99
|
+
$payload->setCurrentWaypoint($firstWaypoint);
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
$input['payload_uuid'] = $payload->uuid;
|
|
95
103
|
} elseif ($request->isString('payload')) {
|
|
96
104
|
$input['payload_uuid'] = Utils::getUuid('payloads', [
|
|
@@ -110,18 +118,18 @@ class OrderController extends Controller
|
|
|
110
118
|
$dropoff = data_get($payloadInput, 'dropoff');
|
|
111
119
|
$return = data_get($payloadInput, 'return');
|
|
112
120
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
if ($pickup) {
|
|
122
|
+
$payload->setPickup($pickup, [
|
|
123
|
+
'callback' => function ($pickup, $payload) {
|
|
124
|
+
$payload->setCurrentWaypoint($pickup);
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if ($dropoff) {
|
|
130
|
+
$payload->setDropoff($dropoff);
|
|
117
131
|
}
|
|
118
132
|
|
|
119
|
-
$payload->setPickup($pickup, [
|
|
120
|
-
'callback' => function ($pickup, $payload) {
|
|
121
|
-
$payload->setCurrentWaypoint($pickup);
|
|
122
|
-
},
|
|
123
|
-
]);
|
|
124
|
-
$payload->setDropoff($dropoff);
|
|
125
133
|
if ($return) {
|
|
126
134
|
$payload->setReturn($return);
|
|
127
135
|
}
|
|
@@ -135,7 +143,10 @@ class OrderController extends Controller
|
|
|
135
143
|
$input['payload_uuid'] = $payload->uuid;
|
|
136
144
|
|
|
137
145
|
// set the first / current waypoint
|
|
138
|
-
$payload->
|
|
146
|
+
$firstWaypoint = $payload->getPickupOrFirstWaypoint();
|
|
147
|
+
if ($firstWaypoint instanceof Place) {
|
|
148
|
+
$payload->setCurrentWaypoint($firstWaypoint);
|
|
149
|
+
}
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
// driver assignment
|
|
@@ -186,13 +197,18 @@ class OrderController extends Controller
|
|
|
186
197
|
$input['type'] = 'default';
|
|
187
198
|
}
|
|
188
199
|
|
|
200
|
+
// if no status is set its default to `created`
|
|
201
|
+
if (!isset($input['status'])) {
|
|
202
|
+
$input['status'] = 'created';
|
|
203
|
+
}
|
|
204
|
+
|
|
189
205
|
// if adhoc set convert to sql ready boolean value 1 or 0
|
|
190
206
|
if (isset($input['adhoc']) && $integratedVendorOrder === null) {
|
|
191
207
|
$input['adhoc'] = Utils::isTrue($input['adhoc']) ? 1 : 0;
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
if (!isset($input['payload_uuid'])) {
|
|
195
|
-
return response()->
|
|
211
|
+
return response()->apiError('Attempted to attach invalid payload to order.');
|
|
196
212
|
}
|
|
197
213
|
|
|
198
214
|
// create the order
|
|
@@ -217,7 +233,7 @@ class OrderController extends Controller
|
|
|
217
233
|
|
|
218
234
|
// dispatch if flagged true
|
|
219
235
|
if ($request->boolean('dispatch') && $integratedVendorOrder === null) {
|
|
220
|
-
$order->
|
|
236
|
+
$order->dispatchWithActivity();
|
|
221
237
|
}
|
|
222
238
|
|
|
223
239
|
// load required relations
|
|
@@ -657,14 +673,61 @@ class OrderController extends Controller
|
|
|
657
673
|
}
|
|
658
674
|
|
|
659
675
|
if (!$order->hasDriverAssigned && !$order->adhoc) {
|
|
660
|
-
return response()->
|
|
676
|
+
return response()->apiError('No driver assigned to dispatch!');
|
|
661
677
|
}
|
|
662
678
|
|
|
663
679
|
if ($order->dispatched) {
|
|
664
|
-
return response()->
|
|
680
|
+
return response()->apiError('Order has already been dispatched!');
|
|
665
681
|
}
|
|
666
682
|
|
|
667
683
|
$order->dispatch();
|
|
684
|
+
$order->insertDispatchActivity();
|
|
685
|
+
|
|
686
|
+
return new OrderResource($order);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Schedules an order using date and time.
|
|
691
|
+
*
|
|
692
|
+
* @param \Fleetbase\FleetOps\Http\Requests\ScheduleOrderRequest
|
|
693
|
+
*
|
|
694
|
+
* @return \Fleetbase\Http\Resources\v1\Order
|
|
695
|
+
*/
|
|
696
|
+
public function scheduleOrder(string $id, ScheduleOrderRequest $request)
|
|
697
|
+
{
|
|
698
|
+
$dateInput = $request->input('date');
|
|
699
|
+
$timeInput = $request->input('time');
|
|
700
|
+
|
|
701
|
+
// get the default tz
|
|
702
|
+
$company = Auth::getCompany();
|
|
703
|
+
$defaultTz = data_get($company, 'timezone', config('app.timezone'));
|
|
704
|
+
$timezoneInput = $request->input('timezone', $defaultTz);
|
|
705
|
+
|
|
706
|
+
try {
|
|
707
|
+
$order = Order::findRecordOrFail($id);
|
|
708
|
+
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
709
|
+
return response()->json(
|
|
710
|
+
[
|
|
711
|
+
'error' => 'Order resource not found.',
|
|
712
|
+
],
|
|
713
|
+
404
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Parse date and time
|
|
718
|
+
$date = Carbon::parse($dateInput);
|
|
719
|
+
if ($timeInput) {
|
|
720
|
+
$time = Carbon::parse($timeInput);
|
|
721
|
+
// Combine date and time
|
|
722
|
+
$date->setTime($time->hour, $time->minute, $time->second);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Set the timezone
|
|
726
|
+
$date->shiftTimezone($timezoneInput);
|
|
727
|
+
|
|
728
|
+
// Update order with new date and time
|
|
729
|
+
$order->scheduled_at = $date;
|
|
730
|
+
$order->save();
|
|
668
731
|
|
|
669
732
|
return new OrderResource($order);
|
|
670
733
|
}
|
|
@@ -692,7 +755,7 @@ class OrderController extends Controller
|
|
|
692
755
|
}
|
|
693
756
|
|
|
694
757
|
if ($order->started) {
|
|
695
|
-
return response()->
|
|
758
|
+
return response()->apiError('Order has already started.');
|
|
696
759
|
}
|
|
697
760
|
|
|
698
761
|
// if the order is adhoc and the parameter of `assign` is set with a valid driver id, assign the driver and continue
|
|
@@ -707,11 +770,11 @@ class OrderController extends Controller
|
|
|
707
770
|
$payload = Payload::where('uuid', $order->payload_uuid)->withoutGlobalScopes()->with(['waypoints', 'waypointMarkers', 'entities'])->first();
|
|
708
771
|
|
|
709
772
|
if ($order->adhoc && !$driver) {
|
|
710
|
-
return response()->
|
|
773
|
+
return response()->apiError('You must send driver to accept adhoc order.');
|
|
711
774
|
}
|
|
712
775
|
|
|
713
776
|
if (!$driver) {
|
|
714
|
-
return response()->
|
|
777
|
+
return response()->apiError('No driver assigned to order.');
|
|
715
778
|
}
|
|
716
779
|
|
|
717
780
|
// get the next order activity
|
|
@@ -723,7 +786,7 @@ class OrderController extends Controller
|
|
|
723
786
|
// if order is not dispatched yet $activity['code'] === 'dispatched' || $order->dispatched === true
|
|
724
787
|
// and not skipping throw order not dispatched error
|
|
725
788
|
if ($isNotDispatched && !$skipDispatch) {
|
|
726
|
-
return response()->
|
|
789
|
+
return response()->apiError('Order has not been dispatched yet and cannot be started.');
|
|
727
790
|
}
|
|
728
791
|
|
|
729
792
|
// if we're going to skip the dispatch get the next activity status and flow and continue
|
|
@@ -760,32 +823,50 @@ class OrderController extends Controller
|
|
|
760
823
|
/**
|
|
761
824
|
* Update an order activity.
|
|
762
825
|
*
|
|
763
|
-
* @param \Fleetbase\Models\Order|string $order
|
|
764
|
-
*
|
|
765
826
|
* @return \Fleetbase\Http\Resources\v1\Order
|
|
766
827
|
*/
|
|
767
|
-
public function updateActivity($
|
|
828
|
+
public function updateActivity($id, Request $request)
|
|
768
829
|
{
|
|
769
830
|
$skipDispatch = $request->or(['skip_dispatch', 'skipDispatch'], false);
|
|
770
831
|
$proof = $request->input('proof', null);
|
|
832
|
+
$order = null;
|
|
833
|
+
|
|
834
|
+
// if instance of order is passed directly to this method
|
|
835
|
+
if ($id instanceof Order) {
|
|
836
|
+
/** @var \Fleetbase\FleetOps\Models\Order $order */
|
|
837
|
+
$order = $id;
|
|
838
|
+
}
|
|
771
839
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
840
|
+
// if string $id
|
|
841
|
+
if (!$order) {
|
|
842
|
+
try {
|
|
843
|
+
$order = Order::findRecordOrFail($id, ['driverAssigned', 'payload.entities', 'payload.currentWaypoint', 'payload.waypoints']);
|
|
844
|
+
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
845
|
+
return response()->json(
|
|
846
|
+
[
|
|
847
|
+
'error' => 'Order resource not found.',
|
|
848
|
+
],
|
|
849
|
+
404
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
778
853
|
|
|
854
|
+
// if no order found
|
|
779
855
|
if (!$order) {
|
|
780
|
-
return response()->
|
|
856
|
+
return response()->apiError('No resource not found.');
|
|
781
857
|
}
|
|
782
858
|
|
|
783
|
-
// if
|
|
859
|
+
// if order is still status of `created` trigger started flag
|
|
784
860
|
if ($order->status === 'created') {
|
|
785
861
|
$order->started = true;
|
|
786
862
|
$order->started_at = now();
|
|
787
863
|
}
|
|
788
864
|
|
|
865
|
+
// if order is already completed
|
|
866
|
+
if ($order->status === 'completed') {
|
|
867
|
+
return response()->apiError('Order is already completed.');
|
|
868
|
+
}
|
|
869
|
+
|
|
789
870
|
$activity = $request->input('activity', Flow::getNextActivity($order));
|
|
790
871
|
|
|
791
872
|
// if we're going to skip the dispatch get the next activity status and flow and continue
|
|
@@ -799,7 +880,7 @@ class OrderController extends Controller
|
|
|
799
880
|
if (!$order->hasDriverAssigned && !$order->adhoc) {
|
|
800
881
|
event(new OrderDispatchFailed($order, 'No driver assigned for order to dispatch to.'));
|
|
801
882
|
|
|
802
|
-
return response()->
|
|
883
|
+
return response()->apiError('No driver assigned for order to dispatch to.');
|
|
803
884
|
}
|
|
804
885
|
|
|
805
886
|
$order->dispatch();
|
|
@@ -844,8 +925,7 @@ class OrderController extends Controller
|
|
|
844
925
|
$order->notifyCompleted();
|
|
845
926
|
}
|
|
846
927
|
|
|
847
|
-
$order->
|
|
848
|
-
$order->insertActivity($activity['status'], $activity['details'] ?? '', $location, $activity['code'], $proof);
|
|
928
|
+
$order->updateActivity($activity, $proof);
|
|
849
929
|
|
|
850
930
|
// also update for each order entities if not multiple drop order
|
|
851
931
|
// all entities will share the same activity status as is one drop order
|
|
@@ -925,7 +1005,7 @@ class OrderController extends Controller
|
|
|
925
1005
|
|
|
926
1006
|
// if not completed respond with error
|
|
927
1007
|
if (!$isCompleted) {
|
|
928
|
-
return response()->
|
|
1008
|
+
return response()->apiError('Not all waypoints completed for order.');
|
|
929
1009
|
}
|
|
930
1010
|
|
|
931
1011
|
$activity = [
|
|
@@ -994,11 +1074,10 @@ class OrderController extends Controller
|
|
|
994
1074
|
$place = $order->payload->waypoints->firstWhere('public_id', $placeId);
|
|
995
1075
|
|
|
996
1076
|
if (!$place) {
|
|
997
|
-
return response()->
|
|
1077
|
+
return response()->apiError('Place resource is not a valid destination.');
|
|
998
1078
|
}
|
|
999
1079
|
|
|
1000
|
-
$order->payload->
|
|
1001
|
-
$order->payload->refresh();
|
|
1080
|
+
$order->payload->setCurrentWaypoint($place);
|
|
1002
1081
|
|
|
1003
1082
|
return new OrderResource($order);
|
|
1004
1083
|
}
|
|
@@ -1050,7 +1129,7 @@ class OrderController extends Controller
|
|
|
1050
1129
|
}
|
|
1051
1130
|
|
|
1052
1131
|
if (!$code) {
|
|
1053
|
-
return response()->
|
|
1132
|
+
return response()->apiError('No QR code data to capture.');
|
|
1054
1133
|
}
|
|
1055
1134
|
|
|
1056
1135
|
$subject = $type === null ? $order : null;
|
|
@@ -1075,7 +1154,7 @@ class OrderController extends Controller
|
|
|
1075
1154
|
}
|
|
1076
1155
|
|
|
1077
1156
|
if (!$subject) {
|
|
1078
|
-
return response()->
|
|
1157
|
+
return response()->apiError('Unable to capture QR code data.');
|
|
1079
1158
|
}
|
|
1080
1159
|
|
|
1081
1160
|
// validate
|
|
@@ -1094,7 +1173,7 @@ class OrderController extends Controller
|
|
|
1094
1173
|
return new ProofResource($proof);
|
|
1095
1174
|
}
|
|
1096
1175
|
|
|
1097
|
-
return response()->
|
|
1176
|
+
return response()->apiError('Unable to validate QR code data.');
|
|
1098
1177
|
}
|
|
1099
1178
|
|
|
1100
1179
|
/**
|
|
@@ -1104,11 +1183,12 @@ class OrderController extends Controller
|
|
|
1104
1183
|
*/
|
|
1105
1184
|
public function captureSignature(string $id, string $subjectId = null, Request $request)
|
|
1106
1185
|
{
|
|
1107
|
-
$disk
|
|
1108
|
-
$bucket
|
|
1109
|
-
$signature
|
|
1110
|
-
$data
|
|
1111
|
-
$
|
|
1186
|
+
$disk = $request->input('disk', config('filesystems.default'));
|
|
1187
|
+
$bucket = $request->input('bucket', config('filesystems.disks.' . $disk . '.bucket', config('filesystems.disks.s3.bucket')));
|
|
1188
|
+
$signature = $request->input('signature');
|
|
1189
|
+
$data = $request->input('data', []);
|
|
1190
|
+
$remarks = $request->input('remarks', 'Verified by Signature');
|
|
1191
|
+
$type = $subjectId ? strtok($subjectId, '_') : null;
|
|
1112
1192
|
|
|
1113
1193
|
try {
|
|
1114
1194
|
$order = Order::findRecordOrFail($id);
|
|
@@ -1122,7 +1202,7 @@ class OrderController extends Controller
|
|
|
1122
1202
|
}
|
|
1123
1203
|
|
|
1124
1204
|
if (!$signature) {
|
|
1125
|
-
return response()->
|
|
1205
|
+
return response()->apiError('No signature data to capture.');
|
|
1126
1206
|
}
|
|
1127
1207
|
|
|
1128
1208
|
$subject = $type === null ? $order : null;
|
|
@@ -1147,7 +1227,7 @@ class OrderController extends Controller
|
|
|
1147
1227
|
}
|
|
1148
1228
|
|
|
1149
1229
|
if (!$subject) {
|
|
1150
|
-
return response()->
|
|
1230
|
+
return response()->apiError('Unable to capture signature data.');
|
|
1151
1231
|
}
|
|
1152
1232
|
|
|
1153
1233
|
// create proof instance
|
|
@@ -1156,7 +1236,7 @@ class OrderController extends Controller
|
|
|
1156
1236
|
'order_uuid' => $order->uuid,
|
|
1157
1237
|
'subject_uuid' => $subject->uuid,
|
|
1158
1238
|
'subject_type' => Utils::getModelClassName($subject),
|
|
1159
|
-
'remarks' =>
|
|
1239
|
+
'remarks' => $remarks,
|
|
1160
1240
|
'raw_data' => $signature,
|
|
1161
1241
|
'data' => $data,
|
|
1162
1242
|
]);
|
|
@@ -7,6 +7,7 @@ use Fleetbase\FleetOps\Http\Requests\UpdatePayloadRequest;
|
|
|
7
7
|
use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
8
8
|
use Fleetbase\FleetOps\Http\Resources\v1\Payload as PayloadResource;
|
|
9
9
|
use Fleetbase\FleetOps\Models\Payload;
|
|
10
|
+
use Fleetbase\FleetOps\Models\Place;
|
|
10
11
|
use Fleetbase\Http\Controllers\Controller;
|
|
11
12
|
use Illuminate\Http\Request;
|
|
12
13
|
use Illuminate\Support\Arr;
|
|
@@ -37,30 +38,34 @@ class PayloadController extends Controller
|
|
|
37
38
|
// create the payload
|
|
38
39
|
$payload = new Payload(Arr::only($input, ['type', 'provider', 'meta', 'cod_amount', 'cod_currency', 'cod_payment_method']));
|
|
39
40
|
|
|
40
|
-
// if no pickup and dropoff extract from waypoints
|
|
41
|
-
if (empty($pickup) && empty($dropoff) && count($waypoints)) {
|
|
42
|
-
$pickup = array_shift($waypoints);
|
|
43
|
-
$dropoff = array_pop($waypoints);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
41
|
// set pickup point
|
|
47
|
-
|
|
42
|
+
if ($pickup) {
|
|
43
|
+
$payload->setPickup($pickup);
|
|
44
|
+
}
|
|
48
45
|
|
|
49
46
|
// set dropoff point
|
|
50
|
-
|
|
47
|
+
if ($dropoff) {
|
|
48
|
+
$payload->setDropoff($dropoff);
|
|
49
|
+
}
|
|
51
50
|
|
|
52
51
|
// set return point
|
|
53
|
-
|
|
52
|
+
if ($return) {
|
|
53
|
+
$payload->setReturn($return);
|
|
54
|
+
}
|
|
54
55
|
|
|
55
56
|
// save payload
|
|
56
57
|
$payload->save();
|
|
57
58
|
|
|
58
|
-
// set waypoints
|
|
59
|
+
// set waypoints and entities after payload is saved
|
|
59
60
|
$payload->setWaypoints($waypoints);
|
|
60
|
-
|
|
61
|
-
// set entities
|
|
62
61
|
$payload->setEntities($entities);
|
|
63
62
|
|
|
63
|
+
// set the first / current waypoint
|
|
64
|
+
$firstWaypoint = $payload->getPickupOrFirstWaypoint();
|
|
65
|
+
if ($firstWaypoint instanceof Place) {
|
|
66
|
+
$payload->setCurrentWaypoint($firstWaypoint);
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
// response the driver resource
|
|
65
70
|
return new PayloadResource($payload);
|
|
66
71
|
}
|
|
@@ -126,6 +131,9 @@ class PayloadController extends Controller
|
|
|
126
131
|
// save the payload
|
|
127
132
|
$payload->save();
|
|
128
133
|
|
|
134
|
+
// make sure entities and waypoints is loaded
|
|
135
|
+
$payload->load(['entities', 'waypoints', 'pickup', 'dropoff', 'return']);
|
|
136
|
+
|
|
129
137
|
// response the payload resource
|
|
130
138
|
return new PayloadResource($payload);
|
|
131
139
|
}
|
|
@@ -66,6 +66,28 @@ class PlaceController extends Controller
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// if we have only latitude/longitude or location BUT no street1 do a reverse lookup
|
|
70
|
+
$requestHasCoordinates = $request->filled(['latitude', 'longitude']);
|
|
71
|
+
$requestHasLocation = $request->filled(['location']);
|
|
72
|
+
$requestMissingStreet = $request->missing('street1');
|
|
73
|
+
if ($requestMissingStreet && ($requestHasCoordinates || $requestHasLocation)) {
|
|
74
|
+
if ($requestHasLocation) {
|
|
75
|
+
$point = Utils::getPointFromMixed($request->input('location'));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if ($requestHasCoordinates) {
|
|
79
|
+
$point = Utils::getPointFromMixed($request->only(['latitude', 'longitude']));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if ($point instanceof Point) {
|
|
83
|
+
$place = Place::createFromReverseGeocodingLookup($point);
|
|
84
|
+
|
|
85
|
+
if ($place instanceof Place) {
|
|
86
|
+
$input = $place->toArray();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
// latitude / longitude
|
|
70
92
|
if ($request->has(['latitude', 'longitude'])) {
|
|
71
93
|
$input['location'] = Utils::getPointFromCoordinates($request->only(['latitude', 'longitude']));
|
|
@@ -141,7 +163,7 @@ class PlaceController extends Controller
|
|
|
141
163
|
try {
|
|
142
164
|
$place = Place::findRecordOrFail($id);
|
|
143
165
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
144
|
-
return response()->
|
|
166
|
+
return response()->apiError('Place resource not found.');
|
|
145
167
|
}
|
|
146
168
|
|
|
147
169
|
// get request input
|
|
@@ -307,7 +329,7 @@ class PlaceController extends Controller
|
|
|
307
329
|
try {
|
|
308
330
|
$place = Place::findRecordOrFail($id);
|
|
309
331
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
310
|
-
return response()->
|
|
332
|
+
return response()->apiError('Place resource not found.');
|
|
311
333
|
}
|
|
312
334
|
|
|
313
335
|
return new PlaceResource($place);
|
|
@@ -323,7 +345,7 @@ class PlaceController extends Controller
|
|
|
323
345
|
try {
|
|
324
346
|
$place = Place::findRecordOrFail($id);
|
|
325
347
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
|
|
326
|
-
return response()->
|
|
348
|
+
return response()->apiError('Place resource not found.');
|
|
327
349
|
}
|
|
328
350
|
|
|
329
351
|
$place->delete();
|
|
@@ -97,7 +97,7 @@ class PurchaseRateController extends Controller
|
|
|
97
97
|
try {
|
|
98
98
|
$integratedVendorOrder = $serviceQuote->integratedVendor->api()->createOrderFromServiceQuote($serviceQuote, $request);
|
|
99
99
|
} catch (\Exception $e) {
|
|
100
|
-
return response()->
|
|
100
|
+
return response()->apiError($e->getMessage());
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -7,7 +7,9 @@ use Fleetbase\FleetOps\Http\Requests\UpdateServiceAreaRequest;
|
|
|
7
7
|
use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
|
|
8
8
|
use Fleetbase\FleetOps\Http\Resources\v1\ServiceArea as ServiceAreaResource;
|
|
9
9
|
use Fleetbase\FleetOps\Models\ServiceArea;
|
|
10
|
+
use Fleetbase\FleetOps\Support\Utils;
|
|
10
11
|
use Fleetbase\Http\Controllers\Controller;
|
|
12
|
+
use Grimzy\LaravelMysqlSpatial\Types\Point;
|
|
11
13
|
use Illuminate\Http\Request;
|
|
12
14
|
|
|
13
15
|
class ServiceAreaController extends Controller
|
|
@@ -24,13 +26,48 @@ class ServiceAreaController extends Controller
|
|
|
24
26
|
// get request input
|
|
25
27
|
$input = $request->only(['name', 'type', 'status']);
|
|
26
28
|
|
|
29
|
+
// get radius for creating service area border - default to 500 meters
|
|
30
|
+
$radius = (int) $request->input('radius', 500);
|
|
31
|
+
|
|
27
32
|
// make sure company is set
|
|
28
33
|
$input['company_uuid'] = session('company');
|
|
29
34
|
|
|
30
|
-
//
|
|
35
|
+
// if parent service area set
|
|
36
|
+
if ($request->filled('parent')) {
|
|
37
|
+
$input['parent_uuid'] = Utils::getUuid('service_areas', [
|
|
38
|
+
'public_id' => $request->input('parent'),
|
|
39
|
+
'company_uuid' => session('company'),
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// if latitude and longitude is provided
|
|
44
|
+
if ($request->has(['latitude', 'longitude'])) {
|
|
45
|
+
// create a polygon given the radius
|
|
46
|
+
$latitude = $request->input('latitude');
|
|
47
|
+
$longitude = $request->input('longitude');
|
|
48
|
+
$point = new Point($latitude, $longitude);
|
|
49
|
+
|
|
50
|
+
if ($point instanceof Point) {
|
|
51
|
+
$input['border'] = ServiceArea::createMultiPolygonFromPoint($point, $radius);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// if a location is provided
|
|
56
|
+
if ($request->has('location')) {
|
|
57
|
+
$location = $request->input('location');
|
|
58
|
+
$point = Utils::getPointFromMixed($location);
|
|
59
|
+
|
|
60
|
+
if ($point instanceof Point) {
|
|
61
|
+
$input['border'] = ServiceArea::createMultiPolygonFromPoint($point, $radius);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
31
64
|
|
|
32
65
|
// create the serviceArea
|
|
33
|
-
|
|
66
|
+
try {
|
|
67
|
+
$serviceArea = ServiceArea::create($input);
|
|
68
|
+
} catch (\Throwable $e) {
|
|
69
|
+
dd($e->getMessage());
|
|
70
|
+
}
|
|
34
71
|
|
|
35
72
|
// response the driver resource
|
|
36
73
|
return new ServiceAreaResource($serviceArea);
|
|
@@ -61,7 +98,38 @@ class ServiceAreaController extends Controller
|
|
|
61
98
|
// get request input
|
|
62
99
|
$input = $request->only(['name', 'type', 'status']);
|
|
63
100
|
|
|
64
|
-
//
|
|
101
|
+
// get radius for creating service area border - default to 500 meters
|
|
102
|
+
$radius = $request->input('radius', 500);
|
|
103
|
+
|
|
104
|
+
// if parent service area set
|
|
105
|
+
if ($request->filled('parent')) {
|
|
106
|
+
$input['parent_uuid'] = Utils::getUuid('service_areas', [
|
|
107
|
+
'public_id' => $request->input('parent'),
|
|
108
|
+
'company_uuid' => session('company'),
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// if latitude and longitude is provided
|
|
113
|
+
if ($request->has(['latitude', 'longitude'])) {
|
|
114
|
+
// create a polygon given the radius
|
|
115
|
+
$latitude = $request->input('latitude');
|
|
116
|
+
$longitude = $request->input('longitude');
|
|
117
|
+
$point = new Point($latitude, $longitude);
|
|
118
|
+
|
|
119
|
+
if ($point instanceof Point) {
|
|
120
|
+
$input['border'] = ServiceArea::createMultiPolygonFromPoint($point, $radius);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// if a location is provided
|
|
125
|
+
if ($request->has('location')) {
|
|
126
|
+
$location = $request->input('location');
|
|
127
|
+
$point = Utils::getPointFromMixed($location);
|
|
128
|
+
|
|
129
|
+
if ($point instanceof Point) {
|
|
130
|
+
$input['border'] = ServiceArea::createMultiPolygonFromPoint($point, $radius);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
65
133
|
|
|
66
134
|
// update the serviceArea
|
|
67
135
|
$serviceArea->update($input);
|
|
@@ -72,7 +72,7 @@ class ServiceQuoteController extends Controller
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// get all waypoints
|
|
75
|
-
$waypoints = $payload->getAllStops()
|
|
75
|
+
$waypoints = $payload->getAllStops();
|
|
76
76
|
|
|
77
77
|
// if quote for single service
|
|
78
78
|
if ($service && $service !== 'all') {
|
|
@@ -30,7 +30,8 @@ class ServiceRateController extends Controller
|
|
|
30
30
|
'rate_calculation_method',
|
|
31
31
|
'currency',
|
|
32
32
|
'base_fee',
|
|
33
|
-
'
|
|
33
|
+
'per_meter_unit',
|
|
34
|
+
'per_meter_flat_rate_fee',
|
|
34
35
|
'meter_fees',
|
|
35
36
|
'meter_fees.*.distance',
|
|
36
37
|
'meter_fees.*.fee',
|
|
@@ -77,7 +78,7 @@ class ServiceRateController extends Controller
|
|
|
77
78
|
ServiceRateFee::create([
|
|
78
79
|
'service_rate_uuid' => $serviceRate->uuid,
|
|
79
80
|
'distance' => Utils::get($meterFee, 'distance'),
|
|
80
|
-
'distance_unit' => 'm',
|
|
81
|
+
'distance_unit' => $request->input('per_meter_unit', 'm'),
|
|
81
82
|
'fee' => Utils::get($meterFee, 'fee'),
|
|
82
83
|
'currency' => $serviceRate->currency,
|
|
83
84
|
]);
|
|
@@ -39,8 +39,8 @@ class TrackingNumberController extends Controller
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
if (is_array($owner)) {
|
|
42
|
-
$input['owner_uuid']
|
|
43
|
-
$input['
|
|
42
|
+
$input['owner_uuid'] = Utils::get($owner, 'uuid');
|
|
43
|
+
$input['owner_type'] = Utils::getModelClassName(Utils::get($owner, 'table'));
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|