You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Data/Federal/FederalPlayer.swift

225 lines
8.2 KiB

//
// FederalPlayer.swift
// PadelClub
//
// Created by Razmig Sarkissian on 01/03/2024.
//
import Foundation
class FederalPlayer: Decodable {
var rank: Int
var lastName: String
var firstName: String
var country: String
var license: String
var points: Double?
var assimilation: String
var tournamentCount: Int?
var ligue: String
var clubCode: String
var club: String
var isMale: Bool
var birthYear: Int?
var progression: Int
var bestRank: Int?
// MARK: - Nationnalite
struct Nationnalite: Hashable, Codable {
let code, codeFov: String
}
required init(from decoder: Decoder) throws {
enum CodingKeys: String, CodingKey {
case nom
case prenom
case licence
case meilleurClassement
case nationnalite
case anneeNaissance
case codeClub
case nomClub
case nomLigue
case rang
case progression
case points
case nombreDeTournois
case assimile
}
let container = try decoder.container(keyedBy: CodingKeys.self)
isMale = (decoder.userInfo[.maleData] as? Bool) == true
let _lastName = try container.decode(String.self, forKey: .nom)
let _firstName = try container.decode(String.self, forKey: .prenom)
lastName = _lastName
firstName = _firstName
if let lic = try? container.decodeIfPresent(Int.self, forKey: .licence) {
license = String(lic)
} else {
license = ""
}
let nationnalite = try container.decode(Nationnalite.self, forKey: .nationnalite)
country = nationnalite.code
bestRank = try container.decodeIfPresent(Int.self, forKey: .meilleurClassement)
birthYear = try container.decodeIfPresent(Int.self, forKey: .anneeNaissance)
clubCode = try container.decode(String.self, forKey: .codeClub)
club = try container.decode(String.self, forKey: .nomClub)
ligue = try container.decode(String.self, forKey: .nomLigue)
rank = try container.decode(Int.self, forKey: .rang)
progression = (try? container.decodeIfPresent(Int.self, forKey: .progression)) ?? 0
let pointsAsInt = try? container.decodeIfPresent(Int.self, forKey: .points)
if let pointsAsInt {
points = Double(pointsAsInt)
} else {
points = nil
}
tournamentCount = try? container.decodeIfPresent(Int.self, forKey: .nombreDeTournois)
let assimile = try container.decode(Bool.self, forKey: .assimile)
assimilation = assimile ? "Oui" : "Non"
}
func exportToCSV() -> String {
let pointsString = points != nil ? String(Int(points!)) : ""
let tournamentCountString = tournamentCount != nil ? String(tournamentCount!) : ""
let strippedLicense = license.strippedLicense ?? ""
let line = ";\(rank);\(lastName);\(firstName);\(country);\(strippedLicense);\(pointsString);\(assimilation);\(tournamentCountString);\(ligue);\(formatNumbers(clubCode));\(club);\(progression.formattedAsRawString());\(bestRank?.formattedAsRawString() ?? "");\(birthYear?.formattedAsRawString() ?? "");"
return line
}
func formatNumbers(_ input: String) -> String {
// Insert spaces at appropriate positions
let formattedString = insertSeparator(input, separator: " ", every: [2, 4])
return formattedString
}
func insertSeparator(_ input: String, separator: String, every positions: [Int]) -> String {
var modifiedString = input
// Adjust for the index shift caused by inserting characters
var offset = 0
// Insert separator at specified positions
for position in positions {
let index = modifiedString.index(modifiedString.startIndex, offsetBy: position + offset)
modifiedString.insert(contentsOf: separator, at: index)
// Increase offset to adjust for the inserted character
offset += separator.count
}
return modifiedString
}
/*
;RANG;NOM;PRENOM;Nationalité;N° Licence;POINTS;Assimilation;NB. DE TOURNOIS JOUES;LIGUE;CODE CLUB;CLUB;
*/
var isManPlayer: Bool {
isMale
}
var isAssimilated: Bool {
assimilation == "Oui"
}
var currentRank: Int {
rank
}
init?(_ data: String, isMale: Bool = false) {
self.isMale = isMale
var result = data.components(separatedBy: .newlines).map { $0.trimmed }
result = result.reversed().drop(while: {
$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}).reversed() as [String]
result = Array(result.drop(while: {
$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}))
//print(result)
if result.count < 11 {
return nil
}
if let _rank = Int(result[0]) {
rank = _rank
} else {
return nil
}
lastName = result[1]
firstName = result[2]
country = result[3]
license = result[4]
// let matches = result[5].matches(of: try! Regex("[0-9]{1,5}\\.00"))
//
// if matches.count == 1 {
// let pts = result[5][matches.first!.range]
// points = Double(pts.replacingOccurrences(of: ",", with: "."))
// if pts.count < result[5].count {
//
// }
// }
//
points = Double(result[5].replacingOccurrences(of: ",", with: "."))
assimilation = result[6]
tournamentCount = Int(result[7])
ligue = result[8]
clubCode = result[9]
club = result[10]
progression = result[safe: 11]?.toInt() ?? 0
bestRank = result[safe: 12]?.toInt()
birthYear = result[safe: 13]?.toInt()
}
static func anonymousCount(mostRecentDateAvailable: Date?) async -> Int? {
let context = PersistenceController.shared.localContainer.newBackgroundContext()
let importedPlayerFetchRequest = ImportedPlayer.fetchRequest()
var predicate = NSPredicate(format: "lastName == %@ && firstName == %@", "", "")
if let mostRecentDateAvailable {
predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, NSPredicate(format: "importDate == %@", mostRecentDateAvailable as CVarArg)])
}
importedPlayerFetchRequest.predicate = predicate
let count = try? context.count(for: importedPlayerFetchRequest)
return count
}
static func lastRank(mostRecentDateAvailable: Date?, man: Bool) async -> (Int, Int?)? {
let context = PersistenceController.shared.localContainer.newBackgroundContext()
let lastPlayerFetch = ImportedPlayer.fetchRequest()
lastPlayerFetch.sortDescriptors = [NSSortDescriptor(keyPath: \ImportedPlayer.rank, ascending: false)]
var predicate = NSPredicate(format: "male == \(man)")
if let mostRecentDateAvailable {
predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, NSPredicate(format: "importDate == %@", mostRecentDateAvailable as CVarArg)])
}
lastPlayerFetch.predicate = predicate
let count = try? context.count(for: lastPlayerFetch)
print("count", count)
do {
if let lr = try context.fetch(lastPlayerFetch).first?.rank {
let fetch = ImportedPlayer.fetchRequest()
var rankPredicate = NSPredicate(format: "rank == %i", lr)
if let mostRecentDateAvailable {
rankPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [rankPredicate, NSPredicate(format: "importDate == %@", mostRecentDateAvailable as CVarArg)])
}
fetch.predicate = rankPredicate
let lastPlayersCount = try context.count(for: fetch)
return (Int(lr) + Int(lastPlayersCount) - 1, count)
}
} catch {
print("ImportedPlayer.fetchRequest", error)
}
return nil
}
}
extension CodingUserInfoKey {
static let maleData = Self(rawValue: "maleData")!
}