Skip to content

PirepStats(): airline/aircraft PAX & Cargo totals show VA-wide figures (whereNotIn scoping bug) #30

Description

@MANFahrer-GF

Summary

DB_StatServices::PirepStats($airline_id, $aircraft_id) reports VA-wide PAX and Cargo totals on every airline-detail / aircraft-detail page, instead of the figures for the selected airline/aircraft. All other stats (flights, time, distance, fuel, landing rate) are correctly scoped — only Total/Avg Passengers and Total/Avg Freight are wrong.

It's most obvious on a small operator: on our install a business-jet airline (6 accepted PIREPs, ~31 pax / ~993 kg total) showed 439,756 passengers and 33,932,376 kg freight — the totals of the whole VA.

Root cause

In Services/DB_StatServices.php, PirepStats():

$allpireps = Pirep::where('state', '!=', PirepState::ACCEPTED)->when(isset($airline_id), ...airline_id...)
    ->when(isset($aircraft_id), ...aircraft_id...)->pluck('id')->toArray();

$pax_amount = PirepFare::where('type', FareType::PASSENGER)->whereNotIn('pirep_id', $allpireps)->sum('count');
// + pax_avg, cgo_amount, cgo_avg

$allpireps is the list of non-accepted PIREPs of this airline only. Using it as a whereNotIn blacklist therefore excludes just that handful of rows and still sums the fares of every other airline's accepted PIREPs. The scoping intent (airline/aircraft) is lost entirely for PAX/CGO.

Suggested fix

Switch from a blacklist to a whitelist of the in-scope accepted PIREPs and use whereIn:

$scoped_pireps = Pirep::where('state', PirepState::ACCEPTED)
    ->when(isset($airline_id),  fn ($q) => $q->where('airline_id', $airline_id))
    ->when(isset($aircraft_id), fn ($q) => $q->where('aircraft_id', $aircraft_id))
    ->pluck('id')->toArray();

if (count($scoped_pireps) > 0) {
    $pax_amount = PirepFare::where('type', FareType::PASSENGER)->whereIn('pirep_id', $scoped_pireps)->sum('count');
    $pax_avg    = PirepFare::where('type', FareType::PASSENGER)->whereIn('pirep_id', $scoped_pireps)->avg('count');
    $cgo_amount = PirepFare::where('type', FareType::CARGO)->whereIn('pirep_id', $scoped_pireps)->sum('count');
    $cgo_avg    = PirepFare::where('type', FareType::CARGO)->whereIn('pirep_id', $scoped_pireps)->avg('count');
} else {
    $pax_amount = 0;
    $cgo_amount = 0;
}

The original < 65500 guard was a workaround for large whereNotIn lists; with a whitelist of accepted PIREPs it's no longer needed (a > 0 guard is enough to skip the work and avoid an empty IN ()).

Note: the global statistics page (PirepStats() with no args) keeps returning VA-wide totals, which is correct — when both $airline_id and $aircraft_id are null the whitelist is simply "all accepted PIREPs". ApiPirepStats() is global by design and unaffected.

Verified on phpVMS 7.x with DisposableBasic v3.7.4. Happy to open a PR if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions