Fixes (#435)
* 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:
parent
c643833496
commit
3ec64c989b
@ -3,8 +3,12 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
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)
|
||||
@ -45,7 +49,7 @@ abstract class HttpException extends SymfonyHttpException
|
||||
/**
|
||||
* Return a response object that can be used by Laravel
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
@ -53,11 +57,6 @@ abstract class HttpException extends SymfonyHttpException
|
||||
$headers['content-type'] = 'application/problem+json';
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
|
||||
return response()
|
||||
->json(
|
||||
$this->getJson(),
|
||||
$this->getStatusCode(),
|
||||
$headers
|
||||
);
|
||||
return response()->json($this->getJson(), $this->getStatusCode(), $headers);
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ use App\Models\Aircraft;
|
||||
/**
|
||||
* Class AircraftNotAtAirport
|
||||
*/
|
||||
class AircraftNotAtAirport extends HttpException
|
||||
class AircraftNotAtAirport extends AbstractHttpException
|
||||
{
|
||||
public const MESSAGE = 'The aircraft is not at the departure airport';
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace App\Exceptions;
|
||||
use App\Models\Aircraft;
|
||||
use App\Models\User;
|
||||
|
||||
class AircraftPermissionDenied extends HttpException
|
||||
class AircraftPermissionDenied extends AbstractHttpException
|
||||
{
|
||||
public const MESSAGE = 'User is not allowed to fly this aircraft';
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
class AirportNotFound extends HttpException
|
||||
class AirportNotFound extends AbstractHttpException
|
||||
{
|
||||
private $icao;
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\Converters;
|
||||
namespace App\Exceptions;
|
||||
|
||||
use App\Exceptions\HttpException;
|
||||
use Exception;
|
||||
|
||||
class NotFound extends HttpException
|
||||
class AssetNotFound extends AbstractHttpException
|
||||
{
|
||||
private $exception;
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\Flight;
|
||||
|
||||
class BidExistsForFlight extends HttpException
|
||||
class BidExistsForFlight extends AbstractHttpException
|
||||
{
|
||||
private $flight;
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Exceptions\Converters;
|
||||
|
||||
use App\Exceptions\HttpException;
|
||||
use App\Exceptions\AbstractHttpException;
|
||||
use Exception;
|
||||
|
||||
class GenericException extends HttpException
|
||||
class GenericExceptionAbstract extends AbstractHttpException
|
||||
{
|
||||
private $exception;
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Exceptions\Converters;
|
||||
|
||||
use App\Exceptions\HttpException;
|
||||
use App\Exceptions\AbstractHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException as SymfonyHttpException;
|
||||
|
||||
class SymfonyException extends HttpException
|
||||
class SymfonyException extends AbstractHttpException
|
||||
{
|
||||
private $exception;
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
namespace App\Exceptions\Converters;
|
||||
|
||||
use App\Exceptions\HttpException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Exceptions\AbstractHttpException;
|
||||
use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
||||
|
||||
class ValidationException extends HttpException
|
||||
class ValidationException extends AbstractHttpException
|
||||
{
|
||||
private $validationException;
|
||||
private $errorDetail;
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\Flight;
|
||||
|
||||
class DuplicateFlight extends HttpException
|
||||
class DuplicateFlight extends AbstractHttpException
|
||||
{
|
||||
private $flight;
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use App\Exceptions\Converters\GenericException;
|
||||
use App\Exceptions\Converters\NotFound;
|
||||
use App\Exceptions\Converters\GenericExceptionAbstract;
|
||||
use App\Exceptions\Converters\SymfonyException;
|
||||
use App\Exceptions\Converters\ValidationException;
|
||||
use Exception;
|
||||
@ -33,7 +32,7 @@ class Handler extends ExceptionHandler
|
||||
protected $dontReport = [
|
||||
AuthenticationException::class,
|
||||
AuthorizationException::class,
|
||||
HttpException::class,
|
||||
AbstractHttpException::class,
|
||||
IlluminateValidationException::class,
|
||||
ModelNotFoundException::class,
|
||||
SymfonyHttpException::class,
|
||||
@ -53,7 +52,7 @@ class Handler extends ExceptionHandler
|
||||
if ($request->is('api/*')) {
|
||||
Log::error('API Error', $exception->getTrace());
|
||||
|
||||
if ($exception instanceof HttpException) {
|
||||
if ($exception instanceof AbstractHttpException) {
|
||||
return $exception->getResponse();
|
||||
}
|
||||
|
||||
@ -63,7 +62,7 @@ class Handler extends ExceptionHandler
|
||||
|
||||
if ($exception instanceof ModelNotFoundException ||
|
||||
$exception instanceof NotFoundHttpException) {
|
||||
$error = new NotFound($exception);
|
||||
$error = new AssetNotFound($exception);
|
||||
return $error->getResponse();
|
||||
}
|
||||
|
||||
@ -79,11 +78,11 @@ class Handler extends ExceptionHandler
|
||||
return $error->getResponse();
|
||||
}
|
||||
|
||||
$error = new GenericException($exception);
|
||||
$error = new GenericExceptionAbstract($exception);
|
||||
return $error->getResponse();
|
||||
}
|
||||
|
||||
if ($exception instanceof HttpException
|
||||
if ($exception instanceof AbstractHttpException
|
||||
&& $exception->getStatusCode() === 403) {
|
||||
return redirect()->guest('login');
|
||||
}
|
||||
@ -112,24 +111,25 @@ class Handler extends ExceptionHandler
|
||||
/**
|
||||
* Render the given HttpException.
|
||||
*
|
||||
* @param HttpException $e
|
||||
* @param AbstractHttpException $e
|
||||
*
|
||||
* @return \Illuminate\Http\Response|Response
|
||||
*/
|
||||
protected function renderHttpException(HttpExceptionInterface $e)
|
||||
{
|
||||
Flash::error($e->getMessage());
|
||||
|
||||
$status = $e->getStatusCode();
|
||||
view()->replaceNamespace('errors', [
|
||||
resource_path('views/layouts/'.config('phpvms.skin').'/errors'),
|
||||
resource_path('views/layouts/'.setting('general.theme', 'default').'/errors'),
|
||||
resource_path('views/errors'),
|
||||
__DIR__.'/views',
|
||||
]);
|
||||
|
||||
if (view()->exists("errors::{$status}")) {
|
||||
//if (view()->exists('layouts' . config('phpvms.skin') .'.errors.' .$status)) {
|
||||
return response()->view("errors::{$status}", [
|
||||
'exception' => $e,
|
||||
'SKIN_NAME' => config('phpvms.skin'),
|
||||
'SKIN_NAME' => setting('general.theme', 'default'),
|
||||
], $status, $e->getHeaders());
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\Pirep;
|
||||
|
||||
class PirepCancelNotAllowed extends HttpException
|
||||
class PirepCancelNotAllowed extends AbstractHttpException
|
||||
{
|
||||
private $pirep;
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\Pirep;
|
||||
|
||||
class PirepCancelled extends HttpException
|
||||
class PirepCancelled extends AbstractHttpException
|
||||
{
|
||||
private $pirep;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
class Unauthenticated extends HttpException
|
||||
class Unauthenticated extends AbstractHttpException
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserBidLimit extends HttpException
|
||||
class UserBidLimit extends AbstractHttpException
|
||||
{
|
||||
private $user;
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace App\Exceptions;
|
||||
use App\Models\Airport;
|
||||
use App\Models\User;
|
||||
|
||||
class UserNotAtAirport extends HttpException
|
||||
class UserNotAtAirport extends AbstractHttpException
|
||||
{
|
||||
public const MESSAGE = 'Pilot is not at the departure airport';
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserPilotIdExists extends HttpException
|
||||
class UserPilotIdExists extends AbstractHttpException
|
||||
{
|
||||
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\UpdateAirlineRequest;
|
||||
use App\Repositories\AirlineRepository;
|
||||
use App\Services\AirlineService;
|
||||
use App\Support\Countries;
|
||||
use Flash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Laracasts\Flash\Flash;
|
||||
use Prettus\Repository\Criteria\RequestCriteria;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* Class AirlinesController
|
||||
*/
|
||||
class AirlinesController extends Controller
|
||||
{
|
||||
private $airlineRepo;
|
||||
private $airlineSvc;
|
||||
|
||||
/**
|
||||
* AirlinesController constructor.
|
||||
*
|
||||
* @param AirlineRepository $airlinesRepo
|
||||
* @param $airlineSvc
|
||||
*/
|
||||
public function __construct(AirlineRepository $airlinesRepo)
|
||||
public function __construct(AirlineRepository $airlinesRepo, AirlineService $airlineSvc)
|
||||
{
|
||||
$this->airlineRepo = $airlinesRepo;
|
||||
$this->airlineSvc = $airlineSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,13 +146,18 @@ class AirlinesController extends Controller
|
||||
*/
|
||||
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');
|
||||
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);
|
||||
|
||||
Flash::success('Airlines deleted successfully.');
|
||||
|
@ -22,15 +22,13 @@ class Acars extends Response
|
||||
$res = parent::toArray($request);
|
||||
|
||||
// Set these to the response units
|
||||
if (!empty($res['distance'])) {
|
||||
$distance = new Distance($res['distance'], config('phpvms.internal_units.distance'));
|
||||
$res['distance'] = $distance->getResponseUnits();
|
||||
}
|
||||
$distance = !empty($res['distance']) ? $res['distance'] : 0;
|
||||
$distance = new Distance($distance, config('phpvms.internal_units.distance'));
|
||||
$res['distance'] = $distance->getResponseUnits();
|
||||
|
||||
if (!empty($res['fuel'])) {
|
||||
$fuel = new Fuel($res['fuel'], config('phpvms.internal_units.fuel'));
|
||||
$res['fuel'] = $fuel->getResponseUnits();
|
||||
}
|
||||
$fuel = !empty($res['fuel']) ? $res['fuel'] : 0;
|
||||
$fuel = new Fuel($fuel, config('phpvms.internal_units.fuel'));
|
||||
$res['fuel'] = $fuel->getResponseUnits();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
@ -96,4 +96,14 @@ class Airline extends Model
|
||||
{
|
||||
$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');
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ use Illuminate\Support\Collection;
|
||||
* @property float fuel_used
|
||||
* @property float distance
|
||||
* @property float planned_distance
|
||||
* @property int level
|
||||
* @property string route
|
||||
* @property int score
|
||||
* @property User user
|
||||
@ -127,6 +128,7 @@ class Pirep extends Model
|
||||
'arr_airport_id' => 'required',
|
||||
'block_fuel' => 'required|numeric',
|
||||
'fuel_used' => 'required|numeric',
|
||||
'level' => 'nullable|numeric',
|
||||
'notes' => 'nullable',
|
||||
'route' => 'nullable',
|
||||
];
|
||||
@ -296,36 +298,6 @@ class Pirep extends Model
|
||||
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
|
||||
*
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Traits\FilesTrait;
|
||||
* @property float cost_block_hour
|
||||
* @property float cost_delay_minute
|
||||
* @property Airline airline
|
||||
* @property int airline_id
|
||||
*/
|
||||
class Subfleet extends Model
|
||||
{
|
||||
|
56
app/Services/AirlineService.php
Normal file
56
app/Services/AirlineService.php
Normal 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;
|
||||
}
|
||||
}
|
@ -123,8 +123,7 @@ if (!function_exists('skin_view')) {
|
||||
return view($template, $vars, $merge_data);
|
||||
}
|
||||
|
||||
// TODO: Look for an overridden template in a special folder
|
||||
$tpl = 'layouts/'.config('phpvms.skin').'/'.$template;
|
||||
$tpl = 'layouts/'.setting('general.theme', 'default').'/'.$template;
|
||||
|
||||
return view($tpl, $vars, $merge_data);
|
||||
}
|
||||
@ -134,6 +133,14 @@ if (!function_exists('skin_view')) {
|
||||
* Shortcut for retrieving a setting value
|
||||
*/
|
||||
if (!function_exists('setting')) {
|
||||
/**
|
||||
* Read a setting from the settings table
|
||||
*
|
||||
* @param $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function setting($key, $default = null)
|
||||
{
|
||||
$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
@ -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/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/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.map": "/assets/admin/js/app.js.map?id=a43168e6da458119da61",
|
||||
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=7eb8b66dce0064082abc",
|
||||
"/assets/installer/js/app.js.map": "/assets/installer/js/app.js.map?id=b277e94eb1368204a7d5",
|
||||
"/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=295a34b9c67c5a178d8a",
|
||||
"/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=917f0f8bcd02d558f615",
|
||||
"/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/img/clear.png": "/assets/admin/img/clear.png?id=63b3af84650a0145d61a",
|
||||
|
@ -3,8 +3,10 @@ const rivets = require('rivets');
|
||||
|
||||
/**
|
||||
* Generic formatter to prepend
|
||||
*
|
||||
* @param value
|
||||
* @param prepend
|
||||
*
|
||||
* @returns {*}
|
||||
*/
|
||||
rivets.formatters.prepend = function (value, prepend) {
|
||||
@ -13,7 +15,9 @@ rivets.formatters.prepend = function (value, prepend) {
|
||||
|
||||
/**
|
||||
* Format minutes into HHh MMm
|
||||
*
|
||||
* @param value
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
rivets.formatters.time_hm = function (value) {
|
||||
@ -26,6 +30,7 @@ rivets.formatters.time_hm = function (value) {
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
rivets.formatters.gt = (value, len) => value.length > len;
|
||||
@ -34,6 +39,7 @@ rivets.formatters.gt = (value, len) => value.length > len;
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
rivets.formatters.lt = (value, len) => value.length < len;
|
||||
@ -42,6 +48,15 @@ rivets.formatters.lt = (value, len) => value.length < len;
|
||||
*
|
||||
* @param value
|
||||
* @param len
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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 class="row">
|
||||
<div class="col-3">
|
||||
<div class="col-6">
|
||||
{{ Form::label('hours', __('flights.flighttime')) }}
|
||||
@if(!empty($pirep) && $pirep->read_only)
|
||||
<p>
|
||||
@ -124,6 +124,22 @@ flight reports that have been filed. You've been warned!
|
||||
<p class="text-danger">{{ $errors->first('minutes') }}</p>
|
||||
@endif
|
||||
</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>
|
||||
|
@ -98,8 +98,8 @@ and being mindful of the rivets bindings
|
||||
<td>{ pirep.aircraft.name }</td>
|
||||
<td>{ pirep.position.altitude }</td>
|
||||
<td>{ pirep.position.gs }</td>
|
||||
<td>{ pirep.position.distance.{{setting('units.distance')}} } /
|
||||
{ pirep.planned_distance.{{setting('units.distance')}} }
|
||||
<td>{ pirep.position.distance.{{setting('units.distance')}} | fallback 0 } /
|
||||
{ pirep.planned_distance.{{setting('units.distance')}} | fallback 0 }
|
||||
</td>
|
||||
<td>{ pirep.status_text }</td>
|
||||
</tr>
|
||||
|
42
tests/AirlineTest.php
Normal file
42
tests/AirlineTest.php
Normal 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));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user