CarbEntryStored+helper.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import CoreData
  2. import Foundation
  3. extension NSPredicate {
  4. static var fpusForChart: NSPredicate {
  5. let date = Date.oneDayAgo
  6. return NSPredicate(format: "isFPU == true AND date >= %@", date as NSDate)
  7. }
  8. static var carbsForChart: NSPredicate {
  9. let date = Date.oneDayAgo
  10. return NSPredicate(format: "isFPU == false AND date >= %@ AND carbs > 0", date as NSDate)
  11. }
  12. static var carbsForStats: NSPredicate {
  13. let date = Date.threeMonthsAgo
  14. return NSPredicate(format: "date >= %@", date as NSDate)
  15. }
  16. static var carbsNotYetUploadedToNightscout: NSPredicate {
  17. let date = Date.oneDayAgo
  18. return NSPredicate(
  19. format: "date >= %@ AND isUploadedToNS == %@ AND isFPU == %@ AND carbs > 0",
  20. date as NSDate,
  21. false as NSNumber,
  22. false as NSNumber
  23. )
  24. }
  25. static var carbsNotYetUploadedToHealth: NSPredicate {
  26. let date = Date.oneDayAgo
  27. return NSPredicate(
  28. format: "date >= %@ AND isUploadedToHealth == %@",
  29. date as NSDate,
  30. false as NSNumber
  31. )
  32. }
  33. static var carbsNotYetUploadedToTidepool: NSPredicate {
  34. let date = Date.oneDayAgo
  35. return NSPredicate(
  36. format: "date >= %@ AND isUploadedToTidepool == %@",
  37. date as NSDate,
  38. false as NSNumber
  39. )
  40. }
  41. static var fpusNotYetUploadedToNightscout: NSPredicate {
  42. let date = Date.oneDayAgo
  43. return NSPredicate(
  44. format: "date >= %@ AND isUploadedToNS == %@ AND isFPU == %@",
  45. date as NSDate,
  46. false as NSNumber,
  47. true as NSNumber
  48. )
  49. }
  50. }
  51. extension CarbEntryStored {
  52. static func fetch(
  53. _ predicate: NSPredicate = .predicateForOneDayAgo,
  54. fetchLimit: Int = 100,
  55. ascending: Bool = false
  56. ) -> NSFetchRequest<CarbEntryStored> {
  57. let request = CarbEntryStored.fetchRequest() as NSFetchRequest<CarbEntryStored>
  58. request.sortDescriptors = [NSSortDescriptor(keyPath: \CarbEntryStored.date, ascending: ascending)]
  59. request.fetchLimit = fetchLimit
  60. request.predicate = predicate
  61. return request
  62. }
  63. }
  64. // MARK: - CarbEntryDTO and Conformance to ImportableDTO
  65. /// Data Transfer Object for Carb entries.
  66. struct CarbEntryDTO: Decodable, ImportableDTO {
  67. var id: UUID?
  68. var carbs: Double
  69. var date: Date?
  70. var fat: Double?
  71. var protein: Double?
  72. var isFPU: Bool?
  73. var note: String?
  74. var enteredBy: String?
  75. // Conformance to ImportableDTO
  76. typealias ManagedObject = CarbEntryStored
  77. /// Stores the DTO in Core Data by mapping it to the corresponding managed object.
  78. func store(in context: NSManagedObjectContext) -> CarbEntryStored {
  79. let carbEntry = CarbEntryStored(context: context)
  80. carbEntry.id = id ?? UUID()
  81. carbEntry.carbs = carbs
  82. carbEntry.date = date ?? Date()
  83. carbEntry.fat = fat ?? 0.0
  84. carbEntry.protein = protein ?? 0.0
  85. carbEntry.isFPU = isFPU ?? false
  86. carbEntry.note = note
  87. carbEntry.isUploadedToNS = true
  88. carbEntry.isUploadedToHealth = true
  89. carbEntry.isUploadedToTidepool = true
  90. return carbEntry
  91. }
  92. }
  93. extension CarbEntryStored: Encodable {
  94. enum CodingKeys: String, CodingKey {
  95. case actualDate
  96. case created_at
  97. case carbs
  98. case fat
  99. case id
  100. case isFPU
  101. case note
  102. case protein
  103. case enteredBy
  104. }
  105. public func encode(to encoder: Encoder) throws {
  106. var container = encoder.container(keyedBy: CodingKeys.self)
  107. let dateFormatter = ISO8601DateFormatter()
  108. dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
  109. let formattedDate = dateFormatter.string(from: date ?? Date())
  110. try container.encode(formattedDate, forKey: .actualDate)
  111. try container.encode(formattedDate, forKey: .created_at)
  112. // TODO: handle this conditionally; pass in the enteredBy string (manual entry or via NS or Apple Health)
  113. try container.encode("Trio", forKey: .enteredBy)
  114. try container.encode(carbs, forKey: .carbs)
  115. try container.encode(fat, forKey: .fat)
  116. try container.encode(isFPU, forKey: .isFPU)
  117. try container.encode(note, forKey: .note)
  118. try container.encode(protein, forKey: .protein)
  119. try container.encode(id, forKey: .id)
  120. }
  121. }