diff --git a/PadelClub/Data/Gen/BaseTournament.swift b/PadelClub/Data/Gen/BaseTournament.swift index 2fe870f..c75bc28 100644 --- a/PadelClub/Data/Gen/BaseTournament.swift +++ b/PadelClub/Data/Gen/BaseTournament.swift @@ -195,6 +195,8 @@ class BaseTournament: SyncedModelObject, SyncedStorable { } enum CodingKeys: String, CodingKey { + case isCanceled = "isCanceled" + case payment = "payment" case _id = "id" case _event = "event" case _name = "name" @@ -221,10 +223,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable { case _qualifiedPerGroupStage = "qualifiedPerGroupStage" case _teamsPerGroupStage = "teamsPerGroupStage" case _entryFee = "entryFee" - case _payment = "payment" + case _payment = "globalId" case _additionalEstimationDuration = "additionalEstimationDuration" case _isDeleted = "isDeleted" - case _isCanceled = "isCanceled" + case _isCanceled = "localId" case _publishTeams = "publishTeams" case _publishSummons = "publishSummons" case _publishGroupStages = "publishGroupStages" @@ -257,7 +259,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable { } private static func _decodePayment(container: KeyedDecodingContainer) throws -> TournamentPayment? { - let data = try container.decodeIfPresent(Data.self, forKey: ._payment) + var data = try container.decodeIfPresent(Data.self, forKey: ._payment) + if data == nil { + data = try container.decodeIfPresent(Data.self, forKey: .payment) + } if let data { do { @@ -290,7 +295,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable { } } private static func _decodeIscanceled(container: KeyedDecodingContainer) throws -> Bool { - let data = try container.decodeIfPresent(Data.self, forKey: ._isCanceled) + var data = try container.decodeIfPresent(Data.self, forKey: ._isCanceled) + if data == nil { + data = try container.decodeIfPresent(Data.self, forKey: .isCanceled) + } if let data { do { let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue) diff --git a/PadelClub/Data/Gen/Tournament.json b/PadelClub/Data/Gen/Tournament.json index 0b474c9..1262af0 100644 --- a/PadelClub/Data/Gen/Tournament.json +++ b/PadelClub/Data/Gen/Tournament.json @@ -137,7 +137,8 @@ "type": "TournamentPayment", "optional": true, "defaultValue": "nil", - "encryption": "tournament_payment" + "encryption": "tournament_payment", + "codingKey": "globalId" }, { "name": "additionalEstimationDuration", @@ -153,7 +154,8 @@ "name": "isCanceled", "type": "Bool", "defaultValue": "false", - "encryption": "tournament_iscanceled" + "encryption": "tournament_iscanceled", + "codingKey": "localId" }, { "name": "publishTeams", diff --git a/PadelClub/Data/Gen/generator.py b/PadelClub/Data/Gen/generator.py index a8ece00..b8ec1dc 100644 --- a/PadelClub/Data/Gen/generator.py +++ b/PadelClub/Data/Gen/generator.py @@ -61,7 +61,7 @@ class SwiftModelGenerator: lines.append("") # CodingKeys - lines.extend(self._generate_coding_keys(properties, is_observable, is_sync)) + lines.extend(self._generate_coding_keys(model_name, properties, is_observable)) lines.append("") # Encryption methods @@ -166,13 +166,22 @@ class SwiftModelGenerator: lines.extend([" }", ""]) # Close the method and add a blank line return lines - def _generate_coding_keys(self, properties: List[Dict[str, Any]], is_observable: bool, is_sync: bool = False) -> List[str]: + def _generate_coding_keys(self, model_name: str, properties: List[Dict[str, Any]], is_observable: bool) -> List[str]: lines = [" enum CodingKeys: String, CodingKey {"] + + if model_name == 'Tournament': + lines.append(" case isCanceled = \"isCanceled\"") + lines.append(" case payment = \"payment\"") + for prop in properties: name = prop['name'] - # Add underscore prefix to case name if observable, but keep the string value without underscore + # Add underscore prefix to case name if observable case_name = f"_{name}" if is_observable else name - lines.append(f" case {case_name} = \"{name}\"") + + # Use custom codingKey if provided, otherwise use the property name + coding_key_value = prop.get("codingKey", name) + + lines.append(f" case {case_name} = \"{coding_key_value}\"") lines.append(" }") return lines @@ -186,7 +195,10 @@ class SwiftModelGenerator: if enc_type == "tournament_payment": lines.extend([ f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer) throws -> TournamentPayment? {{", - f" let data = try container.decodeIfPresent(Data.self, forKey: ._{name})", + f" var data = try container.decodeIfPresent(Data.self, forKey: ._{name})", + " if data == nil {", + " data = try container.decodeIfPresent(Data.self, forKey: .payment)", + " }", " ", " if let data {", " do {", @@ -222,7 +234,10 @@ class SwiftModelGenerator: elif enc_type == "tournament_iscanceled": lines.extend([ f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer) throws -> Bool {{", - f" let data = try container.decodeIfPresent(Data.self, forKey: ._{name})", + f" var data = try container.decodeIfPresent(Data.self, forKey: ._{name})", + " if data == nil {", + " data = try container.decodeIfPresent(Data.self, forKey: .isCanceled)", + " }", " if let data {", " do {", " let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue)", diff --git a/PadelClub/Utils/Patcher.swift b/PadelClub/Utils/Patcher.swift index 94e4447..48ca002 100644 --- a/PadelClub/Utils/Patcher.swift +++ b/PadelClub/Utils/Patcher.swift @@ -53,6 +53,7 @@ enum PatchError: Error { enum Patch: String, CaseIterable { case cleanLogs case syncUpgrade + case updateTournaments var id: String { return "padelclub.app.patch.\(self.rawValue)" @@ -83,6 +84,7 @@ class AutomaticPatcher { switch patch { case .cleanLogs: self._cleanLogs() case .syncUpgrade: self._syncUpgrade() + case .updateTournaments: self._updateTournaments() } } @@ -128,4 +130,7 @@ class AutomaticPatcher { } } + fileprivate static func _updateTournaments() { + DataStore.shared.tournaments.addOrUpdate(contentOfs: DataStore.shared.tournaments) + } } diff --git a/PadelClubTests/ServerDataTests.swift b/PadelClubTests/ServerDataTests.swift index 502bc64..dcc0837 100644 --- a/PadelClubTests/ServerDataTests.swift +++ b/PadelClubTests/ServerDataTests.swift @@ -115,8 +115,14 @@ final class ServerDataTests: XCTestCase { let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true, hideTeamsWeight: true, publishTournament: true, hidePointsEarned: true, publishRankings: true, loserBracketMode: .manual, initialSeedRound: 8, initialSeedCount: 4, accountIsRequired: false, licenseIsRequired: false, minimumPlayerPerTeam: 3, maximumPlayerPerTeam: 5, information: "Super", umpireCustomMail: "razmig@padelclub.app", umpireCustomContact: "Raz", umpireCustomPhone: "+33681598193", hideUmpireMail: true, hideUmpirePhone: true, disableRankingFederalRuling: true, teamCountLimit: false) + tournament.isCanceled = true + tournament.payment = .subscriptionUnit + if let t = try await StoreCenter.main.service().post(tournament) { + assert(t.isCanceled == tournament.isCanceled) + assert(t.payment == tournament.payment) + assert(t.lastUpdate.formatted() == tournament.lastUpdate.formatted()) assert(t.event == tournament.event) assert(t.name == tournament.name)