Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/composer/laravel/pint-1.19.0
Browse files Browse the repository at this point in the history
  • Loading branch information
detheridge02 authored Jan 15, 2025
2 parents d380afa + dcb30e9 commit e4968d2
Show file tree
Hide file tree
Showing 23 changed files with 1,135 additions and 575 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,6 @@ BUGSNAG_FILTERS=password,authid,authpassword,apikey_pub,access_token,x-newrelic-
BUGSNAG_BATCH_SENDING=true
BUGSNAG_NOTIFY_RELEASE_STAGES=production,staging
BUGSNAG_QUERY_BINDINGS=true

BETTERSTACK_SOURCE_TOKEN=
BETTERSTACK_LOG_LEVEL=debug
56 changes: 47 additions & 9 deletions app/Console/Commands/Roster/UpdateRoster.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\NetworkData\Atc;
use App\Models\Roster;
use App\Models\RosterUpdate;
use App\Models\Training\WaitingList;
use App\Models\Training\WaitingList\WaitingListAccount;
use Illuminate\Console\Command;
Expand All @@ -27,6 +28,11 @@ public function handle()
$this->fromDate = Carbon::parse($this->argument('fromDate'))->startOfDay();
$this->toDate = Carbon::parse($this->argument('toDate'))->endOfDay();

$rosterUpdate = RosterUpdate::create([
'period_start' => $this->fromDate,
'period_end' => $this->toDate,
]);

$meetHourRequirement = Atc::with(['account.states'])
->select(['networkdata_atc.account_id'])
->whereBetween('disconnected_at', [$this->fromDate, $this->toDate])
Expand All @@ -38,25 +44,45 @@ public function handle()

// Automatically mark those on the Gander Oceanic roster as eligible
$eligible = $meetHourRequirement->merge(
Http::get(config('services.gander-oceanic.api.base').'/roster')
$ganderControllers = Http::get(config('services.gander-oceanic.api.base').'/roster')
->collect()
->where('active', true)
->pluck('cid')
->flatten()
)->unique();

// On the roster, do not need to be on...
Roster::withoutGlobalScopes()
->whereNotIn('account_id', $eligible)
->get()
$removeFromRoster = Roster::withoutGlobalScopes()
->whereNotIn('account_id', $eligible);

$homeRemovals = $removeFromRoster->whereHas('account', function ($query) {
$query->whereHas('states', function ($query) {
$query
->join('roster', 'mship_account_state.account_id', '=', 'roster.account_id')
->whereIn('mship_state.code', ['DIVISION'])
->orWhereColumn('roster.updated_at', '>', 'mship_account_state.start_at');
});
});

$visitingAndTransferringRemovals = $removeFromRoster->whereHas('account', function ($query) {
$query->whereHas('states', function ($query) {
$query
->join('roster', 'mship_account_state.account_id', '=', 'roster.account_id')
->whereIn('mship_state.code', ['TRANSFERRING', 'VISITING'])
->orWhereColumn('roster.updated_at', '>', 'mship_account_state.start_at');
});
});

$removeFromRoster->get()
->each
->remove();
->remove($rosterUpdate);

// On an ATC waiting list, not on the roster, need to be removed...
WaitingListAccount::whereIn('list_id',
WaitingList::where('department', WaitingList::ATC_DEPARTMENT)->get('id')
)->whereNotIn('account_id', $eligible)
->get()
$removeFromWaitingList = WaitingListAccount::with('waitingList')
->whereIn('list_id', WaitingList::where('department', WaitingList::ATC_DEPARTMENT)->get('id'))
->whereNotIn('account_id', $eligible)
->get();
$removeFromWaitingList
->each
->delete();

Expand All @@ -66,6 +92,18 @@ public function handle()
['account_id']
);

$rosterUpdate->update([
'data' => [
'meetHourRequirement' => $meetHourRequirement->count(),
'ganderControllers' => $ganderControllers->count(),
'eligible' => $eligible->count(),
'removeFromRoster' => $removeFromRoster->count(),
'homeRemovals' => $homeRemovals->count(),
'visitingAndTransferringRemovals' => $visitingAndTransferringRemovals->count(),
'removeFromWaitingList' => $removeFromWaitingList->countBy('list_id'),
],
]);

$this->comment('✅ Roster updated!');
}
}
58 changes: 52 additions & 6 deletions app/Filament/Pages/Operations/GenerateQuarterlyStats.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Filament\Helpers\Pages\BasePage;
use App\Models\Mship\Account;
use App\Models\Mship\Account\Endorsement;
use Carbon\Carbon;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Select;
Expand Down Expand Up @@ -59,12 +60,17 @@ public function submit(): void
$endDate = $startDate->copy()->addMonths(3);

$this->statistics = collect([
['name' => 'Left Division', 'value' => $this->membersLeftDivision($startDate, $endDate)],
['name' => 'Pilots Visiting', 'value' => $this->pilotsVisiting($startDate, $endDate)],
['name' => 'New Joiners as First Division', 'value' => $this->newJoinersAsFirstDivision($startDate, $endDate)],
['name' => 'Members Becoming Inactive', 'value' => $this->membersBecomingInactive($startDate, $endDate)],
['name' => 'Visiting Controllers Above S1', 'value' => $this->visitingControllersAboveS1($startDate, $endDate)],
['name' => 'Completed Transfer (Ex OBS)', 'value' => $this->completedTransfersExObs($startDate, $endDate)],
'Division Membership' => [
['name' => 'Left Division', 'value' => $this->membersLeftDivision($startDate, $endDate)],
['name' => 'Pilots Visiting', 'value' => $this->pilotsVisiting($startDate, $endDate)],
['name' => 'New Joiners as First Division', 'value' => $this->newJoinersAsFirstDivision($startDate, $endDate)],
['name' => 'Members Becoming Inactive', 'value' => $this->membersBecomingInactive($startDate, $endDate)],
['name' => 'Visiting Controllers Above S1', 'value' => $this->visitingControllersAboveS1($startDate, $endDate)],
['name' => 'Completed Transfer (Ex OBS)', 'value' => $this->completedTransfersExObs($startDate, $endDate)],
],
'Completed Mentoring Sessions' => $this->completedMentoringSessions($startDate, $endDate),
'Exam Passes' => $this->examPasses($startDate, $endDate),
'Issued Position Group Endorsements' => $this->issuedPositionGroupEndorsements($startDate, $endDate),
]);
}

Expand Down Expand Up @@ -138,4 +144,44 @@ private function visitingControllersAboveS1($startDate, $endDate)
$q->whereBetween('mship_qualification.id', [3, 10]);
})->count();
}

private function completedMentoringSessions(Carbon $startDate, Carbon $endDate)
{
return DB::connection('cts')
->table('sessions')
->select('rts.name', DB::raw('count(*) as total'))
->join('rts', 'sessions.rts_id', '=', 'rts.id')
->whereBetween('taken_date', [$startDate, $endDate])
->whereNull('cancelled_datetime')
->where('noShow', '=', 0)
->groupBy('rts_id')
->get()
->flatMap(fn ($value) => [['name' => $value->name, 'value' => $value->total]])
->toArray();
}

private function issuedPositionGroupEndorsements(Carbon $startDate, Carbon $endDate)
{
return Endorsement::with('endorsable')
->whereBetween('mship_account_endorsement.created_at', [$startDate, $endDate])
->join('position_groups', 'position_groups.id', 'mship_account_endorsement.endorsable_id')
->groupBy('position_groups.id', 'position_groups.name')
->select(['position_groups.name', 'position_groups.id', DB::raw('count(*) as total')])
->get()
->flatMap(fn ($value) => [['name' => $value->name, 'value' => $value->total]])
->toArray();
}

private function examPasses(Carbon $startDate, Carbon $endDate)
{
return DB::connection('cts')
->table('practical_results')
->select('exam', DB::raw('count(*) as total'))
->whereBetween('date', [$startDate, $endDate])
->where('result', '=', 'P')
->groupBy('exam')
->get()
->flatMap(fn ($value) => [['name' => $value->exam, 'value' => $value->total]])
->toArray();
}
}
82 changes: 82 additions & 0 deletions app/Filament/Resources/RosterUpdateResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace App\Filament\Resources;

use App\Filament\Resources\RosterUpdates\Pages\ListRosterUpdates;
use App\Filament\Resources\RosterUpdates\Pages\ViewRosterUpdate;
use App\Models\RosterUpdate;
use App\Models\Training\WaitingList;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

class RosterUpdateResource extends Resource
{
protected static ?string $model = RosterUpdate::class;

protected static ?string $navigationIcon = 'heroicon-o-list-bullet';

protected static ?string $navigationGroup = 'User Management';

protected static ?int $navigationSort = 2;

public static function form(Form $form): Form
{
return $form
->schema([
Section::make('Details')->schema([
DatePicker::make('created_at')->label('Ran'),
DatePicker::make('period_start'),
DatePicker::make('period_end'),
]),
Section::make('Data')
->statePath('data')
->schema([
TextInput::make('meetHourRequirement')->label('Controllers meeting requirement'),
TextInput::make('ganderControllers')->label('Eligible Gander/Oceanic controllers'),
TextInput::make('removeFromRoster')->label('Removed from roster'),
TextInput::make('homeRemovals')->label('Home members removed from roster'),
TextInput::make('visitingAndTransferringRemovals')->label('V/T removed from roster'),
TextInput::make('removeFromWaitingList')->label('Removed from waiting lists')
->formatStateUsing(fn ($state) => collect($state)->map(function ($value, $key) {
$waitingList = WaitingList::withTrashed()->where('id', '=', $key)?->first();

return "$waitingList?->name: $value";
})->implode('; ')),
]),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('created_at')->label('Ran'),
TextColumn::make('period_start'),
TextColumn::make('period_end'),
])
->actions([
ViewAction::make(),
])->defaultSort('created_at', 'DESC');
}

public static function getRelations(): array
{
return [
//
];
}

public static function getPages(): array
{
return [
'index' => ListRosterUpdates::route('/'),
'view' => ViewRosterUpdate::route('/{record}'),
];
}
}
16 changes: 16 additions & 0 deletions app/Filament/Resources/RosterUpdates/Pages/ListRosterUpdates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Filament\Resources\RosterUpdates\Pages;

use App\Filament\Helpers\Pages\BaseListRecordsPage;
use App\Filament\Resources\RosterUpdateResource;

class ListRosterUpdates extends BaseListRecordsPage
{
protected static string $resource = RosterUpdateResource::class;

protected function getHeaderActions(): array
{
return [];
}
}
16 changes: 16 additions & 0 deletions app/Filament/Resources/RosterUpdates/Pages/ViewRosterUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Filament\Resources\RosterUpdates\Pages;

use App\Filament\Helpers\Pages\BaseViewRecordPage;
use App\Filament\Resources\RosterUpdateResource;

class ViewRosterUpdate extends BaseViewRecordPage
{
protected static string $resource = RosterUpdateResource::class;

protected function getHeaderActions(): array
{
return [];
}
}
2 changes: 1 addition & 1 deletion app/Jobs/UpdateMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function handle()
try {
$member = Account::findOrFail(['id' => $this->accountID])->first();
} catch (ModelNotFoundException $e) {
Log::info("Member {$this->accountID} not found in database. Auth needed to fetch data.");
Log::debug("Member {$this->accountID} not found in database. Auth needed to fetch data.");

return;
}
Expand Down
5 changes: 3 additions & 2 deletions app/Models/Roster.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ public function account()
return $this->belongsTo(Account::class);
}

public function remove()
public function remove(?RosterUpdate $update = null)
{
DB::transaction(function () {
DB::transaction(function () use ($update) {
RosterHistory::create([
'account_id' => $this->account_id,
'original_created_at' => $this->created_at,
'original_updated_at' => $this->updated_at,
'removed_by' => auth()->user()?->getKey(),
'roster_update_id' => $update?->id,
]);

$this->delete();
Expand Down
2 changes: 1 addition & 1 deletion app/Models/RosterHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ class RosterHistory extends Model

protected $table = 'roster_history';

protected $fillable = ['account_id', 'original_created_at', 'original_updated_at', 'removed_by'];
protected $fillable = ['account_id', 'original_created_at', 'original_updated_at', 'removed_by', 'roster_update_id'];
}
16 changes: 16 additions & 0 deletions app/Models/RosterUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

class RosterUpdate extends Model
{
use HasFactory;

protected $fillable = ['period_start', 'period_end', 'data'];

protected $casts = [
'data' => 'json',
];
}
Loading

0 comments on commit e4968d2

Please sign in to comment.