validate([ 'status' => ['nullable', 'in:scheduled,in_progress,at_dumpsite,completed,cancelled'], 'date' => ['nullable', 'date'], 'team_id' => ['nullable', 'integer'], 'per_page' => ['nullable', 'integer', 'min:1', 'max:100'], ]); $perPage = (int) $request->input('per_page', 25); $trips = Trip::query() ->with(['route', 'team', 'truck', 'dumpsite']) ->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status'))) ->when($request->filled('date'), fn ($q) => $q->whereDate('scheduled_date', $request->string('date'))) ->when($request->filled('team_id'), fn ($q) => $q->where('team_id', $request->integer('team_id'))) ->orderByDesc('scheduled_date') ->orderBy('scheduled_start_time') ->paginate($perPage); return $this->ok( TripResource::collection($trips), null, [ 'page' => $trips->currentPage(), 'per_page' => $trips->perPage(), 'total' => $trips->total(), 'last_page' => $trips->lastPage(), ], ); } public function store(StoreTripRequest $request): JsonResponse { $data = $request->validated(); $route = Route::with('stops.dropOffPoint')->findOrFail($data['route_id']); $data['dumpsite_id'] = $data['dumpsite_id'] ?? $route->default_dumpsite_id; $data['truck_id'] = $data['truck_id'] ?? null; $data['created_by_admin_id'] = $request->user()->id; $trip = DB::transaction(function () use ($data, $route) { $trip = Trip::create($data); foreach ($route->stops as $rs) { TripStop::create([ 'trip_id' => $trip->id, 'drop_off_point_id' => $rs->drop_off_point_id, 'sequence' => $rs->sequence, 'status' => TripStop::STATUS_PENDING, ]); } return $trip; }); return $this->created( new TripResource( $trip->fresh()->load(['route', 'team', 'truck', 'dumpsite', 'stops.dropOffPoint']), ), 'Trip scheduled', ); } public function show(Trip $trip): JsonResponse { $trip->load([ 'route', 'team.driver', 'team.scanner', 'truck', 'dumpsite', 'stops.dropOffPoint', 'timelineEvents.recordedBy', ]); return $this->ok(new TripResource($trip)); } public function cancel(Request $request, Trip $trip): JsonResponse { if (in_array($trip->status, [Trip::STATUS_COMPLETED, Trip::STATUS_CANCELLED], true)) { return $this->fail('Trip is already finished', null, 422); } $trip->forceFill(['status' => Trip::STATUS_CANCELLED])->save(); return $this->ok(new TripResource($trip->fresh()->load(['route', 'team'])), 'Trip cancelled'); } }