fix registration import issue

fix p2000 stuff
newoffer2025
Raz 6 months ago
parent 9cb968c441
commit 7cd866185e
  1. 24
      PadelClub.xcodeproj/project.pbxproj
  2. 1
      PadelClub/Extensions/PlayerRegistration+Extensions.swift
  3. 4
      PadelClub/Extensions/TeamRegistration+Extensions.swift
  4. 6
      PadelClub/Utils/FileImportManager.swift
  5. 10
      PadelClub/Views/Cashier/CashierDetailView.swift
  6. 54
      PadelClub/Views/Cashier/CashierSettingsView.swift
  7. 4
      PadelClub/Views/Club/ClubDetailView.swift
  8. 6
      PadelClub/Views/Player/PlayerDetailView.swift
  9. 4
      PadelClub/Views/Tournament/Screen/AddTeamView.swift
  10. 46
      PadelClub/Views/Tournament/Screen/Components/TournamentGeneralSettingsView.swift
  11. 16
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift
  12. 4
      PadelClub/Views/Tournament/TournamentView.swift

@ -3094,7 +3094,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3120,7 +3120,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3141,7 +3141,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3166,7 +3166,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3259,7 +3259,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3285,7 +3285,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3305,7 +3305,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3330,7 +3330,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3351,7 +3351,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
@ -3374,7 +3374,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3394,7 +3394,7 @@
CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements; CODE_SIGN_ENTITLEMENTS = PadelClub/PadelClub.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6; DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -3416,7 +3416,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.2.26; MARKETING_VERSION = 1.2.27;
PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta; PRODUCT_BUNDLE_IDENTIFIER = app.padelclub.beta;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

@ -21,6 +21,7 @@ extension PlayerRegistration {
self.tournamentPlayed = importedPlayer.tournamentPlayed self.tournamentPlayed = importedPlayer.tournamentPlayed
self.points = importedPlayer.getPoints() self.points = importedPlayer.getPoints()
self.clubName = importedPlayer.clubName?.prefixTrimmed(200) self.clubName = importedPlayer.clubName?.prefixTrimmed(200)
self.clubCode = importedPlayer.clubCode?.replaceCharactersFromSet(characterSet: .whitespaces).prefixTrimmed(20)
self.ligueName = importedPlayer.ligueName?.prefixTrimmed(200) self.ligueName = importedPlayer.ligueName?.prefixTrimmed(200)
self.assimilation = importedPlayer.assimilation?.prefixTrimmed(50) self.assimilation = importedPlayer.assimilation?.prefixTrimmed(50)
self.source = .frenchFederation self.source = .frenchFederation

@ -45,6 +45,10 @@ extension TeamRegistration {
player.captain = oldPlayer.captain player.captain = oldPlayer.captain
player.assimilation = oldPlayer.assimilation player.assimilation = oldPlayer.assimilation
player.ligueName = oldPlayer.ligueName player.ligueName = oldPlayer.ligueName
player.registrationStatus = oldPlayer.registrationStatus
player.timeToConfirm = oldPlayer.timeToConfirm
player.paymentId = oldPlayer.paymentId
player.clubMember = oldPlayer.clubMember
} }
} }
} }

@ -307,8 +307,10 @@ class FileImportManager {
if (tournamentCategory == tournament.tournamentCategory && tournamentAgeCategory == tournament.federalTournamentAge) || checkingCategoryDisabled { if (tournamentCategory == tournament.tournamentCategory && tournamentAgeCategory == tournament.federalTournamentAge) || checkingCategoryDisabled {
let playerOne = PlayerRegistration(federalData: Array(resultOne[0...7]), sex: sexPlayerOne, sexUnknown: sexUnknown) let playerOne = PlayerRegistration(federalData: Array(resultOne[0...7]), sex: sexPlayerOne, sexUnknown: sexUnknown)
playerOne?.setComputedRank(in: tournament) playerOne?.setComputedRank(in: tournament)
playerOne?.setClubMember(for: tournament)
let playerTwo = PlayerRegistration(federalData: Array(resultTwo[0...7]), sex: sexPlayerTwo, sexUnknown: sexUnknown) let playerTwo = PlayerRegistration(federalData: Array(resultTwo[0...7]), sex: sexPlayerTwo, sexUnknown: sexUnknown)
playerTwo?.setComputedRank(in: tournament) playerTwo?.setComputedRank(in: tournament)
playerTwo?.setClubMember(for: tournament)
let players = [playerOne, playerTwo].compactMap({ $0 }) let players = [playerOne, playerTwo].compactMap({ $0 })
if players.isEmpty == false { if players.isEmpty == false {
@ -368,8 +370,10 @@ class FileImportManager {
let playerOne = PlayerRegistration(federalData: Array(result[0...7]), sex: sexPlayerOne, sexUnknown: sexUnknown) let playerOne = PlayerRegistration(federalData: Array(result[0...7]), sex: sexPlayerOne, sexUnknown: sexUnknown)
playerOne?.setComputedRank(in: tournament) playerOne?.setComputedRank(in: tournament)
playerOne?.setClubMember(for: tournament)
let playerTwo = PlayerRegistration(federalData: Array(result[8...]), sex: sexPlayerTwo, sexUnknown: sexUnknown) let playerTwo = PlayerRegistration(federalData: Array(result[8...]), sex: sexPlayerTwo, sexUnknown: sexUnknown)
playerTwo?.setComputedRank(in: tournament) playerTwo?.setComputedRank(in: tournament)
playerTwo?.setClubMember(for: tournament)
let players = [playerOne, playerTwo].compactMap({ $0 }) let players = [playerOne, playerTwo].compactMap({ $0 })
if players.isEmpty == false { if players.isEmpty == false {
@ -404,6 +408,7 @@ class FileImportManager {
let registeredPlayers = found?.map({ importedPlayer in let registeredPlayers = found?.map({ importedPlayer in
let player = PlayerRegistration(importedPlayer: importedPlayer) let player = PlayerRegistration(importedPlayer: importedPlayer)
player.setComputedRank(in: tournament) player.setComputedRank(in: tournament)
player.setClubMember(for: tournament)
return player return player
}) })
if let registeredPlayers, registeredPlayers.isEmpty == false { if let registeredPlayers, registeredPlayers.isEmpty == false {
@ -466,6 +471,7 @@ class FileImportManager {
if let found, autoSearch { if let found, autoSearch {
let player = PlayerRegistration(importedPlayer: found) let player = PlayerRegistration(importedPlayer: found)
player.setComputedRank(in: tournament) player.setComputedRank(in: tournament)
player.setClubMember(for: tournament)
player.email = email player.email = email
player.phoneNumber = phoneNumber player.phoneNumber = phoneNumber
return player return player

@ -203,16 +203,14 @@ struct CashierDetailView: View {
DisclosureGroup { DisclosureGroup {
let selectedPlayers = tournament.selectedPlayers() let selectedPlayers = tournament.selectedPlayers()
ForEach(PlayerPaymentType.allCases) { type in ForEach(PlayerPaymentType.allCases) { type in
let count = selectedPlayers.filter({ $0.paymentType == type }).count let players = selectedPlayers.filter({ $0.paymentType == type })
if count > 0 { if players.count > 0 {
LabeledContent { LabeledContent {
if let entryFee = tournament.entryFee { let sum = players.compactMap({ $0.paidAmount(tournament) }).reduce(0.0, +)
let sum = Double(count) * entryFee
Text(sum.formatted(.currency(code: Locale.defaultCurrency()))) Text(sum.formatted(.currency(code: Locale.defaultCurrency())))
}
} label: { } label: {
Text(type.localizedLabel()) Text(type.localizedLabel())
Text(count.formatted()) Text(players.count.formatted())
} }
} }
} }

@ -13,25 +13,50 @@ struct CashierSettingsView: View {
@EnvironmentObject var dataStore: DataStore @EnvironmentObject var dataStore: DataStore
@State private var entryFee: Double? = nil @State private var entryFee: Double? = nil
@State private var clubMemberFeeDeduction: Double? = nil
@Bindable var tournament: Tournament @Bindable var tournament: Tournament
@FocusState private var focusedField: Tournament.CodingKeys? @FocusState private var focusedField: Tournament.CodingKeys?
let priceTags: [Double] = [15.0, 20.0, 25.0] let priceTags: [Double] = [15.0, 20.0, 25.0]
let deductionTags: [Double] = [5.0, 10.0]
init(tournament: Tournament) { init(tournament: Tournament) {
self.tournament = tournament self.tournament = tournament
_entryFee = State(wrappedValue: tournament.entryFee) _entryFee = State(wrappedValue: tournament.entryFee)
_clubMemberFeeDeduction = State(wrappedValue: tournament.clubMemberFeeDeduction)
} }
var body: some View { var body: some View {
List { List {
Section { Section {
LabeledContent {
TextField(tournament.isFree() ? "Gratuite" : "Inscription", value: $entryFee, format: .currency(code: Locale.defaultCurrency())) TextField(tournament.isFree() ? "Gratuite" : "Inscription", value: $entryFee, format: .currency(code: Locale.defaultCurrency()))
.keyboardType(.decimalPad) .keyboardType(.decimalPad)
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.focused($focusedField, equals: ._entryFee) .focused($focusedField, equals: ._entryFee)
} label: {
Text("Frais d'inscription")
}
LabeledContent {
TextField("Réduction", value: $clubMemberFeeDeduction, format: .currency(code: Locale.defaultCurrency()))
.keyboardType(.decimalPad)
.multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity)
.focused($focusedField, equals: ._clubMemberFeeDeduction)
.onChange(of: focusedField) {
if focusedField == ._clubMemberFeeDeduction {
DispatchQueue.main.async {
UIApplication.shared.sendAction(#selector(UIResponder.selectAll(_:)), to: nil, from: nil, for: nil)
}
}
}
} label: {
Text("Réduction membre")
}
.disabled(tournament.isFree())
} header: { } header: {
Text("Prix de l'inscription") Text("Frais d'inscription")
} footer: { } footer: {
Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.") Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.")
} }
@ -104,6 +129,7 @@ struct CashierSettingsView: View {
ToolbarItem(placement: .keyboard) { ToolbarItem(placement: .keyboard) {
HStack { HStack {
if focusedField == ._entryFee {
if tournament.isFree() { if tournament.isFree() {
ForEach(priceTags, id: \.self) { priceTag in ForEach(priceTags, id: \.self) { priceTag in
Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()))) { Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()))) {
@ -122,9 +148,24 @@ struct CashierSettingsView: View {
.buttonStyle(.bordered) .buttonStyle(.bordered)
} }
} else if focusedField == ._clubMemberFeeDeduction {
ForEach(deductionTags, id: \.self) { deductionTag in
Button(deductionTag.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0)))) {
clubMemberFeeDeduction = deductionTag
tournament.clubMemberFeeDeduction = deductionTag
focusedField = nil
}
.buttonStyle(.bordered)
}
Button("Gratuit") {
clubMemberFeeDeduction = entryFee
tournament.clubMemberFeeDeduction = clubMemberFeeDeduction
focusedField = nil
}
.buttonStyle(.bordered)
}
Spacer() Spacer()
Button("Valider") { Button("Valider") {
tournament.entryFee = entryFee
focusedField = nil focusedField = nil
} }
.buttonStyle(.bordered) .buttonStyle(.bordered)
@ -132,7 +173,14 @@ struct CashierSettingsView: View {
} }
} }
} }
.onChange(of: tournament.entryFee) { .onChange(of: focusedField) { old, new in
if old == ._entryFee {
tournament.entryFee = entryFee
} else if old == ._clubMemberFeeDeduction {
tournament.clubMemberFeeDeduction = clubMemberFeeDeduction
}
}
.onChange(of: [tournament.entryFee, tournament.clubMemberFeeDeduction]) {
_save() _save()
} }
} }

@ -245,10 +245,10 @@ struct ClubDetailView: View {
CourtView(court: court) CourtView(court: court)
} }
.onChange(of: zipCode) { .onChange(of: zipCode) {
club.zipCode = zipCode club.zipCode = zipCode.prefixTrimmed(10)
} }
.onChange(of: city) { .onChange(of: city) {
club.city = city club.city = city.prefixTrimmed(100)
} }
.onDisappear { .onDisappear {
if displayContext == .edition && clubDeleted == false { if displayContext == .edition && clubDeleted == false {

@ -80,6 +80,10 @@ struct PlayerDetailView: View {
Toggle("Joueur sur place", isOn: $player.hasArrived) Toggle("Joueur sur place", isOn: $player.hasArrived)
Toggle("Capitaine", isOn: $player.captain).disabled(player.hasPaidOnline()) Toggle("Capitaine", isOn: $player.captain).disabled(player.hasPaidOnline())
//Toggle("Coach", isOn: $player.coach) //Toggle("Coach", isOn: $player.coach)
Toggle(isOn: $player.clubMember) {
Text("Membre du club")
}
} }
Section { Section {
@ -256,7 +260,7 @@ struct PlayerDetailView: View {
// } // }
// } // }
} }
.onChange(of: [player.hasArrived, player.captain, player.coach]) { .onChange(of: [player.hasArrived, player.captain, player.coach, player.clubMember]) {
_save() _save()
} }
.onChange(of: player.sex) { .onChange(of: player.sex) {

@ -155,6 +155,7 @@ struct AddTeamView: View {
players.forEach { player in players.forEach { player in
let newPlayer = PlayerRegistration(importedPlayer: player) let newPlayer = PlayerRegistration(importedPlayer: player)
newPlayer.setComputedRank(in: tournament) newPlayer.setComputedRank(in: tournament)
newPlayer.setClubMember(for: tournament)
createdPlayers = Set<PlayerRegistration>() createdPlayers = Set<PlayerRegistration>()
createdPlayerIds = Set<String>() createdPlayerIds = Set<String>()
createdPlayers.insert(newPlayer) createdPlayers.insert(newPlayer)
@ -176,6 +177,7 @@ struct AddTeamView: View {
players.forEach { player in players.forEach { player in
let newPlayer = PlayerRegistration(importedPlayer: player) let newPlayer = PlayerRegistration(importedPlayer: player)
newPlayer.setComputedRank(in: tournament) newPlayer.setComputedRank(in: tournament)
newPlayer.setClubMember(for: tournament)
createdPlayers.insert(newPlayer) createdPlayers.insert(newPlayer)
createdPlayerIds.insert(newPlayer.id) createdPlayerIds.insert(newPlayer.id)
} }
@ -183,6 +185,7 @@ struct AddTeamView: View {
searchViewModel.selectedPlayers.forEach { player in searchViewModel.selectedPlayers.forEach { player in
let newPlayer = PlayerRegistration(importedPlayer: player) let newPlayer = PlayerRegistration(importedPlayer: player)
newPlayer.setComputedRank(in: tournament) newPlayer.setComputedRank(in: tournament)
newPlayer.setClubMember(for: tournament)
createdPlayers.insert(newPlayer) createdPlayers.insert(newPlayer)
createdPlayerIds.insert(newPlayer.id) createdPlayerIds.insert(newPlayer.id)
} }
@ -336,6 +339,7 @@ struct AddTeamView: View {
}.forEach { player in }.forEach { player in
let player = PlayerRegistration(importedPlayer: player) let player = PlayerRegistration(importedPlayer: player)
player.setComputedRank(in: tournament) player.setComputedRank(in: tournament)
player.setClubMember(for: tournament)
currentSelection.insert(player) currentSelection.insert(player)
} }

@ -16,6 +16,7 @@ struct TournamentGeneralSettingsView: View {
@State private var tournamentName: String = "" @State private var tournamentName: String = ""
@State private var tournamentInformation: String = "" @State private var tournamentInformation: String = ""
@State private var entryFee: Double? = nil @State private var entryFee: Double? = nil
@State private var clubMemberFeeDeduction: Double? = nil
@State private var umpireCustomMail: String @State private var umpireCustomMail: String
@State private var umpireCustomPhone: String @State private var umpireCustomPhone: String
@State private var umpireCustomContact: String @State private var umpireCustomContact: String
@ -24,12 +25,14 @@ struct TournamentGeneralSettingsView: View {
@FocusState private var focusedField: Tournament.CodingKeys? @FocusState private var focusedField: Tournament.CodingKeys?
let priceTags: [Double] = [15.0, 20.0, 25.0] let priceTags: [Double] = [15.0, 20.0, 25.0]
let deductionTags: [Double] = [5.0, 10.0]
init(tournament: Tournament) { init(tournament: Tournament) {
self.tournament = tournament self.tournament = tournament
_tournamentName = State(wrappedValue: tournament.name ?? "") _tournamentName = State(wrappedValue: tournament.name ?? "")
_tournamentInformation = State(wrappedValue: tournament.information ?? "") _tournamentInformation = State(wrappedValue: tournament.information ?? "")
_entryFee = State(wrappedValue: tournament.entryFee) _entryFee = State(wrappedValue: tournament.entryFee)
_clubMemberFeeDeduction = State(wrappedValue: tournament.clubMemberFeeDeduction)
_umpireCustomMail = State(wrappedValue: tournament.umpireCustomMail ?? "") _umpireCustomMail = State(wrappedValue: tournament.umpireCustomMail ?? "")
_umpireCustomPhone = State(wrappedValue: tournament.umpireCustomPhone ?? "") _umpireCustomPhone = State(wrappedValue: tournament.umpireCustomPhone ?? "")
_umpireCustomContact = State(wrappedValue: tournament.umpireCustomContact ?? "") _umpireCustomContact = State(wrappedValue: tournament.umpireCustomContact ?? "")
@ -58,6 +61,24 @@ struct TournamentGeneralSettingsView: View {
} label: { } label: {
Text("Inscription") Text("Inscription")
} }
LabeledContent {
TextField("Réduction", value: $clubMemberFeeDeduction, format: .currency(code: Locale.defaultCurrency()))
.keyboardType(.decimalPad)
.multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity)
.focused($focusedField, equals: ._clubMemberFeeDeduction)
.onChange(of: focusedField) {
if focusedField == ._clubMemberFeeDeduction {
DispatchQueue.main.async {
UIApplication.shared.sendAction(#selector(UIResponder.selectAll(_:)), to: nil, from: nil, for: nil)
}
}
}
} label: {
Text("Réduction membre")
}
.disabled(tournament.isFree())
} footer: { } footer: {
Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.") Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.")
} }
@ -172,6 +193,21 @@ struct TournamentGeneralSettingsView: View {
.buttonStyle(.bordered) .buttonStyle(.bordered)
} }
} else if focusedField == ._clubMemberFeeDeduction {
ForEach(deductionTags, id: \.self) { deductionTag in
Button(deductionTag.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0)))) {
clubMemberFeeDeduction = deductionTag
tournament.clubMemberFeeDeduction = deductionTag
focusedField = nil
}
.buttonStyle(.bordered)
}
Button("Gratuit") {
clubMemberFeeDeduction = entryFee
tournament.clubMemberFeeDeduction = clubMemberFeeDeduction
focusedField = nil
}
.buttonStyle(.bordered)
} else { } else {
if focusedField == ._name, tournamentName.isEmpty == false { if focusedField == ._name, tournamentName.isEmpty == false {
Button("Effacer") { Button("Effacer") {
@ -214,7 +250,7 @@ struct TournamentGeneralSettingsView: View {
.onChange(of: tournament.startDate) { .onChange(of: tournament.startDate) {
_save() _save()
} }
.onChange(of: tournament.entryFee) { .onChange(of: [tournament.entryFee, tournament.clubMemberFeeDeduction]) {
_save() _save()
} }
.onChange(of: [tournament.name, tournament.information, tournament.umpireCustomMail, tournament.umpireCustomPhone, tournament.umpireCustomContact]) { .onChange(of: [tournament.name, tournament.information, tournament.umpireCustomMail, tournament.umpireCustomPhone, tournament.umpireCustomContact]) {
@ -243,6 +279,8 @@ struct TournamentGeneralSettingsView: View {
} }
} else if old == ._entryFee { } else if old == ._entryFee {
tournament.entryFee = entryFee tournament.entryFee = entryFee
} else if old == ._clubMemberFeeDeduction {
tournament.clubMemberFeeDeduction = clubMemberFeeDeduction
} else if old == ._umpireCustomMail { } else if old == ._umpireCustomMail {
_confirmUmpireMail() _confirmUmpireMail()
} else if old == ._umpireCustomPhone { } else if old == ._umpireCustomPhone {
@ -301,11 +339,7 @@ struct TournamentGeneralSettingsView: View {
} }
private func _save() { private func _save() {
do { dataStore.tournaments.addOrUpdate(instance: tournament)
try dataStore.tournaments.addOrUpdate(instance: tournament)
} catch {
Logger.error(error)
}
} }
private func _customUmpireView() -> some View { private func _customUmpireView() -> some View {

@ -32,6 +32,7 @@ struct RegistrationSetupView: View {
@State private var isTemplate: Bool @State private var isTemplate: Bool
@State private var isCorporateTournament: Bool @State private var isCorporateTournament: Bool
@State private var isValidating = false @State private var isValidating = false
@State private var unregisterDeltaInHours: Int
// Online Payment // Online Payment
@State private var enableOnlinePayment: Bool @State private var enableOnlinePayment: Bool
@ -56,6 +57,7 @@ struct RegistrationSetupView: View {
_enableOnlineRegistration = .init(wrappedValue: tournament.enableOnlineRegistration) _enableOnlineRegistration = .init(wrappedValue: tournament.enableOnlineRegistration)
_isTemplate = .init(wrappedValue: tournament.isTemplate) _isTemplate = .init(wrappedValue: tournament.isTemplate)
_isCorporateTournament = .init(wrappedValue: tournament.isCorporateTournament) _isCorporateTournament = .init(wrappedValue: tournament.isCorporateTournament)
_unregisterDeltaInHours = .init(wrappedValue: tournament.unregisterDeltaInHours)
// Registration Date Limit // Registration Date Limit
if let registrationDateLimit = tournament.registrationDateLimit { if let registrationDateLimit = tournament.registrationDateLimit {
_registrationDateLimit = .init(wrappedValue: registrationDateLimit) _registrationDateLimit = .init(wrappedValue: registrationDateLimit)
@ -215,6 +217,18 @@ struct RegistrationSetupView: View {
Text("Si une date de fermeture des inscriptions en ligne est définie, alors plus aucune inscription ne sera possible après cette date. Sinon, la date du début du tournoi ou la date de clôture des inscriptions seront utilisées.") Text("Si une date de fermeture des inscriptions en ligne est définie, alors plus aucune inscription ne sera possible après cette date. Sinon, la date du début du tournoi ou la date de clôture des inscriptions seront utilisées.")
} }
Section {
LabeledContent {
StepperView(count: $unregisterDeltaInHours)
} label: {
Text("\(unregisterDeltaInHours)h avant")
}
} header: {
Text("Limite de désinscription")
} footer: {
Text("Empêche la désinscription plusieurs heures avant le début du tournoi")
}
Section { Section {
if displayWarning() { if displayWarning() {
Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.") Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.")
@ -550,7 +564,7 @@ struct RegistrationSetupView: View {
tournament.enableOnlineRegistration = enableOnlineRegistration tournament.enableOnlineRegistration = enableOnlineRegistration
tournament.isTemplate = isTemplate tournament.isTemplate = isTemplate
tournament.isCorporateTournament = isCorporateTournament tournament.isCorporateTournament = isCorporateTournament
tournament.unregisterDeltaInHours = unregisterDeltaInHours
if enableOnlineRegistration { if enableOnlineRegistration {
tournament.accountIsRequired = userAccountIsRequired tournament.accountIsRequired = userAccountIsRequired
tournament.licenseIsRequired = licenseIsRequired tournament.licenseIsRequired = licenseIsRequired

@ -261,6 +261,10 @@ struct TournamentView: View {
LabelStructure() LabelStructure()
} }
NavigationLink(value: Screen.cashier) {
Text(tournament.isFree() ? "Présence" : "Encaissement")
}
NavigationLink(value: Screen.rankings) { NavigationLink(value: Screen.rankings) {
LabeledContent { LabeledContent {
if tournament.publishRankings == false { if tournament.publishRankings == false {

Loading…
Cancel
Save