177 lines
4.6 KiB
Go
177 lines
4.6 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
type TeamRoster struct {
|
|
bun.BaseModel `bun:"table:team_rosters,alias:tr"`
|
|
TeamID int `bun:",pk,notnull" json:"team_id"`
|
|
SeasonID int `bun:",pk,notnull,unique:player" json:"season_id"`
|
|
LeagueID int `bun:",pk,notnull,unique:player" json:"league_id"`
|
|
PlayerID int `bun:",pk,notnull,unique:player" json:"player_id"`
|
|
IsManager bool `bun:"is_manager,default:'false'" json:"is_manager"`
|
|
|
|
Team *Team `bun:"rel:belongs-to,join:team_id=id" json:"-"`
|
|
Player *Player `bun:"rel:belongs-to,join:player_id=id" json:"-"`
|
|
Season *Season `bun:"rel:belongs-to,join:season_id=id" json:"-"`
|
|
League *League `bun:"rel:belongs-to,join:league_id=id" json:"-"`
|
|
}
|
|
|
|
type TeamWithRoster struct {
|
|
Team *Team
|
|
Season *Season
|
|
League *League
|
|
Manager *Player
|
|
Players []*Player
|
|
}
|
|
|
|
func GetTeamRoster(ctx context.Context, tx bun.Tx, seasonShortName, leagueShortName string, teamID int) (*TeamWithRoster, error) {
|
|
tr := []*TeamRoster{}
|
|
err := tx.NewSelect().
|
|
Model(&tr).
|
|
Relation("Team", func(q *bun.SelectQuery) *bun.SelectQuery {
|
|
return q.Where("team.id = ?", teamID)
|
|
}).
|
|
Relation("Season", func(q *bun.SelectQuery) *bun.SelectQuery {
|
|
return q.Where("season.short_name = ?", seasonShortName)
|
|
}).
|
|
Relation("League", func(q *bun.SelectQuery) *bun.SelectQuery {
|
|
return q.Where("league.short_name = ?", leagueShortName)
|
|
}).
|
|
Relation("Player").Scan(ctx)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "tx.NewSelect")
|
|
}
|
|
team, err := GetTeam(ctx, tx, teamID)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "GetTeam")
|
|
}
|
|
sl, err := GetSeasonLeague(ctx, tx, seasonShortName, leagueShortName)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "GetSeasonLeague")
|
|
}
|
|
var manager *Player
|
|
players := []*Player{}
|
|
for _, tp := range tr {
|
|
if tp.IsManager {
|
|
manager = tp.Player
|
|
} else {
|
|
players = append(players, tp.Player)
|
|
}
|
|
}
|
|
players = append([]*Player{manager}, players...)
|
|
twr := &TeamWithRoster{
|
|
team,
|
|
sl.Season,
|
|
sl.League,
|
|
manager,
|
|
players,
|
|
}
|
|
return twr, nil
|
|
}
|
|
|
|
func AddPlayerToTeam(ctx context.Context, tx bun.Tx, seasonID, leagueID, teamID, playerID int, manager bool, audit *AuditMeta) error {
|
|
season, err := GetByID[Season](tx, seasonID).Get(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "GetSeason")
|
|
}
|
|
league, err := GetByID[League](tx, leagueID).Get(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "GetLeague")
|
|
}
|
|
team, err := GetByID[Team](tx, teamID).Get(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "GetTeam")
|
|
}
|
|
player, err := GetByID[Player](tx, playerID).Get(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "GetPlayer")
|
|
}
|
|
tr := &TeamRoster{
|
|
SeasonID: season.ID,
|
|
LeagueID: league.ID,
|
|
TeamID: team.ID,
|
|
PlayerID: player.ID,
|
|
IsManager: manager,
|
|
}
|
|
err = Insert(tx, tr).WithAudit(audit, nil).Exec(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Insert")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ManageTeamRoster replaces the entire roster for a team in a season/league.
|
|
// It deletes all existing roster entries and inserts the new ones.
|
|
func ManageTeamRoster(ctx context.Context, tx bun.Tx, seasonID, leagueID, teamID, managerID int, playerIDs []int, audit *AuditMeta) error {
|
|
// Delete all existing roster entries for this team/season/league
|
|
_, err := tx.NewDelete().
|
|
Model((*TeamRoster)(nil)).
|
|
Where("season_id = ?", seasonID).
|
|
Where("league_id = ?", leagueID).
|
|
Where("team_id = ?", teamID).
|
|
Exec(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "delete existing roster")
|
|
}
|
|
|
|
// Insert manager if provided
|
|
if managerID > 0 {
|
|
tr := &TeamRoster{
|
|
SeasonID: seasonID,
|
|
LeagueID: leagueID,
|
|
TeamID: teamID,
|
|
PlayerID: managerID,
|
|
IsManager: true,
|
|
}
|
|
err = Insert(tx, tr).Exec(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Insert manager")
|
|
}
|
|
}
|
|
|
|
// Insert players
|
|
for _, playerID := range playerIDs {
|
|
if playerID == managerID {
|
|
continue // Already inserted as manager
|
|
}
|
|
tr := &TeamRoster{
|
|
SeasonID: seasonID,
|
|
LeagueID: leagueID,
|
|
TeamID: teamID,
|
|
PlayerID: playerID,
|
|
IsManager: false,
|
|
}
|
|
err = Insert(tx, tr).Exec(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Insert player")
|
|
}
|
|
}
|
|
|
|
// Log the roster change
|
|
details := map[string]any{
|
|
"season_id": seasonID,
|
|
"league_id": leagueID,
|
|
"team_id": teamID,
|
|
"manager_id": managerID,
|
|
"player_ids": playerIDs,
|
|
}
|
|
info := &AuditInfo{
|
|
"teams.manage_players",
|
|
"team_roster",
|
|
fmt.Sprintf("%d-%d-%d", seasonID, leagueID, teamID),
|
|
details,
|
|
}
|
|
err = LogSuccess(ctx, tx, audit, info)
|
|
if err != nil {
|
|
return errors.Wrap(err, "LogSuccess")
|
|
}
|
|
|
|
return nil
|
|
}
|