fix stuff on manual player creation

multistore
Razmig Sarkissian 1 year ago
parent 2aad3da572
commit 93515db50a
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 22
      PadelClub/Data/Tournament.swift
  3. 2
      PadelClub/Utils/ContactManager.swift
  4. 5
      PadelClub/Views/GroupStage/GroupStageSettingsView.swift
  5. 33
      PadelClub/Views/Player/Components/PlayerPopoverView.swift
  6. 3
      PadelClub/Views/Player/PlayerDetailView.swift
  7. 6
      PadelClub/Views/Round/RoundSettingsView.swift
  8. 19
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  9. 5
      PadelClubTests/ServerDataTests.swift

@ -1919,7 +1919,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 21;
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 = 20;
CURRENT_PROJECT_VERSION = 21;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -48,8 +48,6 @@ class Tournament : ModelObject, Storable {
var publishSummons: Bool = false
var publishGroupStages: Bool = false
var publishBrackets: Bool = false
//local
var shouldVerifyGroupStage: Bool = false
var shouldVerifyBracket: Bool = false
@ -94,9 +92,11 @@ class Tournament : ModelObject, Storable {
case _publishSummons = "publishSummons"
case _publishGroupStages = "publishGroupStages"
case _publishBrackets = "publishBrackets"
case _shouldVerifyGroupStage = "shouldVerifyGroupStage"
case _shouldVerifyBracket = "shouldVerifyBracket"
}
internal init(event: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = false, 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, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil, additionalEstimationDuration: Int = 0, isDeleted: Bool = false, publishTeams: Bool = false, publishSummons: Bool = false, publishGroupStages: Bool = false, publishBrackets: Bool = false) {
internal init(event: String? = nil, name: String? = nil, startDate: Date = Date(), endDate: Date? = nil, creationDate: Date = Date(), isPrivate: Bool = false, 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, closedRegistrationDate: Date? = nil, groupStageAdditionalQualified: Int = 0, courtCount: Int = 2, prioritizeClubMembers: Bool = false, qualifiedPerGroupStage: Int = 1, teamsPerGroupStage: Int = 4, entryFee: Double? = nil, additionalEstimationDuration: Int = 0, isDeleted: Bool = false, publishTeams: Bool = false, publishSummons: Bool = false, publishGroupStages: Bool = false, publishBrackets: Bool = false, shouldVerifyBracket: Bool = false, shouldVerifyGroupStage: Bool = false) {
self.event = event
self.name = name
self.startDate = startDate
@ -128,6 +128,8 @@ class Tournament : ModelObject, Storable {
self.publishSummons = publishSummons
self.publishBrackets = publishBrackets
self.publishGroupStages = publishGroupStages
self.shouldVerifyBracket = shouldVerifyBracket
self.shouldVerifyGroupStage = shouldVerifyGroupStage
}
required init(from decoder: Decoder) throws {
@ -166,7 +168,8 @@ class Tournament : ModelObject, Storable {
publishSummons = try container.decodeIfPresent(Bool.self, forKey: ._publishSummons) ?? false
publishGroupStages = try container.decodeIfPresent(Bool.self, forKey: ._publishGroupStages) ?? false
publishBrackets = try container.decodeIfPresent(Bool.self, forKey: ._publishBrackets) ?? false
shouldVerifyBracket = try container.decodeIfPresent(Bool.self, forKey: ._shouldVerifyBracket) ?? false
shouldVerifyGroupStage = try container.decodeIfPresent(Bool.self, forKey: ._shouldVerifyGroupStage) ?? false
}
fileprivate static let _numberFormatter: NumberFormatter = NumberFormatter()
@ -276,6 +279,8 @@ class Tournament : ModelObject, Storable {
try container.encode(publishSummons, forKey: ._publishSummons)
try container.encode(publishBrackets, forKey: ._publishBrackets)
try container.encode(publishGroupStages, forKey: ._publishGroupStages)
try container.encode(shouldVerifyBracket, forKey: ._shouldVerifyBracket)
try container.encode(shouldVerifyGroupStage, forKey: ._shouldVerifyGroupStage)
}
fileprivate func _encodePayment(container: inout KeyedEncodingContainer<CodingKeys>) throws {
@ -1152,6 +1157,15 @@ class Tournament : ModelObject, Storable {
return TournamentStatus(label: label, completion: completionLabel)
}
func confirmedSummonStatus() -> TournamentStatus {
let selectedSortedTeams = selectedSortedTeams()
let called = selectedSortedTeams.filter { $0.confirmationDate != nil }
let label = called.count.formatted() + " / " + selectedSortedTeams.count.formatted() + " confirmées"
let completion = (Double(called.count) / Double(selectedSortedTeams.count))
let completionLabel = completion.isNaN ? "" : completion.formatted(.percent.precision(.fractionLength(0)))
return TournamentStatus(label: label, completion: completionLabel)
}
func bracketStatus() -> String {
let availableSeeds = availableSeeds()
if availableSeeds.isEmpty == false {

@ -80,7 +80,7 @@ extension ContactType {
[entryFeeMessage, message].compacted().map { $0.trimmed }.joined(separator: "\n\n")
}
var intro = reSummon ? "Suite à des forfaits, vous êtes finalement" : "Vous êtes"
let intro = reSummon ? "Suite à des forfaits, vous êtes finalement" : "Vous êtes"
if let tournament {
return "Bonjour,\n\n\(intro) \(localizedCalled) pour jouer en \(roundLabel.lowercased()) du \(tournament.tournamentTitle(.short)) au \(clubName) le \(date.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide))) à \(date.formatted(Date.FormatStyle().hour().minute())).\n\n" + computedMessage + "\n\n\(signature)"

@ -32,6 +32,11 @@ struct GroupStageSettingsView: View {
Section {
RowButtonView("Valider les poules", role: .destructive) {
tournament.shouldVerifyGroupStage = false
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
}
} footer: {
Text("Suite à changement dans votre liste d'inscrits, veuillez vérifier l'intégrité de vos poules et valider que tout est ok.")

@ -32,7 +32,6 @@ struct PlayerPopoverView: View {
@State private var source: String?
init(source: String?, sex: Int, requiredField: [PlayerCreationField] = [.firstName, .lastName], creationCompletionHandler: @escaping (PlayerRegistration) -> Void) {
let source = source
if let source {
let words = source.components(separatedBy: .whitespaces)
if words.isEmpty == false {
@ -44,6 +43,8 @@ struct PlayerPopoverView: View {
} else {
_firstName = State(wrappedValue: source)
}
_source = State(wrappedValue: source)
}
_sex = State(wrappedValue: sex)
@ -51,7 +52,6 @@ struct PlayerPopoverView: View {
self.requiredField = requiredField
self.creationCompletionHandler = creationCompletionHandler
_source = State(wrappedValue: source)
}
var body: some View {
@ -94,6 +94,7 @@ struct PlayerPopoverView: View {
Spacer()
TextField("Prénom", text: $firstName)
.submitLabel(.next)
.autocorrectionDisabled()
.keyboardType(.alphabet)
.textInputAutocapitalization(.words)
.focused($firstNameIsFocused)
@ -108,6 +109,7 @@ struct PlayerPopoverView: View {
Spacer()
TextField("Nom", text: $lastName)
.submitLabel(.next)
.autocorrectionDisabled()
.textInputAutocapitalization(.words)
.keyboardType(.alphabet)
.focused($lastNameIsFocused)
@ -180,7 +182,6 @@ struct PlayerPopoverView: View {
.onAppear {
firstNameIsFocused = true
}
.autocorrectionDisabled()
.navigationTitle(sex == 1 ? "Nouveau joueur" : "Nouvelle joueuse")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.visible, for: .navigationBar)
@ -199,23 +200,27 @@ struct PlayerPopoverView: View {
}
}
if amountIsFocused || licenseIsFocused {
if licenseIsFocused || amountIsFocused {
ToolbarItem(placement: .keyboard) {
Button("Confirmer") {
if licenseIsFocused {
license = license.trimmed
if requiredField.contains(.license) {
if license.isLicenseNumber {
amountIsFocused = true
HStack {
Spacer()
Button("Confirmer") {
if licenseIsFocused {
license = license.trimmed
if requiredField.contains(.license) {
if license.isLicenseNumber {
amountIsFocused = true
} else {
displayWrongLicenceError = true
}
} else {
displayWrongLicenceError = true
amountIsFocused = true
}
} else {
amountIsFocused = true
amountIsFocused = false
}
} else {
amountIsFocused = false
}
.buttonStyle(.bordered)
}
}
}

@ -46,6 +46,9 @@ struct PlayerDetailView: View {
.focused($textFieldIsFocus)
} label: {
Text("Rang")
if player.rank == nil {
Text("Classement calculé : " + player.computedRank.formatted())
}
}
} header: {
Text("Classement actuel")

@ -6,6 +6,7 @@
//
import SwiftUI
import LeStorage
struct RoundSettingsView: View {
@EnvironmentObject var dataStore: DataStore
@ -18,6 +19,11 @@ struct RoundSettingsView: View {
Section {
RowButtonView("Valider le tableau", role: .destructive) {
tournament.shouldVerifyBracket = false
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
}
} footer: {
Text("Suite à changement dans votre liste d'inscrits, veuillez vérifier l'intégrité de votre tableau et valider que tout est ok.")

@ -120,18 +120,22 @@ struct InscriptionManagerView: View {
}
}
.onAppear {
self.presentationCount += 1
if self.teamsHash == nil {
self.teamsHash = _simpleHash(ids: tournament.selectedSortedTeams().map { $0.id })
}
}
.onDisappear {
self.presentationCount -= 1
if self.presentationCount == 0 {
let newHash = _simpleHash(ids: tournament.selectedSortedTeams().map { $0.id })
if let teamsHash {
self.tournament.shouldVerifyBracket = newHash != teamsHash
self.tournament.shouldVerifyGroupStage = newHash != teamsHash
let newHash = _simpleHash(ids: tournament.selectedSortedTeams().map { $0.id })
if let teamsHash, newHash != teamsHash {
self.teamsHash = newHash
if self.tournament.shouldVerifyBracket == false || self.tournament.shouldVerifyGroupStage == false {
self.tournament.shouldVerifyBracket = true
self.tournament.shouldVerifyGroupStage = true
do {
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
}
}
}
@ -161,6 +165,7 @@ struct InscriptionManagerView: View {
}
.sheet(isPresented: $presentPlayerCreation) {
PlayerPopoverView(source: _searchSource(), sex: _addPlayerSex()) { p in
p.setComputedRank(in: tournament)
createdPlayers.insert(p)
createdPlayerIds.insert(p.id)
}

@ -96,7 +96,7 @@ final class ServerDataTests: XCTestCase {
return
}
let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true)
let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true)
let t = try await Store.main.service().post(tournament)
assert(t.event == tournament.event)
@ -130,7 +130,8 @@ final class ServerDataTests: XCTestCase {
assert(t.publishSummons == tournament.publishSummons)
assert(t.publishGroupStages == tournament.publishGroupStages)
assert(t.publishBrackets == tournament.publishBrackets)
assert(t.shouldVerifyBracket == tournament.shouldVerifyBracket)
assert(t.shouldVerifyGroupStage == tournament.shouldVerifyGroupStage)
}
func testGroupStage() async throws {

Loading…
Cancel
Save