Cleanup Exporter; use firstOrCreate for any missing data we can infer/setup defaults for

This commit is contained in:
Nabeel Shahzad
2018-03-22 12:43:58 -05:00
parent 9657e8bd40
commit fbfd71adcf
11 changed files with 58 additions and 49 deletions

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Services\ImportExport;
use App\Interfaces\ImportExport;
use App\Models\Aircraft;
use App\Models\Enums\AircraftState;
use App\Models\Enums\AircraftStatus;
use App\Models\Subfleet;
use App\Support\ICAO;
/**
* Import aircraft
* @package App\Services\Import
*/
class AircraftImporter extends ImportExport
{
public $assetType = 'aircraft';
/**
* All of the columns that are in the CSV import
* Should match the database fields, for the most part
*/
public static $columns = [
'subfleet',
'name',
'registration',
'hex_code',
'status',
];
/**
* Find the subfleet specified, or just create it on the fly
* @param $type
* @return Subfleet|\Illuminate\Database\Eloquent\Model|null|object|static
*/
protected function getSubfleet($type)
{
$subfleet = Subfleet::firstOrCreate([
'type' => $type,
], ['name' => $type]);
return $subfleet;
}
/**
* Import a flight, parse out the different rows
* @param array $row
* @param int $index
* @return bool
*/
public function import(array $row, $index): bool
{
$subfleet = $this->getSubfleet($row['subfleet']);
$row['subfleet_id'] = $subfleet->id;
# Generate a hex code
if(!$row['hex_code']) {
$row['hex_code'] = ICAO::createHexCode();
}
# Set a default status
if($row['status'] === null) {
$row['status'] = AircraftStatus::ACTIVE;
}
# Just set its state right now as parked
$row['state'] = AircraftState::PARKED;
# Try to add or update
$aircraft = Aircraft::firstOrNew([
'registration' => $row['registration'],
], $row);
try {
$aircraft->save();
} catch(\Exception $e) {
$this->status = 'Error in row '.$index.': '.$e->getMessage();
return false;
}
$this->status = 'Imported '.$row['registration'].' '.$row['name'];
return true;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Services\ImportExport;
use App\Interfaces\ImportExport;
use App\Models\Airport;
/**
* Import airports
* @package App\Services\Import
*/
class AirportImporter extends ImportExport
{
public $assetType = 'airport';
/**
* All of the columns that are in the CSV import
* Should match the database fields, for the most part
*/
public static $columns = [
'iata',
'icao',
'name',
'location',
'country',
'timezone',
'hub',
'lat',
'lon',
];
/**
* Import a flight, parse out the different rows
* @param array $row
* @param int $index
* @return bool
*/
public function import(array $row, $index): bool
{
$row['id'] = $row['icao'];
$row['hub'] = get_truth_state($row['hub']);
$airport = Airport::firstOrNew([
'id' => $row['icao']
], $row);
try {
$airport->save();
} catch(\Exception $e) {
$this->status = 'Error in row '.$index.': '.$e->getMessage();
return false;
}
$this->status = 'Imported ' . $row['icao'];
return true;
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace App\Services\ImportExport;
use App\Interfaces\ImportExport;
use App\Models\Flight;
/**
* The flight importer can be imported or export. Operates on rows
*
* @package App\Services\Import
*/
class FlightExporter extends ImportExport
{
public $assetType = 'flight';
/**
* Set the current columns and other setup
*/
public function __construct()
{
self::$columns = FlightImporter::$columns;
}
/**
* Import a flight, parse out the different rows
* @param Flight $flight
* @return array
*/
public function export(Flight $flight): array
{
$ret = [];
foreach(self::$columns as $column) {
$ret[$column] = $flight->{$column};
}
# Modify special fields
$ret['airline'] = $ret['airline']->icao;
$ret['distance'] = $ret['distance']->toNumber();
$ret['fares'] = $this->getFares($flight);
$ret['fields'] = $this->getFields($flight);
$ret['subfleets'] = $this->getSubfleets($flight);
return $ret;
}
/**
* Return any custom fares that have been made to this flight
* @param Flight $flight
* @return string
*/
protected function getFares(Flight &$flight): string
{
$fares = [];
foreach($flight->fares as $fare) {
$fare_export = [];
if($fare->pivot->price) {
$fare_export['price'] = $fare->pivot->price;
}
if ($fare->pivot->cost) {
$fare_export['cost'] = $fare->pivot->cost;
}
if ($fare->pivot->capacity) {
$fare_export['capacity'] = $fare->pivot->capacity;
}
$fares[$fare->code] = $fare_export;
}
return $this->objectToMultiString($fares);
}
/**
* Parse all of the subfields
* @param Flight $flight
* @return string
*/
protected function getFields(Flight &$flight): string
{
$ret = [];
foreach ($flight->field_values as $field) {
$ret[$field->name] = $field->value;
}
return $this->objectToMultiString($ret);
}
/**
* Create the list of subfleets that are associated here
* @param Flight $flight
* @return string
*/
protected function getSubfleets(Flight &$flight): string
{
$subfleets = [];
foreach($flight->subfleets as $subfleet) {
$subfleets[] = $subfleet->type;
}
return $this->objectToMultiString($subfleets);
}
}

View File

@@ -0,0 +1,167 @@
<?php
namespace App\Services\ImportExport;
use App\Interfaces\ImportExport;
use App\Models\Enums\FlightType;
use App\Models\Fare;
use App\Models\Flight;
use App\Models\Subfleet;
use App\Services\FareService;
use App\Services\FlightService;
use Log;
/**
* The flight importer can be imported or export. Operates on rows
*
* @package App\Services\Import
*/
class FlightImporter extends ImportExport
{
public $assetType = 'flight';
/**
* All of the columns that are in the CSV import
* Should match the database fields, for the most part
*/
public static $columns = [
'airline',
'flight_number',
'route_code',
'route_leg',
'dpt_airport_id',
'arr_airport_id',
'alt_airport_id',
'days',
'dpt_time',
'arr_time',
'level',
'distance',
'flight_time',
'flight_type',
'route',
'notes',
'active',
'subfleets',
'fares',
'fields',
];
/**
*
*/
private $fareSvc,
$flightSvc;
/**
* FlightImportExporter constructor.
*/
public function __construct()
{
$this->fareSvc = app(FareService::class);
$this->flightSvc = app(FlightService::class);
}
/**
* Import a flight, parse out the different rows
* @param array $row
* @param int $index
* @return bool
*/
public function import(array $row, $index)
{
// Get the airline ID from the ICAO code
$airline = $this->getAirline($row['airline']);
// Try to find this flight
$flight = Flight::firstOrNew([
'airline_id' => $airline->id,
'flight_number' => $row['flight_number'],
'route_code' => $row['route_code'],
'route_leg' => $row['route_leg'],
], $row);
// Any specific transformations
// Flight type can be set to P - Passenger, C - Cargo, or H - Charter
$flight->setAttribute('flight_type', FlightType::getFromCode($row['flight_type']));
$flight->setAttribute('active', get_truth_state($row['active']));
try {
$flight->save();
} catch (\Exception $e) {
$this->status = 'Error in row '.$index.': '.$e->getMessage();
return false;
}
$this->processSubfleets($flight, $row['subfleets']);
$this->processFares($flight, $row['fares']);
$this->processFields($flight, $row['fields']);
$this->status = 'Imported row '.$index;
return true;
}
/**
* Parse out all of the subfleets and associate them to the flight
* The subfleet is created if it doesn't exist
* @param Flight $flight
* @param $col
*/
protected function processSubfleets(Flight &$flight, $col): void
{
$count = 0;
$subfleets = $this->parseMultiColumnValues($col);
foreach($subfleets as $subfleet_type) {
$subfleet = Subfleet::firstOrCreate(
['type' => $subfleet_type],
['name' => $subfleet_type]
);
$subfleet->save();
# sync
$flight->subfleets()->syncWithoutDetaching([$subfleet->id]);
$count ++;
}
Log::info('Subfleets added/processed: '.$count);
}
/**
* Parse all of the fares in the multi-format
* @param Flight $flight
* @param $col
*/
protected function processFares(Flight &$flight, $col): void
{
$fares = $this->parseMultiColumnValues($col);
foreach ($fares as $fare_code => $fare_attributes) {
if (\is_int($fare_code)) {
$fare_code = $fare_attributes;
$fare_attributes = [];
}
$fare = Fare::firstOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$this->fareSvc->setForFlight($flight, $fare, $fare_attributes);
}
}
/**
* Parse all of the subfields
* @param Flight $flight
* @param $col
*/
protected function processFields(Flight &$flight, $col): void
{
$pass_fields = [];
$fields = $this->parseMultiColumnValues($col);
foreach($fields as $field_name => $field_value) {
$pass_fields[] = [
'name' => $field_name,
'value' => $field_value,
];
}
$this->flightSvc->updateCustomFields($flight, $pass_fields);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Services\ImportExport;
use App\Interfaces\ImportExport;
use App\Models\Subfleet;
/**
* Import subfleets
* @package App\Services\Import
*/
class SubfleetImporter extends ImportExport
{
public $assetType = 'subfleet';
/**
* All of the columns that are in the CSV import
* Should match the database fields, for the most part
*/
public static $columns = [
'airline',
'type',
'name',
];
/**
* Import a flight, parse out the different rows
* @param array $row
* @param int $index
* @return bool
*/
public function import(array $row, $index)
{
$airline = $this->getAirline($row['airline']);
if(!$airline) {
$this->status = 'Airline '.$row['airline'].' not found, row: '.$index;
return false;
}
$row['airline_id'] = $airline->id;
$subfleet = Subfleet::firstOrNew([
'type' => $row['type']
], $row);
try {
$subfleet->save();
} catch(\Exception $e) {
$this->status = 'Error in row '.$index.': '.$e->getMessage();
return false;
}
$this->status = 'Imported ' . $row['type'];
return true;
}
}