* Add flight level field to PIREP field closes #401

* Default value for distance 0 closes #400

* Block airline deletion if assets exist #367

* Formatting

* Move some of the base exception classes

* Fix skin references to use settings table

* Set default for theme name if setting is wrong
This commit is contained in:
Nabeel S
2019-11-19 10:06:07 -05:00
committed by GitHub
parent c643833496
commit 3ec64c989b
39 changed files with 237 additions and 117 deletions
@@ -3,8 +3,12 @@
namespace App\Exceptions; namespace App\Exceptions;
use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException; use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
abstract class HttpException extends SymfonyHttpException /**
* Abstract class for an exception which needs to satisty the RFC 78707 interface
*/
abstract class AbstractHttpException extends SymfonyHttpException implements HttpExceptionInterface
{ {
/** /**
* Return the RFC 7807 error type (without the URL root) * Return the RFC 7807 error type (without the URL root)
@@ -45,7 +49,7 @@ abstract class HttpException extends SymfonyHttpException
/** /**
* Return a response object that can be used by Laravel * Return a response object that can be used by Laravel
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/ */
public function getResponse() public function getResponse()
{ {
@@ -53,11 +57,6 @@ abstract class HttpException extends SymfonyHttpException
$headers['content-type'] = 'application/problem+json'; $headers['content-type'] = 'application/problem+json';
$headers = array_merge($headers, $this->getHeaders()); $headers = array_merge($headers, $this->getHeaders());
return response() return response()->json($this->getJson(), $this->getStatusCode(), $headers);
->json(
$this->getJson(),
$this->getStatusCode(),
$headers
);
} }
} }
+1 -1
View File
@@ -7,7 +7,7 @@ use App\Models\Aircraft;
/** /**
* Class AircraftNotAtAirport * Class AircraftNotAtAirport
*/ */
class AircraftNotAtAirport extends HttpException class AircraftNotAtAirport extends AbstractHttpException
{ {
public const MESSAGE = 'The aircraft is not at the departure airport'; public const MESSAGE = 'The aircraft is not at the departure airport';
+1 -1
View File
@@ -5,7 +5,7 @@ namespace App\Exceptions;
use App\Models\Aircraft; use App\Models\Aircraft;
use App\Models\User; use App\Models\User;
class AircraftPermissionDenied extends HttpException class AircraftPermissionDenied extends AbstractHttpException
{ {
public const MESSAGE = 'User is not allowed to fly this aircraft'; public const MESSAGE = 'User is not allowed to fly this aircraft';
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Exceptions; namespace App\Exceptions;
class AirportNotFound extends HttpException class AirportNotFound extends AbstractHttpException
{ {
private $icao; private $icao;
@@ -1,11 +1,10 @@
<?php <?php
namespace App\Exceptions\Converters; namespace App\Exceptions;
use App\Exceptions\HttpException;
use Exception; use Exception;
class NotFound extends HttpException class AssetNotFound extends AbstractHttpException
{ {
private $exception; private $exception;
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\Flight; use App\Models\Flight;
class BidExistsForFlight extends HttpException class BidExistsForFlight extends AbstractHttpException
{ {
private $flight; private $flight;
@@ -2,10 +2,10 @@
namespace App\Exceptions\Converters; namespace App\Exceptions\Converters;
use App\Exceptions\HttpException; use App\Exceptions\AbstractHttpException;
use Exception; use Exception;
class GenericException extends HttpException class GenericExceptionAbstract extends AbstractHttpException
{ {
private $exception; private $exception;
@@ -2,10 +2,10 @@
namespace App\Exceptions\Converters; namespace App\Exceptions\Converters;
use App\Exceptions\HttpException; use App\Exceptions\AbstractHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException; use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException;
class SymfonyException extends HttpException class SymfonyException extends AbstractHttpException
{ {
private $exception; private $exception;
@@ -2,11 +2,10 @@
namespace App\Exceptions\Converters; namespace App\Exceptions\Converters;
use App\Exceptions\HttpException; use App\Exceptions\AbstractHttpException;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException as IlluminateValidationException; use Illuminate\Validation\ValidationException as IlluminateValidationException;
class ValidationException extends HttpException class ValidationException extends AbstractHttpException
{ {
private $validationException; private $validationException;
private $errorDetail; private $errorDetail;
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\Flight; use App\Models\Flight;
class DuplicateFlight extends HttpException class DuplicateFlight extends AbstractHttpException
{ {
private $flight; private $flight;
+11 -11
View File
@@ -2,8 +2,7 @@
namespace App\Exceptions; namespace App\Exceptions;
use App\Exceptions\Converters\GenericException; use App\Exceptions\Converters\GenericExceptionAbstract;
use App\Exceptions\Converters\NotFound;
use App\Exceptions\Converters\SymfonyException; use App\Exceptions\Converters\SymfonyException;
use App\Exceptions\Converters\ValidationException; use App\Exceptions\Converters\ValidationException;
use Exception; use Exception;
@@ -33,7 +32,7 @@ class Handler extends ExceptionHandler
protected $dontReport = [ protected $dontReport = [
AuthenticationException::class, AuthenticationException::class,
AuthorizationException::class, AuthorizationException::class,
HttpException::class, AbstractHttpException::class,
IlluminateValidationException::class, IlluminateValidationException::class,
ModelNotFoundException::class, ModelNotFoundException::class,
SymfonyHttpException::class, SymfonyHttpException::class,
@@ -53,7 +52,7 @@ class Handler extends ExceptionHandler
if ($request->is('api/*')) { if ($request->is('api/*')) {
Log::error('API Error', $exception->getTrace()); Log::error('API Error', $exception->getTrace());
if ($exception instanceof HttpException) { if ($exception instanceof AbstractHttpException) {
return $exception->getResponse(); return $exception->getResponse();
} }
@@ -63,7 +62,7 @@ class Handler extends ExceptionHandler
if ($exception instanceof ModelNotFoundException || if ($exception instanceof ModelNotFoundException ||
$exception instanceof NotFoundHttpException) { $exception instanceof NotFoundHttpException) {
$error = new NotFound($exception); $error = new AssetNotFound($exception);
return $error->getResponse(); return $error->getResponse();
} }
@@ -79,11 +78,11 @@ class Handler extends ExceptionHandler
return $error->getResponse(); return $error->getResponse();
} }
$error = new GenericException($exception); $error = new GenericExceptionAbstract($exception);
return $error->getResponse(); return $error->getResponse();
} }
if ($exception instanceof HttpException if ($exception instanceof AbstractHttpException
&& $exception->getStatusCode() === 403) { && $exception->getStatusCode() === 403) {
return redirect()->guest('login'); return redirect()->guest('login');
} }
@@ -112,24 +111,25 @@ class Handler extends ExceptionHandler
/** /**
* Render the given HttpException. * Render the given HttpException.
* *
* @param HttpException $e * @param AbstractHttpException $e
* *
* @return \Illuminate\Http\Response|Response * @return \Illuminate\Http\Response|Response
*/ */
protected function renderHttpException(HttpExceptionInterface $e) protected function renderHttpException(HttpExceptionInterface $e)
{ {
Flash::error($e->getMessage());
$status = $e->getStatusCode(); $status = $e->getStatusCode();
view()->replaceNamespace('errors', [ view()->replaceNamespace('errors', [
resource_path('views/layouts/'.config('phpvms.skin').'/errors'), resource_path('views/layouts/'.setting('general.theme', 'default').'/errors'),
resource_path('views/errors'), resource_path('views/errors'),
__DIR__.'/views', __DIR__.'/views',
]); ]);
if (view()->exists("errors::{$status}")) { if (view()->exists("errors::{$status}")) {
//if (view()->exists('layouts' . config('phpvms.skin') .'.errors.' .$status)) {
return response()->view("errors::{$status}", [ return response()->view("errors::{$status}", [
'exception' => $e, 'exception' => $e,
'SKIN_NAME' => config('phpvms.skin'), 'SKIN_NAME' => setting('general.theme', 'default'),
], $status, $e->getHeaders()); ], $status, $e->getHeaders());
} }
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\Pirep; use App\Models\Pirep;
class PirepCancelNotAllowed extends HttpException class PirepCancelNotAllowed extends AbstractHttpException
{ {
private $pirep; private $pirep;
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\Pirep; use App\Models\Pirep;
class PirepCancelled extends HttpException class PirepCancelled extends AbstractHttpException
{ {
private $pirep; private $pirep;
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Exceptions; namespace App\Exceptions;
class Unauthenticated extends HttpException class Unauthenticated extends AbstractHttpException
{ {
public function __construct() public function __construct()
{ {
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\User; use App\Models\User;
class UserBidLimit extends HttpException class UserBidLimit extends AbstractHttpException
{ {
private $user; private $user;
+1 -1
View File
@@ -5,7 +5,7 @@ namespace App\Exceptions;
use App\Models\Airport; use App\Models\Airport;
use App\Models\User; use App\Models\User;
class UserNotAtAirport extends HttpException class UserNotAtAirport extends AbstractHttpException
{ {
public const MESSAGE = 'Pilot is not at the departure airport'; public const MESSAGE = 'Pilot is not at the departure airport';
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Exceptions;
use App\Models\User; use App\Models\User;
class UserPilotIdExists extends HttpException class UserPilotIdExists extends AbstractHttpException
{ {
public const MESSAGE = 'A user with this pilot ID already exists'; public const MESSAGE = 'A user with this pilot ID already exists';
@@ -6,27 +6,28 @@ use App\Contracts\Controller;
use App\Http\Requests\CreateAirlineRequest; use App\Http\Requests\CreateAirlineRequest;
use App\Http\Requests\UpdateAirlineRequest; use App\Http\Requests\UpdateAirlineRequest;
use App\Repositories\AirlineRepository; use App\Repositories\AirlineRepository;
use App\Services\AirlineService;
use App\Support\Countries; use App\Support\Countries;
use Flash;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Laracasts\Flash\Flash;
use Prettus\Repository\Criteria\RequestCriteria; use Prettus\Repository\Criteria\RequestCriteria;
use Response;
/**
* Class AirlinesController
*/
class AirlinesController extends Controller class AirlinesController extends Controller
{ {
private $airlineRepo; private $airlineRepo;
private $airlineSvc;
/** /**
* AirlinesController constructor. * AirlinesController constructor.
* *
* @param AirlineRepository $airlinesRepo * @param AirlineRepository $airlinesRepo
* @param $airlineSvc
*/ */
public function __construct(AirlineRepository $airlinesRepo) public function __construct(AirlineRepository $airlinesRepo, AirlineService $airlineSvc)
{ {
$this->airlineRepo = $airlinesRepo; $this->airlineRepo = $airlinesRepo;
$this->airlineSvc = $airlineSvc;
} }
/** /**
@@ -145,13 +146,18 @@ class AirlinesController extends Controller
*/ */
public function destroy($id) public function destroy($id)
{ {
$airlines = $this->airlineRepo->findWithoutFail($id); $airline = $this->airlineRepo->findWithoutFail($id);
if (empty($airlines)) { if (empty($airline)) {
Flash::error('Airlines not found'); Flash::error('Airlines not found');
return redirect(route('admin.airlines.index')); return redirect(route('admin.airlines.index'));
} }
if (!$this->airlineSvc->canDeleteAirline($airline)) {
Flash::error('Airlines cannot be deleted; flights/PIREPs/subfleets exist');
return redirect(route('admin.airlines.index'));
}
$this->airlineRepo->delete($id); $this->airlineRepo->delete($id);
Flash::success('Airlines deleted successfully.'); Flash::success('Airlines deleted successfully.');
+6 -8
View File
@@ -22,15 +22,13 @@ class Acars extends Response
$res = parent::toArray($request); $res = parent::toArray($request);
// Set these to the response units // Set these to the response units
if (!empty($res['distance'])) { $distance = !empty($res['distance']) ? $res['distance'] : 0;
$distance = new Distance($res['distance'], config('phpvms.internal_units.distance')); $distance = new Distance($distance, config('phpvms.internal_units.distance'));
$res['distance'] = $distance->getResponseUnits(); $res['distance'] = $distance->getResponseUnits();
}
if (!empty($res['fuel'])) { $fuel = !empty($res['fuel']) ? $res['fuel'] : 0;
$fuel = new Fuel($res['fuel'], config('phpvms.internal_units.fuel')); $fuel = new Fuel($fuel, config('phpvms.internal_units.fuel'));
$res['fuel'] = $fuel->getResponseUnits(); $res['fuel'] = $fuel->getResponseUnits();
}
return $res; return $res;
} }
+10
View File
@@ -96,4 +96,14 @@ class Airline extends Model
{ {
$this->attributes['icao'] = strtoupper($icao); $this->attributes['icao'] = strtoupper($icao);
} }
public function flights()
{
return $this->belongsTo(Flight::class, 'airline_id');
}
public function pireps()
{
return $this->belongsTo(Pirep::class, 'airline_id');
}
} }
+2 -30
View File
@@ -35,6 +35,7 @@ use Illuminate\Support\Collection;
* @property float fuel_used * @property float fuel_used
* @property float distance * @property float distance
* @property float planned_distance * @property float planned_distance
* @property int level
* @property string route * @property string route
* @property int score * @property int score
* @property User user * @property User user
@@ -127,6 +128,7 @@ class Pirep extends Model
'arr_airport_id' => 'required', 'arr_airport_id' => 'required',
'block_fuel' => 'required|numeric', 'block_fuel' => 'required|numeric',
'fuel_used' => 'required|numeric', 'fuel_used' => 'required|numeric',
'level' => 'nullable|numeric',
'notes' => 'nullable', 'notes' => 'nullable',
'route' => 'nullable', 'route' => 'nullable',
]; ];
@@ -296,36 +298,6 @@ class Pirep extends Model
return $field_values->sortBy('source'); return $field_values->sortBy('source');
} }
/**
* Look up the flight, based on the PIREP flight info
*
* @param mixed $value
*
* @return Flight|null
*/
/*public function getFlightAttribute(): ?Flight
{
if (!empty($this->flight_id)) {
return Flight::find($this->flight_id);
}
$where = [
'airline_id' => $this->airline_id,
'flight_number' => $this->flight_number,
'active' => true,
];
if (filled($this->route_code)) {
$where['route_code'] = $this->route_code;
}
if (filled($this->route_leg)) {
$where['route_leg'] = $this->route_leg;
}
return Flight::where($where)->first();
}*/
/** /**
* Set the amount of fuel used * Set the amount of fuel used
* *
+1
View File
@@ -18,6 +18,7 @@ use App\Models\Traits\FilesTrait;
* @property float cost_block_hour * @property float cost_block_hour
* @property float cost_delay_minute * @property float cost_delay_minute
* @property Airline airline * @property Airline airline
* @property int airline_id
*/ */
class Subfleet extends Model class Subfleet extends Model
{ {
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Services;
use App\Contracts\Service;
use App\Models\Airline;
use App\Repositories\AirlineRepository;
use App\Repositories\FlightRepository;
use App\Repositories\PirepRepository;
use App\Repositories\SubfleetRepository;
class AirlineService extends Service
{
private $airlineRepo;
private $flightRepo;
private $pirepRepo;
private $subfleetRepo;
public function __construct(
AirlineRepository $airlineRepo,
FlightRepository $flightRepo,
PirepRepository $pirepRepo,
SubfleetRepository $subfleetRepo
) {
$this->airlineRepo = $airlineRepo;
$this->flightRepo = $flightRepo;
$this->pirepRepo = $pirepRepo;
$this->subfleetRepo = $subfleetRepo;
}
/**
* Can the airline be deleted? Check if there are flights, etc associated with it
*
* @param Airline $airline
*
* @return bool
*/
public function canDeleteAirline(Airline $airline): bool
{
// Check these asset counts in these repositories
$repos = [
$this->pirepRepo,
$this->flightRepo,
$this->subfleetRepo,
];
$w = ['airline_id' => $airline->id];
foreach ($repos as $repo) {
if ($repo->count($w) > 0) {
return false;
}
}
return true;
}
}
+9 -2
View File
@@ -123,8 +123,7 @@ if (!function_exists('skin_view')) {
return view($template, $vars, $merge_data); return view($template, $vars, $merge_data);
} }
// TODO: Look for an overridden template in a special folder $tpl = 'layouts/'.setting('general.theme', 'default').'/'.$template;
$tpl = 'layouts/'.config('phpvms.skin').'/'.$template;
return view($tpl, $vars, $merge_data); return view($tpl, $vars, $merge_data);
} }
@@ -134,6 +133,14 @@ if (!function_exists('skin_view')) {
* Shortcut for retrieving a setting value * Shortcut for retrieving a setting value
*/ */
if (!function_exists('setting')) { if (!function_exists('setting')) {
/**
* Read a setting from the settings table
*
* @param $key
* @param mixed $default
*
* @return mixed|null
*/
function setting($key, $default = null) function setting($key, $default = null)
{ {
$settingRepo = app('setting'); $settingRepo = app('setting');
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -1,14 +1,14 @@
{ {
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=88270e919809fead277c", "/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=218bdf369c2dd02856cc",
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=20b82d8dbacf7e058df2", "/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=20b82d8dbacf7e058df2",
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=9f24c5e6612e74065901", "/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=9f24c5e6612e74065901",
"/assets/frontend/js/app.js.map": "/assets/frontend/js/app.js.map?id=0019c21255cb4eca716d", "/assets/frontend/js/app.js.map": "/assets/frontend/js/app.js.map?id=6b1ab9e89d979ba41fc4",
"/assets/frontend/css/now-ui-kit.css.map": "/assets/frontend/css/now-ui-kit.css.map?id=fdc4f42ad9047d073145", "/assets/frontend/css/now-ui-kit.css.map": "/assets/frontend/css/now-ui-kit.css.map?id=fdc4f42ad9047d073145",
"/assets/admin/css/vendor.min.css.map": "/assets/admin/css/vendor.min.css.map?id=c266c31652dea865307c", "/assets/admin/css/vendor.min.css.map": "/assets/admin/css/vendor.min.css.map?id=c266c31652dea865307c",
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=cd8b03d3b7bd54e960ca", "/assets/admin/js/app.js": "/assets/admin/js/app.js?id=37a4ecf79cdc64e724e5",
"/assets/admin/js/app.js.map": "/assets/admin/js/app.js.map?id=a43168e6da458119da61", "/assets/admin/js/app.js.map": "/assets/admin/js/app.js.map?id=295a34b9c67c5a178d8a",
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=7eb8b66dce0064082abc", "/assets/installer/js/app.js": "/assets/installer/js/app.js?id=aa8661200da32787441c",
"/assets/installer/js/app.js.map": "/assets/installer/js/app.js.map?id=b277e94eb1368204a7d5", "/assets/installer/js/app.js.map": "/assets/installer/js/app.js.map?id=917f0f8bcd02d558f615",
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56", "/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56",
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56", "/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=349344e92fb16221dd56",
"/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a", "/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a",
+15
View File
@@ -3,8 +3,10 @@ const rivets = require('rivets');
/** /**
* Generic formatter to prepend * Generic formatter to prepend
*
* @param value * @param value
* @param prepend * @param prepend
*
* @returns {*} * @returns {*}
*/ */
rivets.formatters.prepend = function (value, prepend) { rivets.formatters.prepend = function (value, prepend) {
@@ -13,7 +15,9 @@ rivets.formatters.prepend = function (value, prepend) {
/** /**
* Format minutes into HHh MMm * Format minutes into HHh MMm
*
* @param value * @param value
*
* @returns {string} * @returns {string}
*/ */
rivets.formatters.time_hm = function (value) { rivets.formatters.time_hm = function (value) {
@@ -26,6 +30,7 @@ rivets.formatters.time_hm = function (value) {
* *
* @param value * @param value
* @param len * @param len
*
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.gt = (value, len) => value.length > len; rivets.formatters.gt = (value, len) => value.length > len;
@@ -34,6 +39,7 @@ rivets.formatters.gt = (value, len) => value.length > len;
* *
* @param value * @param value
* @param len * @param len
*
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.lt = (value, len) => value.length < len; rivets.formatters.lt = (value, len) => value.length < len;
@@ -42,6 +48,15 @@ rivets.formatters.lt = (value, len) => value.length < len;
* *
* @param value * @param value
* @param len * @param len
*
* @returns {boolean} * @returns {boolean}
*/ */
rivets.formatters.eq = (value, len) => value.length > len; rivets.formatters.eq = (value, len) => value.length > len;
/**
* Use a default value if value is null or blank
*
* @param value Value to use
* @param def Default value to use if value is null
*/
rivets.formatters.fallback = (value, def) => value || def;
@@ -95,7 +95,7 @@ flight reports that have been filed. You've been warned!
</div> </div>
<div class="row"> <div class="row">
<div class="col-3"> <div class="col-6">
{{ Form::label('hours', __('flights.flighttime')) }} {{ Form::label('hours', __('flights.flighttime')) }}
@if(!empty($pirep) && $pirep->read_only) @if(!empty($pirep) && $pirep->read_only)
<p> <p>
@@ -124,6 +124,22 @@ flight reports that have been filed. You've been warned!
<p class="text-danger">{{ $errors->first('minutes') }}</p> <p class="text-danger">{{ $errors->first('minutes') }}</p>
@endif @endif
</div> </div>
<div class="col-6">
{{ Form::label('level', __('flights.level')) }} ({{config('phpvms.internal_units.altitude')}})
@if(!empty($pirep) && $pirep->read_only)
<p>{{ $pirep->level }}</p>
@else
<div class="input-group input-group-sm form-group">
{{ Form::number('level', null, [
'class' => 'form-control',
'min' => '0',
'step' => '0.01',
'readonly' => (!empty($pirep) && $pirep->read_only),
]) }}
</div>
<p class="text-danger">{{ $errors->first('level') }}</p>
@endif
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -98,8 +98,8 @@ and being mindful of the rivets bindings
<td>{ pirep.aircraft.name }</td> <td>{ pirep.aircraft.name }</td>
<td>{ pirep.position.altitude }</td> <td>{ pirep.position.altitude }</td>
<td>{ pirep.position.gs }</td> <td>{ pirep.position.gs }</td>
<td>{ pirep.position.distance.{{setting('units.distance')}} } / <td>{ pirep.position.distance.{{setting('units.distance')}} | fallback 0 } /
{ pirep.planned_distance.{{setting('units.distance')}} } { pirep.planned_distance.{{setting('units.distance')}} | fallback 0 }
</td> </td>
<td>{ pirep.status_text }</td> <td>{ pirep.status_text }</td>
</tr> </tr>
+42
View File
@@ -0,0 +1,42 @@
<?php
use App\Services\AirlineService;
class AirlineTest extends TestCase
{
protected $airlineSvc;
public function setUp(): void
{
parent::setUp();
$this->addData('base');
$this->airlineSvc = app(AirlineService::class);
}
/**
* Try deleting an airline which has flights/other assets that exist
*/
public function testDeleteAirlineWithFlight()
{
$airline = factory(App\Models\Airline::class)->create();
factory(App\Models\Flight::class)->create([
'airline_id' => $airline->id,
]);
$this->assertFalse($this->airlineSvc->canDeleteAirline($airline));
}
/**
* Try deleting an airline with existing PIREPs
*/
public function testDeleteAirlineWithPirep()
{
$airline = factory(App\Models\Airline::class)->create();
factory(App\Models\Pirep::class)->create([
'airline_id' => $airline->id,
]);
$this->assertFalse($this->airlineSvc->canDeleteAirline($airline));
}
}