diff --git a/app/Http/Controllers/Admin/AircraftController.php b/app/Http/Controllers/Admin/AircraftController.php index 45810666..cc06d0c7 100644 --- a/app/Http/Controllers/Admin/AircraftController.php +++ b/app/Http/Controllers/Admin/AircraftController.php @@ -174,10 +174,8 @@ class AircraftController extends Controller } /** - * * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - * @throws \League\Csv\Exception * @throws \Illuminate\Validation\ValidationException */ public function import(Request $request) @@ -189,13 +187,12 @@ class AircraftController extends Controller if ($request->isMethod('post')) { ImportRequest::validate($request); - $path = Storage::putFileAs( - 'import', $request->file('csv_file'), 'aircraft' + 'import', $request->file('csv_file'), 'import_aircraft.csv' ); $path = storage_path('app/'.$path); - Log::info('Uploaded flights import file to '.$path); + Log::info('Uploaded aircraft import file to '.$path); $logs = $this->importSvc->importAircraft($path); } @@ -208,7 +205,7 @@ class AircraftController extends Controller * @param Aircraft|null $aircraft * @return mixed */ - protected function return_expenses_view(?Aircraft $aircraft) + protected function return_expenses_view(Aircraft $aircraft) { $aircraft->refresh(); diff --git a/app/Http/Controllers/Admin/AirportController.php b/app/Http/Controllers/Admin/AirportController.php index 402e2778..15bc3dcb 100644 --- a/app/Http/Controllers/Admin/AirportController.php +++ b/app/Http/Controllers/Admin/AirportController.php @@ -198,7 +198,6 @@ class AirportController extends Controller * * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - * @throws \League\Csv\Exception * @throws \Illuminate\Validation\ValidationException */ public function import(Request $request) @@ -210,13 +209,12 @@ class AirportController extends Controller if ($request->isMethod('post')) { ImportRequest::validate($request); - $path = Storage::putFileAs( - 'import', $request->file('csv_file'), 'airports' + 'import', $request->file('csv_file'), 'import_airports.csv' ); $path = storage_path('app/'.$path); - Log::info('Uploaded airports import file to '.$path); + Log::info('Uploaded airport import file to '.$path); $logs = $this->importSvc->importAirports($path); } diff --git a/app/Http/Controllers/Admin/ExpenseController.php b/app/Http/Controllers/Admin/ExpenseController.php index e6385957..b252d3f7 100644 --- a/app/Http/Controllers/Admin/ExpenseController.php +++ b/app/Http/Controllers/Admin/ExpenseController.php @@ -198,7 +198,6 @@ class ExpenseController extends Controller * * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - * @throws \League\Csv\Exception * @throws \Illuminate\Validation\ValidationException */ public function import(Request $request) @@ -210,9 +209,8 @@ class ExpenseController extends Controller if ($request->isMethod('post')) { ImportRequest::validate($request); - $path = Storage::putFileAs( - 'import', $request->file('csv_file'), 'expenses' + 'import', $request->file('csv_file'), 'import_expenses.csv' ); $path = storage_path('app/'.$path); diff --git a/app/Http/Controllers/Admin/FareController.php b/app/Http/Controllers/Admin/FareController.php index ac952753..721d0b9f 100644 --- a/app/Http/Controllers/Admin/FareController.php +++ b/app/Http/Controllers/Admin/FareController.php @@ -3,13 +3,18 @@ namespace App\Http\Controllers\Admin; use App\Http\Requests\CreateFareRequest; +use App\Http\Requests\ImportRequest; use App\Http\Requests\UpdateFareRequest; use App\Interfaces\Controller; use App\Repositories\FareRepository; +use App\Services\ExportService; +use App\Services\ImportService; use Flash; use Illuminate\Http\Request; +use Log; use Prettus\Repository\Criteria\RequestCriteria; use Response; +use Storage; /** * Class FareController @@ -17,16 +22,20 @@ use Response; */ class FareController extends Controller { - private $fareRepository; + private $fareRepo, + $importSvc; /** * FareController constructor. * @param FareRepository $fareRepo + * @param ImportService $importSvc */ public function __construct( - FareRepository $fareRepo + FareRepository $fareRepo, + ImportService $importSvc ) { - $this->fareRepository = $fareRepo; + $this->fareRepo = $fareRepo; + $this->importSvc = $importSvc; } /** @@ -37,8 +46,8 @@ class FareController extends Controller */ public function index(Request $request) { - $this->fareRepository->pushCriteria(new RequestCriteria($request)); - $fares = $this->fareRepository->all(); + $this->fareRepo->pushCriteria(new RequestCriteria($request)); + $fares = $this->fareRepo->all(); return view('admin.fares.index') ->with('fares', $fares); @@ -63,9 +72,9 @@ class FareController extends Controller public function store(CreateFareRequest $request) { $input = $request->all(); - $fare = $this->fareRepository->create($input); - Flash::success('Fare saved successfully.'); + $fare = $this->fareRepo->create($input); + Flash::success('Fare saved successfully.'); return redirect(route('admin.fares.index')); } @@ -76,10 +85,9 @@ class FareController extends Controller */ public function show($id) { - $fare = $this->fareRepository->findWithoutFail($id); + $fare = $this->fareRepo->findWithoutFail($id); if (empty($fare)) { Flash::error('Fare not found'); - return redirect(route('admin.fares.index')); } @@ -93,10 +101,9 @@ class FareController extends Controller */ public function edit($id) { - $fare = $this->fareRepository->findWithoutFail($id); + $fare = $this->fareRepo->findWithoutFail($id); if (empty($fare)) { Flash::error('Fare not found'); - return redirect(route('admin.fares.index')); } @@ -112,16 +119,15 @@ class FareController extends Controller */ public function update($id, UpdateFareRequest $request) { - $fare = $this->fareRepository->findWithoutFail($id); + $fare = $this->fareRepo->findWithoutFail($id); if (empty($fare)) { Flash::error('Fare not found'); - return redirect(route('admin.fares.index')); } - $fare = $this->fareRepository->update($request->all(), $id); - Flash::success('Fare updated successfully.'); + $fare = $this->fareRepo->update($request->all(), $id); + Flash::success('Fare updated successfully.'); return redirect(route('admin.fares.index')); } @@ -132,16 +138,63 @@ class FareController extends Controller */ public function destroy($id) { - $fare = $this->fareRepository->findWithoutFail($id); + $fare = $this->fareRepo->findWithoutFail($id); if (empty($fare)) { Flash::error('Fare not found'); - return redirect(route('admin.fares.index')); } - $this->fareRepository->delete($id); - Flash::success('Fare deleted successfully.'); + $this->fareRepo->delete($id); + Flash::success('Fare deleted successfully.'); return redirect(route('admin.fares.index')); } + + /** + * Run the aircraft exporter + * @param Request $request + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + * @throws \League\Csv\Exception + */ + public function export(Request $request) + { + $exporter = app(ExportService::class); + $fares = $this->fareRepo->all(); + + $path = $exporter->exportFares($fares); + return response() + ->download($path, 'fares.csv', [ + 'content-type' => 'text/csv', + ]) + ->deleteFileAfterSend(true); + } + + /** + * + * @param Request $request + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws \Illuminate\Validation\ValidationException + */ + public function import(Request $request) + { + $logs = [ + 'success' => [], + 'failed' => [], + ]; + + if ($request->isMethod('post')) { + ImportRequest::validate($request); + $path = Storage::putFileAs( + 'import', $request->file('csv_file'), 'import_fares.csv' + ); + + $path = storage_path('app/'.$path); + Log::info('Uploaded fares import file to '.$path); + $logs = $this->importSvc->importFares($path); + } + + return view('admin.fares.import', [ + 'logs' => $logs, + ]); + } } diff --git a/app/Http/Controllers/Admin/FlightController.php b/app/Http/Controllers/Admin/FlightController.php index a3af877d..052082e0 100644 --- a/app/Http/Controllers/Admin/FlightController.php +++ b/app/Http/Controllers/Admin/FlightController.php @@ -334,7 +334,7 @@ class FlightController extends Controller * * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - * @throws \League\Csv\Exception + * @throws \Illuminate\Validation\ValidationException */ public function import(Request $request) { @@ -345,7 +345,7 @@ class FlightController extends Controller if ($request->isMethod('post')) { $path = Storage::putFileAs( - 'import', $request->file('csv_file'), 'flights' + 'import', $request->file('csv_file'), 'import_flights.csv' ); $path = storage_path('app/'.$path); diff --git a/app/Http/Controllers/Admin/SubfleetController.php b/app/Http/Controllers/Admin/SubfleetController.php index 6b46578a..4506be05 100644 --- a/app/Http/Controllers/Admin/SubfleetController.php +++ b/app/Http/Controllers/Admin/SubfleetController.php @@ -245,7 +245,6 @@ class SubfleetController extends Controller * * @param Request $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - * @throws \League\Csv\Exception * @throws \Illuminate\Validation\ValidationException */ public function import(Request $request) @@ -259,11 +258,11 @@ class SubfleetController extends Controller ImportRequest::validate($request); $path = Storage::putFileAs( - 'import', $request->file('csv_file'), 'subfleets' + 'import', $request->file('csv_file'), 'import_subfleets.csv' ); $path = storage_path('app/'.$path); - Log::info('Uploaded flights import file to '.$path); + Log::info('Uploaded subfleets import file to '.$path); $logs = $this->importSvc->importSubfleets($path); } diff --git a/app/Routes/admin.php b/app/Routes/admin.php index 104b910b..214feb8f 100644 --- a/app/Routes/admin.php +++ b/app/Routes/admin.php @@ -30,6 +30,8 @@ Route::group([ Route::resource('expenses', 'ExpenseController'); # fares + Route::get('fares/export', 'FareController@export')->name('fares.export'); + Route::match(['get', 'post'], 'fares/import', 'FareController@import')->name('fares.import'); Route::resource('fares', 'FareController'); # finances diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index 066e180d..cbcf3545 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -7,6 +7,7 @@ use App\Interfaces\Service; use App\Services\ImportExport\AircraftExporter; use App\Services\ImportExport\AirportExporter; use App\Services\ImportExport\ExpenseExporter; +use App\Services\ImportExport\FareExporter; use App\Services\ImportExport\FlightExporter; use Illuminate\Support\Collection; use League\Csv\CharsetConverter; @@ -97,6 +98,18 @@ class ExportService extends Service return $this->runExport($expenses, $exporter); } + /** + * Export all of the fares + * @param Collection $fares + * @return mixed + * @throws \League\Csv\CannotInsertRecord + */ + public function exportFares($fares) + { + $exporter = new FareExporter(); + return $this->runExport($fares, $exporter); + } + /** * Export all of the flights * @param Collection $flights diff --git a/app/Services/ImportExport/FareExporter.php b/app/Services/ImportExport/FareExporter.php new file mode 100644 index 00000000..b3bef9f9 --- /dev/null +++ b/app/Services/ImportExport/FareExporter.php @@ -0,0 +1,39 @@ +{$column}; + } + + return $ret; + } +} diff --git a/app/Services/ImportExport/FareImporter.php b/app/Services/ImportExport/FareImporter.php new file mode 100644 index 00000000..d57767c6 --- /dev/null +++ b/app/Services/ImportExport/FareImporter.php @@ -0,0 +1,53 @@ + $row['code'], + ], $row); + + try { + $fare->save(); + } catch(\Exception $e) { + $this->errorLog('Error in row '.$index.': '.$e->getMessage()); + return false; + } + + $this->log('Imported '.$row['code'].' '.$row['name']); + return true; + } +} diff --git a/app/Services/ImportExport/SubfleetImporter.php b/app/Services/ImportExport/SubfleetImporter.php index b383e909..0f242ef6 100644 --- a/app/Services/ImportExport/SubfleetImporter.php +++ b/app/Services/ImportExport/SubfleetImporter.php @@ -3,7 +3,9 @@ namespace App\Services\ImportExport; use App\Interfaces\ImportExport; +use App\Models\Fare; use App\Models\Subfleet; +use App\Services\FareService; /** * Import subfleets @@ -21,8 +23,19 @@ class SubfleetImporter extends ImportExport 'airline', 'type', 'name', + 'fares', ]; + private $fareSvc; + + /** + * FlightImportExporter constructor. + */ + public function __construct() + { + $this->fareSvc = app(FareService::class); + } + /** * Import a flight, parse out the different rows * @param array $row @@ -45,7 +58,28 @@ class SubfleetImporter extends ImportExport return false; } + $this->processFares($subfleet, $row['fares']); + $this->log('Imported '.$row['type']); return true; } + + /** + * Parse all of the fares in the multi-format + * @param Subfleet $subfleet + * @param $col + */ + protected function processFares(Subfleet &$subfleet, $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->setForSubfleet($subfleet, $fare, $fare_attributes); + } + } } diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 5989f3f5..587ea0eb 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -10,6 +10,7 @@ use App\Repositories\FlightRepository; use App\Services\ImportExport\AircraftImporter; use App\Services\ImportExport\AirportImporter; use App\Services\ImportExport\ExpenseImporter; +use App\Services\ImportExport\FareImporter; use App\Services\ImportExport\FlightImporter; use App\Services\ImportExport\SubfleetImporter; use Illuminate\Validation\ValidationException; @@ -112,7 +113,6 @@ class ImportService extends Service * @param string $csv_file * @param bool $delete_previous * @return mixed - * @throws \League\Csv\Exception * @throws ValidationException */ public function importAircraft($csv_file, bool $delete_previous = true) @@ -135,7 +135,7 @@ class ImportService extends Service * @param string $csv_file * @param bool $delete_previous * @return mixed - * @throws \League\Csv\Exception + * @throws ValidationException */ public function importAirports($csv_file, bool $delete_previous = true) { @@ -157,7 +157,7 @@ class ImportService extends Service * @param string $csv_file * @param bool $delete_previous * @return mixed - * @throws \League\Csv\Exception + * @throws ValidationException */ public function importExpenses($csv_file, bool $delete_previous = true) { @@ -174,12 +174,35 @@ class ImportService extends Service return $this->runImport($reader, $importer); } + /** + * Import fares + * @param string $csv_file + * @param bool $delete_previous + * @return mixed + * @throws ValidationException + */ + public function importFares($csv_file, bool $delete_previous = true) + { + if ($delete_previous) { + # TODO: Delete all from: fares + } + + $reader = $this->openCsv($csv_file); + if (!$reader) { + # TODO: Throw an error + return false; + } + + $importer = new FareImporter(); + return $this->runImport($reader, $importer); + } + /** * Import flights * @param string $csv_file * @param bool $delete_previous * @return mixed - * @throws \League\Csv\Exception + * @throws ValidationException */ public function importFlights($csv_file, bool $delete_previous = true) { @@ -202,7 +225,7 @@ class ImportService extends Service * @param string $csv_file * @param bool $delete_previous * @return mixed - * @throws \League\Csv\Exception + * @throws ValidationException */ public function importSubfleets($csv_file, bool $delete_previous = true) { diff --git a/resources/views/admin/fares/import.blade.php b/resources/views/admin/fares/import.blade.php new file mode 100644 index 00000000..523612ad --- /dev/null +++ b/resources/views/admin/fares/import.blade.php @@ -0,0 +1,5 @@ +@extends('admin.app') +@section('title', 'Import Fares') +@section('content') + @include('admin.common.import', ['route' => 'admin.fares.import']) +@endsection diff --git a/resources/views/admin/fares/index.blade.php b/resources/views/admin/fares/index.blade.php index 6b007351..f0599165 100644 --- a/resources/views/admin/fares/index.blade.php +++ b/resources/views/admin/fares/index.blade.php @@ -2,12 +2,9 @@ @section('title', 'Fares') @section('actions') -