AddCarbsStateModel.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import CoreData
  2. import SwiftUI
  3. extension AddCarbs {
  4. final class StateModel: BaseStateModel<Provider> {
  5. @Injected() var carbsStorage: CarbsStorage!
  6. @Injected() var apsManager: APSManager!
  7. @Injected() var settings: SettingsManager!
  8. @Published var carbs: Decimal = 0
  9. @Published var date = Date()
  10. @Published var protein: Decimal = 0
  11. @Published var fat: Decimal = 0
  12. @Published var carbsRequired: Decimal?
  13. @Published var useFPU: Bool = false
  14. @Published var dish: String = ""
  15. @Published var selection: Presets?
  16. let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
  17. @Environment(\.managedObjectContext) var moc
  18. override func subscribe() {
  19. carbsRequired = provider.suggestion?.carbsReq
  20. useFPU = settingsManager.settings.useFPUconversion
  21. }
  22. func add() {
  23. guard carbs > 0 || fat > 0 || protein > 0 else {
  24. showModal(for: nil)
  25. return
  26. }
  27. if useFPU {
  28. // -------------------------- FPU--------------------------------------
  29. let interval = settings.settings.minuteInterval // Interval betwwen carbs
  30. let timeCap = settings.settings.timeCap // Max Duration
  31. let adjustment = settings.settings.individualAdjustmentFactor
  32. let delay = settings.settings.delay // Tme before first future carb entry
  33. let kcal = protein * 4 + fat * 9
  34. let carbEquivalents = (kcal / 10) * adjustment
  35. let fpus = carbEquivalents / 10
  36. // Duration in hours used for extended boluses with Warsaw Method. Here used for total duration of the computed carbquivalents instead, excluding the configurable delay.
  37. var computedDuration = 0
  38. switch fpus {
  39. case ..<2:
  40. computedDuration = 3
  41. case 2 ..< 3:
  42. computedDuration = 4
  43. case 3 ..< 4:
  44. computedDuration = 5
  45. default:
  46. computedDuration = timeCap
  47. }
  48. // Size of each created carb equivalent if 60 minutes interval
  49. var equivalent: Decimal = carbEquivalents / Decimal(computedDuration)
  50. // Adjust for interval setting other than 60 minutes
  51. equivalent /= Decimal(60 / interval)
  52. // Round to 1 fraction digit
  53. // equivalent = Decimal(round(Double(equivalent * 10) / 10))
  54. let roundedEquivalent: Double = round(Double(equivalent * 10)) / 10
  55. equivalent = Decimal(roundedEquivalent)
  56. // Number of equivalents
  57. var numberOfEquivalents = carbEquivalents / equivalent
  58. // Only use delay in first loop
  59. var firstIndex = true
  60. // New date for each carb equivalent
  61. var useDate = date
  62. // Group and Identify all FPUs together
  63. let fpuID = UUID().uuidString
  64. // Create an array of all future carb equivalents.
  65. var futureCarbArray = [CarbsEntry]()
  66. while carbEquivalents > 0, numberOfEquivalents > 0 {
  67. if firstIndex {
  68. useDate = useDate.addingTimeInterval(delay.minutes.timeInterval)
  69. firstIndex = false
  70. } else { useDate = useDate.addingTimeInterval(interval.minutes.timeInterval) }
  71. let eachCarbEntry = CarbsEntry(
  72. id: UUID().uuidString, createdAt: useDate, carbs: equivalent, enteredBy: CarbsEntry.manual, isFPU: true,
  73. fpuID: fpuID
  74. )
  75. futureCarbArray.append(eachCarbEntry)
  76. numberOfEquivalents -= 1
  77. }
  78. // Save the array
  79. if carbEquivalents > 0 {
  80. carbsStorage.storeCarbs(futureCarbArray)
  81. }
  82. } // ------------------------- END OF TPU ----------------------------------------
  83. // Store the real carbs
  84. if carbs > 0 {
  85. carbsStorage
  86. .storeCarbs([CarbsEntry(
  87. id: UUID().uuidString,
  88. createdAt: date,
  89. carbs: carbs,
  90. enteredBy: CarbsEntry.manual,
  91. isFPU: false, fpuID: nil
  92. )])
  93. }
  94. if settingsManager.settings.skipBolusScreenAfterCarbs {
  95. apsManager.determineBasalSync()
  96. showModal(for: nil)
  97. } else {
  98. showModal(for: .bolus(waitForSuggestion: true))
  99. }
  100. }
  101. func deletePreset() {
  102. if selection != nil {
  103. try? coredataContext.delete(selection!)
  104. try? coredataContext.save()
  105. carbs = 0
  106. fat = 0
  107. protein = 0
  108. }
  109. selection = nil
  110. }
  111. }
  112. }