Guest User

Untitled

a guest
Jan 16th, 2024
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 3.40 KB | None | 0 0
  1. import Foundation
  2.  
  3. struct Transaction: Identifiable, Decodable, Hashable, Sendable {
  4.     let id: Int
  5.     let date: String
  6.     let institution: String
  7.     let account: String
  8.     var merchant: String
  9.     let amount: Double
  10.     let type: TransactionType.RawValue
  11.     var categoryId: Int
  12.     var category: String
  13.     let isPending: Bool
  14.     var isTransfer: Bool
  15.     var isExpense: Bool
  16.     var isEdited: Bool
  17.    
  18.     var dateParsed: Date {
  19.         date.dateParsed()
  20.     }
  21.    
  22.     var month: String {
  23.         dateParsed.formatted(.dateTime.year().month(.wide))
  24.     }
  25.    
  26.     var signedAmount: Double {
  27.         return type == TransactionType.credit.rawValue ? amount : -amount
  28.     }
  29. }
  30.  
  31. enum TransactionType: String {
  32.     case debit = "debit"
  33.     case credit = "credit"
  34. }
  35.  
  36. struct Category {
  37.     let id: Int
  38.     let name: String
  39.     var mainCategoryId: Int?
  40. }
  41.  
  42. import Foundation
  43.  
  44. typealias TransactionPrefixSum = [(String, Double)]
  45.  
  46. final class TransactionListViewModel: ObservableObject {
  47.     static let transactionsURL = "https://designcode.io/data/transactions.json"
  48.     var transactions: [Transaction] = []
  49.    
  50.     init() {
  51.         Task {
  52.             transactions = try await getTransactions()
  53.         }
  54.     }
  55.    
  56.     func getTransactions() async throws -> [Transaction] {
  57.         guard let url = URL(string: TransactionListViewModel.transactionsURL) else {
  58.             print("Invalid URL")
  59.             return []
  60.         }
  61.         do {
  62.             let (data, response) = try await URLSession.shared.data(from: url)
  63.             guard let httpResponse = response as? HTTPURLResponse,
  64.                   (200...299).contains(httpResponse.statusCode) else {
  65.                 print("Error making request: ", (response as! HTTPURLResponse).statusCode)
  66.                 return []
  67.             }
  68.             return try JSONDecoder().decode([Transaction].self, from: data)
  69.         } catch {
  70.             print("Error: ", error)
  71.             return []
  72.         }
  73.     }
  74.    
  75.     func accumulateTransactions() async -> TransactionPrefixSum {
  76.         if transactions.isEmpty {
  77.             transactions = try! await getTransactions()
  78.         }
  79.        
  80.         let today = "02/17/2022".dateParsed()
  81.         let dateInterval = Calendar.current.dateInterval(of: .month, for: today)!
  82.        
  83.         var sum: Double = .zero
  84.         var cumulativeSum = TransactionPrefixSum()
  85.        
  86.         for date in stride(from: dateInterval.start, to: today, by: 60 * 60 * 24) {
  87.             let dailyExpenses = transactions.filter { $0.dateParsed == date && $0.isExpense }
  88.             let dailyTotal = dailyExpenses.reduce(0) { $0 - $1.signedAmount }
  89.            
  90.             sum += dailyTotal
  91.             cumulativeSum.append((date.formatted(), sum))
  92.         }
  93.        
  94.         return cumulativeSum
  95.     }
  96. }
  97.  
  98. extension String {
  99.     func dateParsed() -> Date {
  100.         guard let parsedDate = DateFormatter.allNumericUSA.date(from: self) else { return Date() }
  101.         return parsedDate
  102.     }
  103. }
  104.  
  105. extension DateFormatter {
  106.     static let allNumericUSA: DateFormatter = {
  107. //        print("Initializing DateFormatter")
  108.         let formatter = DateFormatter()
  109.         formatter.dateFormat = "MM/dd/yyyy"
  110.         return formatter
  111.     }()
  112. }
  113.  
  114. let transactionsViewModel = TransactionListViewModel()
  115. Task {
  116.     let transactions = await transactionsViewModel.accumulateTransactions()
  117.     print(transactions)
  118. }
  119.  
Advertisement
Add Comment
Please, Sign In to add comment