payfrit-works-ios/PayfritWorks/Models/TierStatus.swift
2026-02-01 23:38:34 -08:00

197 lines
6.5 KiB
Swift

import Foundation
// MARK: - Tier Status (from tierStatus.cfm)
struct TierStatus: Codable {
var tier: Int
var stripe: StripeInfo
var activation: ActivationInfo
enum CodingKeys: String, CodingKey {
case tier = "TIER"
case stripe = "STRIPE"
case activation = "ACTIVATION"
}
init(tier: Int = 0, stripe: StripeInfo = StripeInfo(), activation: ActivationInfo = ActivationInfo()) {
self.tier = tier
self.stripe = stripe
self.activation = activation
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
tier = (try? c.decode(Int.self, forKey: .tier)) ?? 0
stripe = (try? c.decode(StripeInfo.self, forKey: .stripe)) ?? StripeInfo()
activation = (try? c.decode(ActivationInfo.self, forKey: .activation)) ?? ActivationInfo()
}
struct StripeInfo: Codable {
var hasAccount: Bool
var payoutsEnabled: Bool
var setupIncomplete: Bool
enum CodingKeys: String, CodingKey {
case hasAccount = "HasAccount"
case payoutsEnabled = "PayoutsEnabled"
case setupIncomplete = "SetupIncomplete"
}
init(hasAccount: Bool = false, payoutsEnabled: Bool = false, setupIncomplete: Bool = false) {
self.hasAccount = hasAccount
self.payoutsEnabled = payoutsEnabled
self.setupIncomplete = setupIncomplete
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
hasAccount = (try? c.decode(Bool.self, forKey: .hasAccount)) ?? false
payoutsEnabled = (try? c.decode(Bool.self, forKey: .payoutsEnabled)) ?? false
setupIncomplete = (try? c.decode(Bool.self, forKey: .setupIncomplete)) ?? false
}
}
struct ActivationInfo: Codable {
var balanceCents: Int
var capCents: Int
var remainingCents: Int
var isComplete: Bool
var progressPercent: Int
enum CodingKeys: String, CodingKey {
case balanceCents = "BalanceCents"
case capCents = "CapCents"
case remainingCents = "RemainingCents"
case isComplete = "IsComplete"
case progressPercent = "ProgressPercent"
}
init(balanceCents: Int = 0, capCents: Int = 2500, remainingCents: Int = 2500, isComplete: Bool = false, progressPercent: Int = 0) {
self.balanceCents = balanceCents
self.capCents = capCents
self.remainingCents = remainingCents
self.isComplete = isComplete
self.progressPercent = progressPercent
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
balanceCents = (try? c.decode(Int.self, forKey: .balanceCents)) ?? 0
capCents = (try? c.decode(Int.self, forKey: .capCents)) ?? 2500
remainingCents = (try? c.decode(Int.self, forKey: .remainingCents)) ?? 2500
isComplete = (try? c.decode(Bool.self, forKey: .isComplete)) ?? false
progressPercent = (try? c.decode(Int.self, forKey: .progressPercent)) ?? 0
}
var balanceDollars: String {
String(format: "$%.2f", Double(balanceCents) / 100.0)
}
var capDollars: String {
String(format: "$%.2f", Double(capCents) / 100.0)
}
var progress: Double {
guard capCents > 0 else { return 0 }
return Double(balanceCents) / Double(capCents)
}
}
}
// MARK: - Ledger Response (from ledger.cfm)
struct LedgerResponse: Codable {
var entries: [LedgerEntry]
var totals: LedgerTotals
enum CodingKeys: String, CodingKey {
case entries = "ENTRIES"
case totals = "TOTALS"
}
init(entries: [LedgerEntry] = [], totals: LedgerTotals = LedgerTotals()) {
self.entries = entries
self.totals = totals
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
entries = (try? c.decode([LedgerEntry].self, forKey: .entries)) ?? []
totals = (try? c.decode(LedgerTotals.self, forKey: .totals)) ?? LedgerTotals()
}
}
struct LedgerEntry: Codable, Identifiable {
let id: Int
let taskId: Int
let grossEarningsCents: Int
let activationWithheldCents: Int
let netTransferCents: Int
let status: String
let createdAt: String
enum CodingKeys: String, CodingKey {
case id = "ID"
case taskId = "TaskID"
case grossEarningsCents = "GrossEarningsCents"
case activationWithheldCents = "ActivationWithheldCents"
case netTransferCents = "NetTransferCents"
case status = "Status"
case createdAt = "CreatedAt"
}
var grossDollars: String {
String(format: "$%.2f", Double(grossEarningsCents) / 100.0)
}
var netDollars: String {
String(format: "$%.2f", Double(netTransferCents) / 100.0)
}
var withheldDollars: String {
String(format: "$%.2f", Double(activationWithheldCents) / 100.0)
}
var statusDisplay: String {
switch status {
case "pending_charge": return "Pending"
case "charged": return "Charged"
case "transferred": return "Transferred"
case "reversed": return "Reversed"
default: return status.capitalized
}
}
}
struct LedgerTotals: Codable {
var totalGrossCents: Int
var totalWithheldCents: Int
var totalNetCents: Int
enum CodingKeys: String, CodingKey {
case totalGrossCents = "TotalGrossCents"
case totalWithheldCents = "TotalWithheldCents"
case totalNetCents = "TotalNetCents"
}
init(totalGrossCents: Int = 0, totalWithheldCents: Int = 0, totalNetCents: Int = 0) {
self.totalGrossCents = totalGrossCents
self.totalWithheldCents = totalWithheldCents
self.totalNetCents = totalNetCents
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
totalGrossCents = (try? c.decode(Int.self, forKey: .totalGrossCents)) ?? 0
totalWithheldCents = (try? c.decode(Int.self, forKey: .totalWithheldCents)) ?? 0
totalNetCents = (try? c.decode(Int.self, forKey: .totalNetCents)) ?? 0
}
var totalGrossDollars: String {
String(format: "$%.2f", Double(totalGrossCents) / 100.0)
}
var totalNetDollars: String {
String(format: "$%.2f", Double(totalNetCents) / 100.0)
}
}