phpvms/app/Services/ImportService.php

259 lines
6.5 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
use App\Contracts\ImportExport;
use App\Contracts\Service;
use App\Models\Airport;
2018-03-23 06:17:37 +08:00
use App\Models\Expense;
use App\Repositories\FlightRepository;
use App\Services\ImportExport\AircraftImporter;
use App\Services\ImportExport\AirportImporter;
2018-03-23 06:17:37 +08:00
use App\Services\ImportExport\ExpenseImporter;
2018-03-23 06:48:57 +08:00
use App\Services\ImportExport\FareImporter;
use App\Services\ImportExport\FlightImporter;
use App\Services\ImportExport\SubfleetImporter;
use Illuminate\Support\Facades\Log;
2019-07-18 21:54:03 +08:00
use Illuminate\Support\Facades\Validator;
2018-03-23 06:17:37 +08:00
use Illuminate\Validation\ValidationException;
use League\Csv\Exception;
use League\Csv\Reader;
class ImportService extends Service
{
protected $flightRepo;
/**
* ImporterService constructor.
2018-08-27 00:40:04 +08:00
*
* @param FlightRepository $flightRepo
*/
2018-08-27 00:40:04 +08:00
public function __construct(FlightRepository $flightRepo)
{
$this->flightRepo = $flightRepo;
}
2018-03-23 06:17:37 +08:00
/**
* Throw a validation error back up because it will automatically show
* itself under the CSV file upload, and nothing special needs to be done
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @param $error
* @param $e
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @throws ValidationException
*/
2018-08-27 00:40:04 +08:00
protected function throwError($error, \Exception $e = null): void
2018-03-23 06:17:37 +08:00
{
Log::error($error);
2018-08-27 00:40:04 +08:00
if ($e) {
2018-03-23 06:17:37 +08:00
Log::error($e->getMessage());
}
$validator = Validator::make([], []);
$validator->errors()->add('csv_file', $error);
2018-08-27 00:40:04 +08:00
2018-03-23 06:17:37 +08:00
throw new ValidationException($validator);
}
/**
2019-06-19 06:58:09 +08:00
* @param $csv_file
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return Reader
*/
public function openCsv($csv_file)
{
2018-03-23 06:17:37 +08:00
try {
$reader = Reader::createFromPath($csv_file);
$reader->setDelimiter(',');
$reader->setEnclosure('"');
return $reader;
} catch (Exception $e) {
$this->throwError('Error opening CSV: '.$e->getMessage(), $e);
}
}
/**
2018-03-23 06:17:37 +08:00
* Run the actual importer, pass in one of the Import classes which implements
* the ImportExport interface
2018-08-27 00:40:04 +08:00
*
* @param $file_path
* @param ImportExport $importer
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return array
*/
protected function runImport($file_path, ImportExport $importer): array
{
$reader = $this->openCsv($file_path);
$cols = array_keys($importer->getColumns());
$first_header = $cols[0];
2018-03-23 06:17:37 +08:00
$first = true;
$records = $reader->getRecords($cols);
foreach ($records as $offset => $row) {
// check if the first row being read is the header
2018-03-23 06:17:37 +08:00
if ($first) {
$first = false;
2018-08-27 00:40:04 +08:00
if ($row[$first_header] !== $first_header) {
2018-03-23 06:17:37 +08:00
$this->throwError('CSV file doesn\'t seem to match import type');
}
continue;
}
2018-03-23 06:17:37 +08:00
// Do a sanity check on the number of columns first
if (!$importer->checkColumns($row)) {
$importer->errorLog('Number of columns in row doesn\'t match');
continue;
}
2018-03-23 06:17:37 +08:00
2018-03-23 12:11:59 +08:00
// turn it into a collection and run some filtering
$row = collect($row)->map(function ($val, $index) {
$val = trim($val);
2018-08-27 00:40:04 +08:00
if ($val === '') {
2019-07-18 21:55:10 +08:00
return;
}
return $val;
2018-03-23 12:11:59 +08:00
})->toArray();
2018-08-27 00:40:04 +08:00
// Try to validate
$validator = Validator::make($row, $importer->getColumns());
2018-08-27 00:40:04 +08:00
if ($validator->fails()) {
$errors = 'Error in row '.$offset.','.implode(';', $validator->errors()->all());
$importer->errorLog($errors);
continue;
}
2018-03-23 06:17:37 +08:00
$importer->import($row, $offset);
}
2018-03-23 06:17:37 +08:00
return $importer->status;
}
/**
* Import aircraft
2018-08-27 00:40:04 +08:00
*
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
*/
public function importAircraft($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
2018-08-27 00:40:04 +08:00
// TODO: delete airports
}
$importer = new AircraftImporter();
return $this->runImport($csv_file, $importer);
}
/**
* Import airports
2018-08-27 00:40:04 +08:00
*
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
*/
public function importAirports($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
Airport::truncate();
}
$importer = new AirportImporter();
return $this->runImport($csv_file, $importer);
}
2018-03-23 06:17:37 +08:00
/**
* Import expenses
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:17:37 +08:00
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
2018-03-23 06:17:37 +08:00
*/
public function importExpenses($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
Expense::truncate();
}
$importer = new ExpenseImporter();
return $this->runImport($csv_file, $importer);
2018-03-23 06:17:37 +08:00
}
2018-03-23 06:48:57 +08:00
/**
* Import fares
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
2018-03-23 06:48:57 +08:00
*/
public function importFares($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
2018-08-27 00:40:04 +08:00
// TODO: Delete all from: fares
2018-03-23 06:48:57 +08:00
}
$importer = new FareImporter();
return $this->runImport($csv_file, $importer);
2018-03-23 06:48:57 +08:00
}
/**
* Import flights
2018-08-27 00:40:04 +08:00
*
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
*/
public function importFlights($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
2018-08-27 00:40:04 +08:00
// TODO: Delete all from: flights, flight_field_values
}
$importer = new FlightImporter();
return $this->runImport($csv_file, $importer);
}
/**
* Import subfleets
2018-08-27 00:40:04 +08:00
*
* @param string $csv_file
* @param bool $delete_previous
2018-08-27 00:40:04 +08:00
*
2018-03-23 06:48:57 +08:00
* @throws ValidationException
2018-08-27 00:40:04 +08:00
*
* @return mixed
*/
public function importSubfleets($csv_file, bool $delete_previous = true)
{
if ($delete_previous) {
2018-08-27 00:40:04 +08:00
// TODO: Cleanup subfleet data
}
$importer = new SubfleetImporter();
return $this->runImport($csv_file, $importer);
}
}