'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'; [$hours, $minutes] = explode(':', $time); return str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . $minutes; } public function getPossibleAirlines(string $airlineQuery) { preg_match('/\((\w{2,3})\/(\w{3,4})\)/', $airlineQuery, $matches); $iata = $matches[1] ?? null; $icao = $matches[2] ?? null; $airlines = Airline::when($iata || $icao, function ($query) use ($iata, $icao) { $query->orderByRaw(" CASE WHEN \"IATA_code\" = ? AND \"ICAO_code\" = ? THEN 0 WHEN \"IATA_code\" = ? THEN 1 WHEN \"ICAO_code\" = ? THEN 2 ELSE 3 END ", [$iata, $icao, $iata, $icao]) ->where(function ($q) use ($iata, $icao) { $q->where('IATA_code', $iata) ->orWhere('ICAO_code', $icao); }); }) ->orderByDesc('active') ->limit(10) ->get(['id', 'name', 'IATA_code', 'ICAO_code']) ->map(fn($a) => [ 'value' => $a->id, 'title' => "{$a->name} ({$a->IATA_code}/{$a->ICAO_code})", ]) ->values() ->toArray(); return [ 'airline_options' => $airlines, 'raw_airline' => $airlineQuery, ]; } public function reconcile(Request $request) { $user = Auth::user(); $flightToReconcile = ImportedFlight::where('user_id', $user->id)->orderBy('id')->first(); if (!$flightToReconcile) { return null; } $date = null; if ($flightToReconcile->date) { $date = Carbon::createFromFormat('m-d-y', $flightToReconcile->date)->format('Y-m-d'); } 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(), 'flight_number' => $flightToReconcile->flight_number ?? '', 'date' => $date ?? '', 'dep_time' => $this->formatTime($flightToReconcile->dep_time), 'arr_time' => $this->formatTime($flightToReconcile->arr_time), 'duration' => $this->formatTime($flightToReconcile->duration), 'registration' => $flightToReconcile->registration ?? '', 'note' => $flightToReconcile->note ?? '', 'seat_number' => $flightToReconcile->seat_number ?? '', 'flight_class' => $flightToReconcile->flight_class ?? '', 'seat_type' => $flightToReconcile->seat_type ?? '', 'flight_reason' => $flightToReconcile->flight_reason ?? '', 'airline_options' => $this->getPossibleAirlines($flightToReconcile->airline ?? '')['airline_options'], ]; } public function store(Request $request) { try { $request->validate([ 'csv' => ['required', 'file', 'mimes:csv,txt', 'max:10240'], ]); $path = $request->file('csv')->getRealPath(); $handle = fopen($path, 'r'); fgetcsv($handle); // Read and normalise header row $headers = array_map( fn($h) => strtolower(trim(str_replace(' ', '_', $h))), fgetcsv($handle) ); \Log::debug('CSV headers', $headers); $firstRow = fgetcsv($handle); \Log::debug('First row', $firstRow ?? ['empty']); \Log::debug('Header count: ' . count($headers) . ', Row count: ' . count($firstRow ?? [])); $map = [ 'date' => 'date', 'flight_number' => 'flight_number', 'from' => 'from', 'to' => 'to', 'dep_time' => 'dep_time', 'arr_time' => 'arr_time', 'duration' => 'duration', 'airline' => 'airline', 'aircraft' => 'aircraft', 'registration' => 'registration', 'seat_number' => 'seat_number', 'seat_type' => 'seat_type', 'flight_class' => 'flight_class', 'flight_reason' => 'flight_reason', 'note' => 'note', ]; $userId = Auth::id(); $imported = 0; while (($row = fgetcsv($handle)) !== false) { if (count($row) !== count($headers)) { continue; // skip malformed rows } $raw = array_combine($headers, $row); $data = ['user_id' => $userId]; foreach ($map as $csvKey => $column) { $data[$column] = $raw[$csvKey] ?? null; } ImportedFlight::create($data); $imported++; } fclose($handle); return response()->json(['imported' => $imported]); } catch (\Exception $e) { return response()->json(['message' => $e->getMessage()], 500); } } }