feat: implement trip handover logic and tests

This commit is contained in:
ramram1515
2026-07-03 15:54:26 +08:00
parent 24665a9594
commit 8e93b889ee
4 changed files with 308 additions and 15 deletions

View File

@@ -132,15 +132,19 @@ class AdminTripController extends ApiController
$executor = app(TripExecutor::class);
$childTrip = $executor->createContinuation(
originalTrip: $trip,
admin: $request->user(),
newTeamId: (int) $data['new_team_id'],
newTruckId: isset($data['new_truck_id']) ? (int) $data['new_truck_id'] : null,
endReason: $data['end_reason'],
);
return $this->created(new TripResource($childTrip), 'Continuation trip created');
try {
$childTrip = $executor->createContinuation(
originalTrip: $trip,
admin: $request->user(),
newTeamId: (int) $data['new_team_id'],
newTruckId: isset($data['new_truck_id']) ? (int) $data['new_truck_id'] : null,
endReason: $data['end_reason'],
);
return $this->created(new TripResource($childTrip), 'Continuation trip created');
} catch (\Exception $e) {
return $this->fail('Hand off failed: ' . $e->getMessage(), null, 422);
}
}
public function update(StoreTripRequest $request, Trip $trip): JsonResponse
@@ -159,11 +163,21 @@ class AdminTripController extends ApiController
->where('team_id', $data['team_id'])
->whereDate('scheduled_date', $data['scheduled_date'])
->where('id', '!=', $trip->id)
->whereNotIn('status', [Trip::STATUS_CANCELLED])
->whereNotIn('status', [Trip::STATUS_CANCELLED, Trip::STATUS_COMPLETED, Trip::STATUS_HANDED_OFF])
->first();
if ($teamConflict) {
$conflicts[] = "Team is already scheduled on {$data['scheduled_date']} (trip {$teamConflict->trip_number})";
}
$completedTrip = Trip::query()
->where('team_id', $data['team_id'])
->whereDate('scheduled_date', $data['scheduled_date'])
->where('id', '!=', $trip->id)
->where('status', Trip::STATUS_COMPLETED)
->first();
if ($completedTrip) {
$conflicts[] = "Team is already done with their route for today (trip {$completedTrip->trip_number})";
}
if (! empty($conflicts)) {
return $this->fail('Trip has scheduling conflicts', ['conflicts' => $conflicts], 422);
}
@@ -212,17 +226,26 @@ class AdminTripController extends ApiController
$teamConflict = Trip::query()
->where('team_id', $teamId)
->whereDate('scheduled_date', $scheduledDate)
->whereNotIn('status', [Trip::STATUS_CANCELLED])
->whereNotIn('status', [Trip::STATUS_CANCELLED, Trip::STATUS_COMPLETED, Trip::STATUS_HANDED_OFF])
->first();
if ($teamConflict) {
$conflicts[] = "Team is already scheduled on {$scheduledDate} (trip {$teamConflict->trip_number})";
}
$completedTrip = Trip::query()
->where('team_id', $teamId)
->whereDate('scheduled_date', $scheduledDate)
->where('status', Trip::STATUS_COMPLETED)
->first();
if ($completedTrip) {
$conflicts[] = "Team is already done with their route for today (trip {$completedTrip->trip_number})";
}
if ($truckId) {
$truckConflict = Trip::query()
->where('truck_id', $truckId)
->whereDate('scheduled_date', $scheduledDate)
->whereNotIn('status', [Trip::STATUS_CANCELLED])
->whereNotIn('status', [Trip::STATUS_CANCELLED, Trip::STATUS_COMPLETED, Trip::STATUS_HANDED_OFF])
->first();
if ($truckConflict) {
$conflicts[] = "Truck is already on a trip on {$scheduledDate} ({$truckConflict->trip_number})";