From 55d6b97778f1b611742d8eb3ee493568c010c411 Mon Sep 17 00:00:00 2001 From: Liesel Downes Date: Wed, 23 Oct 2024 22:14:25 +1030 Subject: [PATCH] Allow for mixed auto acknowledge and target DL authority --- .../Controllers/ClxMessagesController.php | 14 ++++---- .../Controllers/RclMessagesController.php | 6 ++-- .../Livewire/Controllers/LtNewPending.php | 32 ++++++++++++++----- app/Http/Requests/RclMessageRequest.php | 7 ++-- app/Models/RclMessage.php | 21 +++++++++--- ...get_datalink_authority_to_rcl_messages.php | 23 +++++++++++++ .../clx/rcl-messages/show.blade.php | 6 +++- resources/views/pilots/rcl/create.blade.php | 15 +++++++-- 8 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 database/migrations/2024_10_23_112029_add_target_datalink_authority_to_rcl_messages.php diff --git a/app/Http/Controllers/ClxMessagesController.php b/app/Http/Controllers/ClxMessagesController.php index 8dfe9e1..2982309 100644 --- a/app/Http/Controllers/ClxMessagesController.php +++ b/app/Http/Controllers/ClxMessagesController.php @@ -298,13 +298,13 @@ public function revertToVoice(Request $request, RclMessage $rclMessage) public function moveToProcessed(Request $request, RclMessage $rclMessage) { $datalinkAuthority = $this->dataService->getActiveControllerAuthority ?? DatalinkAuthority::whereId('NAT')->first(); - $this->cpdlcService->sendMessage( - author: $datalinkAuthority, - recipient: $rclMessage->callsign, - recipientAccount: $rclMessage->vatsimAccount, - message: sprintf(RclResponsesEnum::AcknowledgeMoved->value, strtoupper($datalinkAuthority->description())), - caption: RclResponsesEnum::Acknowledge->text() - ); +// $this->cpdlcService->sendMessage( +// author: $datalinkAuthority, +// recipient: $rclMessage->callsign, +// recipientAccount: $rclMessage->vatsimAccount, +// message: sprintf(RclResponsesEnum::AcknowledgeMoved->value, strtoupper($datalinkAuthority->description())), +// caption: RclResponsesEnum::Acknowledge->text() +// ); $clxMessage = new ClxMessage([ 'vatsim_account_id' => $request->user()->id, diff --git a/app/Http/Controllers/RclMessagesController.php b/app/Http/Controllers/RclMessagesController.php index bb68694..e9e9625 100644 --- a/app/Http/Controllers/RclMessagesController.php +++ b/app/Http/Controllers/RclMessagesController.php @@ -5,6 +5,7 @@ use App\Enums\DatalinkAuthorities; use App\Enums\RclResponsesEnum; use App\Http\Requests\RclMessageRequest; +use App\Models\DatalinkAuthority; use App\Models\RclMessage; use App\Models\Track; use App\Services\CpdlcService; @@ -39,6 +40,7 @@ public function create() 'flight_level' => substr($data?->flight_plan?->altitude, 0, 3) ?? null, 'arrival_icao' => $data?->flight_plan?->arrival ?? null, 'tracks' => Track::whereActive(true)->when($isConcorde, fn ($query) => $query->orWhere('concorde', true))->get(), + 'datalinkAuthorities' => DatalinkAuthority::whereValidRclTarget(true)->pluck('name', 'id'), 'isConcorde' => $isConcorde, '_pageTitle' => 'Request Oceanic Clearance', ]); @@ -59,12 +61,12 @@ public function store(RclMessageRequest $request) $rclMessage->save(); // If RCL auto acknowledgement enabled, send CPDLC acknowledgement - if (config('app.rcl_auto_acknowledgement_enabled')) { + if (config('app.rcl_auto_acknowledgement_enabled') && $rclMessage->targetDatalinkAuthority->auto_acknowledge_participant) { $rclMessage->acknowledged_at = now(); $rclMessage->is_acknowledged = true; $rclMessage->save(); $this->cpdlcService->sendMessage( - author: DatalinkAuthorities::SYS, + author: $rclMessage->targetDatalinkAuthority, recipient: $rclMessage->callsign, recipientAccount: $rclMessage->vatsimAccount, message: sprintf(RclResponsesEnum::Acknowledge->value, strtoupper(DatalinkAuthorities::SYS->description())), diff --git a/app/Http/Livewire/Controllers/LtNewPending.php b/app/Http/Livewire/Controllers/LtNewPending.php index 53bba2a..020d040 100644 --- a/app/Http/Livewire/Controllers/LtNewPending.php +++ b/app/Http/Livewire/Controllers/LtNewPending.php @@ -2,7 +2,9 @@ namespace App\Http\Livewire\Controllers; +use App\Enums\DatalinkAuthorities; use App\Http\Controllers\ClxMessagesController; +use App\Models\DatalinkAuthority; use App\Models\Track; use Illuminate\Database\Eloquent\Builder; use phpDocumentor\Reflection\Types\Boolean; @@ -60,6 +62,10 @@ public function columns(): array ->sortable(), Column::make("Request time", "request_time") ->sortable(), + Column::make("Target") + ->label(function ($row, Column $column) { + return Rclmessage::whereId($row->id)->first()->targetDatalinkAuthority->id ?? 'N/A'; + }), LinkColumn::make('View') // make() has no effect in this case but needs to be set anyway ->title(fn($row) => 'View ' . $row->callsign) ->location(function($row) { @@ -93,23 +99,27 @@ private function scopeWhereRandomRouteing($query) public function filters(): array { - $options = Track::query() + $trackOptions = Track::query() ->orderBy('identifier') ->get() ->keyBy('id') ->map(fn($track) => $track->identifier) ->toArray(); - $options[100] = 'RR'; + $trackOptions[100] = 'RR'; + $authorityOptions = DatalinkAuthority::query() + ->orderBy('id') + ->get() + ->keyBy('id') + ->map(fn($authority) => $authority->name) + ->toArray(); return [ - MultiSelectDropdownFilter::make('Track') - ->options( - $options - ) + MultiSelectFilter::make('Track') + ->options($trackOptions) ->setFirstOption('All') - ->filter(function(Builder $builder, array $value) use ($options) { + ->filter(function(Builder $builder, array $value) use ($trackOptions) { $selections = []; foreach ($value as $selection) { - $selections[] = $options[$selection]; + $selections[] = $trackOptions[$selection]; } if (in_array('RR', $selections)) { unset($value[array_search('100', $value)]); @@ -123,6 +133,12 @@ public function filters(): array $builder->whereIn('track_id', array_values($value)); } }), + MultiSelectFilter::make('Target OCA') + ->options($authorityOptions) + ->setFirstOption('All') + ->filter(function(Builder $builder, array $value) { + $builder->whereIn('target_datalink_authority_id', array_values($value)); + }), SelectFilter::make('Acknowledged') ->options([ '' => 'All', diff --git a/app/Http/Requests/RclMessageRequest.php b/app/Http/Requests/RclMessageRequest.php index c5d4093..98329cd 100644 --- a/app/Http/Requests/RclMessageRequest.php +++ b/app/Http/Requests/RclMessageRequest.php @@ -4,6 +4,7 @@ use App\Enums\DatalinkAuthorities; use App\Enums\RclResponsesEnum; +use App\Models\DatalinkAuthority; use App\Models\Track; use App\Services\CpdlcService; use Carbon\Carbon; @@ -34,6 +35,7 @@ public function rules(): array 'tmi' => 'required|numeric|min:001|max:366', 'random_routeing' => 'nullable|regex:/^[A-Z\/0-9 _]*[A-Z\/0-9][A-Z\/0-9 _]*$/', 'is_concorde' => 'nullable', + 'target_datalink_authority_id' => 'required', ]; } @@ -42,6 +44,7 @@ public function rules(): array 'flight_level.max' => 'You must file a valid flight level.', 'max_flight_level.max' => 'You must file a valid maximum flight level.', 'callsign.alpha_num' => 'Your callsign must be valid with no spaces as you would enter it into your pilot client. E.g. BAW14LA, AAL134', + 'target_datalink_authority_id.required' => 'You must select the first oceanic sector you will be flying through.' ]; public function prepareForValidation() @@ -88,8 +91,8 @@ public function withValidator($validator) /** Entry fix time requirement */ if (config('app.rcl_time_constraints_enabled') && strlen($this->entry_time) == 4) { if (!$this->entryTimeWithinRange($this->entry_time)) { - if (config('app.rcl_auto_acknowledgement_enabled')) { - $this->cpdlcService->sendMessage(author: DatalinkAuthorities::SYS, recipient: $this->callsign, recipientAccount: Auth::user(), message: sprintf(RclResponsesEnum::Contact->value, strtoupper(DatalinkAuthorities::OCEN->description())), caption: RclResponsesEnum::Contact->text()); + if (config('app.rcl_auto_acknowledgement_enabled') && DatalinkAuthority::whereId($this->target_datalink_authority_id)->first()->auto_acknowledge_participant) { + $this->cpdlcService->sendMessage(author: DatalinkAuthority::whereId('SYST')->first(), recipient: $this->callsign, recipientAccount: Auth::user(), message: sprintf(RclResponsesEnum::Contact->value, strtoupper(DatalinkAuthorities::OCEN->description())), caption: RclResponsesEnum::Contact->text()); } $lower = config('app.rcl_lower_limit') + 1; $upper = config('app.rcl_upper_limit') - 1; diff --git a/app/Models/RclMessage.php b/app/Models/RclMessage.php index 0812b94..2dbd35a 100644 --- a/app/Models/RclMessage.php +++ b/app/Models/RclMessage.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\DatalinkAuthorities; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -103,6 +104,11 @@ * @method static Builder|RclMessage acknowledged() * @method static Builder|RclMessage notAcknowledged() * @method static Builder|RclMessage whereTargetDatalinkAuthority($value) + * @property string|null $datalink_authority_id + * @property string|null $target_datalink_authority_id + * @method static Builder|RclMessage whereDatalinkAuthorityId($value) + * @method static Builder|RclMessage whereTargetDatalinkAuthorityId($value) + * @property-read \App\Models\DatalinkAuthority|null $targetDatalinkAuthority * @mixin \Eloquent */ class RclMessage extends Model @@ -143,7 +149,7 @@ public function prunable(): Builder * @var string[] */ protected $fillable = [ - 'vatsim_account_id', 'callsign', 'destination', 'flight_level', 'max_flight_level', 'mach', 'track_id', 'random_routeing', 'entry_fix', 'entry_time', 'tmi', 'request_time', 'free_text', 'atc_rejected', 'upper_flight_level', 'is_concorde', 'previous_entry_time', 'new_entry_time', 'previous_clx_message', 'new_entry_time_notified_at', 'is_acknowledged', 'acknowledged_at' + 'vatsim_account_id', 'callsign', 'destination', 'flight_level', 'max_flight_level', 'mach', 'track_id', 'random_routeing', 'entry_fix', 'entry_time', 'tmi', 'request_time', 'free_text', 'atc_rejected', 'upper_flight_level', 'is_concorde', 'previous_entry_time', 'new_entry_time', 'previous_clx_message', 'new_entry_time_notified_at', 'is_acknowledged', 'acknowledged_at', 'target_datalink_authority_id' ]; /** @@ -267,15 +273,15 @@ public function getDataLinkMessageAttribute(): string { if ($this->is_concorde) { if ($this->track) { - return "{$this->callsign} REQ CONC CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} CONC TRACK {$this->track->identifier} BLOCK LOWER F{$this->flight_level} UPPER F{$this->upper_flight_level} M{$this->mach} TMI {$this->tmi}"; + return "{$this->callsign} TO {$this->targetDatalinkAuthority->name} REQ CONC CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} CONC TRACK {$this->track->identifier} BLOCK LOWER F{$this->flight_level} UPPER F{$this->upper_flight_level} M{$this->mach} TMI {$this->tmi}"; } else { - return "{$this->callsign} REQ CONC CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} {$this->random_routeing} BLOCK LOWER F{$this->flight_level} UPPER F{$this->upper_flight_level} M{$this->mach} TMI {$this->tmi}"; + return "{$this->callsign} TO {$this->targetDatalinkAuthority->name} REQ CONC CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} {$this->random_routeing} BLOCK LOWER F{$this->flight_level} UPPER F{$this->upper_flight_level} M{$this->mach} TMI {$this->tmi}"; } } else { if ($this->track) { - return "{$this->callsign} REQ CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} TRACK {$this->track->identifier} F{$this->flight_level} M{$this->mach} MAX F{$this->max_flight_level} TMI {$this->tmi}"; + return "{$this->callsign} TO {$this->targetDatalinkAuthority->name} REQ CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} TRACK {$this->track->identifier} F{$this->flight_level} M{$this->mach} MAX F{$this->max_flight_level} TMI {$this->tmi}"; } else { - return "{$this->callsign} REQ CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} {$this->random_routeing} F{$this->flight_level} M{$this->mach} MAX F{$this->max_flight_level} TMI {$this->tmi}"; + return "{$this->callsign} TO {$this->targetDatalinkAuthority->name} REQ CLRNCE {$this->destination} VIA {$this->entry_fix}/{$this->entry_time} {$this->random_routeing} F{$this->flight_level} M{$this->mach} MAX F{$this->max_flight_level} TMI {$this->tmi}"; } } } @@ -296,4 +302,9 @@ protected function routeIdentifier(): Attribute get: fn () => $this->track ? $this->track->id : 'RR' ); } + + public function targetDatalinkAuthority(): BelongsTo + { + return $this->belongsTo(DatalinkAuthority::class, 'target_datalink_authority_id'); + } } diff --git a/database/migrations/2024_10_23_112029_add_target_datalink_authority_to_rcl_messages.php b/database/migrations/2024_10_23_112029_add_target_datalink_authority_to_rcl_messages.php new file mode 100644 index 0000000..81354a5 --- /dev/null +++ b/database/migrations/2024_10_23_112029_add_target_datalink_authority_to_rcl_messages.php @@ -0,0 +1,23 @@ +string('target_datalink_authority_id')->nullable(); + $table->foreign('target_datalink_authority_id')->references('id')->on('datalink_authorities')->nullOnDelete(); + }); + } + + public function down(): void + { + Schema::table('rcl_messages', function (Blueprint $table) { + $table->dropForeign('rcl_messages_target_datalink_authority_id_foreign'); + $table->dropColumn('target_datalink_authority_id'); + }); + } +}; diff --git a/resources/views/controllers/clx/rcl-messages/show.blade.php b/resources/views/controllers/clx/rcl-messages/show.blade.php index c66f9d0..c857846 100644 --- a/resources/views/controllers/clx/rcl-messages/show.blade.php +++ b/resources/views/controllers/clx/rcl-messages/show.blade.php @@ -1,4 +1,4 @@ -@extends('_layouts.main') + @extends('_layouts.main') @section('page')
@@ -100,6 +100,10 @@ CID {{ $message->vatsimAccount->full_name }} {{ $message->vatsimAccount->id }} + + Target OCA + {{ $message->targetDatalinkAuthority->id }} +
diff --git a/resources/views/pilots/rcl/create.blade.php b/resources/views/pilots/rcl/create.blade.php index b06df95..2118e88 100644 --- a/resources/views/pilots/rcl/create.blade.php +++ b/resources/views/pilots/rcl/create.blade.php @@ -64,7 +64,7 @@
- +
@if (config('app.ctp_info_enabled'))
Ensure you enter your assigned oceanic flight level as per your booking!
@@ -84,7 +84,7 @@
- +
@if (config('app.ctp_info_enabled'))
Ensure you enter your max flight level as per your booking!
@@ -126,6 +126,17 @@
Oceanic entry
+
+
+ + +
+