From 7a71beeea81d41b304ea7e7a0c5fe2d4eadf6898 Mon Sep 17 00:00:00 2001 From: Raz Date: Fri, 13 Dec 2024 13:58:05 +0100 Subject: [PATCH] fix issues --- PadelClub/Data/PlayerRegistration.swift | 10 ++++-- PadelClub/Data/TeamRegistration.swift | 35 +++++++++++++------ PadelClub/Data/Tournament.swift | 10 ++++++ PadelClub/Extensions/String+Extensions.swift | 18 ++++++++-- PadelClub/Utils/FileImportManager.swift | 33 ++++++++++++----- .../Navigation/Umpire/PadelClubView.swift | 2 +- 6 files changed, 82 insertions(+), 26 deletions(-) diff --git a/PadelClub/Data/PlayerRegistration.swift b/PadelClub/Data/PlayerRegistration.swift index a6968ab..adcadf8 100644 --- a/PadelClub/Data/PlayerRegistration.swift +++ b/PadelClub/Data/PlayerRegistration.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 { diff --git a/PadelClub/Data/TeamRegistration.swift b/PadelClub/Data/TeamRegistration.swift index 0f478e0..070ccf0 100644 --- a/PadelClub/Data/TeamRegistration.swift +++ b/PadelClub/Data/TeamRegistration.swift @@ -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 + } } } diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index a3abbe8..cda83cc 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -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", diff --git a/PadelClub/Extensions/String+Extensions.swift b/PadelClub/Extensions/String+Extensions.swift index 4be124b..00c03b7 100644 --- a/PadelClub/Extensions/String+Extensions.swift +++ b/PadelClub/Extensions/String+Extensions.swift @@ -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 } } diff --git a/PadelClub/Utils/FileImportManager.swift b/PadelClub/Utils/FileImportManager.swift index 49c007f..ee971ab 100644 --- a/PadelClub/Utils/FileImportManager.swift +++ b/PadelClub/Utils/FileImportManager.swift @@ -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) diff --git a/PadelClub/Views/Navigation/Umpire/PadelClubView.swift b/PadelClub/Views/Navigation/Umpire/PadelClubView.swift index fd40480..cb84323 100644 --- a/PadelClub/Views/Navigation/Umpire/PadelClubView.swift +++ b/PadelClub/Views/Navigation/Umpire/PadelClubView.swift @@ -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()