Fix PirepStats(): scope PAX & Cargo totals to the selected airline/aircraft#31
Open
MANFahrer-GF wants to merge 1 commit into
Open
Fix PirepStats(): scope PAX & Cargo totals to the selected airline/aircraft#31MANFahrer-GF wants to merge 1 commit into
MANFahrer-GF wants to merge 1 commit into
Conversation
PirepStats() reported VA-wide PAX and Cargo figures on every airline- and aircraft-detail page. The fare totals used a whereNotIn() blacklist built only from the *non-accepted* pireps of the current scope, so it excluded just those few rows and still summed every other airline's/aircraft's fares. Replace it with a single JOIN grouped by fare type. The airline/aircraft scope lives in the JOIN's WHERE, so the figures are correctly scoped and nothing is materialised into a PHP id array — this also removes the MySQL ~65k WHERE IN limit that the original count() < 65500 guard worked around, so the guard is dropped. Soft-deleted pireps are excluded explicitly since join() bypasses the Pirep SoftDeletes scope. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FatihKoz
approved these changes
May 31, 2026
Owner
FatihKoz
left a comment
There was a problem hiding this comment.
I am ok with the DB::raw(), it is better than using the selectRaw() after all.
Thanks, 1 query version look good.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
DB_StatServices::PirepStats($airline_id, $aircraft_id)reported VA-wide PAX and Cargo figures on every airline- and aircraft-detail page. All other stats (flights, time, distance, fuel, landing rate) were correctly scoped — onlyTotal/Avg PassengersandTotal/Avg Freightwere wrong.On a small operator the effect is dramatic: a business-jet airline with 6 accepted PIREPs (~31 pax / ~993 kg total) showed 439,756 passengers and 33,932,376 kg freight — the whole VA's totals.
Root cause
$allpirepsis the list of non-accepted pireps of the current scope only. Used as awhereNotInblacklist it excludes just those few rows and still sums every other airline's/aircraft's fares, so the scoping intent is lost for PAX/CGO.The constraint you raised (thank you!)
You pointed out the
count($allpireps) < 65500guard exists because a VA with ~200k pireps hit MySQL's hard limit on the number of items in aWHERE ... IN (...)clause. So any fix must not materialise a large id list in PHP — otherwise it just moves the wall.You also asked to prefer plain Eloquent over
selectRaw()with prefixes where possible.What this PR does
A single JOIN grouped by fare type. The airline/aircraft scope lives in the JOIN's
WHERE, so nothing is loaded into PHP — noIN (...)list, no 65k limit, at any VA size — and both PAX and CGO (sum + avg) come back in one query:Notes on style / safety:
selectRawwith a prefixed identifier. OnlyDB::raw('SUM(count)')/AVG(count)aggregates remain, and the bare columnscount/typeare unambiguous because thepirepstable has neither (it usesflight_type) — so no table prefix is needed and it works regardless of the configured DB prefix.join()bypasses thePirepSoftDeletes global scope, so soft-deleted pireps are excluded explicitly viawhereNull('pireps.deleted_at'). (As a side effect this is slightly more correct than the old code, which let fares of soft-deleted pireps through.)count() < 65500guard is removed because no id list is ever built.Verification
Tested on a live install (prefix
phpvms, ≈3,094 accepted pireps, ≈8,800 fare rows) by calling the realPirepStats()method:All identical to the old method's intended results; fare aggregation confirmed at exactly 1 query (via the query log). Empty scope (airline with no pireps) returns sum 0 / avg null and the existing
if ($pax_amount > 0)guards simply omit the rows — no crash.Alternative considered (smaller diff, but slower)
If you'd rather keep the change as close as possible to the current code, a subquery
whereInalso fixes it without a 65k limit (pass a builder, not->pluck(), so Laravel emitsIN (SELECT id FROM pireps WHERE ...)):Trade-offs (both correct, both 65k-safe, soft-deletes handled):
DB::raw()aggregateswhereNull(deleted_at)I went with the JOIN for the single-query performance, but I'm happy to switch this PR to the subquery version if you prefer the smaller, prefix-free diff — your call.
🤖 Generated with Claude Code
Closes #30