Refactoring Simbrief fares and aircraft (#1054)
* Refactoring simbrief fares and aircraft * Hide user full name/email * Sort PIREP fields desc; fix cargo counts * Change the sorting * Extra logs * Fix tests * Return fare information through the API * Style fixes * Test fix * Another test fix * More fixes * Set aircraft and fares in prefile * Formatting
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use App\Contracts\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Add a hub to the subfleet is
|
||||
*/
|
||||
class AddAircraftToSimbrief extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('simbrief', function (Blueprint $table) {
|
||||
$table->unsignedInteger('aircraft_id')
|
||||
->nullable()
|
||||
->after('pirep_id');
|
||||
|
||||
// Temp column to hold the calculated fare data for the API
|
||||
// Remove this once the prefile to acars feature is completed
|
||||
$table->mediumText('fare_data')->nullable()->after('ofp_xml');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -119,8 +119,8 @@ aircraft:
|
||||
-
|
||||
id: 1
|
||||
subfleet_id: 1
|
||||
icao: null
|
||||
iata: null
|
||||
icao: B744
|
||||
iata: 744
|
||||
airport_id: KJFK
|
||||
landing_time: '2020-10-23 07:50:16'
|
||||
name: 'Boeing 747-438'
|
||||
@@ -136,8 +136,8 @@ aircraft:
|
||||
-
|
||||
id: 2
|
||||
subfleet_id: 2
|
||||
icao: null
|
||||
iata: null
|
||||
icao: B777
|
||||
iata: 777
|
||||
airport_id: LGRP
|
||||
landing_time: null
|
||||
name: 'Boeing 777-200'
|
||||
@@ -153,8 +153,8 @@ aircraft:
|
||||
-
|
||||
id: 3
|
||||
subfleet_id: 1
|
||||
icao: null
|
||||
iata: null
|
||||
icao: B744
|
||||
iata: 744
|
||||
airport_id: KAUS
|
||||
landing_time: '2020-10-24 08:50:13'
|
||||
name: 'Boeing 747-412'
|
||||
@@ -170,8 +170,8 @@ aircraft:
|
||||
-
|
||||
id: 4
|
||||
subfleet_id: 1
|
||||
icao: null
|
||||
iata: null
|
||||
icao: B744
|
||||
iata: 744
|
||||
airport_id: KAUS
|
||||
landing_time: null
|
||||
name: 'Boeing 747-436 RETIRED'
|
||||
@@ -187,7 +187,7 @@ aircraft:
|
||||
-
|
||||
id: 5
|
||||
subfleet_id: 4
|
||||
icao: A320
|
||||
icao: 'A320'
|
||||
iata: '320'
|
||||
airport_id: EGLL
|
||||
landing_time: null
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Http\Requests\UpdatePirepRequest;
|
||||
use App\Models\Enums\PirepSource;
|
||||
use App\Models\Enums\PirepState;
|
||||
use App\Models\Enums\PirepStatus;
|
||||
use App\Models\Fare;
|
||||
use App\Models\Pirep;
|
||||
use App\Models\SimBrief;
|
||||
use App\Models\User;
|
||||
@@ -253,23 +254,48 @@ class PirepController extends Controller
|
||||
/**
|
||||
* 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');
|
||||
$brief = SimBrief::find($simbrief_id);
|
||||
$pirep = Pirep::fromSimBrief($brief);
|
||||
$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' => null,
|
||||
'aircraft' => $aircraft,
|
||||
'pirep' => $pirep,
|
||||
'read_only' => false,
|
||||
'airline_list' => $this->airlineRepo->selectBoxList(true),
|
||||
'aircraft_list' => $this->aircraftList(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,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,12 @@ namespace App\Http\Controllers\Frontend;
|
||||
|
||||
use App\Exceptions\AssetNotFound;
|
||||
use App\Models\Aircraft;
|
||||
use App\Models\Enums\FareType;
|
||||
use App\Models\Enums\FlightType;
|
||||
use App\Models\Fare;
|
||||
use App\Models\Flight;
|
||||
use App\Models\SimBrief;
|
||||
use App\Models\User;
|
||||
use App\Repositories\FlightRepository;
|
||||
use App\Services\FareService;
|
||||
use App\Services\SimBriefService;
|
||||
@@ -49,8 +53,9 @@ class SimBriefController
|
||||
|
||||
$flight_id = $request->input('flight_id');
|
||||
$aircraft_id = $request->input('aircraft_id');
|
||||
$flight = $this->flightRepo->with(['subfleets'])->find($flight_id);
|
||||
// $flight = $this->fareSvc->getReconciledFaresForFlight($flight);
|
||||
|
||||
/** @var Flight $flight */
|
||||
$flight = $this->flightRepo->with(['fares', 'subfleets'])->find($flight_id);
|
||||
|
||||
if (!$flight) {
|
||||
flash()->error('Unknown flight');
|
||||
@@ -63,15 +68,15 @@ class SimBriefController
|
||||
return redirect(route('frontend.flights.index'));
|
||||
}
|
||||
|
||||
// If no subfleets defined for flight get them from user
|
||||
if ($flight->subfleets->count() > 0) {
|
||||
$subfleets = $flight->subfleets;
|
||||
} else {
|
||||
$subfleets = $this->userSvc->getAllowableSubfleets($user);
|
||||
}
|
||||
|
||||
// No aircraft selected, show selection form
|
||||
if (!$aircraft_id) {
|
||||
// If no subfleets defined for flight get them from user
|
||||
if ($flight->subfleets->count() > 0) {
|
||||
$subfleets = $flight->subfleets;
|
||||
} else {
|
||||
$subfleets = $this->userSvc->getAllowableSubfleets($user);
|
||||
}
|
||||
|
||||
return view('flights.simbrief_aircraft', [
|
||||
'flight' => $flight,
|
||||
'subfleets' => $subfleets,
|
||||
@@ -90,8 +95,14 @@ class SimBriefController
|
||||
|
||||
// SimBrief profile does not exists and everything else is ok
|
||||
// Select aircraft which will be used for calculations and details
|
||||
/** @var Aircraft $aircraft */
|
||||
$aircraft = Aircraft::where('id', $aircraft_id)->first();
|
||||
|
||||
// Figure out the proper fares to use for this flight/aircraft
|
||||
$all_fares = $this->fareSvc->getFareWithOverrides($aircraft->subfleet->fares, $flight->fares);
|
||||
|
||||
// TODO: Reconcile the fares for this aircraft w/ proper for the flight/subfleet
|
||||
|
||||
// Get passenger and baggage weights with failsafe defaults
|
||||
if ($flight->flight_type === FlightType::CHARTER_PAX_ONLY) {
|
||||
$pax_weight = setting('simbrief.charter_pax_weight', 168);
|
||||
@@ -115,14 +126,86 @@ class SimBriefController
|
||||
$loadmax = 100;
|
||||
}
|
||||
|
||||
// Load fares for passengers
|
||||
|
||||
$loaddist = []; // The load distribution string
|
||||
|
||||
$pax_load_sheet = [];
|
||||
$tpaxfig = 0;
|
||||
|
||||
/** @var Fare $fare */
|
||||
foreach ($all_fares as $fare) {
|
||||
if ($fare->type !== FareType::PASSENGER || empty($fare->capacity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count = floor(($fare->capacity * rand($loadmin, $loadmax)) / 100);
|
||||
$tpaxfig += $count;
|
||||
$pax_load_sheet[] = [
|
||||
'id' => $fare->id,
|
||||
'code' => $fare->code,
|
||||
'name' => $fare->name,
|
||||
'type' => $fare->type,
|
||||
'capacity' => (int) $fare->capacity,
|
||||
'count' => $count,
|
||||
];
|
||||
|
||||
$loaddist[] = $fare->code.' '.$count;
|
||||
}
|
||||
|
||||
// Calculate total weights
|
||||
if (setting('units.weight') === 'kg') {
|
||||
$tpaxload = round(($pax_weight * $tpaxfig) / 2.205);
|
||||
$tbagload = round(($bag_weight * $tpaxfig) / 2.205);
|
||||
} else {
|
||||
$tpaxload = round($pax_weight * $tpaxfig);
|
||||
$tbagload = round($bag_weight * $tpaxfig);
|
||||
}
|
||||
|
||||
// Load up fares for cargo
|
||||
|
||||
$tcargoload = 0;
|
||||
$cargo_load_sheet = [];
|
||||
foreach ($all_fares as $fare) {
|
||||
if ($fare->type !== FareType::CARGO || empty($fare->capacity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count = ceil((($fare->capacity - $tbagload) * rand($loadmin, $loadmax)) / 100);
|
||||
$tcargoload += $count;
|
||||
$cargo_load_sheet[] = [
|
||||
'id' => $fare->id,
|
||||
'code' => $fare->code,
|
||||
'name' => $fare->name,
|
||||
'type' => $fare->type,
|
||||
'capacity' => $fare->capacity,
|
||||
'count' => $count,
|
||||
];
|
||||
|
||||
$loaddist[] = $fare->code.' '.$count;
|
||||
}
|
||||
|
||||
$tpayload = $tpaxload + $tbagload + $tcargoload;
|
||||
|
||||
$request->session()->put('simbrief_fares', array_merge($pax_load_sheet, $cargo_load_sheet));
|
||||
|
||||
// Show the main simbrief form
|
||||
return view('flights.simbrief_form', [
|
||||
'flight' => $flight,
|
||||
'aircraft' => $aircraft,
|
||||
'pax_weight' => $pax_weight,
|
||||
'bag_weight' => $bag_weight,
|
||||
'loadmin' => $loadmin,
|
||||
'loadmax' => $loadmax,
|
||||
'user' => Auth::user(),
|
||||
'flight' => $flight,
|
||||
'aircraft' => $aircraft,
|
||||
'pax_weight' => $pax_weight,
|
||||
'bag_weight' => $bag_weight,
|
||||
'loadmin' => $loadmin,
|
||||
'loadmax' => $loadmax,
|
||||
'pax_load_sheet' => $pax_load_sheet,
|
||||
'cargo_load_sheet' => $cargo_load_sheet,
|
||||
'tpaxfig' => $tpaxfig,
|
||||
'tpaxload' => $tpaxload,
|
||||
'tbagload' => $tbagload,
|
||||
'tpayload' => $tpayload,
|
||||
'tcargoload' => $tcargoload,
|
||||
'loaddist' => implode(' ', $loaddist),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -227,6 +310,7 @@ class SimBriefController
|
||||
|
||||
/**
|
||||
* Check whether the OFP was generated. Pass in two items, the flight_id and ofp_id
|
||||
* This does the actual "attachment" of the Simbrief to the flight
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
@@ -234,10 +318,14 @@ class SimBriefController
|
||||
*/
|
||||
public function check_ofp(Request $request)
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$ofp_id = $request->input('ofp_id');
|
||||
$flight_id = $request->input('flight_id');
|
||||
$aircraft_id = $request->input('aircraft_id');
|
||||
$fares = $request->session()->get('simbrief_fares', []);
|
||||
|
||||
$simbrief = $this->simBriefSvc->downloadOfp(Auth::user()->id, $ofp_id, $flight_id);
|
||||
$simbrief = $this->simBriefSvc->downloadOfp($user->id, $ofp_id, $flight_id, $aircraft_id, $fares);
|
||||
if ($simbrief === null) {
|
||||
$error = new AssetNotFound(new Exception('Simbrief OFP not found'));
|
||||
return $error->getResponse();
|
||||
|
||||
@@ -17,6 +17,7 @@ class Fare extends Resource
|
||||
'name' => $this->name,
|
||||
'capacity' => $this->capacity,
|
||||
'cost' => $this->cost,
|
||||
'count' => $this->count ?? 0,
|
||||
'price' => $this->price,
|
||||
'type' => $this->type,
|
||||
'notes' => $this->notes,
|
||||
|
||||
@@ -11,9 +11,27 @@ class SimBrief extends Resource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
$data = [
|
||||
'id' => $this->id,
|
||||
'url' => url(route('api.flights.briefing', ['id' => $this->id])),
|
||||
];
|
||||
|
||||
try {
|
||||
if (!empty($this->fare_data)) {
|
||||
$fares = [];
|
||||
$fare_data = json_decode($this->fare_data, true);
|
||||
foreach ($fare_data as $fare) {
|
||||
$fares[] = new \App\Models\Fare($fare);
|
||||
}
|
||||
|
||||
$this->aircraft->subfleet->fares = collect($fares);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Invalid fare data
|
||||
}
|
||||
|
||||
$data['subfleet'] = new Subfleet($this->aircraft->subfleet);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ class User extends Resource
|
||||
'id' => $this->id,
|
||||
'pilot_id' => $this->pilot_id,
|
||||
'ident' => $this->ident,
|
||||
'name' => $this->name,
|
||||
'name' => $this->name_private,
|
||||
'name_private' => $this->name_private,
|
||||
'email' => $this->email,
|
||||
'avatar' => $this->resolveAvatarUrl(),
|
||||
'rank_id' => $this->rank_id,
|
||||
'home_airport' => $this->home_airport_id,
|
||||
|
||||
@@ -20,12 +20,14 @@ class Fare extends Model
|
||||
public $table = 'fares';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'code',
|
||||
'name',
|
||||
'type',
|
||||
'price',
|
||||
'cost',
|
||||
'capacity',
|
||||
'count',
|
||||
'notes',
|
||||
'active',
|
||||
];
|
||||
@@ -34,6 +36,7 @@ class Fare extends Model
|
||||
'price' => 'float',
|
||||
'cost' => 'float',
|
||||
'capacity' => 'integer',
|
||||
'count' => 'integer',
|
||||
'type' => 'integer',
|
||||
'active' => 'boolean',
|
||||
];
|
||||
|
||||
@@ -305,7 +305,9 @@ class Pirep extends Model
|
||||
public function getFieldsAttribute()
|
||||
{
|
||||
$custom_fields = PirepField::all();
|
||||
$field_values = PirepFieldValue::where('pirep_id', $this->id)->get();
|
||||
$field_values = PirepFieldValue::where('pirep_id', $this->id)
|
||||
->orderBy('created_at', 'asc')
|
||||
->get();
|
||||
|
||||
// Merge the field values into $fields
|
||||
foreach ($custom_fields as $field) {
|
||||
@@ -321,7 +323,7 @@ class Pirep extends Model
|
||||
}
|
||||
}
|
||||
|
||||
return $field_values->sortBy('source');
|
||||
return $field_values;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,11 +13,13 @@ use Illuminate\Support\Collection;
|
||||
* @property string $acars_xml
|
||||
* @property string $ofp_xml
|
||||
* @property string $ofp_html
|
||||
* @property string $fare_data JSON string of the fare data that was generated
|
||||
* @property Collection $images
|
||||
* @property Collection $files
|
||||
* @property Flight $flight
|
||||
* @property User $user
|
||||
* @property SimBriefXML $xml
|
||||
* @property Aircraft $aircraft
|
||||
* @property string $acars_flightplan_url
|
||||
*/
|
||||
class SimBrief extends Model
|
||||
@@ -29,9 +31,11 @@ class SimBrief extends Model
|
||||
'id',
|
||||
'user_id',
|
||||
'flight_id',
|
||||
'aircraft_id',
|
||||
'pirep_id',
|
||||
'acars_xml',
|
||||
'ofp_xml',
|
||||
'fare_data',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
@@ -80,6 +84,11 @@ class SimBrief extends Model
|
||||
* Relationships
|
||||
*/
|
||||
|
||||
public function aircraft()
|
||||
{
|
||||
return $this->belongsTo(Aircraft::class, 'aircraft_id');
|
||||
}
|
||||
|
||||
public function flight()
|
||||
{
|
||||
if (!empty($this->attributes['flight_id'])) {
|
||||
|
||||
@@ -51,6 +51,7 @@ class BidService extends Service
|
||||
'flight',
|
||||
'flight.fares',
|
||||
'flight.simbrief',
|
||||
'flight.simbrief.aircraft',
|
||||
'flight.subfleets',
|
||||
'flight.subfleets.aircraft',
|
||||
'flight.subfleets.fares',
|
||||
|
||||
@@ -172,6 +172,24 @@ class FareService extends Service
|
||||
return $fare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the fares for an aircraft. check the pivot
|
||||
* table to see if the price/cost/capacity has been overridden
|
||||
* and return the correct amounts.
|
||||
*
|
||||
* @param Subfleet $subfleet
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getForSubfleet(Subfleet $subfleet)
|
||||
{
|
||||
$fares = $subfleet->fares->map(function ($fare) {
|
||||
return $this->getFares($fare);
|
||||
});
|
||||
|
||||
return $fares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a fare to an flight
|
||||
*
|
||||
@@ -240,24 +258,6 @@ class FareService extends Service
|
||||
return $subfleet;
|
||||
}
|
||||
|
||||
/**
|
||||
* return all the fares for an aircraft. check the pivot
|
||||
* table to see if the price/cost/capacity has been overridden
|
||||
* and return the correct amounts.
|
||||
*
|
||||
* @param Subfleet $subfleet
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getForSubfleet(Subfleet $subfleet)
|
||||
{
|
||||
$fares = $subfleet->fares->map(function ($fare) {
|
||||
return $this->getFares($fare);
|
||||
});
|
||||
|
||||
return $fares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the fare from a subfleet
|
||||
*
|
||||
|
||||
@@ -29,11 +29,18 @@ class SimBriefService extends Service
|
||||
* @param string $user_id User who generated this
|
||||
* @param string $ofp_id The SimBrief OFP ID
|
||||
* @param string $flight_id The flight ID
|
||||
* @param string $ac_id The aircraft ID
|
||||
* @param array $fares Full list of fares for the flightß
|
||||
*
|
||||
* @return SimBrief|null
|
||||
*/
|
||||
public function downloadOfp(string $user_id, string $ofp_id, string $flight_id)
|
||||
{
|
||||
public function downloadOfp(
|
||||
string $user_id,
|
||||
string $ofp_id,
|
||||
string $flight_id,
|
||||
string $ac_id,
|
||||
array $fares = []
|
||||
) {
|
||||
$uri = str_replace('{id}', $ofp_id, config('phpvms.simbrief_url'));
|
||||
|
||||
$opts = [
|
||||
@@ -57,11 +64,17 @@ class SimBriefService extends Service
|
||||
$ofp = simplexml_load_string($body, SimBriefXML::class);
|
||||
|
||||
$attrs = [
|
||||
'user_id' => $user_id,
|
||||
'flight_id' => $flight_id,
|
||||
'ofp_xml' => $ofp->asXML(),
|
||||
'user_id' => $user_id,
|
||||
'flight_id' => $flight_id,
|
||||
'aircraft_id' => $ac_id,
|
||||
'ofp_xml' => $ofp->asXML(),
|
||||
];
|
||||
|
||||
// encode the fares data to JSONß
|
||||
if (!empty($fares)) {
|
||||
$attrs['fare_data'] = json_encode($fares);
|
||||
}
|
||||
|
||||
// Try to download the XML file for ACARS. If it doesn't work, try to modify the main OFP
|
||||
$acars_xml = $this->getAcarsOFP($ofp);
|
||||
if (empty($acars_xml)) {
|
||||
|
||||
Reference in New Issue
Block a user