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.

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