paca_championship
Raz 11 months ago
parent 59fe22662b
commit 7a71beeea8
  1. 10
      PadelClub/Data/PlayerRegistration.swift
  2. 35
      PadelClub/Data/TeamRegistration.swift
  3. 10
      PadelClub/Data/Tournament.swift
  4. 18
      PadelClub/Extensions/String+Extensions.swift
  5. 33
      PadelClub/Utils/FileImportManager.swift
  6. 2
      PadelClub/Views/Navigation/Umpire/PadelClubView.swift

@ -47,7 +47,7 @@ final class PlayerRegistration: ModelObject, Storable {
func localizedSourceLabel() -> String {
switch source {
case .frenchFederation:
case .frenchFederation, .frenchFederationVerified:
return "Via la base fédérale"
case .beachPadel:
return "Via le fichier beach-padel"
@ -180,6 +180,7 @@ final class PlayerRegistration: ModelObject, Storable {
let values = [
lastName.uppercased(),
firstName.capitalized,
isVerified(),
"=\"" + formattedLicense() + "\"",
"\(computedRank)",
isNVEQ ? "NVEQ" : "EQ",
@ -189,11 +190,15 @@ final class PlayerRegistration: ModelObject, Storable {
}
}
func isVerified() -> String {
source == .frenchFederationVerified ? "ok" : ""
}
func championshipAlerts(tournament: Tournament) -> [ChampionshipAlert] {
var alerts = [ChampionshipAlert]()
if isUnranked() && source == nil {
alerts.append(.unranked(self))
} else {
} else if source != .frenchFederationVerified {
if tournament.tournamentCategory == .men && isMalePlayer() == false {
alerts.append(.playerSexInvalid(self))
}
@ -516,6 +521,7 @@ final class PlayerRegistration: ModelObject, Storable {
case frenchFederation = 0
case beachPadel = 1
case onlineRegistration = 2
case frenchFederationVerified = 3
}
enum PlayerSexType: Int, Hashable, CaseIterable, Identifiable, Codable {

@ -390,7 +390,7 @@ final class TeamRegistration: ModelObject, Storable {
formattedInscriptionDate(exportFormat) ?? "",
alertCountFormatted(teamIndex: index),
alertDescription(teamIndex: index),
"\(weight)",
teamWeightFormatted(),
jokerWeightFormatted(),
playerCountFormatted(),
nveqCountFormatted(),
@ -427,6 +427,10 @@ final class TeamRegistration: ModelObject, Storable {
}
}
func teamWeightFormatted() -> String {
let value = players().prefix(6).map({ $0.computedRank }).reduce(0,+)
return "\(value)"
}
func unrankedCountFormatted() -> String {
players().filter({ $0.isUnranked() && $0.source == nil }).count.formatted()
}
@ -445,15 +449,15 @@ final class TeamRegistration: ModelObject, Storable {
let players = players()
if teamIndex <= 16, players.filter({ $0.isNVEQ }).count > 2 {
alerts.append(.tooManyNVEQ(self))
}
if teamIndex <= 16, players.count > 8 {
alerts.append(.tooManyPlayers(self))
}
// if teamIndex <= 16, players.filter({ $0.isNVEQ }).count > 2 {
// alerts.append(.tooManyNVEQ(self))
//
// }
//
// if teamIndex <= 16, players.count > 8 {
// alerts.append(.tooManyPlayers(self))
//
// }
players.forEach { pr in
alerts.append(contentsOf: pr.championshipAlerts(tournament: tournament))
@ -497,12 +501,21 @@ final class TeamRegistration: ModelObject, Storable {
} else {
return nil
}
case .csv, .championship:
case .csv:
if let registrationDate {
return registrationDate.formatted(.dateTime.weekday().day().month().hour().minute())
} else {
return nil
}
case .championship:
if let registrationDate {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter.string(from: registrationDate)
} else {
return nil
}
}
}

@ -623,51 +623,61 @@ defer {
// "E-mail",
"JOUEUR 1 - Nom",
"JOUEUR 1 - Prénom",
"JOUEUR 1 - Vérif",
"JOUEUR 1 - Licence",
"JOUEUR 1 - Ranking",
"JOUEUR 1 - Statut",
"JOUEUR 2 - Nom",
"JOUEUR 2 - Prénom",
"JOUEUR 2 - Vérif",
"JOUEUR 2 - Licence",
"JOUEUR 2 - Ranking",
"JOUEUR 2 - Statut",
"JOUEUR 3 - Nom",
"JOUEUR 3 - Prénom",
"JOUEUR 3 - Vérif",
"JOUEUR 3 - Licence",
"JOUEUR 3 - Ranking",
"JOUEUR 3 - Statut",
"JOUEUR 4 - Nom",
"JOUEUR 4 - Prénom",
"JOUEUR 4 - Vérif",
"JOUEUR 4 - Licence",
"JOUEUR 4 - Ranking",
"JOUEUR 4 - Statut",
"JOUEUR 5 - Nom",
"JOUEUR 5 - Prénom",
"JOUEUR 5 - Vérif",
"JOUEUR 5 - Licence",
"JOUEUR 5 - Ranking",
"JOUEUR 5 - Statut",
"JOUEUR 6 - Nom",
"JOUEUR 6 - Prénom",
"JOUEUR 6 - Vérif",
"JOUEUR 6 - Licence",
"JOUEUR 6 - Ranking",
"JOUEUR 6 - Statut",
"JOUEUR 7 - Nom",
"JOUEUR 7 - Prénom",
"JOUEUR 7 - Vérif",
"JOUEUR 7 - Licence",
"JOUEUR 7 - Ranking",
"JOUEUR 7 - Statut",
"JOUEUR 8 - Nom",
"JOUEUR 8 - Prénom",
"JOUEUR 8 - Vérif",
"JOUEUR 8 - Licence",
"JOUEUR 8 - Ranking",
"JOUEUR 8 - Statut",
"JOUEUR 9 - Nom",
"JOUEUR 9 - Prénom",
"JOUEUR 9 - Vérif",
"JOUEUR 9 - Licence",
"JOUEUR 9 - Ranking",
"JOUEUR 9 - Statut",
"JOUEUR 10 - Nom",
"JOUEUR 10 - Prénom",
"JOUEUR 10 - Vérif",
"JOUEUR 10 - Licence",
"JOUEUR 10 - Ranking",
"JOUEUR 10 - Statut",

@ -209,11 +209,23 @@ extension LosslessStringConvertible {
extension String {
func createFile(_ withName: String = "temp", _ exportedFormat: ExportFormat = .rawText) -> URL {
let url = FileManager.default.temporaryDirectory
.appendingPathComponent(withName)
.appendingPathExtension(exportedFormat.suffix)
.appendingPathComponent(withName)
.appendingPathExtension(exportedFormat.suffix)
let string = self
try? FileManager.default.removeItem(at: url)
try? string.write(to: url, atomically: true, encoding: .utf8)
// Add BOM for Excel to properly recognize UTF-8
if exportedFormat == .championship || exportedFormat == .csv {
let bom = Data([0xEF, 0xBB, 0xBF])
let stringData = string.data(using: .utf8)!
let dataWithBOM = bom + stringData
try? dataWithBOM.write(to: url, options: .atomic)
} else {
// For other formats, write normally with UTF-8
try? string.write(to: url, atomically: true, encoding: .utf8)
}
return url
}
}

@ -473,6 +473,8 @@ class FileImportManager {
let licenceId : String? = data[safe: 7]?.prefixTrimmed(50)
let club : String? = data[safe: 8]?.prefixTrimmed(200)
let status : String? = data[safe: 9]
let verified : String? = data[safe: 10]
let isVerified = verified == "ok"
if chunkMode == .byColumn {
let predicate = NSPredicate(format: "license == %@", licenceId!.strippedLicense!)
fetchRequest.predicate = predicate
@ -483,11 +485,17 @@ class FileImportManager {
player.sourceName = lastName
player.isNVEQ = status == "NVEQ"
player.clubCode = found.clubCode
if isVerified {
player.source = .frenchFederationVerified
}
return player
} else {
let player = PlayerRegistration(firstName: firstName, lastName: lastName, licenceId: licenceId, rank: rank, sex: sex, clubName: club, phoneNumber: phoneNumber, email: email)
player.sourceName = lastName
player.isNVEQ = status == "NVEQ"
if isVerified {
player.source = .frenchFederationVerified
}
if rank == nil {
player.setComputedRank(in: tournament)
} else {
@ -574,12 +582,14 @@ extension Array where Element == String {
let sex = teamType.lowercased().contains("dames") ? "f" : "m"
// Process up to 10 players
let count = 6
for i in 0..<10 {
let lastNameIndex = 12 + (i * 5)
let firstNameIndex = 13 + (i * 5)
let licenseIndex = 14 + (i * 5)
let rankingIndex = 15 + (i * 5)
let statusIndex = 16 + (i * 5)
let lastNameIndex = 12 + (i * count)
let firstNameIndex = 13 + (i * count)
let validationStatusIndex = 14 + (i * count)
let licenseIndex = 15 + (i * count)
let rankingIndex = 16 + (i * count)
let statusIndex = 17 + (i * count)
guard lastNameIndex < components.count,
!components[lastNameIndex].isEmpty else {
@ -609,7 +619,8 @@ extension Array where Element == String {
ranking: nil,
status: status,
email: nil,
mobileNumber: nil
mobileNumber: nil,
validationStatus: components[validationStatusIndex]
)
players.append(player)
}
@ -668,6 +679,7 @@ struct PlayerChampionship {
let status: Status
let email: String?
let mobileNumber: String?
let validationStatus: String?
static func captain(_ components: [String]) -> PlayerChampionship {
let fullName = components[6].components(separatedBy: " ")
@ -681,7 +693,8 @@ struct PlayerChampionship {
ranking: 0,
status: .captain,
email: components[8],
mobileNumber: components[7]
mobileNumber: components[7],
validationStatus: nil
)
}
@ -697,7 +710,8 @@ struct PlayerChampionship {
ranking: 0,
status: .coach,
email: components[11],
mobileNumber: components[10]
mobileNumber: components[10],
validationStatus: nil
)
}
@ -712,7 +726,8 @@ struct PlayerChampionship {
"",
licenseNumber.replaceCharactersFromSet(characterSet: .whitespacesAndNewlines),
"",
status.rawValue
status.rawValue,
validationStatus ?? ""
]
return components.joined(separator: separator)

@ -269,7 +269,7 @@ func fetchPlayerData(for licenseID: String) async throws -> [Player]? {
request.setValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
// Add cookies if needed (example cookie header value shown, replace with valid cookies)
request.setValue("JSESSIONID=0A23429250749BFDD2A869CC1AF504E6; AWSALB=aUE6ypZc8yvsIjM20SSKgQgvtnVb6NJQrngf7HjwQfL7T9xbgAsOsywQZ5gIJ68SaOrUMk3Wa4wpGDbTBi8s2uICY+P7pUNijn83S1VG19Ut9448W4xvlczp1nh1; AWSALBCORS=aUE6ypZc8yvsIjM20SSKgQgvtnVb6NJQrngf7HjwQfL7T9xbgAsOsywQZ5gIJ68SaOrUMk3Wa4wpGDbTBi8s2uICY+P7pUNijn83S1VG19Ut9448W4xvlczp1nh1; datadome=bkjv7vJ9V9vQ7MP9KJcsYXOSlEfkwTFS5B4scCfp1ugdXe2jsnXTTUeiwz7TFdjd04_WqZMH2U2zqV4mmTklpMBYF46~iqCugDRCrPgLvqSc1~KLwJw4h3dm5m6gH9HK; xtan=-; xtant=1; tc_cj_v2=%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMMORPMMMQNNZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMMQMPMPMKOPZZZ%5D; tc_cj_v2_cmp=; tc_cj_v2_med=; tCdebugLib=1; _pcid=%7B%22browserId%22%3A%22m42mi4kbtfuyj367%22%2C%22_t%22%3A%22mjr1fm32%7Cm42mi4r2%22%7D; _pctx=%7Bu%7DN4IgrgzgpgThIC4B2YA2qA05owMoBcBDfSREQpAeyRCwgEt8oBJAE0RXSwH18yBbAFYwAjADN%2BAZgCsAH34AWAEz96CmNJABfIA; _pprv=eyJjb25zZW50Ijp7IjAiOnsibW9kZSI6ImVzc2VudGlhbCJ9LCI3Ijp7Im1vZGUiOiJvcHQtaW4ifX0sInB1cnBvc2VzIjpudWxsLCJfdCI6Im1qcjFmbHdofG00Mm1pNGtoIn0%3D; TCID=124122155494907703483; TCPID=124115115191501043230; xtvrn=$548419$; visid_incap_2712217=PSfJngzoSuiowsuXXhvOu5K+7mUAAAAAQUIPAAAAAAAleL9ldvN/FC1VykkU9ret; SessionStatId=10.91.140.42.1662124965429001", forHTTPHeaderField: "Cookie")
request.setValue("JSESSIONID=0DB857387EF49025B1A0559774FFFEBA; datadome=yp6ACsLMYiE4WEK2rf31mwP2xtk5EPcVjEKEhjO0qslv89_AOhlUVrMbokM~Rsp3Nfr_KxchUoLdRJvWScouGa8VzSixfwTLigI29EvJ8LbSj1OGmYgaO4kSW0WZU5YD; AWSALB=HQBL6o2O7dDDLA/e/Qt7dWBxG0X7qrzHFNZ6kFgjO18BsOFcLd4m77EbVc8u7jmKH3qdhV3TmsARJpWNWNt3ZzL1kg+tDeKoyFkWKFbqsmFykZEuoQXxI5y+Gswp; AWSALBCORS=HQBL6o2O7dDDLA/e/Qt7dWBxG0X7qrzHFNZ6kFgjO18BsOFcLd4m77EbVc8u7jmKH3qdhV3TmsARJpWNWNt3ZzL1kg+tDeKoyFkWKFbqsmFykZEuoQXxI5y+Gswp; xtan=-; xtant=1; tc_cj_v2=%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMMORPMMMQNNZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMMQMPMPMKOPZZZ%5D; tc_cj_v2_cmp=; tc_cj_v2_med=; tCdebugLib=1; _pcid=%7B%22browserId%22%3A%22m42mi4kbtfuyj367%22%2C%22_t%22%3A%22mjr1fm32%7Cm42mi4r2%22%7D; _pctx=%7Bu%7DN4IgrgzgpgThIC4B2YA2qA05owMoBcBDfSREQpAeyRCwgEt8oBJAE0RXSwH18yBbAFYwAjADN%2BAZgCsAH34AWAEz96CmNJABfIA; _pprv=eyJjb25zZW50Ijp7IjAiOnsibW9kZSI6ImVzc2VudGlhbCJ9LCI3Ijp7Im1vZGUiOiJvcHQtaW4ifX0sInB1cnBvc2VzIjpudWxsLCJfdCI6Im1qcjFmbHdofG00Mm1pNGtoIn0%3D; TCID=124122155494907703483; TCPID=124115115191501043230; xtvrn=$548419$; visid_incap_2712217=PSfJngzoSuiowsuXXhvOu5K+7mUAAAAAQUIPAAAAAAAleL9ldvN/FC1VykkU9ret; SessionStatId=10.91.140.42.1662124965429001", forHTTPHeaderField: "Cookie")
let (data, _) = try await URLSession.shared.data(for: request)
let decoder = JSONDecoder()

Loading…
Cancel
Save