added stats to team page
This commit is contained in:
@@ -269,6 +269,102 @@ func GetFinalizedResultsForFixtures(ctx context.Context, tx bun.Tx, fixtureIDs [
|
||||
return resultMap, nil
|
||||
}
|
||||
|
||||
// AggregatedPlayerStats holds summed stats for a player across multiple fixtures.
|
||||
type AggregatedPlayerStats struct {
|
||||
PlayerID int `bun:"player_id"`
|
||||
PlayerName string `bun:"player_name"`
|
||||
GamesPlayed int `bun:"games_played"`
|
||||
Score int `bun:"total_score"`
|
||||
Goals int `bun:"total_goals"`
|
||||
Assists int `bun:"total_assists"`
|
||||
Saves int `bun:"total_saves"`
|
||||
Shots int `bun:"total_shots"`
|
||||
Blocks int `bun:"total_blocks"`
|
||||
Passes int `bun:"total_passes"`
|
||||
}
|
||||
|
||||
// GetAggregatedPlayerStatsForTeam returns aggregated period-3 stats for all mapped
|
||||
// players on a given team across all finalized fixture results.
|
||||
func GetAggregatedPlayerStatsForTeam(
|
||||
ctx context.Context,
|
||||
tx bun.Tx,
|
||||
teamID int,
|
||||
fixtureIDs []int,
|
||||
) ([]*AggregatedPlayerStats, error) {
|
||||
if len(fixtureIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var stats []*AggregatedPlayerStats
|
||||
err := tx.NewRaw(`
|
||||
SELECT
|
||||
frps.player_id AS player_id,
|
||||
COALESCE(p.name, frps.player_username) AS player_name,
|
||||
COUNT(DISTINCT frps.fixture_result_id) AS games_played,
|
||||
COALESCE(SUM(frps.score), 0) AS total_score,
|
||||
COALESCE(SUM(frps.goals), 0) AS total_goals,
|
||||
COALESCE(SUM(frps.assists), 0) AS total_assists,
|
||||
COALESCE(SUM(frps.saves), 0) AS total_saves,
|
||||
COALESCE(SUM(frps.shots), 0) AS total_shots,
|
||||
COALESCE(SUM(frps.blocks), 0) AS total_blocks,
|
||||
COALESCE(SUM(frps.passes), 0) AS total_passes
|
||||
FROM fixture_result_player_stats frps
|
||||
JOIN fixture_results fr ON fr.id = frps.fixture_result_id
|
||||
LEFT JOIN players p ON p.id = frps.player_id
|
||||
WHERE fr.finalized = true
|
||||
AND fr.fixture_id IN (?)
|
||||
AND frps.team_id = ?
|
||||
AND frps.period_num = 3
|
||||
AND frps.player_id IS NOT NULL
|
||||
GROUP BY frps.player_id, COALESCE(p.name, frps.player_username)
|
||||
ORDER BY total_score DESC
|
||||
`, bun.In(fixtureIDs), teamID).Scan(ctx, &stats)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "tx.NewRaw")
|
||||
}
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// TeamRecord holds win/loss/draw record and goal totals for a team.
|
||||
type TeamRecord struct {
|
||||
Played int
|
||||
Wins int
|
||||
Losses int
|
||||
Draws int
|
||||
GoalsFor int
|
||||
GoalsAgainst int
|
||||
}
|
||||
|
||||
// ComputeTeamRecord calculates W-L-D and GF/GA from fixtures and results.
|
||||
func ComputeTeamRecord(teamID int, fixtures []*Fixture, resultMap map[int]*FixtureResult) *TeamRecord {
|
||||
rec := &TeamRecord{}
|
||||
for _, f := range fixtures {
|
||||
res, ok := resultMap[f.ID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rec.Played++
|
||||
isHome := f.HomeTeamID == teamID
|
||||
if isHome {
|
||||
rec.GoalsFor += res.HomeScore
|
||||
rec.GoalsAgainst += res.AwayScore
|
||||
} else {
|
||||
rec.GoalsFor += res.AwayScore
|
||||
rec.GoalsAgainst += res.HomeScore
|
||||
}
|
||||
won := (isHome && res.Winner == "home") || (!isHome && res.Winner == "away")
|
||||
lost := (isHome && res.Winner == "away") || (!isHome && res.Winner == "home")
|
||||
if won {
|
||||
rec.Wins++
|
||||
} else if lost {
|
||||
rec.Losses++
|
||||
} else {
|
||||
rec.Draws++
|
||||
}
|
||||
}
|
||||
return rec
|
||||
}
|
||||
|
||||
// GetFixtureTeamRosters returns all team players with participation status for a fixture.
|
||||
// Returns: map["home"|"away"] -> []*PlayerWithPlayStatus
|
||||
func GetFixtureTeamRosters(
|
||||
|
||||
Reference in New Issue
Block a user