|
|
|
|
@ -14,7 +14,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
|
|
|
|
|
var id: String = Store.randomId() |
|
|
|
|
var event: String? |
|
|
|
|
var creator: String? |
|
|
|
|
var name: String? |
|
|
|
|
var startDate: Date |
|
|
|
|
var endDate: Date? |
|
|
|
|
@ -33,7 +32,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
var federalLevelCategory: TournamentLevel |
|
|
|
|
var federalAgeCategory: FederalTournamentAge |
|
|
|
|
var groupStageCourtCount: Int? |
|
|
|
|
var seedCount: Int |
|
|
|
|
var closedRegistrationDate: Date? |
|
|
|
|
var groupStageAdditionalQualified: Int |
|
|
|
|
var courtCount: Int = 2 |
|
|
|
|
@ -85,9 +83,8 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
case _payment = "globalId" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
internal init(event: String? = nil, creator: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = true, groupStageFormat: MatchFormat? = nil, roundFormat: MatchFormat? = nil, loserRoundFormat: MatchFormat? = nil, groupStageSortMode: GroupStageOrderingMode, groupStageCount: Int = 4, rankSourceDate: Date? = nil, dayDuration: Int = 1, teamCount: Int = 24, teamSorting: TeamSortingType? = nil, federalCategory: TournamentCategory, federalLevelCategory: TournamentLevel, federalAgeCategory: FederalTournamentAge, groupStageCourtCount: Int? = nil, seedCount: Int = 8, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil) { |
|
|
|
|
internal init(event: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = true, groupStageFormat: MatchFormat? = nil, roundFormat: MatchFormat? = nil, loserRoundFormat: MatchFormat? = nil, groupStageSortMode: GroupStageOrderingMode, groupStageCount: Int = 4, rankSourceDate: Date? = nil, dayDuration: Int = 1, teamCount: Int = 24, teamSorting: TeamSortingType? = nil, federalCategory: TournamentCategory, federalLevelCategory: TournamentLevel, federalAgeCategory: FederalTournamentAge, groupStageCourtCount: Int? = nil, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil) { |
|
|
|
|
self.event = event |
|
|
|
|
self.creator = creator |
|
|
|
|
self.name = name |
|
|
|
|
self.startDate = startDate |
|
|
|
|
self.endDate = endDate |
|
|
|
|
@ -106,7 +103,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
self.federalLevelCategory = federalLevelCategory |
|
|
|
|
self.federalAgeCategory = federalAgeCategory |
|
|
|
|
self.groupStageCourtCount = groupStageCourtCount |
|
|
|
|
self.seedCount = seedCount |
|
|
|
|
self.closedRegistrationDate = closedRegistrationDate |
|
|
|
|
self.groupStageAdditionalQualified = groupStageAdditionalQualified |
|
|
|
|
self.courtCount = courtCount |
|
|
|
|
@ -120,7 +116,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
let container = try decoder.container(keyedBy: CodingKeys.self) |
|
|
|
|
id = try container.decode(String.self, forKey: ._id) |
|
|
|
|
event = try container.decodeIfPresent(String.self, forKey: ._event) |
|
|
|
|
creator = try container.decodeIfPresent(String.self, forKey: ._creator) |
|
|
|
|
name = try container.decodeIfPresent(String.self, forKey: ._name) |
|
|
|
|
startDate = try container.decode(Date.self, forKey: ._startDate) |
|
|
|
|
endDate = try container.decodeIfPresent(Date.self, forKey: ._endDate) |
|
|
|
|
@ -139,7 +134,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
federalLevelCategory = try container.decode(TournamentLevel.self, forKey: ._federalLevelCategory) |
|
|
|
|
federalAgeCategory = try container.decode(FederalTournamentAge.self, forKey: ._federalAgeCategory) |
|
|
|
|
groupStageCourtCount = try container.decodeIfPresent(Int.self, forKey: ._groupStageCourtCount) |
|
|
|
|
seedCount = try container.decode(Int.self, forKey: ._seedCount) |
|
|
|
|
closedRegistrationDate = try container.decodeIfPresent(Date.self, forKey: ._closedRegistrationDate) |
|
|
|
|
groupStageAdditionalQualified = try container.decode(Int.self, forKey: ._groupStageAdditionalQualified) |
|
|
|
|
courtCount = try container.decode(Int.self, forKey: ._courtCount) |
|
|
|
|
@ -189,7 +183,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
|
|
|
|
|
try container.encode(id, forKey: ._id) |
|
|
|
|
try container.encodeIfPresent(event, forKey: ._event) |
|
|
|
|
try container.encodeIfPresent(creator, forKey: ._creator) |
|
|
|
|
try container.encodeIfPresent(name, forKey: ._name) |
|
|
|
|
try container.encode(startDate, forKey: ._startDate) |
|
|
|
|
try container.encodeIfPresent(endDate, forKey: ._endDate) |
|
|
|
|
@ -208,7 +201,6 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
try container.encode(federalLevelCategory, forKey: ._federalLevelCategory) |
|
|
|
|
try container.encode(federalAgeCategory, forKey: ._federalAgeCategory) |
|
|
|
|
try container.encodeIfPresent(groupStageCourtCount, forKey: ._groupStageCourtCount) |
|
|
|
|
try container.encode(seedCount, forKey: ._seedCount) |
|
|
|
|
try container.encodeIfPresent(closedRegistrationDate, forKey: ._closedRegistrationDate) |
|
|
|
|
try container.encode(groupStageAdditionalQualified, forKey: ._groupStageAdditionalQualified) |
|
|
|
|
try container.encode(courtCount, forKey: ._courtCount) |
|
|
|
|
@ -512,6 +504,10 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
let groupStages = groupStages() |
|
|
|
|
return groupStages.filter({ $0.hasStarted() && $0.hasEnded() == false }).sorted(by: \.index).first ?? groupStages.first |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func matchesWithSpace() -> [Match] { |
|
|
|
|
getActiveRound()?.playedMatches().filter({ $0.hasSpaceLeft() }) ?? [] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getActiveRound(withSeeds: Bool = false) -> Round? { |
|
|
|
|
let rounds = rounds() |
|
|
|
|
@ -719,7 +715,7 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
var teamsToImport = [TeamRegistration]() |
|
|
|
|
teams.forEach { team in |
|
|
|
|
if let previousTeam = team.previousTeam { |
|
|
|
|
previousTeam.updatePlayers(team.players) |
|
|
|
|
previousTeam.updatePlayers(team.players, inTournamentCategory: team.tournamentCategory) |
|
|
|
|
teamsToImport.append(previousTeam) |
|
|
|
|
} else { |
|
|
|
|
let newTeam = addTeam(team.players, registrationDate: team.registrationDate) |
|
|
|
|
@ -745,7 +741,7 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
let selectedTeams : [TeamRegistration] = selectedSortedTeams() |
|
|
|
|
let callDateIssue : [TeamRegistration] = selectedTeams.filter { $0.callDate != nil && isStartDateIsDifferentThanCallDate($0) } |
|
|
|
|
let duplicates : [PlayerRegistration] = duplicates(in: players) |
|
|
|
|
let problematicPlayers : [PlayerRegistration] = players.filter({ $0.sex == -1 }) |
|
|
|
|
let problematicPlayers : [PlayerRegistration] = players.filter({ $0.sex == nil }) |
|
|
|
|
let inadequatePlayers : [PlayerRegistration] = inadequatePlayers(in: players) |
|
|
|
|
let playersWithoutValidLicense : [PlayerRegistration] = playersWithoutValidLicense(in: players) |
|
|
|
|
let playersMissing : [TeamRegistration] = selectedTeams.filter({ $0.unsortedPlayers().count < 2 }) |
|
|
|
|
@ -851,7 +847,7 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
teams.forEach { team in |
|
|
|
|
let players = team.unsortedPlayers() |
|
|
|
|
players.forEach { $0.setWeight(in: self) } |
|
|
|
|
team.setWeight(from: players) |
|
|
|
|
team.setWeight(from: players, inTournamentCategory: tournamentCategory) |
|
|
|
|
try? DataStore.shared.playerRegistrations.addOrUpdate(contentOfs: players) |
|
|
|
|
} |
|
|
|
|
try? DataStore.shared.teamRegistrations.addOrUpdate(contentOfs: teams) |
|
|
|
|
@ -879,7 +875,7 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
let dataURLs = SourceFileManager.shared.allFiles.filter({ $0.dateFromPath == newDate }) |
|
|
|
|
let sources = dataURLs.map { CSVParser(url: $0) } |
|
|
|
|
|
|
|
|
|
try await player.updateRank(from: sources, lastRank: (player.sex == 0 ? lastRankWoman : lastRankMan) ?? 0) |
|
|
|
|
try await player.updateRank(from: sources, lastRank: (player.sex == .female ? lastRankWoman : lastRankMan) ?? 0) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1163,10 +1159,17 @@ class Tournament : ModelObject, Storable { |
|
|
|
|
selectedSortedTeams().firstIndex(where: { $0.id == team.id }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func labelIndexOf(team: TeamRegistration) -> String? { |
|
|
|
|
if let teamIndex = indexOf(team: team) { |
|
|
|
|
return "#" + (teamIndex + 1).formatted() |
|
|
|
|
} else { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func addTeam(_ players: Set<PlayerRegistration>, registrationDate: Date? = nil) -> TeamRegistration { |
|
|
|
|
let team = TeamRegistration(tournament: id, registrationDate: registrationDate ?? Date()) |
|
|
|
|
team.tournamentCategory = tournamentCategory |
|
|
|
|
team.setWeight(from: Array(players)) |
|
|
|
|
team.setWeight(from: Array(players), inTournamentCategory: tournamentCategory) |
|
|
|
|
players.forEach { player in |
|
|
|
|
player.teamRegistration = team.id |
|
|
|
|
} |
|
|
|
|
@ -1445,6 +1448,42 @@ fileprivate extension Bool { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//extension Tournament { |
|
|
|
|
// enum CodingKeys: String, CodingKey { |
|
|
|
|
// case _id = "id" |
|
|
|
|
// case _event = "event" |
|
|
|
|
// case _name = "name" |
|
|
|
|
// case _startDate = "startDate" |
|
|
|
|
// case _endDate = "endDate" |
|
|
|
|
// case _creationDate = "creationDate" |
|
|
|
|
// case _isPrivate = "isPrivate" |
|
|
|
|
// case _groupStageFormat = "groupStageFormat" |
|
|
|
|
// case _roundFormat = "roundFormat" |
|
|
|
|
// case _loserRoundFormat = "loserRoundFormat" |
|
|
|
|
// case _groupStageSortMode = "groupStageSortMode" |
|
|
|
|
// case _groupStageCount = "groupStageCount" |
|
|
|
|
// case _rankSourceDate = "rankSourceDate" |
|
|
|
|
// case _dayDuration = "dayDuration" |
|
|
|
|
// case _teamCount = "teamCount" |
|
|
|
|
// case _teamSorting = "teamSorting" |
|
|
|
|
// case _federalCategory = "federalCategory" |
|
|
|
|
// case _federalLevelCategory = "federalLevelCategory" |
|
|
|
|
// case _federalAgeCategory = "federalAgeCategory" |
|
|
|
|
// case _groupStageCourtCount = "groupStageCourtCount" |
|
|
|
|
// case _closedRegistrationDate = "closedRegistrationDate" |
|
|
|
|
// case _groupStageAdditionalQualified = "groupStageAdditionalQualified" |
|
|
|
|
// case _courtCount = "courtCount" |
|
|
|
|
// case _prioritizeClubMembers = "prioritizeClubMembers" |
|
|
|
|
// case _qualifiedPerGroupStage = "qualifiedPerGroupStage" |
|
|
|
|
// case _teamsPerGroupStage = "teamsPerGroupStage" |
|
|
|
|
// case _entryFee = "entryFee" |
|
|
|
|
// case _additionalEstimationDuration = "additionalEstimationDuration" |
|
|
|
|
// case _isDeleted = "isDeleted" |
|
|
|
|
// case _isCanceled = "localId" |
|
|
|
|
// case _payment = "globalId" |
|
|
|
|
// } |
|
|
|
|
//} |
|
|
|
|
|
|
|
|
|
extension Tournament: Hashable { |
|
|
|
|
static func == (lhs: Tournament, rhs: Tournament) -> Bool { |
|
|
|
|
lhs.id == rhs.id |
|
|
|
|
@ -1504,12 +1543,12 @@ extension Tournament { |
|
|
|
|
let tournamentLevel = TournamentLevel.mostUsed(inTournaments: tournaments) |
|
|
|
|
let tournamentCategory = TournamentCategory.mostUsed(inTournaments: tournaments) |
|
|
|
|
let federalTournamentAge = FederalTournamentAge.mostUsed(inTournaments: tournaments) |
|
|
|
|
|
|
|
|
|
return Tournament(creator: DataStore.shared.user?.id, groupStageSortMode: .snake, rankSourceDate: rankSourceDate, teamSorting: tournamentLevel.defaultTeamSortingType, federalCategory: tournamentCategory, federalLevelCategory: tournamentLevel, federalAgeCategory: federalTournamentAge) |
|
|
|
|
//creator: DataStore.shared.user?.id |
|
|
|
|
return Tournament(groupStageSortMode: .snake, rankSourceDate: rankSourceDate, teamSorting: tournamentLevel.defaultTeamSortingType, federalCategory: tournamentCategory, federalLevelCategory: tournamentLevel, federalAgeCategory: federalTournamentAge) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static func fake() -> Tournament { |
|
|
|
|
return Tournament(event: "Roland Garros", creator: "", name: "Magic P100", startDate: Date(), endDate: Date(), creationDate: Date(), isPrivate: false, groupStageFormat: .nineGames, roundFormat: nil, loserRoundFormat: nil, groupStageSortMode: .snake, groupStageCount: 4, rankSourceDate: nil, dayDuration: 2, teamCount: 24, teamSorting: .rank, federalCategory: .men, federalLevelCategory: .p100, federalAgeCategory: .a45, groupStageCourtCount: nil, seedCount: 8, closedRegistrationDate: nil, groupStageAdditionalQualified: 0, courtCount: 4, prioritizeClubMembers: false, qualifiedPerGroupStage: 2, teamsPerGroupStage: 4, entryFee: nil) |
|
|
|
|
return Tournament(event: "Roland Garros", name: "Magic P100", startDate: Date(), endDate: Date(), creationDate: Date(), isPrivate: false, groupStageFormat: .nineGames, roundFormat: nil, loserRoundFormat: nil, groupStageSortMode: .snake, groupStageCount: 4, rankSourceDate: nil, dayDuration: 2, teamCount: 24, teamSorting: .rank, federalCategory: .men, federalLevelCategory: .p100, federalAgeCategory: .a45, groupStageCourtCount: nil, closedRegistrationDate: nil, groupStageAdditionalQualified: 0, courtCount: 4, prioritizeClubMembers: false, qualifiedPerGroupStage: 2, teamsPerGroupStage: 4, entryFee: nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|