From 1b0694a7089967a34441c6849e200d8011471a90 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 27 Aug 2024 10:13:55 +0200 Subject: [PATCH] First draft for new subscription --- PadelClub/Data/Tournament.swift | 20 +++++++++++++++++-- PadelClub/Views/Calling/CallView.swift | 16 +++++++++------ .../Calling/Components/MenuWarningView.swift | 16 +++++++++------ PadelClub/Views/Calling/SendToAllView.swift | 16 +++++++++------ PadelClub/Views/Match/MatchDetailView.swift | 16 +++++++++------ .../Views/Tournament/Subscription/Guard.swift | 4 ++-- .../Tournament/Subscription/StoreItem.swift | 4 +++- .../Views/Tournament/TournamentView.swift | 10 ++++++---- 8 files changed, 69 insertions(+), 33 deletions(-) diff --git a/PadelClub/Data/Tournament.swift b/PadelClub/Data/Tournament.swift index 5ab4fd8..0445c22 100644 --- a/PadelClub/Data/Tournament.swift +++ b/PadelClub/Data/Tournament.swift @@ -391,7 +391,7 @@ final class Tournament : ModelObject, Storable { // MARK: - /// Warning: if the enum has more than 10 cases, the payment algo is broken - enum TournamentPayment: Int, CaseIterable { + enum TournamentPayment: Int, Codable, CaseIterable { case free, unit, subscriptionUnit, unlimited var isSubscription: Bool { @@ -2022,16 +2022,32 @@ defer { case cantPayTournament } - func payIfNecessary() throws { + private let userCanPayCall: ServiceCall = ServiceCall(path: "can-pay-tournament/", method: .post, requiresToken: true) + struct ClubPayload: Codable { + var club: String + } + struct PaymentReturn: Codable { + var payment: TournamentPayment? + } + + func payIfNecessary() async throws { if self.payment != nil { return } if let payment = Guard.main.paymentForNewTournament() { self.payment = payment try DataStore.shared.tournaments.addOrUpdate(instance: self) return } + + let services = try StoreCenter.main.service() + if let clubId = self.club()?.id { + let pr: PaymentReturn = try await services.runCall(userCanPayCall, payload: ClubPayload(club: clubId)) + self.payment = pr.payment + } + throw PaymentError.cantPayTournament } + } fileprivate extension Bool { diff --git a/PadelClub/Views/Calling/CallView.swift b/PadelClub/Views/Calling/CallView.swift index 0423958..9b3c273 100644 --- a/PadelClub/Views/Calling/CallView.swift +++ b/PadelClub/Views/Calling/CallView.swift @@ -234,12 +234,16 @@ struct CallView: View { } } - fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { - do { - try self.tournament.payIfNecessary() - handler() - } catch { - self.showSubscriptionView = true + fileprivate func _payTournamentAndExecute(_ handler: @escaping () -> ()) { + Task { + do { + try await tournament.payIfNecessary() + handler() + } catch { + DispatchQueue.main.async { + self.showSubscriptionView = true + } + } } } diff --git a/PadelClub/Views/Calling/Components/MenuWarningView.swift b/PadelClub/Views/Calling/Components/MenuWarningView.swift index 71eacb7..b1cd4db 100644 --- a/PadelClub/Views/Calling/Components/MenuWarningView.swift +++ b/PadelClub/Views/Calling/Components/MenuWarningView.swift @@ -150,12 +150,16 @@ struct MenuWarningView: View { } } - fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { - do { - try tournament.payIfNecessary() - handler() - } catch { - self.showSubscriptionView = true + fileprivate func _payTournamentAndExecute(_ handler: @escaping () -> ()) { + Task { + do { + try await tournament.payIfNecessary() + handler() + } catch { + DispatchQueue.main.async { + self.showSubscriptionView = true + } + } } } diff --git a/PadelClub/Views/Calling/SendToAllView.swift b/PadelClub/Views/Calling/SendToAllView.swift index e54392e..d2b0405 100644 --- a/PadelClub/Views/Calling/SendToAllView.swift +++ b/PadelClub/Views/Calling/SendToAllView.swift @@ -244,12 +244,16 @@ struct SendToAllView: View { } } - fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { - do { - try tournament.payIfNecessary() - handler() - } catch { - self.showSubscriptionView = true + fileprivate func _payTournamentAndExecute(_ handler: @escaping () -> ()) { + Task { + do { + try await tournament.payIfNecessary() + handler() + } catch { + DispatchQueue.main.async { + self.showSubscriptionView = true + } + } } } diff --git a/PadelClub/Views/Match/MatchDetailView.swift b/PadelClub/Views/Match/MatchDetailView.swift index 0944147..6aa7638 100644 --- a/PadelClub/Views/Match/MatchDetailView.swift +++ b/PadelClub/Views/Match/MatchDetailView.swift @@ -498,14 +498,18 @@ struct MatchDetailView: View { } } - fileprivate func _payTournamentAndExecute(_ handler: () -> ()) { + fileprivate func _payTournamentAndExecute(_ handler: @escaping () -> ()) { guard let tournament = match.currentTournament() else { fatalError("missing tournament") } - do { - try tournament.payIfNecessary() - handler() - } catch { - self.showSubscriptionView = true + Task { + do { + try await tournament.payIfNecessary() + handler() + } catch { + DispatchQueue.main.async { + self.showSubscriptionView = true + } + } } } diff --git a/PadelClub/Views/Tournament/Subscription/Guard.swift b/PadelClub/Views/Tournament/Subscription/Guard.swift index a0e91b9..0442453 100644 --- a/PadelClub/Views/Tournament/Subscription/Guard.swift +++ b/PadelClub/Views/Tournament/Subscription/Guard.swift @@ -141,7 +141,7 @@ import LeStorage var currentPlan: StoreItem? { #if DEBUG - return .monthlyUnlimited + return nil #else if let currentBestPlan = self.currentBestPlan, let plan = StoreItem(rawValue: currentBestPlan.productID) { return plan @@ -195,7 +195,7 @@ import LeStorage func paymentForNewTournament() -> Tournament.TournamentPayment? { switch self.currentPlan { - case .monthlyUnlimited: + case .monthlyUnlimited, .monthlyUnlimited: return Tournament.TournamentPayment.unlimited case .fivePerMonth: if let purchaseDate = self.currentBestPlan?.originalPurchaseDate { diff --git a/PadelClub/Views/Tournament/Subscription/StoreItem.swift b/PadelClub/Views/Tournament/Subscription/StoreItem.swift index 79bab93..25336fb 100644 --- a/PadelClub/Views/Tournament/Subscription/StoreItem.swift +++ b/PadelClub/Views/Tournament/Subscription/StoreItem.swift @@ -8,6 +8,7 @@ import Foundation enum StoreItem: String, Identifiable, CaseIterable { + case monthlyClub = "app.padelclub.tournament.subscription.monthly.club" case monthlyUnlimited = "app.padelclub.tournament.subscription.unlimited" case fivePerMonth = "app.padelclub.tournament.subscription.five.per.month" case unit = "app.padelclub.tournament.unit" @@ -22,6 +23,7 @@ enum StoreItem: String, Identifiable, CaseIterable { var systemImage: String { switch self { + case .monthlyClub: return "trophy.circle.fill" case .monthlyUnlimited: return "infinity.circle.fill" case .fivePerMonth: return "star.circle.fill" case .unit: return "tennisball.circle.fill" @@ -30,7 +32,7 @@ enum StoreItem: String, Identifiable, CaseIterable { var isConsumable: Bool { switch self { - case .monthlyUnlimited, .fivePerMonth: return false + case .monthlyUnlimited, .fivePerMonth, .monthlyClub: return false case .unit: return true } } diff --git a/PadelClub/Views/Tournament/TournamentView.swift b/PadelClub/Views/Tournament/TournamentView.swift index fa14f46..e3c1185 100644 --- a/PadelClub/Views/Tournament/TournamentView.swift +++ b/PadelClub/Views/Tournament/TournamentView.swift @@ -156,10 +156,12 @@ struct TournamentView: View { #if DEBUG Button { - do { - try self.tournament.payIfNecessary() - } catch { - Logger.error(error) + Task { + do { + try await self.tournament.payIfNecessary() + } catch { + Logger.error(error) + } } } label: { Label("Payer le tournoi", systemImage: "dollarsign.circle.fill")