Added Imported Flights Table
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Airline;
|
||||
use App\Models\ImportedFlight;
|
||||
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';
|
||||
|
||||
[$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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user