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

@ -320,11 +320,9 @@ class FlightController extends Controller
public function export(Request $request) public function export(Request $request)
{ {
$exporter = app(ExportService::class); $exporter = app(ExportService::class);
$path = storage_path('app/import/export_flight.csv');
$flights = $this->flightRepo->all(); $flights = $this->flightRepo->all();
$exporter->exportFlights($flights, $path);
$path = $exporter->exportFlights($flights);
return response() return response()
->download($path, 'flights.csv', [ ->download($path, 'flights.csv', [
'content-type' => 'text/csv', 'content-type' => 'text/csv',

View File

@ -10,6 +10,7 @@ use App\Models\Airline;
*/ */
class ImportExport class ImportExport
{ {
public $assetType;
public $status; public $status;
/** /**
@ -18,13 +19,17 @@ class ImportExport
public static $columns = []; public static $columns = [];
/** /**
* Get the airline from the ICAO * Get the airline from the ICAO. Create it if it doesn't exist
* @param $code * @param $code
* @return \App\Models\Airline * @return \Illuminate\Database\Eloquent\Model
*/ */
public function getAirline($code) public function getAirline($code)
{ {
return Airline::where('icao', $code)->first(); $airline = Airline::firstOrCreate([
'icao' => $code,
], ['name' => $code]);
return $airline;
} }
/** /**

View File

@ -17,6 +17,7 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
* @property mixed route_leg * @property mixed route_leg
* @property Collection field_values * @property Collection field_values
* @property Collection fares * @property Collection fares
* @property Collection subfleets
*/ */
class Flight extends Model class Flight extends Model
{ {

View File

@ -5,10 +5,12 @@ namespace App\Services;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Interfaces\Service; use App\Interfaces\Service;
use App\Repositories\FlightRepository; use App\Repositories\FlightRepository;
use App\Services\Import\FlightExporter; use App\Services\ImportExport\FlightExporter;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use League\Csv\CharsetConverter; use League\Csv\CharsetConverter;
use League\Csv\Writer; use League\Csv\Writer;
use Illuminate\Support\Facades\Storage;
/** /**
* Class ExportService * Class ExportService
@ -27,12 +29,12 @@ class ExportService extends Service
} }
/** /**
* @param $csv_file * @param string $path
* @return Writer * @return Writer
*/ */
public function openCsv($csv_file): Writer public function openCsv($path): Writer
{ {
$writer = Writer::createFromPath($csv_file, 'w+'); $writer = Writer::createFromPath($path, 'w+');
CharsetConverter::addTo($writer, 'utf-8', 'iso-8859-15'); CharsetConverter::addTo($writer, 'utf-8', 'iso-8859-15');
return $writer; return $writer;
} }
@ -40,19 +42,27 @@ class ExportService extends Service
/** /**
* Run the actual importer * Run the actual importer
* @param Collection $collection * @param Collection $collection
* @param Writer $writer
* @param ImportExport $exporter * @param ImportExport $exporter
* @return bool * @return string
* @throws \League\Csv\CannotInsertRecord * @throws \League\Csv\CannotInsertRecord
*/ */
protected function runExport(Collection $collection, Writer $writer, ImportExport $exporter): bool protected function runExport(Collection $collection, ImportExport $exporter): string
{ {
$filename = 'export_' . $exporter->assetType . '.csv';
Storage::makeDirectory(storage_path('app/import'));
$path = storage_path('app/import/'.$filename.'.csv');
$writer = $this->openCsv($path);
// Write out the header first
$writer->insertOne($exporter->getColumns()); $writer->insertOne($exporter->getColumns());
// Write the rest of the rows
foreach ($collection as $row) { foreach ($collection as $row) {
$writer->insertOne($exporter->export($row)); $writer->insertOne($exporter->export($row));
} }
return true; return $path;
} }
/** /**
@ -62,11 +72,9 @@ class ExportService extends Service
* @return mixed * @return mixed
* @throws \League\Csv\Exception * @throws \League\Csv\Exception
*/ */
public function exportFlights($flights, $csv_file) public function exportFlights($flights)
{ {
$writer = $this->openCsv($csv_file);
$exporter = new FlightExporter(); $exporter = new FlightExporter();
return $this->runExport($flights, $writer, $exporter); return $this->runExport($flights, $exporter);
} }
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Services\Import; namespace App\Services\ImportExport;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Models\Aircraft; use App\Models\Aircraft;
@ -15,6 +15,8 @@ use App\Support\ICAO;
*/ */
class AircraftImporter extends ImportExport class AircraftImporter extends ImportExport
{ {
public $assetType = 'aircraft';
/** /**
* All of the columns that are in the CSV import * All of the columns that are in the CSV import
* Should match the database fields, for the most part * Should match the database fields, for the most part
@ -34,15 +36,9 @@ class AircraftImporter extends ImportExport
*/ */
protected function getSubfleet($type) protected function getSubfleet($type)
{ {
$subfleet = Subfleet::where(['type' => $type])->first(); $subfleet = Subfleet::firstOrCreate([
if (!$subfleet) { 'type' => $type,
$subfleet = new Subfleet([ ], ['name' => $type]);
'type' => $type,
'name' => $type,
]);
$subfleet->save();
}
return $subfleet; return $subfleet;
} }
@ -53,7 +49,7 @@ class AircraftImporter extends ImportExport
* @param int $index * @param int $index
* @return bool * @return bool
*/ */
public function import(array $row, $index) public function import(array $row, $index): bool
{ {
$subfleet = $this->getSubfleet($row['subfleet']); $subfleet = $this->getSubfleet($row['subfleet']);

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Services\Import; namespace App\Services\ImportExport;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Models\Airport; use App\Models\Airport;
@ -11,6 +11,8 @@ use App\Models\Airport;
*/ */
class AirportImporter extends ImportExport class AirportImporter extends ImportExport
{ {
public $assetType = 'airport';
/** /**
* All of the columns that are in the CSV import * All of the columns that are in the CSV import
* Should match the database fields, for the most part * Should match the database fields, for the most part
@ -33,7 +35,7 @@ class AirportImporter extends ImportExport
* @param int $index * @param int $index
* @return bool * @return bool
*/ */
public function import(array $row, $index) public function import(array $row, $index): bool
{ {
$row['id'] = $row['icao']; $row['id'] = $row['icao'];
$row['hub'] = get_truth_state($row['hub']); $row['hub'] = get_truth_state($row['hub']);

View File

@ -1,13 +1,9 @@
<?php <?php
namespace App\Services\Import; namespace App\Services\ImportExport;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Models\Enums\FlightType;
use App\Models\Fare;
use App\Models\Flight; use App\Models\Flight;
use App\Models\Subfleet;
use Log;
/** /**
* The flight importer can be imported or export. Operates on rows * The flight importer can be imported or export. Operates on rows
@ -16,6 +12,8 @@ use Log;
*/ */
class FlightExporter extends ImportExport class FlightExporter extends ImportExport
{ {
public $assetType = 'flight';
/** /**
* Set the current columns and other setup * Set the current columns and other setup
*/ */

View File

@ -1,13 +1,12 @@
<?php <?php
namespace App\Services\Import; namespace App\Services\ImportExport;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Models\Enums\FlightType; use App\Models\Enums\FlightType;
use App\Models\Fare; use App\Models\Fare;
use App\Models\Flight; use App\Models\Flight;
use App\Models\Subfleet; use App\Models\Subfleet;
use App\Repositories\AirlineRepository;
use App\Services\FareService; use App\Services\FareService;
use App\Services\FlightService; use App\Services\FlightService;
use Log; use Log;
@ -19,6 +18,8 @@ use Log;
*/ */
class FlightImporter extends ImportExport class FlightImporter extends ImportExport
{ {
public $assetType = 'flight';
/** /**
* All of the columns that are in the CSV import * All of the columns that are in the CSV import
* Should match the database fields, for the most part * Should match the database fields, for the most part
@ -49,8 +50,7 @@ class FlightImporter extends ImportExport
/** /**
* *
*/ */
private $airlineRepo, private $fareSvc,
$fareSvc,
$flightSvc; $flightSvc;
/** /**
@ -58,7 +58,6 @@ class FlightImporter extends ImportExport
*/ */
public function __construct() public function __construct()
{ {
$this->airlineRepo = app(AirlineRepository::class);
$this->fareSvc = app(FareService::class); $this->fareSvc = app(FareService::class);
$this->flightSvc = app(FlightService::class); $this->flightSvc = app(FlightService::class);
} }
@ -113,7 +112,7 @@ class FlightImporter extends ImportExport
$count = 0; $count = 0;
$subfleets = $this->parseMultiColumnValues($col); $subfleets = $this->parseMultiColumnValues($col);
foreach($subfleets as $subfleet_type) { foreach($subfleets as $subfleet_type) {
$subfleet = Subfleet::firstOrNew( $subfleet = Subfleet::firstOrCreate(
['type' => $subfleet_type], ['type' => $subfleet_type],
['name' => $subfleet_type] ['name' => $subfleet_type]
); );
@ -142,7 +141,7 @@ class FlightImporter extends ImportExport
$fare_attributes = []; $fare_attributes = [];
} }
$fare = Fare::firstOrNew(['code' => $fare_code], ['name' => $fare_code]); $fare = Fare::firstOrCreate(['code' => $fare_code], ['name' => $fare_code]);
$this->fareSvc->setForFlight($flight, $fare, $fare_attributes); $this->fareSvc->setForFlight($flight, $fare, $fare_attributes);
} }
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Services\Import; namespace App\Services\ImportExport;
use App\Interfaces\ImportExport; use App\Interfaces\ImportExport;
use App\Models\Subfleet; use App\Models\Subfleet;
@ -11,6 +11,8 @@ use App\Models\Subfleet;
*/ */
class SubfleetImporter extends ImportExport class SubfleetImporter extends ImportExport
{ {
public $assetType = 'subfleet';
/** /**
* All of the columns that are in the CSV import * All of the columns that are in the CSV import
* Should match the database fields, for the most part * Should match the database fields, for the most part

View File

@ -6,10 +6,10 @@ use App\Interfaces\ImportExport;
use App\Interfaces\Service; use App\Interfaces\Service;
use App\Models\Airport; use App\Models\Airport;
use App\Repositories\FlightRepository; use App\Repositories\FlightRepository;
use App\Services\Import\AircraftImporter; use App\Services\ImportExport\AircraftImporter;
use App\Services\Import\AirportImporter; use App\Services\ImportExport\AirportImporter;
use App\Services\Import\FlightImporter; use App\Services\ImportExport\FlightImporter;
use App\Services\Import\SubfleetImporter; use App\Services\ImportExport\SubfleetImporter;
use League\Csv\Reader; use League\Csv\Reader;
/** /**

View File

@ -253,7 +253,7 @@ class ImporterTest extends TestCase
// Test the conversion // Test the conversion
$exporter = new \App\Services\Import\FlightExporter(); $exporter = new \App\Services\ImportExport\FlightExporter();
$exported = $exporter->export($flight); $exported = $exporter->export($flight);
$this->assertEquals('VMS', $exported['airline']); $this->assertEquals('VMS', $exported['airline']);