@fleetbase/fleetops-engine 0.6.16 → 0.6.18

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 (49) hide show
  1. package/addon/components/layout/fleet-ops-sidebar.hbs +25 -0
  2. package/addon/templates/virtual.hbs +3 -3
  3. package/composer.json +3 -2
  4. package/extension.json +1 -1
  5. package/package.json +1 -1
  6. package/server/migrations/2025_08_11_170800_add_company_index_to_routes_table.php +21 -0
  7. package/server/migrations/2025_08_28_054920_create_warranties_table.php +56 -0
  8. package/server/migrations/2025_08_28_054921_create_telematics_table.php +60 -0
  9. package/server/migrations/2025_08_28_054922_create_assets_table.php +94 -0
  10. package/server/migrations/2025_08_28_054925_create_devices_table.php +190 -0
  11. package/server/migrations/2025_08_28_054926_create_device_events_table.php +99 -0
  12. package/server/migrations/2025_08_28_054926_create_sensors_table.php +62 -0
  13. package/server/migrations/2025_08_28_054927_create_parts_table.php +73 -0
  14. package/server/migrations/2025_08_28_054929_create_equipments_table.php +58 -0
  15. package/server/migrations/2025_08_28_054930_create_work_orders_table.php +85 -0
  16. package/server/migrations/2025_08_28_054931_create_maintenances_table.php +79 -0
  17. package/server/migrations/2025_08_28_082002_update_vehicles_table_telematics.php +60 -0
  18. package/server/src/Http/Controllers/Api/v1/OrderController.php +19 -1
  19. package/server/src/Http/Controllers/Internal/v1/OrderController.php +31 -8
  20. package/server/src/Http/Resources/v1/Order.php +111 -60
  21. package/server/src/Models/Asset.php +548 -0
  22. package/server/src/Models/Contact.php +2 -0
  23. package/server/src/Models/Device.php +435 -0
  24. package/server/src/Models/DeviceEvent.php +501 -0
  25. package/server/src/Models/Driver.php +2 -0
  26. package/server/src/Models/Entity.php +27 -50
  27. package/server/src/Models/Equipment.php +483 -0
  28. package/server/src/Models/Fleet.php +2 -0
  29. package/server/src/Models/FuelReport.php +2 -0
  30. package/server/src/Models/Issue.php +2 -0
  31. package/server/src/Models/Maintenance.php +549 -0
  32. package/server/src/Models/Order.php +32 -112
  33. package/server/src/Models/OrderConfig.php +8 -0
  34. package/server/src/Models/Part.php +502 -0
  35. package/server/src/Models/Payload.php +101 -20
  36. package/server/src/Models/Place.php +10 -4
  37. package/server/src/Models/Sensor.php +510 -0
  38. package/server/src/Models/ServiceArea.php +1 -1
  39. package/server/src/Models/Telematic.php +336 -0
  40. package/server/src/Models/Vehicle.php +45 -1
  41. package/server/src/Models/VehicleDevice.php +1 -1
  42. package/server/src/Models/Vendor.php +2 -0
  43. package/server/src/Models/Warranty.php +413 -0
  44. package/server/src/Models/Waypoint.php +2 -0
  45. package/server/src/Models/WorkOrder.php +532 -0
  46. package/server/src/Support/Utils.php +5 -0
  47. package/server/src/Traits/HasTrackingNumber.php +64 -10
  48. package/server/src/Traits/Maintainable.php +307 -0
  49. package/server/src/Traits/PayloadAccessors.php +126 -0
@@ -0,0 +1,62 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('sensors', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
18
+
19
+ $table->string('name')->nullable()->index();
20
+ $table->string('slug')->nullable()->index();
21
+ $table->string('sensor_type')->index(); // temp, humidity, door, fuel, pressure, vibration, cargo-weight, etc.
22
+ $table->string('unit')->nullable(); // C, F, %, psi, kg, etc.
23
+ $table->float('min_threshold')->nullable();
24
+ $table->float('max_threshold')->nullable();
25
+ $table->boolean('threshold_inclusive')->default(true);
26
+ $table->string('type')->nullable()->index();
27
+
28
+ $table->timestamp('last_reading_at')->nullable()->index();
29
+ $table->string('last_value')->nullable(); // use string to store raw value
30
+ $table->json('calibration')->nullable(); // { offset, slope, notes }
31
+ $table->unsignedInteger('report_frequency_sec')->nullable();
32
+
33
+ // A sensor can belong to a device, asset, or any other entity
34
+ $table->string('sensorable_type')->nullable();
35
+ $table->uuid('sensorable_uuid')->nullable();
36
+ $table->index(['sensorable_type', 'sensorable_uuid']);
37
+
38
+ // Optionally coupled to a device (if it streams via a device)
39
+ $table->foreignUuid('device_uuid')->nullable()->constrained('devices', 'uuid')->nullOnDelete();
40
+ $table->foreignUuid('warranty_uuid')->nullable()->constrained('warranties', 'uuid')->nullOnDelete();
41
+
42
+ $table->json('meta')->nullable();
43
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
44
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
45
+
46
+ $table->softDeletes();
47
+ $table->timestamps();
48
+
49
+ $table->index(['company_uuid', 'sensor_type']);
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Reverse the migrations.
55
+ */
56
+ public function down(): void
57
+ {
58
+ Schema::disableForeignKeyConstraints();
59
+ Schema::dropIfExists('sensors');
60
+ Schema::enableForeignKeyConstraints();
61
+ }
62
+ };
@@ -0,0 +1,73 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('parts', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
18
+ $table->foreignUuid('category_uuid')->nullable()->constrained('categories', 'uuid')->nullOnDelete();
19
+
20
+ $table->string('sku')->nullable()->index();
21
+ $table->string('name')->index();
22
+ $table->string('manufacturer')->nullable()->index();
23
+ $table->string('model')->nullable();
24
+ $table->string('serial_number')->nullable()->index();
25
+ $table->string('barcode')->nullable()->index();
26
+ $table->string('type')->nullable()->index();
27
+ $table->string('slug')->nullable()->index();
28
+
29
+ $table->text('description')->nullable();
30
+ $table->foreignUuid('vendor_uuid')->nullable()->constrained('vendors', 'uuid')->nullOnDelete();
31
+
32
+ $table->integer('quantity_on_hand')->default(0);
33
+ $table->decimal('unit_cost', 12, 2)->nullable();
34
+ $table->decimal('msrp', 12, 2)->nullable();
35
+ $table->integer('reorder_point')->default(5);
36
+ $table->integer('reorder_quantity')->default(10);
37
+ $table->integer('max_stock_level')->nullable();
38
+ $table->integer('reserved_quantity')->default(0);
39
+
40
+ $table->integer('allocated_quantity')->default(0); // -- Allocated but not used
41
+ $table->string('inventory_method')->default('fifo'); // -- fifo, lifo, weighted_average
42
+
43
+ // Optional default target (e.g., a part kept for a specific asset or vehicle)
44
+ $table->string('asset_type')->nullable();
45
+ $table->uuid('asset_uuid')->nullable();
46
+ $table->index(['asset_type', 'asset_uuid']);
47
+
48
+ $table->foreignUuid('warranty_uuid')->nullable()->constrained('warranties', 'uuid')->nullOnDelete();
49
+
50
+ $table->json('specs')->nullable();
51
+ $table->json('meta')->nullable();
52
+
53
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
54
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
55
+
56
+ $table->timestamp('last_ordered_at')->nullable();
57
+ $table->softDeletes();
58
+ $table->timestamps();
59
+
60
+ $table->unique(['company_uuid', 'sku']);
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Reverse the migrations.
66
+ */
67
+ public function down(): void
68
+ {
69
+ Schema::disableForeignKeyConstraints();
70
+ Schema::dropIfExists('parts');
71
+ Schema::enableForeignKeyConstraints();
72
+ }
73
+ };
@@ -0,0 +1,58 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('equipments', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
18
+ $table->foreignUuid('category_uuid')->nullable()->constrained('categories', 'uuid')->nullOnDelete();
19
+
20
+ $table->string('name')->index();
21
+ $table->string('code')->nullable()->index();
22
+ $table->string('type')->nullable()->index(); // ppe, tool, accessory, fridge unit, etc.
23
+ $table->string('status')->default('active')->index();
24
+ $table->string('slug')->nullable()->index();
25
+ $table->string('serial_number')->nullable()->index();
26
+ $table->string('manufacturer')->nullable();
27
+ $table->string('model')->nullable();
28
+
29
+ // Can be assigned to an asset, device, driver, or facility
30
+ $table->string('equipable_type')->nullable();
31
+ $table->uuid('equipable_uuid')->nullable();
32
+ $table->index(['equipable_type', 'equipable_uuid']);
33
+
34
+ $table->date('purchased_at')->nullable();
35
+ $table->integer('purchase_price')->nullable();
36
+ $table->string('currency')->nullable();
37
+
38
+ $table->foreignUuid('warranty_uuid')->nullable()->constrained('warranties', 'uuid')->nullOnDelete();
39
+
40
+ $table->json('meta')->nullable();
41
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
42
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
43
+
44
+ $table->softDeletes();
45
+ $table->timestamps();
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Reverse the migrations.
51
+ */
52
+ public function down(): void
53
+ {
54
+ Schema::disableForeignKeyConstraints();
55
+ Schema::dropIfExists('equipments');
56
+ Schema::enableForeignKeyConstraints();
57
+ }
58
+ };
@@ -0,0 +1,85 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('work_orders', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
18
+ $table->foreignUuid('category_uuid')->nullable()->constrained('categories', 'uuid')->nullOnDelete();
19
+
20
+ $table->string('code')->nullable()->index(); // external WO number
21
+ $table->string('subject')->index();
22
+ $table->string('status')->default('open')->index(); // open, in_progress, blocked, done, canceled
23
+ $table->string('priority')->nullable()->index(); // low, normal, high, critical
24
+
25
+ // What the WO is for asset, equipment, device, place, etc.
26
+ $table->string('target_type')->nullable();
27
+ $table->uuid('target_uuid')->nullable();
28
+ $table->index(['target_type', 'target_uuid']);
29
+
30
+ // Who it's assigned to (contact/technician/team/user/vendor)
31
+ $table->string('assignee_type')->nullable();
32
+ $table->uuid('assignee_uuid')->nullable();
33
+ $table->index(['assignee_type', 'assignee_uuid']);
34
+
35
+ $table->timestamp('opened_at')->nullable()->index();
36
+ $table->timestamp('due_at')->nullable()->index();
37
+ $table->timestamp('closed_at')->nullable()->index();
38
+
39
+ // -- Resource Planning
40
+ $table->json('required_skills')->nullable(); // -- Skills needed for work
41
+ $table->json('required_certifications')->nullable(); // -- Certs needed
42
+ $table->integer('estimated_duration_hours')->nullable();
43
+ $table->integer('actual_duration_hours')->nullable();
44
+ $table->json('resource_requirements')->nullable(); // -- Tools, parts, etc.
45
+
46
+ // -- Scheduling & Dependencies
47
+ $table->timestamp('earliest_start_date')->nullable();
48
+ $table->timestamp('latest_completion_date')->nullable();
49
+ $table->string('scheduling_priority')->default('normal'); // -- low, normal, high, urgent
50
+ $table->boolean('can_be_split')->default(false); // -- Can work be divided
51
+
52
+ // -- Cost Management
53
+ $table->integer('estimated_cost')->nullable();
54
+ $table->integer('approved_budget')->nullable();
55
+ $table->integer('actual_cost')->nullable();
56
+ $table->string('currency')->nullable();
57
+ $table->json('cost_breakdown')->nullable(); // -- Labor, parts, overhead
58
+ $table->string('cost_center')->nullable()->index();
59
+ $table->string('budget_code')->nullable()->index();
60
+
61
+ $table->text('instructions')->nullable();
62
+ $table->text('completion_notes')->nullable();
63
+ $table->json('checklist')->nullable(); // [{title, required, done_at}, ...]
64
+ $table->json('meta')->nullable();
65
+
66
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
67
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
68
+
69
+ $table->softDeletes();
70
+ $table->timestamps();
71
+
72
+ $table->index(['company_uuid', 'status', 'priority']);
73
+ });
74
+ }
75
+
76
+ /**
77
+ * Reverse the migrations.
78
+ */
79
+ public function down(): void
80
+ {
81
+ Schema::disableForeignKeyConstraints();
82
+ Schema::dropIfExists('work_orders');
83
+ Schema::enableForeignKeyConstraints();
84
+ }
85
+ };
@@ -0,0 +1,79 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::create('maintenances', function (Blueprint $table) {
14
+ $table->increments('id');
15
+ $table->uuid('uuid')->index();
16
+ $table->string('_key')->nullable()->index();
17
+ $table->foreignUuid('company_uuid')->constrained('companies', 'uuid')->cascadeOnDelete();
18
+ $table->foreignUuid('category_uuid')->nullable()->constrained('categories', 'uuid')->nullOnDelete();
19
+
20
+ // Target of maintenance (usually an asset; could be equipment)
21
+ $table->string('maintainable_type')->nullable();
22
+ $table->uuid('maintainable_uuid')->nullable();
23
+ $table->index(['maintainable_type', 'maintainable_uuid']);
24
+
25
+ $table->foreignUuid('work_order_uuid')->nullable()->constrained('work_orders', 'uuid')->nullOnDelete();
26
+
27
+ $table->string('type')->nullable()->index(); // scheduled, unscheduled, inspection, corrective
28
+ $table->string('status')->default('open')->index(); // open, in_progress, done, canceled
29
+ $table->string('priority')->nullable()->index(); // low, normal, high, critical
30
+
31
+ $table->timestamp('scheduled_at')->nullable()->index();
32
+ $table->timestamp('started_at')->nullable()->index();
33
+ $table->timestamp('completed_at')->nullable()->index();
34
+
35
+ $table->unsignedBigInteger('odometer')->nullable();
36
+ $table->unsignedBigInteger('engine_hours')->nullable();
37
+
38
+ // Downtime
39
+ $table->integer('estimated_downtime_hours')->nullable();
40
+ $table->timestamp('downtime_start')->nullable();
41
+ $table->timestamp('downtime_end')->nullable();
42
+
43
+ // Vendor or internal performer
44
+ $table->string('performed_by_type')->nullable();
45
+ $table->uuid('performed_by_uuid')->nullable();
46
+ $table->index(['performed_by_type', 'performed_by_uuid']);
47
+
48
+ $table->text('summary')->nullable();
49
+ $table->text('notes')->nullable();
50
+ $table->json('line_items')->nullable(); // [{part_uuid, qty, unit_cost}, ...]
51
+ $table->integer('labor_cost')->nullable();
52
+ $table->integer('parts_cost')->nullable();
53
+ $table->integer('tax')->nullable();
54
+ $table->integer('total_cost')->nullable();
55
+ $table->string('currency')->nullable();
56
+
57
+ $table->json('attachments')->nullable();
58
+ $table->json('meta')->nullable();
59
+
60
+ $table->foreignUuid('created_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
61
+ $table->foreignUuid('updated_by_uuid')->nullable()->constrained('users', 'uuid')->nullOnDelete();
62
+
63
+ $table->softDeletes();
64
+ $table->timestamps();
65
+
66
+ $table->index(['company_uuid', 'status', 'type']);
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Reverse the migrations.
72
+ */
73
+ public function down(): void
74
+ {
75
+ Schema::disableForeignKeyConstraints();
76
+ Schema::dropIfExists('maintenances');
77
+ Schema::enableForeignKeyConstraints();
78
+ }
79
+ };
@@ -0,0 +1,60 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ return new class extends Migration {
8
+ /**
9
+ * Run the migrations.
10
+ */
11
+ public function up(): void
12
+ {
13
+ Schema::table('vehicles', function (Blueprint $table) {
14
+ $table->foreignUuid('telematic_uuid')->after('company_uuid')->nullable()->constrained('telematics', 'uuid')->nullOnDelete();
15
+ $table->foreignUuid('warranty_uuid')->after('telematic_uuid')->nullable()->constrained('warranties', 'uuid')->nullOnDelete();
16
+ $table->foreignUuid('category_uuid')->after('telematic_uuid')->nullable()->constrained('categories', 'uuid')->nullOnDelete();
17
+
18
+ // Identification
19
+ $table->string('serial_number')->nullable()->after('plate_number');
20
+ $table->string('call_sign')->nullable()->after('plate_number');
21
+
22
+ // Financial Tracking
23
+ $table->integer('acquisition_cost')->nullable()->after('vin_data');
24
+ $table->integer('current_value')->nullable()->after('vin_data');
25
+ $table->integer('depreciation_rate')->nullable()->after('vin_data'); // -- Annual percentage
26
+ $table->integer('insurance_value')->nullable()->after('vin_data');
27
+ $table->string('currency')->nullable()->after('vin_data');
28
+ $table->string('financing_status')->nullable()->index()->after('vin_data'); // -- owned, leased, financed
29
+ $table->timestamp('lease_expires_at')->nullable()->index()->after('slug');
30
+ $table->timestamp('purchased_at')->nullable()->index()->after('slug');
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Reverse the migrations.
36
+ */
37
+ public function down(): void
38
+ {
39
+ Schema::disableForeignKeyConstraints();
40
+ Schema::table('vehicles', function (Blueprint $table) {
41
+ $table->dropForeign(['telematic_uuid']);
42
+ $table->dropForeign(['warranty_uuid']);
43
+ $table->dropForeign(['category_uuid']);
44
+ $table->dropColumn('telematic_uuid');
45
+ $table->dropColumn('warranty_uuid');
46
+ $table->dropColumn('category_uuid');
47
+ $table->dropColumn('serial_number');
48
+ $table->dropColumn('call_sign');
49
+ $table->dropColumn('acquisition_cost');
50
+ $table->dropColumn('current_value');
51
+ $table->dropColumn('depreciation_rate');
52
+ $table->dropColumn('insurance_value');
53
+ $table->dropColumn('currency');
54
+ $table->dropColumn('financing_status');
55
+ $table->dropColumn('lease_expires_at');
56
+ $table->dropColumn('purchased_at');
57
+ });
58
+ Schema::enableForeignKeyConstraints();
59
+ }
60
+ };
@@ -30,11 +30,13 @@ use Fleetbase\Models\Company;
30
30
  use Fleetbase\Models\File;
31
31
  use Fleetbase\Models\Setting;
32
32
  use Fleetbase\Support\Auth;
33
+ use Fleetbase\Support\TemplateString;
33
34
  use Illuminate\Database\Eloquent\ModelNotFoundException;
34
35
  use Illuminate\Http\Request;
35
36
  use Illuminate\Http\UploadedFile;
36
37
  use Illuminate\Support\Arr;
37
38
  use Illuminate\Support\Carbon;
39
+ use Illuminate\Support\Facades\Log;
38
40
  use Illuminate\Support\Facades\Storage;
39
41
  use Illuminate\Support\Str;
40
42
  use Illuminate\Validation\ValidationException;
@@ -461,6 +463,14 @@ class OrderController extends Controller
461
463
  ]);
462
464
  }
463
465
 
466
+ // vehicle assignment
467
+ if ($request->has('vehicle')) {
468
+ $input['vehicle_assigned_uuid'] = Utils::getUuid('vehicles', [
469
+ 'public_id' => $request->input('vehicle'),
470
+ 'company_uuid' => session('company'),
471
+ ]);
472
+ }
473
+
464
474
  // facilitator assignment
465
475
  if ($request->has('facilitator')) {
466
476
  $facilitator = Utils::getUuid(
@@ -901,7 +911,11 @@ class OrderController extends Controller
901
911
  $order->save();
902
912
 
903
913
  // trigger start event
904
- event(new OrderStarted($order));
914
+ try {
915
+ event(new OrderStarted($order));
916
+ } catch (\Exception $e) {
917
+ Log::debug('Unable to complete order started event', ['error' => $e->getMessage(), 'order' => $order]);
918
+ }
905
919
 
906
920
  // set order as drivers current order
907
921
  $driver->current_job_uuid = $order->uuid;
@@ -1091,6 +1105,10 @@ class OrderController extends Controller
1091
1105
  $activity->set('pod_method', $order->pod_method);
1092
1106
  }
1093
1107
 
1108
+ // resolved status and details
1109
+ $activity->set('_resolved_status', TemplateString::resolve($activity->get('status', ''), $order));
1110
+ $activity->set('_resolved_details', TemplateString::resolve($activity->get('details', ''), $order));
1111
+
1094
1112
  return $activity;
1095
1113
  });
1096
1114
 
@@ -32,6 +32,7 @@ use Fleetbase\Http\Requests\Internal\BulkDeleteRequest;
32
32
  use Fleetbase\Models\CustomFieldValue;
33
33
  use Fleetbase\Models\File;
34
34
  use Fleetbase\Models\Type;
35
+ use Fleetbase\Support\TemplateString;
35
36
  use Illuminate\Database\Eloquent\ModelNotFoundException;
36
37
  use Illuminate\Http\Request;
37
38
  use Illuminate\Support\Facades\DB;
@@ -722,20 +723,42 @@ class OrderController extends FleetOpsController
722
723
  *
723
724
  * @return \Illuminate\Http\Response
724
725
  */
725
- public function nextActivity(string $id)
726
+ public function nextActivity(string $id, Request $request)
726
727
  {
727
- $order = Order::withoutGlobalScopes()
728
- ->where('uuid', $id)
729
- ->orWhere('public_id', $id)
730
- ->first();
728
+ $waypointId = $request->input('waypoint');
731
729
 
732
- if (!$order) {
730
+ try {
731
+ $order = Order::findRecordOrFail($id, ['payload']);
732
+ } catch (ModelNotFoundException $exception) {
733
733
  return response()->error('No order found.');
734
734
  }
735
735
 
736
- $nextActivities = $order->config()->nextActivity();
736
+ // Get waypoint record if available
737
+ $waypoint = null;
738
+ if ($waypointId) {
739
+ $waypoint = Waypoint::where('payload_uuid', $order->payload_uuid)->whereHas('place', function ($query) use ($waypointId) {
740
+ $query->where('public_id', $waypointId);
741
+ })->first();
742
+ }
743
+
744
+ $activities = $order->config()->nextActivity($waypoint);
745
+
746
+ // If activity is to complete order add proof of delivery properties if required
747
+ // This is a temporary fix until activity is updated to handle POD on it's own
748
+ $activities = $activities->map(function ($activity) use ($order) {
749
+ if ($activity->completesOrder() && $order->pod_required) {
750
+ $activity->set('require_pod', true);
751
+ $activity->set('pod_method', $order->pod_method);
752
+ }
753
+
754
+ // resolved status and details
755
+ $activity->set('_resolved_status', TemplateString::resolve($activity->get('status', ''), $order));
756
+ $activity->set('_resolved_details', TemplateString::resolve($activity->get('details', ''), $order));
757
+
758
+ return $activity;
759
+ });
737
760
 
738
- return response()->json($nextActivities);
761
+ return response()->json($activities);
739
762
  }
740
763
 
741
764
  /**