Schema, model, Filament, cron, and visibility-semantics foundations required by the RouteForge change. Four phases delivered as one coherent change. Verified against four spec files (flight-bundles, flight-time-storage, subfleet-capability, flight-visibility). Phase 1.1 \xe2\x80\x94 Flight time columns - flights.departure_time, flights.arrival_time TIME NULL - Flight model accessors (Hi-format) + mutators (FlightTimeParser) - FlightTimeParser supports 9 formats + Z/L/tz suffix stripping - Migration backfills inline via chunked raw DB::table->update() - Legacy dpt_time/arr_time VARCHAR columns preserved for one release Phase 1.2 \xe2\x80\x94 Subfleet capability columns - subfleets.cruise_speed, max_range_nm, route_types (CSV VARCHAR(64)) - FlightTypesCast splits/sorts/dedupes/logs-on-invalid - routeforge defaults in config/phpvms.php - SubfleetForm Operational Capability section Phase 1.3 \xe2\x80\x94 Flight Bundles - flight_bundles table + flights.bundle_id NOT NULL FK - Default bundle seeded inline; existing flights backfilled - FlightBundle model + factory + BundleObserver (queued recompute) - FlightBundleResource as sole Flights nav entry (slug=flights, icon=OutlinedMap, sort=2) - Nested FlightResource under FlightBundleResource (slug=flight, parentResource, create+edit only, no nav entry) - FlightsRelationManager with relatedResource for full-page row actions - FlightForm: bundle selector removed (route-bound), date inputs hidden when parent bundle owns dates, XSS-safe placeholder link - Date columns stored as TIMESTAMP UTC, UI converts to local tz - Soft-deleting a bundle leaves children non-deleted; visibility recompute sets visible=false (no cascade delete) - Spatie Shield permissions: flight_bundle.* seeded Phase 1.4 \xe2\x80\x94 Visibility semantics - flights.active renamed to flights.enabled (admin source of truth) - flights.visible is cron-managed combined state - SetActiveFlights cron deleted; SetVisibleFlights cron added - Two-pass bulk SQL UPDATE scoped by bundle, chunks of 500 - RecomputeBundleVisibility queued job dispatched on bundle save/restore - Flight::scopeVisible added; scopeActive retained as plain alias - Pilot-facing read sites use ->visible() (AirportController fix) - FlightResource JSON + FlightExporter CSV expose both enabled+active - Four-state status badge (Disabled / Disabled by Bundle / Enabled Out of Window / Enabled & In Window) replaces Visible toggle - 5 visibility indexes added Verification - 469 Pest tests passed (2058 assertions) - phpstan level 5 clean (646 files) - pint --test clean - rector --dry-run clean - All four spec files PASS (28 requirements + 36 scenarios verified by kimi-spec-reviewer) Migration path documented in docs/UPGRADING.md and openspec/changes/ schema-modernization-for-routeforge/.
76 lines
2.1 KiB
PHP
76 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\LegacyImporter;
|
|
|
|
use App\Models\Flight;
|
|
use Exception;
|
|
|
|
class FlightImporter extends BaseImporter
|
|
{
|
|
protected $table = 'schedules';
|
|
|
|
public function run($start = 0): void
|
|
{
|
|
$this->comment('--- FLIGHT SCHEDULE IMPORT ---');
|
|
|
|
$fields = [
|
|
'id',
|
|
'code',
|
|
'flightnum',
|
|
'depicao',
|
|
'arricao',
|
|
'route',
|
|
'distance',
|
|
'flightlevel',
|
|
'deptime',
|
|
'arrtime',
|
|
'flighttime',
|
|
'notes',
|
|
'enabled',
|
|
];
|
|
|
|
$count = 0;
|
|
$rows = $this->db->readRows($this->table, $this->idField, $start, $fields);
|
|
foreach ($rows as $row) {
|
|
$airline_id = $this->idMapper->getMapping('airlines', $row->code);
|
|
|
|
$flight_num = trim((string) $row->flightnum);
|
|
|
|
$attrs = [
|
|
'dpt_airport_id' => $row->depicao,
|
|
'arr_airport_id' => $row->arricao,
|
|
'route' => $row->route ?: '',
|
|
'distance' => round($row->distance ?: 0, 2),
|
|
'level' => $row->flightlevel ?: 0,
|
|
'dpt_time' => $row->deptime ?: '',
|
|
'arr_time' => $row->arrtime ?: '',
|
|
'flight_time' => $this->convertDuration($row->flighttime) ?: '',
|
|
'notes' => $row->notes ?: '',
|
|
'enabled' => $row->enabled ?: true,
|
|
];
|
|
|
|
try {
|
|
$w = ['airline_id' => $airline_id, 'flight_number' => $flight_num];
|
|
// $flight = Flight::updateOrCreate($w, $attrs);
|
|
$flight = Flight::create(array_merge($w, $attrs));
|
|
} catch (Exception $e) {
|
|
$this->error($e->getMessage());
|
|
|
|
continue;
|
|
}
|
|
|
|
$this->idMapper->addMapping('flights', $row->id, $flight->id);
|
|
|
|
// TODO: deserialize route_details into ACARS table
|
|
|
|
if ($flight->wasRecentlyCreated) {
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
$this->info('Imported '.$count.' flights');
|
|
}
|
|
}
|