@fleetbase/fleetops-engine 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +4 -4
  2. package/addon/components/admin/navigator-app.hbs +5 -0
  3. package/addon/components/admin/navigator-app.js +27 -0
  4. package/addon/components/driver-form-panel.js +13 -19
  5. package/addon/components/leaflet-draw-control.js +2 -3
  6. package/addon/components/live-map.js +7 -4
  7. package/addon/components/modals/driver-assign-order.hbs +2 -2
  8. package/addon/components/modals/order-import.hbs +5 -5
  9. package/addon/components/modals/order-new-activity.hbs +1 -1
  10. package/addon/components/order-config/entities-editor.js +3 -5
  11. package/addon/components/route-list.hbs +2 -2
  12. package/addon/components/vendor-form-panel.js +1 -1
  13. package/addon/controllers/application.js +2 -2
  14. package/addon/controllers/base-controller.js +31 -0
  15. package/addon/controllers/management/contacts/index/details.js +2 -2
  16. package/addon/controllers/management/contacts/index/edit.js +2 -2
  17. package/addon/controllers/management/contacts/index/new.js +2 -2
  18. package/addon/controllers/management/contacts/index.js +2 -2
  19. package/addon/controllers/management/drivers/index/details.js +2 -2
  20. package/addon/controllers/management/drivers/index/edit.js +28 -2
  21. package/addon/controllers/management/drivers/index/new.js +2 -2
  22. package/addon/controllers/management/drivers/index.js +11 -24
  23. package/addon/controllers/management/fleets/index/details.js +2 -2
  24. package/addon/controllers/management/fleets/index/edit.js +2 -2
  25. package/addon/controllers/management/fleets/index/new.js +2 -2
  26. package/addon/controllers/management/fleets/index.js +9 -9
  27. package/addon/controllers/management/fuel-reports/index/details.js +2 -2
  28. package/addon/controllers/management/fuel-reports/index/edit.js +2 -2
  29. package/addon/controllers/management/fuel-reports/index/new.js +2 -2
  30. package/addon/controllers/management/fuel-reports/index.js +2 -2
  31. package/addon/controllers/management/issues/index/details.js +2 -2
  32. package/addon/controllers/management/issues/index/edit.js +2 -2
  33. package/addon/controllers/management/issues/index/new.js +2 -2
  34. package/addon/controllers/management/issues/index.js +2 -9
  35. package/addon/controllers/management/places/index/details.js +2 -2
  36. package/addon/controllers/management/places/index/edit.js +2 -2
  37. package/addon/controllers/management/places/index/new.js +2 -2
  38. package/addon/controllers/management/places/index.js +2 -2
  39. package/addon/controllers/management/vehicles/index/details.js +2 -2
  40. package/addon/controllers/management/vehicles/index/edit.js +2 -2
  41. package/addon/controllers/management/vehicles/index/new.js +2 -2
  42. package/addon/controllers/management/vehicles/index.js +11 -12
  43. package/addon/controllers/management/vendors/index/details.js +2 -2
  44. package/addon/controllers/management/vendors/index/edit.js +2 -2
  45. package/addon/controllers/management/vendors/index/new.js +2 -2
  46. package/addon/controllers/management/vendors/index.js +2 -8
  47. package/addon/controllers/management.js +2 -2
  48. package/addon/controllers/operations/orders/index/config/types.js +2 -2
  49. package/addon/controllers/operations/orders/index/config.js +2 -2
  50. package/addon/controllers/operations/orders/index/new.js +64 -44
  51. package/addon/controllers/operations/orders/index/view.js +11 -4
  52. package/addon/controllers/operations/orders/index.js +2 -2
  53. package/addon/controllers/operations/scheduler/index.js +2 -2
  54. package/addon/controllers/operations/service-rates/index/edit.js +12 -18
  55. package/addon/controllers/operations/service-rates/index/new.js +16 -22
  56. package/addon/controllers/operations/service-rates/index.js +2 -2
  57. package/addon/engine.js +6 -0
  58. package/addon/helpers/waypoint-label.js +6 -1
  59. package/addon/routes/application.js +4 -15
  60. package/addon/routes/management/contacts/index.js +9 -5
  61. package/addon/routes/management/drivers/index.js +7 -3
  62. package/addon/routes/management/fleets/index.js +9 -5
  63. package/addon/routes/management/fuel-reports/index.js +9 -5
  64. package/addon/routes/management/issues/index.js +9 -5
  65. package/addon/routes/management/places/index.js +9 -5
  66. package/addon/routes/management/vehicles/index/details.js +2 -2
  67. package/addon/routes/management/vehicles/index.js +9 -0
  68. package/addon/routes/management/vendors/index.js +9 -6
  69. package/addon/routes/operations/orders/index/view.js +6 -2
  70. package/addon/routes/operations/orders/index.js +7 -1
  71. package/addon/routes/operations/orders.js +0 -1
  72. package/addon/routes/operations/service-rates/index.js +9 -27
  73. package/addon/routes/operations/service-rates.js +1 -8
  74. package/addon/styles/fleetops-engine.css +14 -7
  75. package/addon/templates/operations/orders/index/new.hbs +7 -7
  76. package/addon/templates/operations/orders/index/view.hbs +17 -16
  77. package/addon/utils/waypoint-label.js +3 -0
  78. package/app/controllers/{operations/zones/index.js → base-controller.js} +1 -1
  79. package/app/utils/waypoint-label.js +1 -0
  80. package/composer.json +1 -1
  81. package/config/environment.js +11 -1
  82. package/extension.json +1 -1
  83. package/index.js +1 -0
  84. package/package.json +47 -41
  85. package/server/migrations/2023_11_28_074244_add_supplier_uuid_column_to_entities_table.php +33 -0
  86. package/server/migrations/2023_12_14_100209_add_meta_column_on_driver_table.php +30 -0
  87. package/server/src/Http/Controllers/Api/v1/DriverController.php +7 -4
  88. package/server/src/Http/Controllers/Api/v1/OrderController.php +118 -42
  89. package/server/src/Http/Controllers/Api/v1/PayloadController.php +41 -43
  90. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +43 -2
  91. package/server/src/Http/Controllers/Internal/v1/MorphController.php +48 -16
  92. package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +41 -0
  93. package/server/src/Http/Controllers/Internal/v1/OrderController.php +3 -2
  94. package/server/src/Http/Controllers/Internal/v1/PlaceController.php +2 -2
  95. package/server/src/Http/Requests/CreateDriverRequest.php +2 -0
  96. package/server/src/Http/Requests/CreateOrderRequest.php +18 -4
  97. package/server/src/Http/Requests/CreatePayloadRequest.php +23 -7
  98. package/server/src/Http/Requests/CreatePlaceRequest.php +9 -5
  99. package/server/src/Http/Requests/CreateTrackingStatusRequest.php +69 -12
  100. package/server/src/Http/Requests/CreateVehicleRequest.php +5 -3
  101. package/server/src/Http/Resources/v1/Entity.php +3 -0
  102. package/server/src/Http/Resources/v1/Order.php +3 -2
  103. package/server/src/Models/Driver.php +5 -2
  104. package/server/src/Models/Entity.php +1 -1
  105. package/server/src/Models/Order.php +2 -2
  106. package/server/src/Models/Payload.php +27 -9
  107. package/server/src/Models/Place.php +28 -5
  108. package/server/src/Models/TrackingStatus.php +9 -3
  109. package/server/src/Models/VehicleDevice.php +28 -0
  110. package/server/src/Models/Vendor.php +16 -0
  111. package/server/src/Observers/DriverObserver.php +1 -1
  112. package/server/src/routes.php +8 -0
  113. package/tsconfig.declarations.json +10 -0
  114. package/addon/components/file-icon.js +0 -1
  115. package/addon/controllers/operations/zones/index.js +0 -475
  116. package/addon/routes/operations/dispatch.js +0 -3
  117. package/addon/routes/operations/zones/index.js +0 -25
  118. package/addon/routes/operations/zones.js +0 -7
  119. package/addon/templates/operations/dispatch.hbs +0 -1
  120. package/addon/templates/operations/zones/index.hbs +0 -72
  121. package/addon/templates/operations/zones.hbs +0 -1
  122. package/app/components/file-icon.js +0 -1
@@ -7,10 +7,9 @@ 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;
11
- use Fleetbase\FleetOps\Models\Waypoint;
12
10
  use Fleetbase\Http\Controllers\Controller;
13
11
  use Illuminate\Http\Request;
12
+ use Illuminate\Support\Arr;
14
13
 
15
14
  // use Fleetbase\FleetOps\Support\Utils;
16
15
 
@@ -25,41 +24,42 @@ class PayloadController extends Controller
25
24
  */
26
25
  public function create(CreatePayloadRequest $request)
27
26
  {
28
- // get request input
29
- $input = $request->only(['pickup', 'dropoff', 'type', 'return', 'waypoints', 'customer', 'meta', 'cod_amount', 'cod_currency', 'cod_payment_method']);
27
+ $input = $request->all();
28
+ $entities = data_get($input, 'entities', []);
29
+ $waypoints = data_get($input, 'waypoints', []);
30
+ $pickup = data_get($input, 'pickup');
31
+ $dropoff = data_get($input, 'dropoff');
32
+ $return = data_get($input, 'return');
30
33
 
31
34
  // make sure company is set
32
35
  $input['company_uuid'] = session('company');
33
36
 
34
37
  // create the payload
35
- $payload = new Payload($input);
38
+ $payload = new Payload(Arr::only($input, ['type', 'provider', 'meta', 'cod_amount', 'cod_currency', 'cod_payment_method']));
39
+
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
+ }
36
45
 
37
46
  // set pickup point
38
- $payload->setPickup($request->input('pickup'));
47
+ $payload->setPickup($pickup);
39
48
 
40
49
  // set dropoff point
41
- $payload->setDropoff($request->input('dropoff'));
50
+ $payload->setDropoff($dropoff);
42
51
 
43
52
  // set return point
44
- $payload->setReturn($request->input('return'));
53
+ $payload->setReturn($return);
45
54
 
46
55
  // save payload
47
56
  $payload->save();
48
57
 
49
58
  // set waypoints
50
- if ($request->has('waypoints') && is_array($request->input('waypoints'))) {
51
- foreach ($request->input('waypoints') as $index => $place) {
52
- // get place
53
- $id = Place::createFromMixed($place);
54
-
55
- // create waypoint
56
- Waypoint::create([
57
- 'place_uuid' => $id,
58
- 'payload_uuid' => $payload->uuid,
59
- 'order' => $index,
60
- ]);
61
- }
62
- }
59
+ $payload->setWaypoints($waypoints);
60
+
61
+ // set entities
62
+ $payload->setEntities($entities);
63
63
 
64
64
  // response the driver resource
65
65
  return new PayloadResource($payload);
@@ -88,42 +88,40 @@ class PayloadController extends Controller
88
88
  }
89
89
 
90
90
  // get request input
91
- $input = $request->only(['pickup', 'dropoff', 'type', 'return', 'waypoints', 'customer', 'meta', 'cod_amount', 'cod_currency', 'cod_payment_method']);
91
+ $input = $request->all();
92
+ $entities = data_get($input, 'entities', []);
93
+ $waypoints = data_get($input, 'waypoints', []);
94
+ $pickup = data_get($input, 'pickup');
95
+ $dropoff = data_get($input, 'dropoff');
96
+ $return = data_get($input, 'return');
92
97
 
93
98
  // pickup assignment
94
- if ($request->has('pickup')) {
95
- $payload->setPickup($request->input('pickup'));
99
+ if ($pickup) {
100
+ $payload->setPickup($pickup);
96
101
  }
97
102
 
98
103
  // dropoff assignment
99
- if ($request->has('dropoff')) {
100
- $payload->setDropoff($request->input('dropoff'));
104
+ if ($dropoff) {
105
+ $payload->setDropoff($dropoff);
101
106
  }
102
107
 
103
108
  // return assignment
104
- if ($request->has('return')) {
105
- $payload->setReturn($request->input('return'));
109
+ if ($return) {
110
+ $payload->setReturn($return);
106
111
  }
107
112
 
108
113
  // set waypoints
109
- if ($request->has('waypoints') && is_array($request->input('waypoints'))) {
110
- $waypointCount = $payload->waypoints->count() ?? 0;
111
-
112
- foreach ($request->input('waypoints') as $index => $place) {
113
- // get place
114
- $id = Place::createFromMixed($place);
115
-
116
- // create waypoint
117
- Waypoint::create([
118
- 'place_uuid' => $id,
119
- 'payload_uuid' => $payload->uuid,
120
- 'order' => $index + $waypointCount,
121
- ]);
122
- }
114
+ if ($waypoints) {
115
+ $payload->setWaypoints($waypoints);
116
+ }
117
+
118
+ // set entities
119
+ if ($entities) {
120
+ $payload->setEntities($entities);
123
121
  }
124
122
 
125
123
  // update the payload
126
- $payload->fill($input);
124
+ $payload->fill(array_filter(Arr::only($input, ['type', 'provider', 'meta', 'cod_amount', 'cod_currency', 'cod_payment_method'])));
127
125
 
128
126
  // save the payload
129
127
  $payload->save();
@@ -6,9 +6,11 @@ use Fleetbase\FleetOps\Http\Requests\CreateTrackingStatusRequest;
6
6
  use Fleetbase\FleetOps\Http\Requests\UpdateTrackingStatusRequest;
7
7
  use Fleetbase\FleetOps\Http\Resources\v1\DeletedResource;
8
8
  use Fleetbase\FleetOps\Http\Resources\v1\TrackingStatus as TrackingStatusResource;
9
+ use Fleetbase\FleetOps\Models\Order;
9
10
  use Fleetbase\FleetOps\Models\TrackingStatus;
10
11
  use Fleetbase\FleetOps\Support\Utils;
11
12
  use Fleetbase\Http\Controllers\Controller;
13
+ use Grimzy\LaravelMysqlSpatial\Types\Point;
12
14
  use Illuminate\Http\Request;
13
15
 
14
16
  class TrackingStatusController extends Controller
@@ -23,7 +25,24 @@ class TrackingStatusController extends Controller
23
25
  public function create(CreateTrackingStatusRequest $request)
24
26
  {
25
27
  // get request input
26
- $input = $request->only(['status', 'details', 'code', 'city', 'province', 'postal_code', 'country', 'latitude', 'longitude']);
28
+ $input = $request->only(['status', 'details', 'code', 'city', 'province', 'postal_code', 'country', 'location', 'latitude', 'longitude']);
29
+
30
+ // if no location provided but latitude/longitude
31
+ if (empty($input['location']) && isset($input['latitude']) && isset($input['longitude'])) {
32
+ $latitude = data_get($input, 'latitude');
33
+ $longitude = data_get($input, 'longitude');
34
+
35
+ // unset latitude and longitude
36
+ unset($input['latitude'], $input['longitude']);
37
+
38
+ // create location
39
+ $input['location'] = new Point($latitude, $longitude);
40
+ }
41
+
42
+ // if no code set create a code from the status
43
+ if (empty($input['code'])) {
44
+ $input['code'] = TrackingStatus::prepareCode($input['status']);
45
+ }
27
46
 
28
47
  // make sure company is set
29
48
  $input['company_uuid'] = session('company');
@@ -36,6 +55,11 @@ class TrackingStatusController extends Controller
36
55
  ]);
37
56
  }
38
57
 
58
+ // tracking number assignment
59
+ if ($request->has('order')) {
60
+ $input['tracking_number_uuid'] = Order::where('public_id', $request->input('order'))->value('tracking_number_uuid');
61
+ }
62
+
39
63
  // create the trackingStatus
40
64
  $trackingStatus = TrackingStatus::create($input);
41
65
 
@@ -66,7 +90,24 @@ class TrackingStatusController extends Controller
66
90
  }
67
91
 
68
92
  // get request input
69
- $input = $request->only(['status', 'details', 'code', 'city', 'province', 'postal_code', 'country', 'latitude', 'longitude']);
93
+ $input = $request->only(['status', 'details', 'code', 'city', 'province', 'postal_code', 'country', 'location', 'latitude', 'longitude']);
94
+
95
+ // if no location provided but latitude/longitude
96
+ if (empty($input['location']) && isset($input['latitude']) && isset($input['longitude'])) {
97
+ $latitude = data_get($input, 'latitude');
98
+ $longitude = data_get($input, 'longitude');
99
+
100
+ // unset latitude and longitude
101
+ unset($input['latitude'], $input['longitude']);
102
+
103
+ // create location
104
+ $input['location'] = new Point($latitude, $longitude);
105
+ }
106
+
107
+ // if no code set create a code from the status
108
+ if (empty($input['code'])) {
109
+ $input['code'] = TrackingStatus::prepareCode($input['status']);
110
+ }
70
111
 
71
112
  // update the trackingStatus
72
113
  $trackingStatus->update($input);
@@ -2,12 +2,16 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Http\Filter\ContactFilter;
6
+ use Fleetbase\FleetOps\Http\Filter\VendorFilter;
5
7
  use Fleetbase\FleetOps\Models\Contact;
6
8
  use Fleetbase\FleetOps\Models\IntegratedVendor;
7
9
  use Fleetbase\FleetOps\Models\Vendor;
8
10
  use Fleetbase\FleetOps\Support\Utils;
9
11
  use Fleetbase\Http\Controllers\Controller;
10
12
  use Illuminate\Http\Request;
13
+ use Illuminate\Pagination\LengthAwarePaginator;
14
+ use Illuminate\Support\Facades\URL;
11
15
  use Illuminate\Support\Str;
12
16
 
13
17
  class MorphController extends Controller
@@ -21,18 +25,26 @@ class MorphController extends Controller
21
25
  {
22
26
  $query = $request->input('query');
23
27
  $limit = $request->input('limit', 12);
28
+ $page = $request->input('page', 1);
24
29
  $type = Str::lower($request->segment(4));
25
30
  $resourceType = Str::lower(Utils::singularize($type));
26
31
 
27
- $contacts = Contact::searchWhere('name', $query)
32
+ $contactsQuery = Contact::searchWhere('name', $query)
28
33
  ->where('company_uuid', session('company'))
29
- ->limit($limit)
30
- ->get();
34
+ ->filter(new ContactFilter($request));
31
35
 
32
- $vendors = Vendor::searchWhere('name', $query)
36
+ $vendorsQuery = Vendor::searchWhere('name', $query)
33
37
  ->where('company_uuid', session('company'))
34
- ->limit($limit)
35
- ->get();
38
+ ->filter(new VendorFilter($request));
39
+
40
+ // Get total count for pagination
41
+ $totalContacts = $contactsQuery->count();
42
+ $totalVendors = $vendorsQuery->count();
43
+ $total = $totalContacts + $totalVendors;
44
+
45
+ // Get paginated items
46
+ $contacts = $contactsQuery->limit($limit)->get();
47
+ $vendors = $vendorsQuery->limit($limit)->get();
36
48
 
37
49
  $results = collect([...$contacts, ...$vendors])
38
50
  ->sortBy('name')
@@ -59,19 +71,39 @@ class MorphController extends Controller
59
71
  }
60
72
  }
61
73
 
62
- // convert to array
63
- $results = $results->toArray();
64
-
65
74
  // set resource type
66
- $results = array_map(
67
- function ($attributes) use ($resourceType) {
68
- $attributes['type'] = $resourceType;
75
+ $results = $results->map(
76
+ function ($item) use ($resourceType) {
77
+ $item['type'] = $resourceType;
69
78
 
70
- return $attributes;
71
- },
72
- $results
79
+ return $item;
80
+ }
73
81
  );
74
82
 
75
- return response()->json([$type => $results]);
83
+ // Create a LengthAwarePaginator instance
84
+ $results = new LengthAwarePaginator(
85
+ $results->forPage($page, $limit),
86
+ $total,
87
+ $limit,
88
+ $page,
89
+ ['path' => URL::current()]
90
+ );
91
+
92
+ // Manually structure the response
93
+ $response = [
94
+ $type => $results->items(),
95
+ 'meta' => [
96
+ 'total' => $results->total(),
97
+ 'per_page' => $results->perPage(),
98
+ 'current_page' => $results->currentPage(),
99
+ 'last_page' => $results->lastPage(),
100
+ 'next_page_url' => $results->nextPageUrl(),
101
+ 'prev_page_url' => $results->previousPageUrl(),
102
+ 'from' => $results->firstItem(),
103
+ 'to' => $results->lastItem(),
104
+ ],
105
+ ];
106
+
107
+ return response()->json($response);
76
108
  }
77
109
  }
@@ -0,0 +1,41 @@
1
+ <?php
2
+
3
+ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
+
5
+ use Fleetbase\Http\Controllers\Controller;
6
+ use Fleetbase\Models\ApiCredential;
7
+ use Fleetbase\Models\User;
8
+
9
+ class NavigatorController extends Controller
10
+ {
11
+ public function linkApp()
12
+ {
13
+ $adminUser = User::where('type', 'admin')->first();
14
+
15
+ if ($adminUser->company) {
16
+ $apiCredential = ApiCredential::firstOrCreate(
17
+ [
18
+ 'user_uuid' => $adminUser->uuid,
19
+ 'company_uuid' => $adminUser->company_uuid,
20
+ 'name' => 'NavigationAppLinker',
21
+ ],
22
+ [
23
+ 'user_uuid' => $adminUser->uuid,
24
+ 'company_uuid' => $adminUser->company->uuid,
25
+ 'name' => 'NavigationAppLinker',
26
+ ]
27
+ );
28
+
29
+ return redirect()->away('flbnavigator://configure?key=' . $apiCredential->key . '&host=' . url()->secure('/'));
30
+ }
31
+
32
+ return response()->error('Organization for linking not found.');
33
+ }
34
+
35
+ public function getLinkAppUrl()
36
+ {
37
+ return response()->json([
38
+ 'linkUrl' => url('int/v1/fleet-ops/navigator/link-app'),
39
+ ]);
40
+ }
41
+ }
@@ -129,6 +129,7 @@ class OrderController extends FleetOpsController
129
129
  public function importFromFiles(Request $request)
130
130
  {
131
131
  $info = Utils::lookupIp();
132
+ $disk = $request->input('disk', config('filesystems.default'));
132
133
  $files = $request->input('files');
133
134
  $files = File::whereIn('uuid', $files)->get();
134
135
  $country = $request->input('country', Utils::or($info, ['country_name', 'region'], 'Singapore'));
@@ -143,7 +144,7 @@ class OrderController extends FleetOpsController
143
144
  }
144
145
 
145
146
  try {
146
- $data = Excel::toArray(new OrdersImport(), $file->path, 's3');
147
+ $data = Excel::toArray(new OrdersImport(), $file->path, $disk);
147
148
  } catch (\Exception $e) {
148
149
  return response()->error('Invalid file, unable to proccess.');
149
150
  }
@@ -177,7 +178,7 @@ class OrderController extends FleetOpsController
177
178
  $entity = new Entity(['name' => $itemName]);
178
179
  $entity->setAttribute('destination_uuid', $place->uuid);
179
180
  $entity->setAttribute('_import_id', $importId);
180
- $entity->setMetas($place->getMeta());
181
+ $entity->setMeta($place->getMeta());
181
182
  $entities[] = $entity;
182
183
  }
183
184
  }
@@ -76,7 +76,7 @@ class PlaceController extends FleetOpsController
76
76
  }
77
77
  }
78
78
 
79
- return response()->json($results);
79
+ return response()->json($results)->withHeaders(['Cache-Control' => 'no-cache']);
80
80
  }
81
81
 
82
82
  /**
@@ -113,7 +113,7 @@ class PlaceController extends FleetOpsController
113
113
  }
114
114
  }
115
115
 
116
- return response()->json($results);
116
+ return response()->json($results)->withHeaders(['Cache-Control' => 'no-cache']);
117
117
  }
118
118
 
119
119
  /**
@@ -2,6 +2,7 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
+ use Fleetbase\FleetOps\Rules\ResolvablePoint;
5
6
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
7
  use Illuminate\Validation\Rule;
7
8
 
@@ -37,6 +38,7 @@ class CreateDriverRequest extends FleetbaseRequest
37
38
  'status' => 'nullable|string|in:active,inactive',
38
39
  'vendor' => 'nullable|exists:vendors,public_id',
39
40
  'job' => 'nullable|exists:orders,public_id',
41
+ 'location' => ['nullable', new ResolvablePoint()],
40
42
  ];
41
43
  }
42
44
 
@@ -46,8 +46,16 @@ class CreateOrderRequest extends FleetbaseRequest
46
46
 
47
47
  if ($this->isArray('payload')) {
48
48
  $validations['payload'] = 'required';
49
- $validations['payload.pickup'] = 'required';
50
- $validations['payload.dropoff'] = 'required';
49
+
50
+ if ($this->missing('payload.waypoints')) {
51
+ $validations['payload.pickup'] = 'required';
52
+ $validations['payload.dropoff'] = 'required';
53
+ }
54
+
55
+ if ($this->missing(['payload.pickup', 'payload.dropoff'])) {
56
+ $validations['payload.waypoints'] = 'required|array|min:2';
57
+ }
58
+
51
59
  $validations['payload.return'] = 'nullable';
52
60
  }
53
61
 
@@ -57,8 +65,14 @@ class CreateOrderRequest extends FleetbaseRequest
57
65
  }
58
66
 
59
67
  if ($this->missing('payload') && $this->isMethod('POST')) {
60
- $validations['pickup'] = 'required';
61
- $validations['dropoff'] = 'required';
68
+ if ($this->missing('waypoints')) {
69
+ $validations['pickup'] = 'required';
70
+ $validations['dropoff'] = 'required';
71
+ }
72
+
73
+ if ($this->missing(['pickup', 'dropoff'])) {
74
+ $validations['waypoints'] = 'required|array|min:2';
75
+ }
62
76
  }
63
77
 
64
78
  return $validations;
@@ -25,13 +25,29 @@ class CreatePayloadRequest extends FleetbaseRequest
25
25
  public function rules()
26
26
  {
27
27
  return [
28
- 'pickup' => 'required',
29
- 'dropoff' => 'required',
30
- 'return' => 'nullable',
31
- 'waypoints' => 'nullable|array',
32
- 'type' => 'required',
33
- 'cod_currency' => [Rule::requiredIf($this->has(['cod_amount'])), 'size:3'],
34
- 'cod_payment_method' => [Rule::requiredIf($this->has(['cod_amount'])), 'in:card,check,cash,bank_transfer'],
28
+ 'entities' => 'array',
29
+ 'waypoints' => 'array',
30
+ 'return' => 'nullable',
31
+ 'type' => 'required',
32
+ 'cod_currency' => [Rule::requiredIf($this->has(['cod_amount'])), 'size:3'],
33
+ 'cod_payment_method' => [Rule::requiredIf($this->has(['cod_amount'])), 'in:card,check,cash,bank_transfer'],
35
34
  ];
35
+
36
+ if ($this->missing('waypoints')) {
37
+ $validations['pickup'] = 'required';
38
+ $validations['dropoff'] = 'required';
39
+ }
40
+
41
+ if ($this->isString('pickup')) {
42
+ $validations['pickup'] = 'required|exists:places,public_id';
43
+ }
44
+
45
+ if ($this->isString('dropoff')) {
46
+ $validations['dropoff'] = 'required|exists:places,public_id';
47
+ }
48
+
49
+ if ($this->missing(['pickup', 'dropoff'])) {
50
+ $validations['waypoints'] = 'required|array|min:2';
51
+ }
36
52
  }
37
53
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
+ use Fleetbase\FleetOps\Rules\ResolvablePoint;
5
6
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
7
  use Fleetbase\Rules\ExistsInAny;
7
8
  use Illuminate\Validation\Rule;
@@ -28,11 +29,14 @@ class CreatePlaceRequest extends FleetbaseRequest
28
29
  public function rules()
29
30
  {
30
31
  return [
31
- 'name' => [Rule::requiredIf($this->isMethod('POST'))],
32
- 'street1' => [Rule::requiredIf($this->isMethod('POST'))],
33
- 'customer' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
34
- 'contact' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
35
- 'vendor' => 'nullable|exists:vendors,public_id',
32
+ 'name' => [Rule::requiredIf($this->isMethod('POST'))],
33
+ 'street1' => [Rule::requiredIf($this->isMethod('POST'))],
34
+ 'customer' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
35
+ 'contact' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
36
+ 'vendor' => 'nullable|exists:vendors,public_id',
37
+ 'location' => ['nullable', new ResolvablePoint()],
38
+ 'latitude' => 'nullable',
39
+ 'longitude' => 'nullable',
36
40
  ];
37
41
  }
38
42
  }
@@ -2,7 +2,11 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
+ use Fleetbase\FleetOps\Models\Order;
6
+ use Fleetbase\FleetOps\Models\TrackingNumber;
7
+ use Fleetbase\FleetOps\Rules\ResolvablePoint;
5
8
  use Fleetbase\Http\Requests\FleetbaseRequest;
9
+ use Illuminate\Support\Str;
6
10
  use Illuminate\Validation\Rule;
7
11
 
8
12
  class CreateTrackingStatusRequest extends FleetbaseRequest
@@ -24,19 +28,72 @@ class CreateTrackingStatusRequest extends FleetbaseRequest
24
28
  */
25
29
  public function rules()
26
30
  {
27
- return [
28
- 'tracking_number' => [
31
+ $validations = [
32
+ 'tracking_number' => array_filter([
29
33
  'required',
30
- Rule::exists('tracking_numbers')->where(function ($query) {
31
- $query->where('public_id', $this->input('tracking_number'));
32
- $query->whereDoesntHave('status', function ($q) {
33
- $q->where('code', $this->input('code'));
34
- });
35
- }),
36
- ],
37
- 'status' => 'required|string',
38
- 'details' => 'required|string',
39
- 'code' => 'required|string',
34
+ $this->isMethod('POST') ? Rule::exists('tracking_numbers', 'public_id') : null,
35
+ $this->isMethod('POST') ? static::uniqueStatus($this) : null,
36
+ ]),
37
+ 'location' => [new ResolvablePoint()],
38
+ 'code' => 'nullable|string|min:3',
39
+ 'status' => ['required', 'string', 'min:3'],
40
+ 'details' => 'nullable|string',
40
41
  ];
42
+
43
+ if ($this->isMethod('POST') && $this->missing('tracking_number') && $this->has('order')) {
44
+ $validations['tracking_number'] = 'nullable';
45
+ $validations['order'] = [
46
+ 'required',
47
+ Rule::exists('orders', 'public_id'),
48
+ static::uniqueStatus($this),
49
+ ];
50
+ }
51
+
52
+ if ($this->missing(['latitude', 'longitude'])) {
53
+ $validations['location'] = ['required', new ResolvablePoint()];
54
+ } elseif ($this->missing('location')) {
55
+ $validations['latitude'] = 'required';
56
+ $validations['longitude'] = 'required';
57
+ }
58
+
59
+ return $validations;
60
+ }
61
+
62
+ /**
63
+ * Custom rule to ensure status is unique for an order or tracking number.
64
+ *
65
+ * @return \Closure
66
+ */
67
+ private static function uniqueStatus($request)
68
+ {
69
+ return function ($attribute, $value, $fail) use ($request) {
70
+ $trackingNumber = $request->input('tracking_number');
71
+ $orderId = $request->input('order');
72
+ $status = $request->input('status');
73
+ $exists = false;
74
+
75
+ // if duplicate status enabled skip
76
+ if ($request->boolean('duplicate')) {
77
+ return;
78
+ }
79
+
80
+ if ($trackingNumber) {
81
+ $exists = TrackingNumber::where('public_id', $trackingNumber)->whereHas('statuses', function ($query) use ($status) {
82
+ $query->where('status', $status);
83
+ $query->orWhere('status', Str::title($status));
84
+ })->exists();
85
+ } elseif ($orderId) {
86
+ $exists = Order::where('public_id', $orderId)->whereHas('trackingNumber', function ($query) use ($status) {
87
+ $query->whereHas('statuses', function ($query) use ($status) {
88
+ $query->where('status', $status);
89
+ $query->orWhere('status', Str::title($status));
90
+ });
91
+ })->exists();
92
+ }
93
+
94
+ if ($exists) {
95
+ $fail('The status "' . Str::title($status) . '" has already been applied to the order.');
96
+ }
97
+ };
41
98
  }
42
99
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
+ use Fleetbase\FleetOps\Rules\ResolvablePoint;
5
6
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
7
 
7
8
  class CreateVehicleRequest extends FleetbaseRequest
@@ -24,9 +25,10 @@ class CreateVehicleRequest extends FleetbaseRequest
24
25
  public function rules()
25
26
  {
26
27
  return [
27
- 'status' => 'nullable|in:operational,maintenance,decommissioned',
28
- 'vendor' => 'nullable|exists:vendors,public_id',
29
- 'driver' => 'nullable|exists:drivers,public_id',
28
+ 'status' => 'nullable|in:operational,maintenance,decommissioned',
29
+ 'vendor' => 'nullable|exists:vendors,public_id',
30
+ 'driver' => 'nullable|exists:drivers,public_id',
31
+ 'location' => ['nullable', new ResolvablePoint()],
30
32
  ];
31
33
  }
32
34
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Resources\v1;
4
4
 
5
+ use Fleetbase\FleetOps\Support\Utils;
5
6
  use Fleetbase\Http\Resources\FleetbaseResource;
6
7
  use Fleetbase\Support\Http;
7
8
  use Fleetbase\Support\Resolve;
@@ -24,11 +25,13 @@ class Entity extends FleetbaseResource
24
25
  'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
25
26
  'customer_uuid' => $this->when(Http::isInternalRequest(), $this->customer_uuid),
26
27
  'customer_type' => $this->when(Http::isInternalRequest(), $this->customer_type),
28
+ 'supplier_uuid' => $this->when(Http::isInternalRequest(), $this->supplier_uuid),
27
29
  'internal_id' => $this->internal_id,
28
30
  'name' => $this->name,
29
31
  'type' => $this->type ?? null,
30
32
  'destination' => $this->when(Http::isPublicRequest(), data_get($this, 'destination.public_id'), null),
31
33
  'customer' => $this->setCustomerType(Resolve::resourceForMorph($this->customer_type, $this->customer_uuid)),
34
+ 'supplier' => $this->whenLoaded('supplier', $this->supplier),
32
35
  'tracking_number' => new TrackingNumber($this->trackingNumber),
33
36
  'description' => $this->description ?? null,
34
37
  'photo_url' => $this->photo_url ?? null,