clean up text and summon stuff

multistore
Razmig Sarkissian 1 year ago
parent 11e3995a95
commit d3c658c615
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 17
      PadelClub/Data/Match.swift
  3. 8
      PadelClub/Data/TeamRegistration.swift
  4. 16
      PadelClub/Data/Tournament.swift
  5. 2
      PadelClub/Views/Calling/CallSettingsView.swift
  6. 4
      PadelClub/Views/Calling/CallView.swift
  7. 2
      PadelClub/Views/Club/Shared/ClubCourtSetupView.swift
  8. 8
      PadelClub/Views/Match/Components/MatchDateView.swift
  9. 43
      PadelClub/Views/Tournament/Screen/Components/TournamentClubSettingsView.swift
  10. 15
      PadelClub/Views/Tournament/Screen/TableStructureView.swift

@ -1919,7 +1919,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -1957,7 +1957,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 13;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -148,6 +148,18 @@ class Match: ModelObject, Storable {
return scores
}
func cleanScheduleAndSave(_ targetStartDate: Date? = nil) {
startDate = targetStartDate
endDate = nil
followingMatch()?.cleanScheduleAndSave(nil)
_loserMatch()?.cleanScheduleAndSave(nil)
do {
try DataStore.shared.matches.addOrUpdate(instance: self)
} catch {
Logger.error(error)
}
}
func resetMatch() {
losingTeamId = nil
winningTeamId = nil
@ -289,6 +301,11 @@ class Match: ModelObject, Storable {
Store.main.filter(isIncluded: { $0.round == round && $0.index > index }).sorted(by: \.index).first
}
func followingMatch() -> Match? {
guard let nextRoundId = roundObject?.nextRound()?.id else { return nil }
return Store.main.filter(isIncluded: { $0.round == nextRoundId && $0.index == index / 2 }).first
}
func getDuration() -> Int {
if let tournament = currentTournament() {
matchFormat.getEstimatedDuration(tournament.additionalEstimationDuration)

@ -64,6 +64,14 @@ class TeamRegistration: ModelObject, Storable {
bracketPosition = seedPosition
}
func expectedSummonDate() -> Date? {
if let groupStageStartDate = groupStageObject()?.startDate {
return groupStageStartDate
} else if let roundMatchStartDate = initialMatch()?.startDate {
return roundMatchStartDate
}
return nil
}
var initialWeight: Int {
lockedWeight ?? weight

@ -844,13 +844,9 @@ class Tournament : ModelObject, Storable {
}
func isStartDateIsDifferentThanCallDate(_ team: TeamRegistration) -> Bool {
guard let callDate = team.callDate else { return true }
if let groupStageStartDate = team.groupStageObject()?.startDate {
return Calendar.current.compare(callDate, to: groupStageStartDate, toGranularity: .minute) != ComparisonResult.orderedSame
} else if let roundMatchStartDate = team.initialMatch()?.startDate {
return Calendar.current.compare(callDate, to: roundMatchStartDate, toGranularity: .minute) != ComparisonResult.orderedSame
}
return true
guard let summonDate = team.callDate else { return true }
guard let expectedSummonDate = team.expectedSummonDate() else { return true }
return Calendar.current.compare(summonDate, to: expectedSummonDate, toGranularity: .minute) != ComparisonResult.orderedSame
}
func availableToStart(_ allMatches: [Match]) -> [Match] {
@ -1082,8 +1078,8 @@ class Tournament : ModelObject, Storable {
func callStatus() -> TournamentStatus {
let selectedSortedTeams = selectedSortedTeams()
let called = selectedSortedTeams.filter{ $0.called() }
let label = called.count.formatted() + " / " + selectedSortedTeams.count.formatted() + " paires convoquées"
let called = selectedSortedTeams.filter { isStartDateIsDifferentThanCallDate($0) == false }
let label = called.count.formatted() + " / " + selectedSortedTeams.count.formatted() + " convoquées au bon horaire"
let completion = (Double(called.count) / Double(selectedSortedTeams.count))
let completionLabel = completion.isNaN ? "" : completion.formatted(.percent.precision(.fractionLength(0)))
return TournamentStatus(label: label, completion: completionLabel)
@ -1121,7 +1117,7 @@ class Tournament : ModelObject, Storable {
return [teamCount.formatted() + " équipes", groupStageLabel].compactMap({ $0 }).joined(separator: ", ")
}
func buildStructure() {
func deleteAndBuildEverything() {
deleteStructure()
deleteGroupStages()
buildGroupStages()

@ -43,7 +43,7 @@ struct CallSettingsView: View {
RowButtonView("Tout le monde a été convoqué", role: .destructive) {
let teams = tournament.unsortedTeams()
teams.forEach { team in
team.callDate = Date()
team.callDate = team.expectedSummonDate()
}
try? dataStore.teamRegistrations.addOrUpdate(contentOfs: teams)
}

@ -31,7 +31,7 @@ struct CallView: View {
Text(startDate.formatted(.dateTime.weekday().day(.twoDigits).month().year()))
}
Spacer()
Text("paires convoquées")
Text("convoquées au bon horaire")
}
.font(.caption)
.foregroundColor(.secondary)
@ -130,7 +130,6 @@ struct CallView: View {
MessageComposeView(recipients: recipients, body: body) { result in
switch result {
case .cancelled:
_called(true)
break
case .failed:
self.sentError = .messageFailed
@ -153,7 +152,6 @@ struct CallView: View {
switch result {
case .cancelled, .saved:
self.contactType = nil
_called(true)
case .failed:
self.contactType = nil
self.sentError = .mailFailed

@ -17,7 +17,7 @@ struct ClubCourtSetupView: View {
@ViewBuilder
var body: some View {
Section {
TournamentFieldsManagerView(localizedStringKey: "Terrains", count: $club.courtCount)
TournamentFieldsManagerView(localizedStringKey: "Terrains du club", count: $club.courtCount)
.disabled(displayContext == .lockedForEditing)
.onChange(of: club.courtCount) {
if displayContext != .addition {

@ -46,15 +46,11 @@ struct MatchDateView: View {
let tournament = match.currentTournament()
let estimatedDuration = tournament != nil ? match.matchFormat.getEstimatedDuration(tournament!.additionalEstimationDuration) : match.matchFormat.getEstimatedDuration()
Button("Décaler de \(estimatedDuration) minutes") {
match.startDate = match.startDate?.addingTimeInterval(Double(estimatedDuration) * 60.0)
match.endDate = nil
_save()
match.cleanScheduleAndSave(match.startDate?.addingTimeInterval(Double(estimatedDuration) * 60.0))
}
}
Button("Retirer l'horaire") {
match.startDate = nil
match.endDate = nil
_save()
match.cleanScheduleAndSave()
}
}
} label: {

@ -49,6 +49,49 @@ struct TournamentClubSettingsView: View {
}
}
Section {
TournamentFieldsManagerView(localizedStringKey: "Terrains pour le tournoi", count: $tournament.courtCount)
if let event = tournament.eventObject() {
NavigationLink {
CourtAvailabilitySettingsView(event: event)
.environment(tournament)
} label: {
Text("Préciser la disponibilité des terrains")
}
}
} footer: {
if let club = tournament.club() {
if tournament.courtCount < club.courtCount {
let plural = tournament.courtCount.pluralSuffix
let verb = tournament.courtCount > 1 ? "seront" : "sera"
Text("En réduisant les terrains maximum, seul\(plural) le\(plural) \(tournament.courtCount) premier\(plural) terrain\(plural) \(verb) utilisé\(plural)") + Text(", par contre, si vous augmentez le nombre de terrains, vous pourrez plutôt préciser quel terrain n'est pas disponible.")
} else if tournament.courtCount > club.courtCount {
let isCreatedByUser = club.hasBeenCreated(by: dataStore.user.id)
Button {
do {
club.courtCount = tournament.courtCount
try dataStore.clubs.addOrUpdate(instance: club)
} catch {
Logger.error(error)
}
} label: {
if isCreatedByUser {
Text("Vous avez indiqué plus de terrains dans ce tournoi que dans le club.")
+ Text("Mettre à jour le club ?").underline().foregroundStyle(.master)
} else {
Label("Vous avez indiqué plus de terrains dans ce tournoi que dans le club.", systemImage: "exclamationmark.triangle.fill").foregroundStyle(.logoRed)
}
}
.buttonStyle(.plain)
.disabled(isCreatedByUser == false)
}
}
}
if let selectedClub {
ClubCourtSetupView(club: selectedClub, displayContext: selectedClub.hasBeenCreated(by: dataStore.user.id) ? .edition : .lockedForEditing, selectedCourt: $selectedCourt)
.onChange(of: selectedClub.courtCount) {

@ -204,15 +204,15 @@ struct TableStructureView: View {
}
}
.disabled(updatedElements.isEmpty)
.confirmationDialog("Mise à jour de la structure", isPresented: $presentRefreshStructureWarning, actions: {
.confirmationDialog("Refaire la structure", isPresented: $presentRefreshStructureWarning, actions: {
if requirements.allSatisfy({ $0 == .groupStage }) {
Button("Mettre à jour les poules") {
Button("Refaire les poules") {
_save(rebuildEverything: false)
}
}
Button("Tout mettre à jour", role: .destructive) {
Button("Tout refaire", role: .destructive) {
_save(rebuildEverything: true)
}
@ -234,10 +234,6 @@ struct TableStructureView: View {
do {
let requirements = Set(updatedElements.compactMap { $0.requiresRebuilding })
if (rebuildEverything == false && requirements.contains(.all)) || rebuildEverything {
tournament.deleteStructure()
}
tournament.teamCount = teamCount
tournament.groupStageCount = groupStageCount
tournament.teamsPerGroupStage = teamsPerGroupStage
@ -245,8 +241,9 @@ struct TableStructureView: View {
tournament.groupStageAdditionalQualified = groupStageAdditionalQualified
if (rebuildEverything == false && requirements.contains(.all)) || rebuildEverything {
tournament.buildStructure()
tournament.deleteAndBuildEverything()
} else if (rebuildEverything == false && requirements.contains(.groupStage)) {
tournament.deleteGroupStages()
tournament.buildGroupStages()
}
@ -342,7 +339,7 @@ extension TableStructureView {
var rebuildingRequirementMessage: String {
switch self {
case .groupStage:
return "Si vous le souhaitez, seulement les poules seront mis à jour. Le tableau ne sera pas modifié."
return "Si vous le souhaitez, seulement les poules seront refaites. Le tableau ne sera pas modifié."
case .all:
return "Tous les matchs seront re-générés. La position des têtes de série sera remise à zéro et les poules seront reconstruites."
}

Loading…
Cancel
Save