Save user flights
This commit is contained in:
@@ -5,38 +5,17 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Aircraft;
|
||||
use App\Models\Airline;
|
||||
use App\Models\Airport;
|
||||
use App\Models\FlightClass;
|
||||
use App\Models\FlightReason;
|
||||
use App\Models\ImportedFlight;
|
||||
use App\Models\SeatType;
|
||||
use App\Models\UserFlight;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class FlightImportController extends Controller
|
||||
{
|
||||
|
||||
const array FLIGHT_CLASSES = [
|
||||
0 => 'Please Select',
|
||||
1 => 'Economy',
|
||||
2 => 'Business',
|
||||
3 => 'First',
|
||||
4 => 'Premium Economy',
|
||||
5 => 'Private',
|
||||
];
|
||||
|
||||
const array SEAT_TYPES = [
|
||||
0 => 'Please Select',
|
||||
1 => 'Window',
|
||||
2 => 'Middle',
|
||||
3 => 'Aisle',
|
||||
];
|
||||
|
||||
const array FLIGHT_REASONS = [
|
||||
0 => 'Please Select',
|
||||
1 => 'Pleasure',
|
||||
2 => 'Business',
|
||||
3 => 'Crew',
|
||||
4 => 'Other',
|
||||
];
|
||||
|
||||
private function formatTime(?string $time): string
|
||||
{
|
||||
if (!$time) return '00:00';
|
||||
@@ -45,6 +24,15 @@ class FlightImportController extends Controller
|
||||
return str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . $minutes;
|
||||
}
|
||||
|
||||
private function selectOptions($model): array
|
||||
{
|
||||
return $model::orderBy('id')
|
||||
->get(['id', 'name'])
|
||||
->map(fn($item) => ['value' => $item->id, 'title' => $item->name])
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function getPossibleAircraft(string $aircraftQuery) {
|
||||
preg_match('/\((\w+)\)/', $aircraftQuery, $matches);
|
||||
$designator = $matches[1] ?? null;
|
||||
@@ -153,19 +141,10 @@ class FlightImportController extends Controller
|
||||
|
||||
|
||||
return [
|
||||
'flight_classes' => collect(self::FLIGHT_CLASSES)->map(fn($title, $value) => [
|
||||
'value' => $value,
|
||||
'title' => $title,
|
||||
])->values(),
|
||||
'flight_reasons' => collect(self::FLIGHT_REASONS)->map(fn($title, $value) => [
|
||||
'value' => $value,
|
||||
'title' => $title,
|
||||
])->values(),
|
||||
'seat_types' => collect(self::SEAT_TYPES)->map(fn($title, $value) => [
|
||||
'value' => $value,
|
||||
'title' => $title,
|
||||
])->values(),
|
||||
|
||||
'imported_flight_id' => $flightToReconcile->id,
|
||||
'flight_classes' => $this->selectOptions(FlightClass::class),
|
||||
'flight_reasons' => $this->selectOptions(FlightReason::class),
|
||||
'seat_types' => $this->selectOptions(SeatType::class),
|
||||
'flight_number' => $flightToReconcile->flight_number ?? '',
|
||||
'date' => $date ?? '',
|
||||
'dep_time' => $this->formatTime($flightToReconcile->dep_time),
|
||||
@@ -184,32 +163,90 @@ class FlightImportController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
public function save(Request $request){
|
||||
public function save(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'date' => 'required|date',
|
||||
'flight_number' => 'required|string',
|
||||
'from_id' => 'required|integer|exists:airports,id',
|
||||
'to_id' => 'required|integer|exists:airports,id',
|
||||
'dep_time' => 'nullable|date_format:H:i',
|
||||
'arr_time' => 'nullable|date_format:H:i',
|
||||
'duration' => 'required|date_format:H:i',
|
||||
'airline_id' => 'nullable|integer|exists:airlines,id',
|
||||
'aircraft_id' => 'nullable|integer|exists:aircraft,id',
|
||||
'registration' => 'nullable|string',
|
||||
'seat_number' => 'nullable|string',
|
||||
'seat_type_id' => 'nullable|integer',
|
||||
'flight_class_id' => 'nullable|integer',
|
||||
'flight_reason_id' => 'nullable|integer',
|
||||
'note' => 'nullable|string',
|
||||
],[
|
||||
'from_id.required' => 'Please select a departure airport.',
|
||||
'to_id.required' => 'Please select an arrival airport.',
|
||||
'dep_time.date_format' => 'Departure time must be in HH:MM format, i.e: 01:25',
|
||||
'arr_time.date_format' => 'Arrival time must be in HH:MM format, i.e: 12:25',
|
||||
'duration.date_format' => 'Must be in HH:MM format, e.g: 03:37',
|
||||
'duration.required' => 'A duration is required to be able to accurately calculate the arrival date',
|
||||
'date' => 'required|date',
|
||||
'imported_flight_id' => 'required|exists:imported_flights,id',
|
||||
'flight_number' => 'required|string',
|
||||
'from_id' => 'required|integer|exists:airports,id',
|
||||
'to_id' => 'required|integer|exists:airports,id',
|
||||
'dep_time' => 'nullable|date_format:H:i',
|
||||
'arr_time' => 'nullable|date_format:H:i',
|
||||
'duration' => 'required|date_format:H:i',
|
||||
'airline_id' => 'nullable|integer|exists:airlines,id',
|
||||
'aircraft_id' => 'nullable|integer|exists:aircraft,id',
|
||||
'registration' => 'nullable|string',
|
||||
'seat_number' => 'nullable|string',
|
||||
'seat_type_id' => 'nullable|integer|exists:seat_types,id',
|
||||
'flight_class_id' => 'nullable|integer|exists:flight_classes,id',
|
||||
'flight_reason_id' => 'nullable|integer|exists:flight_reasons,id',
|
||||
'note' => 'nullable|string',
|
||||
], [
|
||||
'imported_flight_id.required' => 'The flight you are trying to reconcile needs to be reimported or refreshed.',
|
||||
'from_id.required' => 'Please select a departure airport.',
|
||||
'to_id.required' => 'Please select an arrival airport.',
|
||||
'dep_time.date_format' => 'Departure time must be in HH:MM format, i.e: 01:25',
|
||||
'arr_time.date_format' => 'Arrival time must be in HH:MM format, i.e: 12:25',
|
||||
'duration.date_format' => 'Must be in HH:MM format, e.g: 03:37',
|
||||
'duration.required' => 'A duration is required to be able to accurately calculate the arrival date',
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
$departureAirport = Airport::find($validated['from_id']);
|
||||
$arrivalAirport = Airport::find($validated['to_id']);
|
||||
|
||||
// Parse departure in local airport timezone, then convert to UTC
|
||||
$depTime = $validated['dep_time'] ?? '00:00';
|
||||
$departure = Carbon::createFromFormat(
|
||||
'Y-m-d H:i',
|
||||
$validated['date'] . ' ' . $depTime,
|
||||
$departureAirport->timezone
|
||||
)->utc();
|
||||
|
||||
// Calculate duration-based arrival in UTC
|
||||
[$durationHours, $durationMinutes] = explode(':', $validated['duration']);
|
||||
$durationArrival = $departure->copy()
|
||||
->addHours((int) $durationHours)
|
||||
->addMinutes((int) $durationMinutes);
|
||||
|
||||
// If arrival time provided, parse it in arrival airport timezone and convert to UTC
|
||||
if (!empty($validated['arr_time'])) {
|
||||
$arrival = Carbon::createFromFormat(
|
||||
'Y-m-d H:i',
|
||||
$validated['date'] . ' ' . $validated['arr_time'],
|
||||
$arrivalAirport->timezone
|
||||
)->utc();
|
||||
|
||||
// If arrival is not after departure, fall back to duration-based arrival
|
||||
if ($arrival->lte($departure)) {
|
||||
$arrival = $durationArrival;
|
||||
}
|
||||
} else {
|
||||
$arrival = $durationArrival;
|
||||
}
|
||||
|
||||
UserFlight::create([
|
||||
'user_id' => $user->id,
|
||||
'departure_date' => $departure,
|
||||
'arrival_date' => $arrival,
|
||||
'flight_number' => $validated['flight_number'],
|
||||
'departure_airport_id' => $validated['from_id'],
|
||||
'arrival_airport_id' => $validated['to_id'],
|
||||
'airline_id' => $validated['airline_id'] ?? null,
|
||||
'aircraft_id' => $validated['aircraft_id'] ?? null,
|
||||
'aircraft_registration' => $validated['registration'] ?? null,
|
||||
'seat_number' => $validated['seat_number'] ?? null,
|
||||
'seat_type_id' => $validated['seat_type_id'] ?? null,
|
||||
'flight_class_id' => $validated['flight_class_id'] ?? null,
|
||||
'flight_reason_id' => $validated['flight_reason_id'] ?? null,
|
||||
'note' => $validated['note'] ?? null,
|
||||
]);
|
||||
|
||||
ImportedFlight::destroy($validated['imported_flight_id']);
|
||||
|
||||
return redirect()->route('reconcile');
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user