polscm32 2 лет назад
Родитель
Сommit
7641d0d537

+ 165 - 116
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -94,8 +94,6 @@ extension Bolus {
 
         let now = Date.now
 
-        private let treatmentsVM = TreatmentsViewModel()
-
         let context = CoreDataStack.shared.persistentContainer.viewContext
 
         override func subscribe() {
@@ -243,37 +241,87 @@ extension Bolus {
                 .roundBolus(amount: max(insulinCalculated, 0))
         }
 
+        func setupInsulinRequired() {
+            DispatchQueue.main.async {
+                self.insulinRequired = self.provider.suggestion?.insulinReq ?? 0
+
+                var conversion: Decimal = 1.0
+                if self.units == .mmolL {
+                    conversion = 0.0555
+                }
+
+                self.evBG = self.provider.suggestion?.eventualBG ?? 0
+                self.insulin = self.provider.suggestion?.insulinForManualBolus ?? 0
+                self.target = self.provider.suggestion?.current_target ?? 0
+                self.isf = self.provider.suggestion?.isf ?? 0
+                self.iob = self.provider.suggestion?.iob ?? 0
+                self.currentBG = (self.provider.suggestion?.bg ?? 0)
+                self.cob = self.provider.suggestion?.cob ?? 0
+                self.basal = self.provider.suggestion?.rate ?? 0
+                self.carbRatio = self.provider.suggestion?.carbRatio ?? 0
+
+                if self.settingsManager.settings.insulinReqPercentage != 100 {
+                    self.insulinRecommended = self.insulin * (self.settingsManager.settings.insulinReqPercentage / 100)
+                } else { self.insulinRecommended = self.insulin }
+
+                self.errorString = self.provider.suggestion?.manualBolusErrorString ?? 0
+                if self.errorString != 0 {
+                    self.error = true
+                    self.minGuardBG = (self.provider.suggestion?.minGuardBG ?? 0) * conversion
+                    self.minDelta = (self.provider.suggestion?.minDelta ?? 0) * conversion
+                    self.expectedDelta = (self.provider.suggestion?.expectedDelta ?? 0) * conversion
+                    self.minPredBG = (self.provider.suggestion?.minPredBG ?? 0) * conversion
+                } else { self.error = false }
+
+                self.insulinRecommended = self.apsManager
+                    .roundBolus(amount: max(self.insulinRecommended, 0))
+
+                if self.useCalc {
+                    self.getCurrentBasal()
+                    self.getDeltaBG()
+                    self.insulinCalculated = self.calculateInsulin()
+                }
+            }
+        }
+
+        // MARK: - Button tasks
+
         @MainActor func invokeTreatmentsTask() {
             Task {
-                if amount > 0 {
-                    if !externalInsulin {
-                        await add()
-                    } else {
-                        do {
-                            await addExternalInsulin()
-                        }
-                    }
+                let isInsulinGiven = amount > 0
+                let isCarbsPresent = carbs > 0
+
+                if isInsulinGiven {
+                    try await handleInsulin(isExternal: externalInsulin)
+                } else if isCarbsPresent {
                     waitForSuggestion = true
                 } else {
-                    if carbs > 0 {
-                        waitForSuggestion = true
-                    } else {
-                        hideModal()
-                    }
+                    hideModal()
+                    return
                 }
-                addCarbs()
+
+                saveMeal()
                 addButtonPressed = true
 
                 // if glucose data is stale end the custom loading animation by hiding the modal
-                // alternatively only set waitforSuggestion to false...
-                let lastGlucoseDate = glucoseStorage.lastGlucoseDate()
-                guard lastGlucoseDate >= Date().addingTimeInterval(-12.minutes.timeInterval) else {
-                    return hideModal()
-                }
+//                guard glucoseOfLast20Min.first?.date ?? now >= Date().addingTimeInterval(-12.minutes.timeInterval) else {
+//                    return hideModal()
+//                }
             }
         }
 
-        @MainActor func add() async {
+        // MARK: - Insulin
+
+        @MainActor private func handleInsulin(isExternal: Bool) async throws {
+            if !isExternal {
+                await addPumpInsulin()
+            } else {
+                await addExternalInsulin()
+            }
+            waitForSuggestion = true
+        }
+
+        @MainActor func addPumpInsulin() async {
             guard amount > 0 else {
                 showModal(for: nil)
                 return
@@ -285,6 +333,7 @@ extension Bolus {
                 let authenticated = try await unlockmanager.unlock()
                 if authenticated {
                     apsManager.enactBolus(amount: maxAmount, isSMB: false)
+                    savePumpInsulin(amount: amount)
                 } else {
                     print("authentication failed")
                 }
@@ -299,54 +348,103 @@ extension Bolus {
             }
         }
 
-        func setupInsulinRequired() {
-            DispatchQueue.main.async {
-                self.insulinRequired = self.provider.suggestion?.insulinReq ?? 0
-
-                var conversion: Decimal = 1.0
-                if self.units == .mmolL {
-                    conversion = 0.0555
+        private func savePumpInsulin(amount: Decimal) {
+            let newItem = InsulinStored(context: context)
+            newItem.id = UUID()
+            newItem.amount = amount as NSDecimalNumber
+            newItem.date = Date()
+            newItem.external = false
+            newItem.isSMB = false
+            self.context.perform {
+                do {
+                    try self.context.save()
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved pump insulin to core data"
+                    )
+                } catch {
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to save pump insulin to core data"
+                    )
                 }
 
-                self.evBG = self.provider.suggestion?.eventualBG ?? 0
-                self.insulin = self.provider.suggestion?.insulinForManualBolus ?? 0
-                self.target = self.provider.suggestion?.current_target ?? 0
-                self.isf = self.provider.suggestion?.isf ?? 0
-                self.iob = self.provider.suggestion?.iob ?? 0
-                self.currentBG = (self.provider.suggestion?.bg ?? 0)
-                self.cob = self.provider.suggestion?.cob ?? 0
-                self.basal = self.provider.suggestion?.rate ?? 0
-                self.carbRatio = self.provider.suggestion?.carbRatio ?? 0
+            }
+        }
 
-                if self.settingsManager.settings.insulinReqPercentage != 100 {
-                    self.insulinRecommended = self.insulin * (self.settingsManager.settings.insulinReqPercentage / 100)
-                } else { self.insulinRecommended = self.insulin }
+        // MARK: - EXTERNAL INSULIN
 
-                self.errorString = self.provider.suggestion?.manualBolusErrorString ?? 0
-                if self.errorString != 0 {
-                    self.error = true
-                    self.minGuardBG = (self.provider.suggestion?.minGuardBG ?? 0) * conversion
-                    self.minDelta = (self.provider.suggestion?.minDelta ?? 0) * conversion
-                    self.expectedDelta = (self.provider.suggestion?.expectedDelta ?? 0) * conversion
-                    self.minPredBG = (self.provider.suggestion?.minPredBG ?? 0) * conversion
-                } else { self.error = false }
+        @MainActor func addExternalInsulin() async {
+            guard amount > 0 else {
+                showModal(for: nil)
+                return
+            }
 
-                self.insulinRecommended = self.apsManager
-                    .roundBolus(amount: max(self.insulinRecommended, 0))
+            amount = min(amount, maxBolus * 3)
 
-                if self.useCalc {
-                    self.getCurrentBasal()
-                    self.getDeltaBG()
-                    self.insulinCalculated = self.calculateInsulin()
+            do {
+                let authenticated = try await unlockmanager.unlock()
+                if authenticated {
+                    storeExternalInsulinEvent()
+                } else {
+                    print("authentication failed")
+                }
+            } catch {
+                print("authentication error for external insulin: \(error.localizedDescription)")
+                DispatchQueue.main.async {
+                    self.waitForSuggestion = false
+                    if self.addButtonPressed {
+                        self.hideModal()
+                    }
+                }
+            }
+        }
+
+        private func storeExternalInsulinEvent() {
+            pumpHistoryStorage.storeEvents(
+                [
+                    PumpHistoryEvent(
+                        id: UUID().uuidString,
+                        type: .bolus,
+                        timestamp: date,
+                        amount: amount,
+                        duration: nil,
+                        durationMin: nil,
+                        rate: nil,
+                        temp: nil,
+                        carbInput: nil,
+                        isExternal: true
+                    )
+                ]
+            )
+            debug(.default, "External insulin saved to pumphistory.json")
+
+            // save to core data asynchronously
+            self.context.perform {
+                let newItem = InsulinStored(context: self.context)
+                newItem.amount = (self.amount) as NSDecimalNumber
+                newItem.date = Date()
+                newItem.external = true
+                newItem.isSMB = false
+                do {
+                    try self.context.save()
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved carbs to core data"
+                    )
+                } catch {
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to save carbs to core data"
+                    )
                 }
             }
+            
+            // perform determine basal sync
+            apsManager.determineBasalSync()
         }
 
         // MARK: - Carbs
 
         // we need to also fetch the data after we have saved them in order to update the array and the UI because of the MVVM Architecture
 
-        func addCarbs() {
+        func saveMeal() {
             guard carbs > 0 || fat > 0 || protein > 0 else { return }
             carbs = min(carbs, maxCarbs)
             id_ = UUID().uuidString
@@ -383,15 +481,17 @@ extension Bolus {
                 newCarbEntry.carbs = Double(carbs)
                 newCarbEntry.fat = Double(fat)
                 newCarbEntry.protein = Double(protein)
-                do {
-                    try self.context.save()
-                    debugPrint(
-                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved carbs to core data"
-                    )
-                } catch {
-                    debugPrint(
-                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to save carbs to core data"
-                    )
+                self.context.perform {
+                    do {
+                        try self.context.save()
+                        debugPrint(
+                            "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved carbs to core data"
+                        )
+                    } catch {
+                        debugPrint(
+                            "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to save carbs to core data"
+                        )
+                    }
                 }
             }
         }
@@ -522,57 +622,6 @@ extension Bolus {
                 }
             }
         }
-
-        // MARK: EXTERNAL INSULIN
-
-        @MainActor func addExternalInsulin() async {
-            guard amount > 0 else {
-                showModal(for: nil)
-                return
-            }
-
-            amount = min(amount, maxBolus * 3)
-
-            do {
-                let authenticated = try await unlockmanager.unlock()
-                if authenticated {
-                    storeExternalInsulinEvent()
-                } else {
-                    print("authentication failed")
-                }
-            } catch {
-                print("authentication error for external insulin: \(error.localizedDescription)")
-                DispatchQueue.main.async {
-                    self.waitForSuggestion = false
-                    if self.addButtonPressed {
-                        self.hideModal()
-                    }
-                }
-            }
-        }
-
-        private func storeExternalInsulinEvent() {
-            pumpHistoryStorage.storeEvents(
-                [
-                    PumpHistoryEvent(
-                        id: UUID().uuidString,
-                        type: .bolus,
-                        timestamp: date,
-                        amount: amount,
-                        duration: nil,
-                        durationMin: nil,
-                        rate: nil,
-                        temp: nil,
-                        carbInput: nil,
-                        isExternal: true
-                    )
-                ]
-            )
-            debug(.default, "External insulin saved to pumphistory.json")
-
-            // perform determine basal sync
-            apsManager.determineBasalSync()
-        }
     }
 }
 

+ 1 - 1
FreeAPS/Sources/Modules/Bolus/View/DefaultBolusCalcRootView.swift

@@ -116,7 +116,7 @@ extension Bolus {
                     Section {
                         Button {
                             Task {
-                                await state.add()
+//                                add()
                                 state.hideModal()
                                 keepForNextWiew = true
                             }

+ 7 - 0
Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents

@@ -60,6 +60,13 @@
         <attribute name="tempBasal" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <relationship name="insulin" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Oref0Suggestion" inverseName="computedInsulinDistribution" inverseEntity="Oref0Suggestion"/>
     </entity>
+    <entity name="InsulinStored" representedClassName="InsulinStored" syncable="YES" codeGenerationType="class">
+        <attribute name="amount" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="external" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
+        <attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
+        <attribute name="isSMB" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
+    </entity>
     <entity name="LastLoop" representedClassName="LastLoop" syncable="YES" codeGenerationType="class">
         <attribute name="cob" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
         <attribute name="iob" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>