@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.
Files changed (74) hide show
  1. package/addon/components/admin/navigator-app.hbs +6 -3
  2. package/addon/components/layout/fleet-ops-sidebar/fleet-listing.hbs +5 -1
  3. package/addon/components/layout/fleet-ops-sidebar/fleet-listing.js +98 -1
  4. package/addon/components/layout/fleet-ops-sidebar.hbs +5 -1
  5. package/addon/components/layout/fleet-ops-sidebar.js +1 -0
  6. package/addon/controllers/management/drivers/index/edit.js +0 -26
  7. package/addon/engine.js +4 -4
  8. package/addon/styles/fleetops-engine.css +17 -0
  9. package/addon/templates/operations/service-rates/index/new.hbs +1 -1
  10. package/composer.json +2 -2
  11. package/extension.json +1 -1
  12. package/package.json +1 -1
  13. package/server/config/fleetops.php +4 -1
  14. package/server/src/Casts/MultiPolygon.php +14 -3
  15. package/server/src/Casts/Point.php +12 -2
  16. package/server/src/Casts/Polygon.php +19 -4
  17. package/server/src/Http/Controllers/Api/v1/DriverController.php +34 -18
  18. package/server/src/Http/Controllers/Api/v1/EntityController.php +36 -1
  19. package/server/src/Http/Controllers/Api/v1/LabelController.php +2 -2
  20. package/server/src/Http/Controllers/Api/v1/OrderController.php +139 -59
  21. package/server/src/Http/Controllers/Api/v1/PayloadController.php +20 -12
  22. package/server/src/Http/Controllers/Api/v1/PlaceController.php +25 -3
  23. package/server/src/Http/Controllers/Api/v1/PurchaseRateController.php +1 -1
  24. package/server/src/Http/Controllers/Api/v1/ServiceAreaController.php +71 -3
  25. package/server/src/Http/Controllers/Api/v1/ServiceQuoteController.php +1 -1
  26. package/server/src/Http/Controllers/Api/v1/ServiceRateController.php +3 -2
  27. package/server/src/Http/Controllers/Api/v1/TrackingNumberController.php +2 -2
  28. package/server/src/Http/Controllers/Api/v1/TrackingStatusController.php +2 -2
  29. package/server/src/Http/Controllers/Api/v1/VehicleController.php +22 -2
  30. package/server/src/Http/Controllers/Api/v1/ZoneController.php +59 -3
  31. package/server/src/Http/Controllers/Internal/v1/DriverController.php +148 -0
  32. package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +38 -0
  33. package/server/src/Http/Controllers/Internal/v1/OrderController.php +11 -1
  34. package/server/src/Http/Filter/TrackingStatusFilter.php +10 -0
  35. package/server/src/Http/Requests/CancelOrderRequest.php +1 -2
  36. package/server/src/Http/Requests/CreateContactRequest.php +5 -4
  37. package/server/src/Http/Requests/CreateDriverRequest.php +13 -11
  38. package/server/src/Http/Requests/CreateEntityRequest.php +7 -4
  39. package/server/src/Http/Requests/CreateOrderRequest.php +2 -2
  40. package/server/src/Http/Requests/CreatePayloadRequest.php +1 -1
  41. package/server/src/Http/Requests/CreatePlaceRequest.php +46 -4
  42. package/server/src/Http/Requests/CreatePurchaseRateRequest.php +3 -2
  43. package/server/src/Http/Requests/CreateServiceAreaRequest.php +24 -4
  44. package/server/src/Http/Requests/CreateServiceRateRequest.php +22 -21
  45. package/server/src/Http/Requests/CreateTrackingStatusRequest.php +9 -8
  46. package/server/src/Http/Requests/CreateVehicleRequest.php +6 -4
  47. package/server/src/Http/Requests/CreateZoneRequest.php +24 -5
  48. package/server/src/Http/Requests/QueryServiceQuotesRequest.php +11 -10
  49. package/server/src/Http/Requests/ScheduleOrderRequest.php +32 -0
  50. package/server/src/Http/Requests/UpdateContactRequest.php +0 -13
  51. package/server/src/Http/Requests/UpdateServiceAreaRequest.php +1 -23
  52. package/server/src/Http/Requests/UpdateServiceQuoteRequest.php +1 -23
  53. package/server/src/Http/Requests/UpdateServiceRateRequest.php +1 -23
  54. package/server/src/Http/Requests/UpdateTrackingStatusRequest.php +1 -26
  55. package/server/src/Http/Resources/v1/DeletedResource.php +2 -9
  56. package/server/src/Http/Resources/v1/Entity.php +47 -44
  57. package/server/src/Http/Resources/v1/Order.php +1 -1
  58. package/server/src/Http/Resources/v1/ServiceArea.php +2 -2
  59. package/server/src/Http/Resources/v1/Vehicle.php +1 -3
  60. package/server/src/Http/Resources/v1/Zone.php +2 -4
  61. package/server/src/Models/Entity.php +99 -3
  62. package/server/src/Models/Order.php +75 -7
  63. package/server/src/Models/Payload.php +104 -33
  64. package/server/src/Models/Place.php +56 -17
  65. package/server/src/Models/ServiceArea.php +285 -18
  66. package/server/src/Models/ServiceRate.php +10 -6
  67. package/server/src/Models/TrackingNumber.php +18 -24
  68. package/server/src/Models/TrackingStatus.php +2 -6
  69. package/server/src/Models/Vehicle.php +2 -2
  70. package/server/src/Models/Waypoint.php +0 -10
  71. package/server/src/Models/Zone.php +132 -5
  72. package/server/src/Support/Flow.php +17 -3
  73. package/server/src/Support/Utils.php +143 -9
  74. package/server/src/routes.php +58 -3
@@ -105,8 +105,8 @@ class TrackingStatusController extends Controller
105
105
  }
106
106
 
107
107
  // if no code set create a code from the status
108
- if (empty($input['code'])) {
109
- $input['code'] = TrackingStatus::prepareCode($input['status']);
108
+ if (empty($trackingStatus->code)) {
109
+ $input['code'] = TrackingStatus::prepareCode(data_get($input, 'status', $trackingStatus->status));
110
110
  }
111
111
 
112
112
  // update the trackingStatus
@@ -24,13 +24,18 @@ class VehicleController extends Controller
24
24
  public function create(CreateVehicleRequest $request)
25
25
  {
26
26
  // get request input
27
- $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'location', 'altitude', 'heading', 'speed']);
27
+ $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'online', 'location', 'altitude', 'heading', 'speed']);
28
28
  // make sure company is set
29
29
  $input['company_uuid'] = session('company');
30
30
 
31
31
  // create instance of vehicle model
32
32
  $vehicle = new Vehicle();
33
33
 
34
+ // set default online
35
+ if (!isset($input['online'])) {
36
+ $input['online'] = 0;
37
+ }
38
+
34
39
  // vendor assignment
35
40
  if ($request->has('vendor')) {
36
41
  $input['vendor_uuid'] = Utils::getUuid('vendors', [
@@ -39,6 +44,11 @@ class VehicleController extends Controller
39
44
  ]);
40
45
  }
41
46
 
47
+ // latitude / longitude
48
+ if ($request->has(['latitude', 'longitude'])) {
49
+ $input['location'] = Utils::getPointFromCoordinates($request->only(['latitude', 'longitude']));
50
+ }
51
+
42
52
  // apply user input to vehicle
43
53
  $vehicle = $vehicle->fill($input);
44
54
 
@@ -90,7 +100,7 @@ class VehicleController extends Controller
90
100
  }
91
101
 
92
102
  // get request input
93
- $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'location', 'altitude', 'heading', 'speed']);
103
+ $input = $request->only(['status', 'make', 'model', 'year', 'trim', 'type', 'plate_number', 'vin', 'meta', 'location', 'online', 'altitude', 'heading', 'speed']);
94
104
 
95
105
  // vendor assignment
96
106
  if ($request->has('vendor')) {
@@ -100,6 +110,16 @@ class VehicleController extends Controller
100
110
  ]);
101
111
  }
102
112
 
113
+ // set default online
114
+ if (!isset($input['online'])) {
115
+ $input['online'] = 0;
116
+ }
117
+
118
+ // latitude / longitude
119
+ if ($request->has(['latitude', 'longitude'])) {
120
+ $input['location'] = Utils::getPointFromCoordinates($request->only(['latitude', 'longitude']));
121
+ }
122
+
103
123
  // update the vehicle w/ user input
104
124
  $vehicle->fill($input);
105
125
 
@@ -9,6 +9,7 @@ use Fleetbase\FleetOps\Http\Resources\v1\Zone as ZoneResource;
9
9
  use Fleetbase\FleetOps\Models\Zone;
10
10
  use Fleetbase\FleetOps\Support\Utils;
11
11
  use Fleetbase\Http\Controllers\Controller;
12
+ use Grimzy\LaravelMysqlSpatial\Types\Point;
12
13
  use Illuminate\Http\Request;
13
14
 
14
15
  class ZoneController extends Controller
@@ -23,7 +24,10 @@ class ZoneController extends Controller
23
24
  public function create(CreateZoneRequest $request)
24
25
  {
25
26
  // get request input
26
- $input = $request->only(['name', 'boundary', 'status', 'description', 'color', 'stroke_color']);
27
+ $input = $request->only(['name', 'border', 'status', 'description', 'color', 'stroke_color']);
28
+
29
+ // get radius for creating zone border - default to 500 meters
30
+ $radius = $request->input('radius', 500);
27
31
 
28
32
  // make sure company is set
29
33
  $input['company_uuid'] = session('company');
@@ -36,10 +40,37 @@ class ZoneController extends Controller
36
40
  ]);
37
41
  }
38
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'] = Zone::createPolygonFromPoint($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'] = Zone::createPolygonFromPoint($point, $radius);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * @todo if missing location, latitude, longitude and border
67
+ * then create a zone from the center of the service area provided
68
+ */
69
+
39
70
  // create the zone
40
71
  $zone = Zone::create($input);
41
72
 
42
- // response the driver resource
73
+ // response the zone resource
43
74
  return new ZoneResource($zone);
44
75
  }
45
76
 
@@ -66,7 +97,10 @@ class ZoneController extends Controller
66
97
  }
67
98
 
68
99
  // get request input
69
- $input = $request->only(['name', 'boundary', 'status', 'description', 'color', 'stroke_color']);
100
+ $input = $request->only(['name', 'border', 'status', 'description', 'color', 'stroke_color']);
101
+
102
+ // get radius for creating zone border - default to 500 meters
103
+ $radius = $request->input('radius', 500);
70
104
 
71
105
  // service area assignment
72
106
  if ($request->has('service_area')) {
@@ -76,6 +110,28 @@ class ZoneController extends Controller
76
110
  ]);
77
111
  }
78
112
 
113
+ // if latitude and longitude is provided
114
+ if ($request->has(['latitude', 'longitude'])) {
115
+ // create a polygon given the radius
116
+ $latitude = $request->input('latitude');
117
+ $longitude = $request->input('longitude');
118
+ $point = new Point($latitude, $longitude);
119
+
120
+ if ($point instanceof Point) {
121
+ $input['border'] = Zone::createPolygonFromPoint($point, $radius);
122
+ }
123
+ }
124
+
125
+ // if a location is provided
126
+ if ($request->has('location')) {
127
+ $location = $request->input('location');
128
+ $point = Utils::getPointFromMixed($location);
129
+
130
+ if ($point instanceof Point) {
131
+ $input['border'] = Zone::createPolygonFromPoint($point, $radius);
132
+ }
133
+ }
134
+
79
135
  // update the zone
80
136
  $zone->update($input);
81
137
 
@@ -4,14 +4,18 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
5
  use Fleetbase\Exceptions\FleetbaseRequestValidationException;
6
6
  use Fleetbase\FleetOps\Exports\DriverExport;
7
+ use Fleetbase\FleetOps\Http\Controllers\Api\v1\DriverController as ApiDriverController;
7
8
  use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
9
+ use Fleetbase\FleetOps\Http\Requests\Internal\AssignOrderRequest;
8
10
  use Fleetbase\FleetOps\Http\Requests\Internal\CreateDriverRequest;
9
11
  use Fleetbase\FleetOps\Http\Requests\Internal\UpdateDriverRequest;
10
12
  use Fleetbase\FleetOps\Models\Driver;
13
+ use Fleetbase\FleetOps\Models\Order;
11
14
  use Fleetbase\FleetOps\Support\Utils;
12
15
  use Fleetbase\Http\Requests\ExportRequest;
13
16
  use Fleetbase\Models\Invite;
14
17
  use Fleetbase\Models\User;
18
+ use Fleetbase\Models\VerificationCode;
15
19
  use Fleetbase\Notifications\UserInvited;
16
20
  use Illuminate\Http\Request;
17
21
  use Illuminate\Support\Facades\DB;
@@ -267,4 +271,148 @@ class DriverController extends FleetOpsController
267
271
 
268
272
  return Excel::download(new DriverExport(), $fileName);
269
273
  }
274
+
275
+ /**
276
+ * Assigns a driver to a specified order.
277
+ *
278
+ * @param Fleetbase\FleetOps\Http\Requests\Internal\AssignOrderRequest $request
279
+ *
280
+ * @return \Illuminate\Http\Response $response
281
+ */
282
+ public function assignOrder(AssignOrderRequest $request)
283
+ {
284
+ $driver = Driver::where('public_id', $request->driver)->first();
285
+ $order = Order::where('public_id', $request->order)->first();
286
+
287
+ if ($order->hasDriverAssigned) {
288
+ return response()->error('A driver is already assigned to this order.');
289
+ }
290
+
291
+ if ($order->isDriver($driver)) {
292
+ return response()->error('The driver is already assigned to this order.');
293
+ }
294
+
295
+ $order->assignDriver($driver);
296
+
297
+ return response()->json([
298
+ 'status' => 'ok',
299
+ 'message' => 'Driver assigned',
300
+ ]);
301
+ }
302
+
303
+ /**
304
+ * Update drivers geolocation data.
305
+ *
306
+ * @return \Illuminate\Http\Response
307
+ */
308
+ public function track(string $id, Request $request)
309
+ {
310
+ return app(ApiDriverController::class)->track($id, $request);
311
+ }
312
+
313
+ /**
314
+ * Query for Storefront Customer orders.
315
+ *
316
+ * @return \Fleetbase\Http\Resources\Storefront\Customer
317
+ */
318
+ public function registerDevice(Request $request)
319
+ {
320
+ return app(ApiDriverController::class)->registerDevice($request);
321
+ }
322
+
323
+ /**
324
+ * Authenticates customer using login credentials and returns with auth token.
325
+ *
326
+ * @return \Fleetbase\Http\Resources\Storefront\Customer
327
+ */
328
+ public function login(Request $request)
329
+ {
330
+ return app(ApiDriverController::class)->login($request);
331
+ }
332
+
333
+ /**
334
+ * Attempts authentication with phone number via SMS verification.
335
+ *
336
+ * @return \Illuminate\Http\Response
337
+ */
338
+ public function loginWithPhone()
339
+ {
340
+ $phone = static::phone();
341
+
342
+ // Check if user exists
343
+ $user = User::where('phone', $phone)->whereNull('deleted_at')->withoutGlobalScopes()->first();
344
+
345
+ if (!$user) {
346
+ return response()->error('No driver with this phone # found.');
347
+ }
348
+
349
+ // Generate verification token
350
+ VerificationCode::generateSmsVerificationFor($user, 'driver_login', function ($verification) {
351
+ return 'Your ' . config('app.name') . ' verification code is ' . $verification->code;
352
+ });
353
+
354
+ return response()->json(['status' => 'OK']);
355
+ }
356
+
357
+ /**
358
+ * Verifys SMS code and sends auth token with driver resource.
359
+ *
360
+ * @return \Fleetbase\Http\Resources\FleetOps\Driver
361
+ */
362
+ public function verifyCode(Request $request)
363
+ {
364
+ $identity = Utils::isEmail($request->identity) ? $request->identity : static::phone($request->identity);
365
+ $code = $request->input('code');
366
+ $for = $request->input('for', 'driver_login');
367
+ $attrs = $request->input(['name', 'phone', 'email']);
368
+
369
+ if ($for === 'create_driver') {
370
+ return app(ApiDriverController::class)->create($request);
371
+ }
372
+
373
+ // Check if user exists
374
+ $user = User::where('phone', $identity)->orWhere('email', $identity)->first();
375
+ if (!$user) {
376
+ return response()->error('Unable to verify code.');
377
+ }
378
+
379
+ // Find and verify code
380
+ $verificationCode = VerificationCode::where(['subject_uuid' => $user->uuid, 'code' => $code, 'for' => $for])->exists();
381
+ if (!$verificationCode && $code !== config('fleetops.navigator.bypass_verification_code')) {
382
+ return response()->error('Invalid verification code!');
383
+ }
384
+
385
+ // Get driver record
386
+ $driver = Driver::where('user_uuid', $user->uuid)->whereNull('deleted_at')->withoutGlobalScopes()->first();
387
+ if (!$driver) {
388
+ return response()->error('No driver/agent record found for login.');
389
+ }
390
+
391
+ // Generate auth token
392
+ try {
393
+ $token = $user->createToken($driver->uuid);
394
+ } catch (\Exception $e) {
395
+ return response()->error($e->getMessage());
396
+ }
397
+
398
+ $driver->token = $token->plainTextToken;
399
+
400
+ return new $this->resource($driver);
401
+ }
402
+
403
+ /**
404
+ * Patches phone number with international code.
405
+ */
406
+ public static function phone(string $phone = null): string
407
+ {
408
+ if ($phone === null) {
409
+ $phone = request()->input('phone');
410
+ }
411
+
412
+ if (!Str::startsWith($phone, '+')) {
413
+ $phone = '+' . $phone;
414
+ }
415
+
416
+ return $phone;
417
+ }
270
418
  }
@@ -3,8 +3,12 @@
3
3
  namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
4
4
 
5
5
  use Fleetbase\Http\Controllers\Controller;
6
+ use Fleetbase\Http\Resources\Organization;
6
7
  use Fleetbase\Models\ApiCredential;
8
+ use Fleetbase\Models\Company;
7
9
  use Fleetbase\Models\User;
10
+ use Illuminate\Http\Request;
11
+ use Illuminate\Support\Str;
8
12
 
9
13
  class NavigatorController extends Controller
10
14
  {
@@ -38,4 +42,38 @@ class NavigatorController extends Controller
38
42
  'linkUrl' => url('int/v1/fleet-ops/navigator/link-app'),
39
43
  ]);
40
44
  }
45
+
46
+ public function getCurrentOrganization(Request $request)
47
+ {
48
+ $token = $request->bearerToken();
49
+ $isSecretKey = Str::startsWith($token, '$');
50
+
51
+ // Depending on API key format set the connection to find credential on
52
+ $connection = Str::startsWith($token, 'flb_test_') ? 'sandbox' : 'mysql';
53
+
54
+ // Find the API Credential record
55
+ $findApKey = ApiCredential::on($connection)
56
+ ->where(function ($query) use ($isSecretKey, $token) {
57
+ if ($isSecretKey) {
58
+ $query->where('secret', $token);
59
+ } else {
60
+ $query->where('key', $token);
61
+ }
62
+ })
63
+ ->with(['company.owner'])
64
+ ->withoutGlobalScopes();
65
+
66
+ // Get the api credential model record
67
+ $apiCredential = $findApKey->first();
68
+
69
+ // Handle no api credential found
70
+ if (!$apiCredential) {
71
+ return response()->error('No API key found to fetch company details with.');
72
+ }
73
+
74
+ // Get the organization owning the API key
75
+ $organization = Company::where('uuid', $apiCredential->company_uuid)->first();
76
+
77
+ return new Organization($organization);
78
+ }
41
79
  }
@@ -62,6 +62,16 @@ class OrderController extends FleetOpsController
62
62
 
63
63
  $input['integrated_vendor_order'] = $integratedVendorOrder;
64
64
  }
65
+
66
+ // if no type is set its default to default
67
+ if (!isset($input['type'])) {
68
+ $input['type'] = 'default';
69
+ }
70
+
71
+ // if no status is set its default to `created`
72
+ if (!isset($input['status'])) {
73
+ $input['status'] = 'created';
74
+ }
65
75
  },
66
76
  function (&$request, Order &$order, &$requestInput) {
67
77
  $input = $request->input('order');
@@ -101,7 +111,7 @@ class OrderController extends FleetOpsController
101
111
  $order->purchaseServiceQuote($serviceQuote);
102
112
 
103
113
  // dispatch if flagged true
104
- $order->firstDispatch();
114
+ $order->firstDispatchWithActivity();
105
115
 
106
116
  // load tracking number
107
117
  $order->load(['trackingNumber']);
@@ -11,6 +11,16 @@ class TrackingStatusFilter extends Filter
11
11
  $this->builder->where('company_uuid', $this->session->get('company'));
12
12
  }
13
13
 
14
+ public function trackingNumber(string $trackingNumber)
15
+ {
16
+ $this->builder->whereHas('trackingNumber', function ($query) use ($trackingNumber) {
17
+ $query->where(function ($query) use ($trackingNumber) {
18
+ $query->where('public_id', $trackingNumber);
19
+ $query->orWhere('uuid', $trackingNumber);
20
+ });
21
+ });
22
+ }
23
+
14
24
  public function order(string $order)
15
25
  {
16
26
  $this->builder->whereHas(
@@ -2,7 +2,6 @@
2
2
 
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
- use Fleetbase\FleetOps\Support\Utils;
6
5
  use Fleetbase\Http\Requests\FleetbaseRequest;
7
6
 
8
7
  class CancelOrderRequest extends FleetbaseRequest
@@ -14,7 +13,7 @@ class CancelOrderRequest extends FleetbaseRequest
14
13
  */
15
14
  public function authorize()
16
15
  {
17
- return Utils::notEmpty(session('user'));
16
+ return request()->session()->has('api_credential');
18
17
  }
19
18
 
20
19
  /**
@@ -3,6 +3,7 @@
3
3
  namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
5
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
+ use Illuminate\Validation\Rules\RequiredIf;
6
7
 
7
8
  class CreateContactRequest extends FleetbaseRequest
8
9
  {
@@ -24,10 +25,10 @@ class CreateContactRequest extends FleetbaseRequest
24
25
  public function rules()
25
26
  {
26
27
  return [
27
- 'name' => 'required',
28
- 'type' => 'required',
29
- 'email' => 'nullable|email',
30
- 'phone' => 'nullable',
28
+ 'name' => ['required'],
29
+ 'type' => [new RequiredIf($this->isMethod('POST'))],
30
+ 'email' => ['nullable', 'email'],
31
+ 'phone' => ['nullable'],
31
32
  ];
32
33
  }
33
34
  }
@@ -28,17 +28,19 @@ class CreateDriverRequest extends FleetbaseRequest
28
28
  $isCreating = $this->isMethod('POST');
29
29
 
30
30
  return [
31
- 'name' => [Rule::requiredIf($isCreating)],
32
- 'email' => [Rule::requiredIf($isCreating), Rule::when($this->filled('email'), ['email']), Rule::when($isCreating, [Rule::unique('users')->whereNull('deleted_at')])],
33
- 'phone' => [Rule::requiredIf($isCreating), Rule::when($isCreating, [Rule::unique('users')->whereNull('deleted_at')])],
34
- 'password' => 'nullable|string',
35
- 'country' => 'nullable|size:2',
36
- 'city' => 'nullable|string',
37
- 'vehicle' => 'nullable|string|starts_with:vehicle_|exists:drivers,public_id',
38
- 'status' => 'nullable|string|in:active,inactive',
39
- 'vendor' => 'nullable|exists:vendors,public_id',
40
- 'job' => 'nullable|exists:orders,public_id',
41
- 'location' => ['nullable', new ResolvablePoint()],
31
+ 'name' => [Rule::requiredIf($isCreating)],
32
+ 'email' => [Rule::requiredIf($isCreating), Rule::when($this->filled('email'), ['email']), Rule::when($isCreating, [Rule::unique('users')->whereNull('deleted_at')])],
33
+ 'phone' => [Rule::requiredIf($isCreating), Rule::when($isCreating, [Rule::unique('users')->whereNull('deleted_at')])],
34
+ 'password' => 'nullable|string',
35
+ 'country' => 'nullable|size:2',
36
+ 'city' => 'nullable|string',
37
+ 'vehicle' => 'nullable|string|starts_with:vehicle_|exists:drivers,public_id',
38
+ 'status' => 'nullable|string|in:active,inactive',
39
+ 'vendor' => 'nullable|exists:vendors,public_id',
40
+ 'job' => 'nullable|exists:orders,public_id',
41
+ 'location' => ['nullable', new ResolvablePoint()],
42
+ 'latitude' => ['nullable', 'required_with:longitude'],
43
+ 'longitude' => ['nullable', 'required_with:latitude'],
42
44
  ];
43
45
  }
44
46
 
@@ -27,16 +27,19 @@ class CreateEntityRequest extends FleetbaseRequest
27
27
  return [
28
28
  'name' => [Rule::requiredIf($this->isMethod('POST'))],
29
29
  'type' => [Rule::requiredIf($this->isMethod('POST'))],
30
- 'email' => 'nullable|email',
30
+ 'destination' => ['nullable', Rule::exists('places', 'public_id')->whereNull('deleted_at')],
31
+ 'waypoint' => ['nullable', Rule::exists('places', 'public_id')->whereNull('deleted_at')],
32
+ 'payload' => ['nullable', Rule::exists('payloads', 'public_id')->whereNull('deleted_at'), 'required_with:destination,waypoint'],
33
+ 'email' => ['nullable', 'email'],
31
34
  'weight' => 'nullable',
32
35
  'weight_unit' => [Rule::requiredIf($this->has('weight')), 'in:g,oz,lb,kg'],
33
36
  'length' => 'nullable',
34
37
  'width' => 'nullable',
35
38
  'height' => 'nullable',
36
39
  'dimensions_unit' => [Rule::requiredIf($this->has(['length', 'width', 'height'])), 'in:cm,in,ft,mm,m,yd'],
37
- 'declared_value' => 'nullable',
38
- 'price' => 'nullable',
39
- 'sales_price' => 'nullable',
40
+ 'declared_value' => ['nullable', 'numeric'],
41
+ 'price' => ['nullable', 'numeric'],
42
+ 'sales_price' => ['nullable', 'numeric'],
40
43
  'currency' => [Rule::requiredIf($this->has(['declared_value', 'price', 'sales_price'])), 'size:3'],
41
44
  ];
42
45
  }
@@ -26,11 +26,11 @@ class CreateOrderRequest extends FleetbaseRequest
26
26
  {
27
27
  $validations = [
28
28
  'adhoc' => 'in:true,false,1,0',
29
- 'dispatch' => 'boolean',
29
+ 'dispatch' => ['nullable', 'boolean'],
30
30
  'adhoc_distance' => 'numeric',
31
31
  'pod_required' => 'in:true,false,1,0',
32
32
  'pod_method' => 'in:' . config('api.pod_methods'),
33
- 'scheduled_at' => 'date',
33
+ 'scheduled_at' => ['nullable', 'date'],
34
34
  'driver' => 'nullable|exists:drivers,public_id',
35
35
  'service_quote' => 'nullable|exists:service_quotes,public_id',
36
36
  'purchase_rate' => 'nullable|exists:purchase_rates,public_id',
@@ -28,7 +28,7 @@ class CreatePayloadRequest extends FleetbaseRequest
28
28
  'entities' => 'array',
29
29
  'waypoints' => 'array',
30
30
  'return' => 'nullable',
31
- 'type' => 'required',
31
+ 'type' => [Rule::requiredIf($this->isMethod('POST'))],
32
32
  'cod_currency' => [Rule::requiredIf($this->has(['cod_amount'])), 'size:3'],
33
33
  'cod_payment_method' => [Rule::requiredIf($this->has(['cod_amount'])), 'in:card,check,cash,bank_transfer'],
34
34
  ];
@@ -29,14 +29,56 @@ class CreatePlaceRequest extends FleetbaseRequest
29
29
  public function rules()
30
30
  {
31
31
  return [
32
- 'name' => [Rule::requiredIf($this->isMethod('POST'))],
33
- 'street1' => [Rule::requiredIf($this->isMethod('POST'))],
32
+ 'name' => [
33
+ Rule::requiredIf(function () {
34
+ $isCreating = $this->isMethod('POST');
35
+ $hasCoordiantes = $this->filled('latitude') && $this->filled('longitude');
36
+ $hasLocation = $this->filled('location');
37
+ $hasStreet = $this->filled('street1');
38
+
39
+ // if creating then it's required
40
+ if ($isCreating) {
41
+ // if either has coordinated or location then it's not required
42
+ if ($hasCoordiantes || $hasLocation) {
43
+ return false;
44
+ }
45
+
46
+ // if street1 provided then it's not required
47
+ if ($hasStreet) {
48
+ return false;
49
+ }
50
+
51
+ return true;
52
+ }
53
+
54
+ return false;
55
+ }),
56
+ ],
57
+ 'street1' => [
58
+ Rule::requiredIf(function () {
59
+ $isCreating = $this->isMethod('POST');
60
+ $hasCoordiantes = $this->filled('latitude') && $this->filled('longitude');
61
+ $hasLocation = $this->filled('location');
62
+
63
+ // if creating then it's required
64
+ if ($isCreating) {
65
+ // if either has coordinated or location then it's not required
66
+ if ($hasCoordiantes || $hasLocation) {
67
+ return false;
68
+ }
69
+
70
+ return true;
71
+ }
72
+
73
+ return false;
74
+ }),
75
+ ],
34
76
  'customer' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
35
77
  'contact' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
36
78
  'vendor' => 'nullable|exists:vendors,public_id',
37
79
  'location' => ['nullable', new ResolvablePoint()],
38
- 'latitude' => 'nullable',
39
- 'longitude' => 'nullable',
80
+ 'latitude' => ['nullable', 'required_with:longitude'],
81
+ 'longitude' => ['nullable', 'required_with:latitude'],
40
82
  ];
41
83
  }
42
84
  }
@@ -4,6 +4,7 @@ namespace Fleetbase\FleetOps\Http\Requests;
4
4
 
5
5
  use Fleetbase\Http\Requests\FleetbaseRequest;
6
6
  use Fleetbase\Rules\ExistsInAny;
7
+ use Illuminate\Validation\Rule;
7
8
 
8
9
  class CreatePurchaseRateRequest extends FleetbaseRequest
9
10
  {
@@ -25,8 +26,8 @@ class CreatePurchaseRateRequest extends FleetbaseRequest
25
26
  public function rules()
26
27
  {
27
28
  return [
28
- 'service_quote' => 'required|exists:service_quotes,public_id',
29
- 'order' => 'nullable|exists:orders,public_id',
29
+ 'service_quote' => ['required', Rule::exists('service_quotes', 'public_id')->whereNull('deleted_at')],
30
+ 'order' => ['nullable', Rule::exists('orders', 'public_id')->whereNull('deleted_at')],
30
31
  'customer' => ['nullable', new ExistsInAny(['vendors', 'contacts'], 'public_id')],
31
32
  ];
32
33
  }