aircraftRepo = $aircraftRepo; $this->airlineRepo = $airlineRepo; $this->pirepRepo = $pirepRepo; $this->airportRepo = $airportRepo; $this->pirepFieldRepo = $pirepFieldRepo; $this->fareSvc = $fareSvc; $this->flightRepo = $flightRepo; $this->geoSvc = $geoSvc; $this->pirepSvc = $pirepSvc; $this->userSvc = $userSvc; } /** * Dropdown with aircraft grouped by subfleet * * @param mixed $add_blank * * @return array */ public function aircraftList($add_blank = false) { $aircraft = []; $subfleets = $this->userSvc->getAllowableSubfleets(Auth::user()); if ($add_blank) { $aircraft[''] = ''; } foreach ($subfleets as $subfleet) { $tmp = []; foreach ($subfleet->aircraft as $ac) { $tmp[$ac->id] = $ac['name'].' - '.$ac['registration']; } $aircraft[$subfleet->name] = $tmp; } return $aircraft; } /** * Save any custom fields found * * @param Pirep $pirep * @param Request $request */ protected function saveCustomFields(Pirep $pirep, Request $request) { $custom_fields = []; $pirep_fields = $this->pirepFieldRepo->all(); foreach ($pirep_fields as $field) { if (!$request->filled($field->slug)) { continue; } $custom_fields[] = [ 'name' => $field->name, 'slug' => $field->slug, 'value' => $request->input($field->slug), 'source' => PirepSource::MANUAL, ]; } Log::info('PIREP Custom Fields', $custom_fields); $this->pirepSvc->updateCustomFields($pirep->id, $custom_fields); } /** * Save the fares that have been specified/saved * * @param Pirep $pirep * @param Request $request * * @throws \Exception */ protected function saveFares(Pirep $pirep, Request $request) { $fares = []; if (!$pirep->aircraft) { return; } foreach ($pirep->aircraft->subfleet->fares as $fare) { $field_name = 'fare_'.$fare->id; if (!$request->filled($field_name)) { $count = 0; } else { $count = $request->input($field_name); } $fares[] = [ 'fare_id' => $fare->id, 'count' => $count, ]; } $this->fareSvc->saveForPirep($pirep, $fares); } /** * @param Request $request * * @throws \Prettus\Repository\Exceptions\RepositoryException * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function index(Request $request) { $user = Auth::user(); $where = [['user_id', $user->id]]; $where[] = ['state', '<>', PirepState::CANCELLED]; $with = ['airline', 'aircraft', 'dpt_airport', 'arr_airport', 'fares', 'comments']; $this->pirepRepo->with($with) ->pushCriteria(new WhereCriteria($request, $where)); $pireps = $this->pirepRepo->orderBy('created_at', 'desc')->paginate(); return view('pireps.index', [ 'user' => $user, 'pireps' => $pireps, ]); } /** * @param $id * * @return mixed */ public function show($id) { $pirep = $this->pirepRepo->with(['simbrief'])->find($id); if (empty($pirep)) { Flash::error('Pirep not found'); return redirect(route('frontend.pirep.index')); } $map_features = $this->geoSvc->pirepGeoJson($pirep); return view('pireps.show', [ 'pirep' => $pirep, 'map_features' => $map_features, 'user' => Auth::user(), ]); } /** * Return the fares form for a given aircraft * * @param Request $request * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function fares(Request $request) { $aircraft_id = $request->input('aircraft_id'); $aircraft = $this->aircraftRepo->find($aircraft_id); return view('pireps.fares', [ 'aircraft' => $aircraft, 'read_only' => false, ]); } /** * Create a new flight report * * @param \Illuminate\Http\Request $request * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function create(Request $request) { $pirep = null; // See if request has a ?flight_id, so we can pre-populate the fields from the flight // Makes filing easier, but we can also more easily find a bid and close it if ($request->has('flight_id')) { $flight = $this->flightRepo->find($request->input('flight_id')); $pirep = Pirep::fromFlight($flight); } /** * They have a SimBrief ID, load that up and figure out the flight that it's from */ $fare_values = []; $simbrief = null; $simbrief_id = null; $aircraft = null; if ($request->has('sb_id')) { $simbrief_id = $request->input('sb_id'); $simbrief = SimBrief::find($simbrief_id); $pirep = Pirep::fromSimBrief($simbrief); $aircraft = $simbrief->aircraft; $aircraft_list[$aircraft->subfleet->name] = []; $aircraft_list[$aircraft->subfleet->name][$aircraft->id] = $aircraft->name.' - '.$aircraft->registration; // Convert the fare data into the expected output format if (!empty($simbrief->fare_data)) { $fare_values = json_decode($simbrief->fare_data, true); $fares = []; $fare_data = json_decode($simbrief->fare_data, true); foreach ($fare_data as $fare) { $fares[] = new Fare($fare); } $aircraft->subfleet->fares = collect($fares); } // TODO: Set more fields from the Simbrief to the PIREP form } else { $aircraft_list = $this->aircraftList(true); } return view('pireps.create', [ 'aircraft' => $aircraft, 'pirep' => $pirep, 'read_only' => false, 'airline_list' => $this->airlineRepo->selectBoxList(true), 'aircraft_list' => $aircraft_list, 'airport_list' => $this->airportRepo->selectBoxList(true), 'pirep_fields' => $this->pirepFieldRepo->all(), 'field_values' => [], 'fare_values' => $fare_values, 'simbrief_id' => $simbrief_id, 'simbrief' => $simbrief, ]); } /** * @param CreatePirepRequest $request * * @throws \Exception * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function store(CreatePirepRequest $request) { /** @var User $user */ $user = Auth::user(); $pirep = new Pirep($request->post()); $pirep->user_id = $user->id; $attrs = $request->all(); $attrs['submit'] = strtolower($attrs['submit']); if ($attrs['submit'] === 'submit') { // Are they allowed at this airport? if (setting('pilots.only_flights_from_current') && $user->curr_airport_id !== $pirep->dpt_airport_id) { Log::info( 'Pilot '.$user->id .' not at departure airport (curr='.$user->curr_airport_id .', dpt='.$pirep->dpt_airport_id.')' ); return $this->flashError( 'You are currently not at the departure airport!', 'frontend.pireps.create' ); } // Can they fly this aircraft? if (setting('pireps.restrict_aircraft_to_rank', false) && !$this->userSvc->aircraftAllowed($user, $pirep->aircraft_id)) { Log::info('Pilot '.$user->id.' not allowed to fly aircraft'); return $this->flashError( 'You are not allowed to fly this aircraft!', 'frontend.pireps.create' ); } // is the aircraft in the right place? /* @noinspection NotOptimalIfConditionsInspection */ // Get the aircraft $aircraft = $this->aircraftRepo->findWithoutFail($pirep->aircraft_id); if ($aircraft === null) { Log::error('Aircraft for PIREP not found, id='.$pirep->aircraft_id); return $this->flashError( 'The aircraft for the PIREP hasn\'t been found', 'frontend.pireps.create' ); } if (setting('pireps.only_aircraft_at_dpt_airport') && $aircraft->airport_id !== $pirep->dpt_airport_id ) { Log::info('Aircraft '.$pirep->aircraft_id.' not at departure airport (curr='.$pirep->aircraft->airport_id.', apt='.$pirep->dpt_airport_id.')'); return $this->flashError( 'This aircraft is not positioned at the departure airport!', 'frontend.pireps.create' ); } // Make sure this isn't a duplicate $dupe_pirep = $this->pirepSvc->findDuplicate($pirep); if ($dupe_pirep !== false) { Log::info('Duplicate PIREP found'); return $this->flashError( 'This PIREP has already been filed.', 'frontend.pireps.create' ); } } // Any special fields $hours = (int) $request->input('hours', 0); $minutes = (int) $request->input('minutes', 0); $pirep->flight_time = Time::hoursToMinutes($hours) + $minutes; // Set the correct fuel units $pirep->block_fuel = new Fuel((float) $request->input('block_fuel'), setting('units.fuel')); $pirep->fuel_used = new Fuel((float) $request->input('fuel_used'), setting('units.fuel')); // Put the time that this is currently submitted $attrs['submitted_at'] = Carbon::now('UTC'); $pirep->submitted_at = Carbon::now('UTC'); $pirep = $this->pirepSvc->create($pirep); $this->saveCustomFields($pirep, $request); $this->saveFares($pirep, $request); $this->pirepSvc->saveRoute($pirep); if ($request->has('sb_id')) { $brief = SimBrief::find($request->input('sb_id')); if ($brief !== null) { /** @var SimBriefService $sbSvc */ $sbSvc = app(SimBriefService::class); $sbSvc->attachSimbriefToPirep($pirep, $brief); } } // Depending on the button they selected, set an initial state // Can be saved as a draft or just submitted if ($attrs['submit'] === 'save') { if (!$pirep->read_only) { $pirep->state = PirepState::DRAFT; } $pirep->save(); Flash::success('PIREP saved successfully.'); } elseif ($attrs['submit'] === 'submit') { $this->pirepSvc->submit($pirep); Flash::success('PIREP submitted!'); } return redirect(route('frontend.pireps.show', [$pirep->id])); } /** * Show the form for editing the specified Pirep. * * @param int $id * * @return mixed */ public function edit($id) { /** @var Pirep $pirep */ $pirep = $this->pirepRepo->findWithoutFail($id); if (empty($pirep)) { Flash::error('Pirep not found'); return redirect(route('frontend.pireps.index')); } if ($pirep->user_id !== Auth::id()) { Flash::error('Cannot edit someone else\'s PIREP!'); return redirect(route('admin.pireps.index')); } // Eager load the subfleet and fares under it if ($pirep->aircraft) { $pirep->aircraft->load('subfleet.fares'); } $simbrief_id = null; if ($pirep->simbrief) { $simbrief_id = $pirep->simbrief->id; } $time = new Time($pirep->flight_time); $pirep->hours = $time->hours; $pirep->minutes = $time->minutes; // set the custom fields foreach ($pirep->fields as $field) { if ($field->slug === null) { $field->slug = str_slug($field->name); } $field_name = 'field_'.$field->slug; $pirep->{$field_name} = $field->value; } // set the fares foreach ($pirep->fares as $fare) { $field_name = 'fare_'.$fare->fare_id; $pirep->{$field_name} = $fare->count; } return view('pireps.edit', [ 'pirep' => $pirep, 'aircraft' => $pirep->aircraft, 'aircraft_list' => $this->aircraftList(true), 'airline_list' => $this->airlineRepo->selectBoxList(), 'airport_list' => $this->airportRepo->selectBoxList(), 'pirep_fields' => $this->pirepFieldRepo->all(), 'simbrief_id' => $simbrief_id, ]); } /** * @param $id * @param UpdatePirepRequest $request * * @throws \Prettus\Validator\Exceptions\ValidatorException * @throws \Exception * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function update($id, UpdatePirepRequest $request) { /** @var User $user */ $user = Auth::user(); /** @var Pirep $pirep */ $pirep = $this->pirepRepo->findWithoutFail($id); if (empty($pirep)) { Flash::error('Pirep not found'); return redirect(route('admin.pireps.index')); } if ($user->id !== $pirep->user_id) { Flash::error('Cannot edit someone else\'s PIREP!'); return redirect(route('admin.pireps.index')); } $orig_route = $pirep->route; $attrs = $request->all(); $attrs['submit'] = strtolower($attrs['submit']); // Fix the time $attrs['flight_time'] = Time::init( $attrs['minutes'], $attrs['hours'] )->getMinutes(); $pirep = $this->pirepRepo->update($attrs, $id); // A route change in the PIREP, so update the saved points in the ACARS table if ($pirep->route !== $orig_route) { $this->pirepSvc->saveRoute($pirep); } $this->saveCustomFields($pirep, $request); $this->saveFares($pirep, $request); if ($attrs['submit'] === 'save') { Flash::success('PIREP saved successfully.'); } elseif ($attrs['submit'] === 'submit') { $this->pirepSvc->submit($pirep); Flash::success('PIREP submitted!'); } elseif ($attrs['submit'] === 'delete' || $attrs['submit'] === 'cancel') { $this->pirepSvc->delete($pirep); Flash::success('PIREP deleted!'); return redirect(route('frontend.pireps.index')); } return redirect(route('frontend.pireps.show', [$pirep->id])); } /** * Submit the PIREP * * @param $id * @param Request $request * * @throws \Exception * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function submit($id, Request $request) { $pirep = $this->pirepRepo->findWithoutFail($id); if (empty($pirep)) { Flash::error('PIREP not found'); return redirect(route('admin.pireps.index')); } if ($pirep->user_id !== Auth::id()) { Flash::error('Cannot edit someone else\'s PIREP!'); return redirect(route('admin.pireps.index')); } $this->pirepSvc->submit($pirep); return redirect(route('frontend.pireps.show', [$pirep->id])); } }