phpvms/app/Services/ImportExport/FlightImporter.php

274 lines
7.7 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\ImportExport;
use App\Contracts\ImportExport;
use App\Models\Enums\Days;
use App\Models\Enums\FlightType;
use App\Models\Fare;
use App\Models\Flight;
use App\Models\Subfleet;
use App\Services\AirportService;
use App\Services\FareService;
use App\Services\FlightService;
use Log;
/**
* The flight importer can be imported or export. Operates on rows
*/
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' => 'required',
'flight_number' => 'required',
'route_code' => 'nullable',
'route_leg' => 'nullable',
'dpt_airport' => 'required',
'arr_airport' => 'required',
'alt_airport' => 'nullable',
'days' => 'nullable',
'dpt_time' => 'nullable',
'arr_time' => 'nullable',
'level' => 'nullable|integer',
'distance' => 'nullable|numeric',
'flight_time' => 'required|integer',
'flight_type' => 'required|alpha',
'route' => 'nullable',
'notes' => 'nullable',
'active' => 'nullable|boolean',
'subfleets' => 'nullable',
'fares' => 'nullable',
'fields' => 'nullable',
];
private $airportSvc;
2018-08-27 00:40:04 +08:00
private $fareSvc;
private $flightSvc;
/**
* FlightImportExporter constructor.
*/
public function __construct()
{
$this->airportSvc = app(AirportService::class);
$this->fareSvc = app(FareService::class);
$this->flightSvc = app(FlightService::class);
}
/**
* Import a flight, parse out the different rows
2018-08-27 00:40:04 +08:00
*
* @param array $row
* @param int $index
2018-08-27 00:40:04 +08:00
*
* @return bool
*/
2018-03-23 06:17:37 +08:00
public function import(array $row, $index): bool
{
// Get the airline ID from the ICAO code
$airline = $this->getAirline($row['airline']);
// Check if the imported flight is a duplicate
/*$temp_flight = new Flight([
'airline_id' => $airline->id,
'flight_number' => $row['flight_number'],
'route_code' => $row['route_code'],
'route_leg' => $row['route_leg'],
]);
if($this->flightSvc->isFlightDuplicate($temp_flight)) {
$this->errorLog('Error in row '.$index.': Duplicate flight number detected');
return false;
}*/
// 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);
$row['dpt_airport'] = strtoupper($row['dpt_airport']);
$row['arr_airport'] = strtoupper($row['arr_airport']);
2018-03-23 08:59:35 +08:00
// Airport atttributes
$flight->setAttribute('days', $this->setDays($row['days']));
2018-03-23 08:59:35 +08:00
$flight->setAttribute('dpt_airport_id', $row['dpt_airport']);
$flight->setAttribute('arr_airport_id', $row['arr_airport']);
if ($row['alt_airport']) {
$flight->setAttribute('alt_airport_id', $row['alt_airport']);
}
// Any specific transformations
2018-03-30 00:47:37 +08:00
// Check for a valid value
$flight_type = $row['flight_type'];
2018-08-27 00:40:04 +08:00
if (!array_key_exists($flight_type, FlightType::labels())) {
$flight_type = FlightType::SCHED_PAX;
2018-03-30 00:47:37 +08:00
}
$flight->setAttribute('flight_type', $flight_type);
$flight->setAttribute('active', get_truth_state($row['active']));
try {
$flight->save();
} catch (\Exception $e) {
2018-03-23 06:17:37 +08:00
$this->errorLog('Error in row '.$index.': '.$e->getMessage());
return false;
}
2018-03-23 08:59:35 +08:00
// Create/check that they exist
$this->processAirport($row['dpt_airport']);
$this->processAirport($row['arr_airport']);
if ($row['alt_airport']) {
$this->processAirport($row['alt_airport']);
}
// Check/calculate the distance
if (empty($row['distance'])) {
$row['distance'] = $this->airportSvc->calculateDistance(
$row['dpt_airport'],
$row['arr_airport']
);
}
$this->processSubfleets($flight, $row['subfleets']);
$this->processFares($flight, $row['fares']);
$this->processFields($flight, $row['fields']);
2018-03-23 06:17:37 +08:00
$this->log('Imported row '.$index);
return true;
}
/**
* Return the mask of the days
2018-08-27 00:40:04 +08:00
*
* @param $day_str
2018-08-27 00:40:04 +08:00
*
* @return int|mixed
*/
protected function setDays($day_str)
{
2018-08-27 00:40:04 +08:00
if (!$day_str) {
return 0;
}
$days = [];
2018-08-27 00:40:04 +08:00
if (strpos($day_str, '1') !== false) {
$days[] = Days::MONDAY;
}
if (strpos($day_str, '2') !== false) {
$days[] = Days::TUESDAY;
}
if (strpos($day_str, '3') !== false) {
$days[] = Days::WEDNESDAY;
}
if (strpos($day_str, '4') !== false) {
$days[] = Days::THURSDAY;
}
if (strpos($day_str, '5') !== false) {
$days[] = Days::FRIDAY;
}
if (strpos($day_str, '6') !== false) {
$days[] = Days::SATURDAY;
}
if (strpos($day_str, '7') !== false) {
$days[] = Days::SUNDAY;
}
return Days::getDaysMask($days);
}
2018-03-23 08:59:35 +08:00
/**
* Process the airport
2018-08-27 00:40:04 +08:00
*
2018-03-23 08:59:35 +08:00
* @param $airport
2018-08-27 00:40:04 +08:00
*
2018-03-23 08:59:35 +08:00
* @return \Illuminate\Database\Eloquent\Model
*/
protected function processAirport($airport)
{
return $this->airportSvc->lookupAirportIfNotFound($airport);
2018-03-23 08:59:35 +08:00
}
/**
* Parse out all of the subfleets and associate them to the flight
* The subfleet is created if it doesn't exist
2018-08-27 00:40:04 +08:00
*
* @param Flight $flight
* @param $col
*/
protected function processSubfleets(Flight &$flight, $col): void
{
$count = 0;
$subfleets = $this->parseMultiColumnValues($col);
2018-08-27 00:40:04 +08:00
foreach ($subfleets as $subfleet_type) {
$subfleet = Subfleet::updateOrCreate(
['type' => $subfleet_type],
['name' => $subfleet_type]
);
$subfleet->save();
2018-08-27 00:40:04 +08:00
// sync
$flight->subfleets()->syncWithoutDetaching([$subfleet->id]);
2018-08-27 00:40:04 +08:00
$count++;
}
Log::info('Subfleets added/processed: '.$count);
}
/**
* Parse all of the fares in the multi-format
2018-08-27 00:40:04 +08:00
*
* @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::updateOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$this->fareSvc->setForFlight($flight, $fare, $fare_attributes);
}
}
/**
* Parse all of the subfields
2018-08-27 00:40:04 +08:00
*
* @param Flight $flight
* @param $col
*/
protected function processFields(Flight &$flight, $col): void
{
$pass_fields = [];
$fields = $this->parseMultiColumnValues($col);
2018-08-27 00:40:04 +08:00
foreach ($fields as $field_name => $field_value) {
$pass_fields[] = [
2018-08-27 00:40:04 +08:00
'name' => $field_name,
'value' => $field_value,
];
}
$this->flightSvc->updateCustomFields($flight, $pass_fields);
}
}