add accountGroupStageBreakTime groupStageRotationDifference in matchscheduler and uniqueRandomIndex in team reg

newoffer2025
Raz 6 months ago
parent 3d29d25f63
commit 0fe8728a8a
  1. 98
      PadelClub/Views/Planning/PlanningSettingsView.swift
  2. 22
      PadelClub/Views/Team/EditingTeamView.swift
  3. 3
      PadelClubTests/ServerDataTests.swift

@ -463,24 +463,42 @@ struct PlanningSettingsView: View {
Text("Classement") Text("Classement")
} }
Section {
Toggle(isOn: $matchScheduler.accountGroupStageBreakTime) {
Text("Tenir compte des temps de pause réglementaires")
}
} header: {
Text("Poule")
}
Section { Section {
Toggle(isOn: $matchScheduler.rotationDifferenceIsImportant) { Toggle(isOn: $matchScheduler.rotationDifferenceIsImportant) {
Text("Forcer une rotation d'attente supplémentaire entre 2 phases") Text("Forcer une rotation d'attente supplémentaire entre 2 phases")
} }
LabeledContent { LabeledContent {
StepperView(count: $matchScheduler.upperBracketRotationDifference, minimum: 0, maximum: 2) StepperView(count: $matchScheduler.upperBracketRotationDifference, minimum: 0)
} label: { } label: {
Text("Tableau") Text("Tableau")
} }
.disabled(matchScheduler.rotationDifferenceIsImportant == false) .disabled(matchScheduler.rotationDifferenceIsImportant == false)
LabeledContent { LabeledContent {
StepperView(count: $matchScheduler.loserBracketRotationDifference, minimum: 0, maximum: 2) StepperView(count: $matchScheduler.loserBracketRotationDifference, minimum: 0)
} label: { } label: {
Text("Classement") Text("Classement")
} }
.disabled(matchScheduler.rotationDifferenceIsImportant == false) .disabled(matchScheduler.rotationDifferenceIsImportant == false)
LabeledContent {
StepperView(count: $matchScheduler.groupStageRotationDifference, minimum: 0)
} label: {
Text("Poule")
}
.disabled(matchScheduler.rotationDifferenceIsImportant == false)
} footer: { } footer: {
Text("Cette option ajoute du temps entre 2 rotations, permettant ainsi de mieux configurer plusieurs tournois se déroulant en même temps.") Text("Cette option ajoute du temps entre 2 rotations, permettant ainsi de mieux configurer plusieurs tournois se déroulant en même temps.")
} }
@ -517,83 +535,11 @@ struct PlanningSettingsView: View {
} }
private func _groupMatchesByDay(matches: [Match]) -> [Date: [Match]] { private func _groupMatchesByDay(matches: [Match]) -> [Date: [Match]] {
var matchesByDay = [Date: [Match]]() tournament.groupMatchesByDay(matches: matches)
let calendar = Calendar.current
for match in matches {
// Extract day/month/year and create a date with only these components
let components = calendar.dateComponents([.year, .month, .day], from: match.computedStartDateForSorting)
let strippedDate = calendar.date(from: components)!
// Group matches by the strippedDate (only day/month/year)
if matchesByDay[strippedDate] == nil {
matchesByDay[strippedDate] = []
}
let shouldIncludeMatch: Bool
switch match.matchType {
case .groupStage:
shouldIncludeMatch = !matchesByDay[strippedDate]!.filter { $0.groupStage != nil }.compactMap { $0.groupStage }.contains(match.groupStage!)
case .bracket:
shouldIncludeMatch = !matchesByDay[strippedDate]!.filter { $0.round != nil }.compactMap { $0.round }.contains(match.round!)
case .loserBracket:
shouldIncludeMatch = true
}
if shouldIncludeMatch {
matchesByDay[strippedDate]!.append(match)
}
}
return matchesByDay
} }
private func _matchCountPerDay(matchesByDay: [Date: [Match]], tournament: Tournament) -> [Date: NSCountedSet] { private func _matchCountPerDay(matchesByDay: [Date: [Match]], tournament: Tournament) -> [Date: NSCountedSet] {
let days = matchesByDay.keys tournament.matchCountPerDay(matchesByDay: matchesByDay)
var matchCountPerDay = [Date: NSCountedSet]()
for day in days {
if let matches = matchesByDay[day] {
var groupStageCount = 0
let countedSet = NSCountedSet()
for match in matches {
switch match.matchType {
case .groupStage:
if let groupStage = match.groupStageObject {
if groupStageCount < groupStage.size - 1 {
groupStageCount = groupStage.size - 1
}
}
case .bracket:
countedSet.add(match.matchFormat)
case .loserBracket:
break
}
}
if groupStageCount > 0 {
for _ in 0..<groupStageCount {
countedSet.add(tournament.groupStageMatchFormat)
}
}
if let loserRounds = matches.filter({ $0.round != nil }).filter({ $0.roundObject?.parent == nil }).sorted(by: \.computedStartDateForSorting).last?.roundObject?.loserRounds() {
let ids = matches.map { $0.id }
for loserRound in loserRounds {
if let first = loserRound.playedMatches().first {
if ids.contains(first.id) {
countedSet.add(first.matchFormat)
}
}
}
}
matchCountPerDay[day] = countedSet
}
}
return matchCountPerDay
} }
private func _formatPerDayView(matchCountPerDay: [Date: NSCountedSet]) -> some View { private func _formatPerDayView(matchCountPerDay: [Date: NSCountedSet]) -> some View {

@ -29,6 +29,8 @@ struct EditingTeamView: View {
@State private var isProcessingRefund = false @State private var isProcessingRefund = false
@State private var refundMessage: String? @State private var refundMessage: String?
@State private var registrationDateModified: Date @State private var registrationDateModified: Date
@State private var uniqueRandomIndex: Int
var messageSentFailed: Binding<Bool> { var messageSentFailed: Binding<Bool> {
Binding { Binding {
@ -48,6 +50,7 @@ struct EditingTeamView: View {
return return
registrationDate != team.registrationDate registrationDate != team.registrationDate
|| uniqueRandomIndex != team.uniqueRandomIndex
|| walkOut != team.walkOut || walkOut != team.walkOut
|| wildCardBracket != team.wildCardBracket || wildCardBracket != team.wildCardBracket
|| wildCardGroupStage != team.wildCardGroupStage || wildCardGroupStage != team.wildCardGroupStage
@ -69,6 +72,7 @@ struct EditingTeamView: View {
_walkOut = State(wrappedValue: team.walkOut) _walkOut = State(wrappedValue: team.walkOut)
_wildCardBracket = State(wrappedValue: team.wildCardBracket) _wildCardBracket = State(wrappedValue: team.wildCardBracket)
_wildCardGroupStage = State(wrappedValue: team.wildCardGroupStage) _wildCardGroupStage = State(wrappedValue: team.wildCardGroupStage)
_uniqueRandomIndex = .init(wrappedValue: team.uniqueRandomIndex)
} }
private func _resetTeam() { private func _resetTeam() {
@ -77,6 +81,7 @@ struct EditingTeamView: View {
team.wildCardGroupStage = false team.wildCardGroupStage = false
team.walkOut = false team.walkOut = false
team.wildCardBracket = false team.wildCardBracket = false
team.uniqueRandomIndex = 0
} }
var body: some View { var body: some View {
@ -206,6 +211,16 @@ struct EditingTeamView: View {
} }
} }
Section {
LabeledContent {
StepperView(count: $uniqueRandomIndex, minimum: 0)
} label: {
Text("Ordre à poids de paire égal")
}
} footer: {
Text("Si plusieurs équipes ont le même poids et que leur position est tiré au sort, ce champ permet de les positionner correctement dans l'ordre croissant.")
}
Section { Section {
HStack { HStack {
TextField("Nom de l'équipe", text: $name) TextField("Nom de l'équipe", text: $name)
@ -287,6 +302,7 @@ struct EditingTeamView: View {
team.wildCardBracket = wildCardBracket team.wildCardBracket = wildCardBracket
team.wildCardGroupStage = wildCardGroupStage team.wildCardGroupStage = wildCardGroupStage
team.walkOut = walkOut team.walkOut = walkOut
team.uniqueRandomIndex = uniqueRandomIndex
_save() _save()
} }
@ -295,6 +311,7 @@ struct EditingTeamView: View {
walkOut = team.walkOut walkOut = team.walkOut
wildCardBracket = team.wildCardBracket wildCardBracket = team.wildCardBracket
wildCardGroupStage = team.wildCardGroupStage wildCardGroupStage = team.wildCardGroupStage
uniqueRandomIndex = team.uniqueRandomIndex
} }
}, message: { }, message: {
Text("Ce changement peut entraîner l'entrée ou la sortie d'une équipe de votre sélection. Padel Club préviendra automatiquement une équipe inscrite en ligne de son nouveau statut.") Text("Ce changement peut entraîner l'entrée ou la sortie d'une équipe de votre sélection. Padel Club préviendra automatiquement une équipe inscrite en ligne de son nouveau statut.")
@ -394,6 +411,11 @@ struct EditingTeamView: View {
} }
} }
} }
.onChange(of: uniqueRandomIndex) {
if canSaveWithoutWarning() {
_save()
}
}
.onChange(of: [walkOut, wildCardBracket, wildCardGroupStage]) { .onChange(of: [walkOut, wildCardBracket, wildCardGroupStage]) {
if canSaveWithoutWarning() { if canSaveWithoutWarning() {
if walkOut == false && team.walkOut == true { if walkOut == false && team.walkOut == true {

@ -270,7 +270,7 @@ final class ServerDataTests: XCTestCase {
return return
} }
let teamRegistration = TeamRegistration(tournament: tournamentId, groupStage: groupStageId, registrationDate: Date(), callDate: Date(), bracketPosition: 1, groupStagePosition: 2, comment: "comment", source: "source", sourceValue: "source V", logo: "logo", name: "Stax", walkOut: true, wildCardBracket: true, wildCardGroupStage: true, weight: 1, lockedWeight: 11, confirmationDate: Date(), qualified: true) let teamRegistration = TeamRegistration(tournament: tournamentId, groupStage: groupStageId, registrationDate: Date(), callDate: Date(), bracketPosition: 1, groupStagePosition: 2, comment: "comment", source: "source", sourceValue: "source V", logo: "logo", name: "Stax", walkOut: true, wildCardBracket: true, wildCardGroupStage: true, weight: 1, lockedWeight: 11, confirmationDate: Date(), qualified: true, finalRanking: 100, pointsEarned: 10, uniqueRandomIndex: 1)
teamRegistration.storeId = "123" teamRegistration.storeId = "123"
if let tr: TeamRegistration = try await StoreCenter.main.service().post(teamRegistration) { if let tr: TeamRegistration = try await StoreCenter.main.service().post(teamRegistration) {
@ -297,6 +297,7 @@ final class ServerDataTests: XCTestCase {
assert(tr.qualified == teamRegistration.qualified) assert(tr.qualified == teamRegistration.qualified)
assert(tr.finalRanking == teamRegistration.finalRanking) assert(tr.finalRanking == teamRegistration.finalRanking)
assert(tr.pointsEarned == teamRegistration.pointsEarned) assert(tr.pointsEarned == teamRegistration.pointsEarned)
assert(tr.uniqueRandomIndex == teamRegistration.uniqueRandomIndex)
} else { } else {
XCTFail("missing data") XCTFail("missing data")
} }

Loading…
Cancel
Save