paca_championship
Raz 10 months ago
parent a206c351c3
commit 472a456465
  1. 30
      PadelClub/Data/PlayerRegistration.swift
  2. 2
      PadelClub/Data/TeamRegistration.swift
  3. 21
      PadelClub/Data/Tournament.swift
  4. 11
      PadelClub/Utils/FileImportManager.swift
  5. 4
      PadelClub/Utils/SwiftParser.swift
  6. 2
      PadelClub/Views/Navigation/Umpire/PadelClubView.swift
  7. 3
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift

@ -44,6 +44,7 @@ final class PlayerRegistration: ModelObject, Storable {
var clubCode: String?
var sourceName: String?
var isNveq: Bool = false
var isEQConfirmed: Bool?
func localizedSourceLabel() -> String {
switch source {
@ -196,9 +197,16 @@ final class PlayerRegistration: ModelObject, Storable {
var duplicatePlayers: Int?
func championshipAlerts(tournament: Tournament, allPlayers: [(String, String)]) -> [ChampionshipAlert] {
func championshipAlerts(tournament: Tournament, allPlayers: [(String, String)], forRegional: Bool) -> [ChampionshipAlert] {
var alerts = [ChampionshipAlert]()
if forRegional {
if isNveq == false && (isEQConfirmed == false || isEQConfirmed == nil) {
alerts.append(.notEQ(isEQConfirmed, self))
}
}
if duplicatePlayers == nil {
let teamClubCode = self.team()?.clubCode
let strippedLicense = self.licenceId?.strippedLicense
@ -347,7 +355,25 @@ final class PlayerRegistration: ModelObject, Storable {
return "non classé" + (isMalePlayer() ? "" : "e")
}
}
func verifyEQ(from sources: [CSVParser]) async throws {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func updateRank()", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
if let dataFound = try await history(from: sources) {
print("dataFound.clubCode == clubCode", dataFound.clubCode, clubCode)
isEQConfirmed = dataFound.clubCode == clubCode
} else {
print("not found")
isEQConfirmed = nil
}
}
func updateRank(from sources: [CSVParser], lastRank: Int) async throws {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()

@ -460,7 +460,7 @@ final class TeamRegistration: ModelObject, Storable {
}
players.forEach { pr in
alerts.append(contentsOf: pr.championshipAlerts(tournament: tournament, allPlayers: allPlayers))
alerts.append(contentsOf: pr.championshipAlerts(tournament: tournament, allPlayers: allPlayers, forRegional: teamIndex <= 16))
}
return alerts

@ -1678,6 +1678,27 @@ defer {
try await player.updateRank(from: sources, lastRank: (player.sex == .female ? lastRankWoman : lastRankMan) ?? 0)
}
}
func verifyEQ() async throws {
#if DEBUG_TIME //DEBUGING TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func updateRank()", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
guard let newDate = URL.importDateFormatter.date(from: "08-2024") else { return }
let dataURLs = SourceFileManager.shared.allFiles.filter { $0.dateFromPath == newDate }
let sources = dataURLs.map { CSVParser(url: $0) }
let teams = selectedSortedTeams().prefix(16)
let players = teams.flatMap({ $0.unsortedPlayers() })
try await players.concurrentForEach { player in
try await player.verifyEQ(from: sources)
}
}
func missingUnrankedValue() -> Bool {
return maleUnrankedValue == nil || femaleUnrankedValue == nil

@ -778,9 +778,12 @@ enum ChampionshipAlert: LocalizedError {
case playerAgeInvalid(PlayerRegistration)
case playerSexInvalid(PlayerRegistration)
case duplicate(Int, PlayerRegistration)
case notEQ(Bool?, PlayerRegistration)
var errorDescription: String? {
switch self {
case .notEQ(_, let playerRegistration):
return playerRegistration.errorDescription(championshipAlert: self)
case .duplicate(_, let playerRegistration):
return playerRegistration.errorDescription(championshipAlert: self)
case .clubCodeInvalid(let teamRegistration):
@ -813,6 +816,12 @@ extension PlayerRegistration {
func errorDescription(championshipAlert: ChampionshipAlert) -> String? {
var message = self.playerLabel() + " - " + self.formattedLicense() + " -> "
switch championshipAlert {
case .notEQ(let bool, _):
if bool == nil {
message += "EQ INVERIFIABLE"
} else {
message += "EQ INVALIDE"
}
case .duplicate(let count, _):
message += "DOUBLON : " + count.formatted()
case .clubCodeInvalid, .tooManyNVEQ, .tooManyPlayers:

@ -65,6 +65,10 @@ struct Line: Identifiable {
var assimilation: String? {
data[7]
}
var clubCode: String? {
data[10]?.replaceCharactersFromSet(characterSet: .whitespaces)
}
}
struct CSVParser: AsyncSequence, AsyncIteratorProtocol {

@ -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=C27A8C305B9B1A3E8DD70300AFB8980E; AWSALB=qZ18nw7AsrBeo+X8yPL5RPFGerM9nePHqhVS3EasXJ3vRSskWtrVlkSQS7rhugIkndpGm918I4UqvfxpaDJxjgsVwXY6AoC40AfUXdFosITMK9hLbxbLlqm/XK3/; AWSALBCORS=qZ18nw7AsrBeo+X8yPL5RPFGerM9nePHqhVS3EasXJ3vRSskWtrVlkSQS7rhugIkndpGm918I4UqvfxpaDJxjgsVwXY6AoC40AfUXdFosITMK9hLbxbLlqm/XK3/; datadome=phzBnXmnx632ekfRiFl~WQEPoMTPKvFn~OfNIMzjCyv9vbaigh9182wiJhvkRJvddV8EvlHyszjEovY0zYcQ2k45QCdLMPuKlBIVOTh~OWk1HF8EIszhio6USnidWq5Y; tc_cj_v2=%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMMORPMMMQNNZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMMQMPMPMKOPZZZ%5D777%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMPLNJNKJQQJZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMPLNJNLQOJKZZZ%5D; tc_cj_v2_cmp=; tc_cj_v2_med=; SSESS7ba44afc36c80c3faa2b8fa87e7742c5=EFTV9aCrNCaJM7Soo-1OemOQ0qdJXpp7cqiYrMSoQRQ; incap_ses_188_2712217=bHGnCqoz+kuioZ6sNumbAhntfGcAAAAAyRoEUqalcEb2ssM0ElLpsQ==; TCSESSION=1251114295811051390969; incap_ses_2222_2712217=TZW0OzHRREDHgyiHhyHWHtPae2cAAAAAZtkxEWEK6Umt8kLgVqiHxg==; nlbi_2712217=xjnrKu85cRfbMwOCb9lUTgAAAADQ43pUbl/hRFX1Q8fYrJlG; _pcid=%7B%22browserId%22%3A%22m42mi4kbtfuyj367%22%2C%22_t%22%3A%22mjr1fm32%7Cm42mi4r2%22%7D; _pctx=%7Bu%7DN4IgrgzgpgThIC4B2YA2qA05owMoBcBDfSREQpAeyRCwgEt8oBJAE0RXSwH18yBbAFYwAjADN%2BAZgCsAH34AWAEz96CmNJABfIA; _pprv=eyJjb25zZW50Ijp7IjAiOnsibW9kZSI6ImVzc2VudGlhbCJ9LCI3Ijp7Im1vZGUiOiJvcHQtaW4ifX0sInB1cnBvc2VzIjpudWxsLCJfdCI6Im1qcjFmbHdofG00Mm1pNGtoIn0%3D; xtan=-; xtant=1; TCID=124122155494907703483; TCPID=124115115191501043230; xtvrn=$548419$; visid_incap_2712217=PSfJngzoSuiowsuXXhvOu5K+7mUAAAAAQUIPAAAAAAAleL9ldvN/FC1VykkU9ret; SessionStatId=10.91.140.42.1662124965429001", forHTTPHeaderField: "Cookie")
request.setValue("JSESSIONID=C4B647EB27A036891E29D27FD83CE29B; AWSALB=1btRrmQjbf1VjZH74hBI3+OcfTO/HfJWbf+wm0kpBEVz9jUgvXb+UO4FkcIimuferhUjEfWmENKUS1SYmHCkndtiaR5x89W9uHYi/JTO3zn1ZO2JRCjvEgY7BNJm; AWSALBCORS=1btRrmQjbf1VjZH74hBI3+OcfTO/HfJWbf+wm0kpBEVz9jUgvXb+UO4FkcIimuferhUjEfWmENKUS1SYmHCkndtiaR5x89W9uHYi/JTO3zn1ZO2JRCjvEgY7BNJm; datadome=thpudGMDaIXBt6W8GjURPii9mF0ovaPnNozziskvWhA0uZ7bt~ZX3CICjEZEV5J4GXL151J19_NsLGL5wNT2BZ9NJUbJciEo9YJdFp_OKwlM13_dYqIrJ5rlKW65SPOg; _pcid=%7B%22browserId%22%3A%22m42mi4kbtfuyj367%22%2C%22_t%22%3A%22mjr1fm32%7Cm42mi4r2%22%7D; _pctx=%7Bu%7DN4IgrgzgpgThIC4B2YA2qA05owMoBcBDfSREQpAeyRCwgEt8oBJAE0RXSwH18yBbAFYwAjADN%2BAZgCsAH34AWAEz96CmNJABfIA; _pprv=eyJjb25zZW50Ijp7IjAiOnsibW9kZSI6ImVzc2VudGlhbCJ9LCI3Ijp7Im1vZGUiOiJvcHQtaW4ifX0sInB1cnBvc2VzIjpudWxsLCJfdCI6Im1qcjFmbHdofG00Mm1pNGtoIn0%3D; tc_cj_v2=%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMMORPMMMQNNZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMMQMPMPMKOPZZZ%5D777%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMPLNJNKJQQJZZZ%5D777m_iZZZ%22**%22%27%20ZZZKQMPLNJNLQOJKZZZ%5D777%5Ecl_%5Dny%5B%5D%5D_mmZZZZZZKQMPLONOQNSNSZZZ%5D; tc_cj_v2_cmp=; tc_cj_v2_med=; SSESS7ba44afc36c80c3faa2b8fa87e7742c5=EFTV9aCrNCaJM7Soo-1OemOQ0qdJXpp7cqiYrMSoQRQ; xtan=-; xtant=1; 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()

@ -948,6 +948,9 @@ struct InscriptionManagerView: View {
_setHash()
}
RowButtonView("Verify EQ") {
await try? tournament.verifyEQ()
}
Button("Generate file") {
self.shareFile = tournament.pasteDataForImporting(.championship).createFile(self.tournament.tournamentTitle()+"-inscriptions", .championship)
}

Loading…
Cancel
Save