소스 검색

Merge branch 'core-data-sync-trio' of github.com:dnzxy/Open-iAPS into trio/settings-refactor

Deniz Cengiz 1 년 전
부모
커밋
ee62064675

+ 29 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -18,6 +18,11 @@
 		110AEDED2C51A0AE00615CC9 /* ShortcutsConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110AEDE82C51A0AE00615CC9 /* ShortcutsConfigProvider.swift */; };
 		110AEDEE2C51A0AE00615CC9 /* ShortcutsConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110AEDE92C51A0AE00615CC9 /* ShortcutsConfigStateModel.swift */; };
 		17A9D0899046B45E87834820 /* CarbRatioEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8D5F457B5AFF763F8CF3DF /* CarbRatioEditorProvider.swift */; };
+		118DF76A2C5ECBC60067FEB7 /* ApplyOverridePresetIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DF7642C5ECBC60067FEB7 /* ApplyOverridePresetIntent.swift */; };
+		118DF76B2C5ECBC60067FEB7 /* CancelOverrideIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DF7652C5ECBC60067FEB7 /* CancelOverrideIntent.swift */; };
+		118DF76C2C5ECBC60067FEB7 /* ListOverridePresetIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DF7662C5ECBC60067FEB7 /* ListOverridePresetIntent.swift */; };
+		118DF76D2C5ECBC60067FEB7 /* OverridePresetEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DF7672C5ECBC60067FEB7 /* OverridePresetEntity.swift */; };
+		118DF76E2C5ECBC60067FEB7 /* OverridePresetsIntentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118DF7682C5ECBC60067FEB7 /* OverridePresetsIntentRequest.swift */; };
 		19012CDC291D2CB900FB8210 /* LoopStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19012CDB291D2CB900FB8210 /* LoopStats.swift */; };
 		190EBCC429FF136900BA767D /* UserInterfaceSettingsDataFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 190EBCC329FF136900BA767D /* UserInterfaceSettingsDataFlow.swift */; };
 		190EBCC629FF138000BA767D /* UserInterfaceSettingsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 190EBCC529FF138000BA767D /* UserInterfaceSettingsProvider.swift */; };
@@ -592,6 +597,12 @@
 		110AEDE72C51A0AE00615CC9 /* ShortcutsConfigDataFlow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsConfigDataFlow.swift; sourceTree = "<group>"; };
 		110AEDE82C51A0AE00615CC9 /* ShortcutsConfigProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsConfigProvider.swift; sourceTree = "<group>"; };
 		110AEDE92C51A0AE00615CC9 /* ShortcutsConfigStateModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsConfigStateModel.swift; sourceTree = "<group>"; };
+		118DF7642C5ECBC60067FEB7 /* ApplyOverridePresetIntent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplyOverridePresetIntent.swift; sourceTree = "<group>"; };
+		118DF7652C5ECBC60067FEB7 /* CancelOverrideIntent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancelOverrideIntent.swift; sourceTree = "<group>"; };
+		118DF7662C5ECBC60067FEB7 /* ListOverridePresetIntent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListOverridePresetIntent.swift; sourceTree = "<group>"; };
+		118DF7672C5ECBC60067FEB7 /* OverridePresetEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverridePresetEntity.swift; sourceTree = "<group>"; };
+		118DF7682C5ECBC60067FEB7 /* OverridePresetsIntentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverridePresetsIntentRequest.swift; sourceTree = "<group>"; };
+		12204445D7632AF09264A979 /* PreferencesEditorDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PreferencesEditorDataFlow.swift; sourceTree = "<group>"; };
 		19012CDB291D2CB900FB8210 /* LoopStats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopStats.swift; sourceTree = "<group>"; };
 		190EBCC329FF136900BA767D /* UserInterfaceSettingsDataFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInterfaceSettingsDataFlow.swift; sourceTree = "<group>"; };
 		190EBCC529FF138000BA767D /* UserInterfaceSettingsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInterfaceSettingsProvider.swift; sourceTree = "<group>"; };
@@ -1254,6 +1265,18 @@
 			path = ShortcutsConfig;
 			sourceTree = "<group>";
 		};
+		118DF7692C5ECBC60067FEB7 /* Override */ = {
+			isa = PBXGroup;
+			children = (
+				118DF7642C5ECBC60067FEB7 /* ApplyOverridePresetIntent.swift */,
+				118DF7652C5ECBC60067FEB7 /* CancelOverrideIntent.swift */,
+				118DF7662C5ECBC60067FEB7 /* ListOverridePresetIntent.swift */,
+				118DF7672C5ECBC60067FEB7 /* OverridePresetEntity.swift */,
+				118DF7682C5ECBC60067FEB7 /* OverridePresetsIntentRequest.swift */,
+			);
+			path = Override;
+			sourceTree = "<group>";
+		};
 		18B49BC9587A59E3A347C1CD /* View */ = {
 			isa = PBXGroup;
 			children = (
@@ -2355,6 +2378,7 @@
 		CE7CA3422A064973004BE681 /* Shortcuts */ = {
 			isa = PBXGroup;
 			children = (
+				118DF7692C5ECBC60067FEB7 /* Override */,
 				110AEDE22C5193D100615CC9 /* Bolus */,
 				CE1856F32ADC4835007E39C7 /* Carbs */,
 				CE7CA3432A064973004BE681 /* AppShortcuts.swift */,
@@ -3130,6 +3154,7 @@
 				DD1745262C55526F00211FAC /* SMBSettingsRootView.swift in Sources */,
 				3811DE3025C9D49500A708ED /* HomeStateModel.swift in Sources */,
 				38BF021725E7CBBC00579895 /* PumpManagerExtensions.swift in Sources */,
+				118DF76E2C5ECBC60067FEB7 /* OverridePresetsIntentRequest.swift in Sources */,
 				CEE9A6552BBB418300EB5194 /* CalibrationsProvider.swift in Sources */,
 				19F95FF529F10FCF00314DDC /* StatProvider.swift in Sources */,
 				38F3B2EF25ED8E2A005C48AA /* TempTargetsStorage.swift in Sources */,
@@ -3246,6 +3271,7 @@
 				DD57C4C72C4C7103001A5B28 /* CarbEntryStored+CoreDataProperties.swift in Sources */,
 				DD57C4C82C4C7103001A5B28 /* OpenAPS_Battery+CoreDataClass.swift in Sources */,
 				DD57C4C92C4C7103001A5B28 /* OpenAPS_Battery+CoreDataProperties.swift in Sources */,
+				118DF76D2C5ECBC60067FEB7 /* OverridePresetEntity.swift in Sources */,
 				DD57C4CA2C4C7103001A5B28 /* GlucoseStored+CoreDataClass.swift in Sources */,
 				DD57C4CB2C4C7103001A5B28 /* GlucoseStored+CoreDataProperties.swift in Sources */,
 				DD57C4CC2C4C7103001A5B28 /* OverrideStored+CoreDataClass.swift in Sources */,
@@ -3274,6 +3300,7 @@
 				CEE9A6592BBB418300EB5194 /* CalibrationsDataFlow.swift in Sources */,
 				3811DE3525C9D49500A708ED /* HomeRootView.swift in Sources */,
 				38E98A2925F52C9300C0CED0 /* Error+Extensions.swift in Sources */,
+				118DF76C2C5ECBC60067FEB7 /* ListOverridePresetIntent.swift in Sources */,
 				38EA05DA261F6E7C0064E39B /* SimpleLogReporter.swift in Sources */,
 				3811DE6125C9D4D500A708ED /* ViewModifiers.swift in Sources */,
 				3811DEAC25C9D88300A708ED /* NightscoutManager.swift in Sources */,
@@ -3419,6 +3446,7 @@
 				A33352ED40476125EBAC6EE0 /* CarbRatioEditorDataFlow.swift in Sources */,
 				17A9D0899046B45E87834820 /* CarbRatioEditorProvider.swift in Sources */,
 				69B9A368029F7EB39F525422 /* CarbRatioEditorStateModel.swift in Sources */,
+				118DF76B2C5ECBC60067FEB7 /* CancelOverrideIntent.swift in Sources */,
 				38E44538274E411700EC9A94 /* Disk+[Data].swift in Sources */,
 				98641AF4F92123DA668AB931 /* CarbRatioEditorRootView.swift in Sources */,
 				BDF34F902C10CF8C00D51995 /* CoreDataStack.swift in Sources */,
@@ -3473,6 +3501,7 @@
 				BD1661312B82ADAB00256551 /* CustomProgressView.swift in Sources */,
 				C967DACD3B1E638F8B43BE06 /* ManualTempBasalStateModel.swift in Sources */,
 				38E4453B274E411700EC9A94 /* Disk+VolumeInformation.swift in Sources */,
+				118DF76A2C5ECBC60067FEB7 /* ApplyOverridePresetIntent.swift in Sources */,
 				7BCFACB97C821041BA43A114 /* ManualTempBasalRootView.swift in Sources */,
 				38E44534274E411700EC9A94 /* Disk+InternalHelpers.swift in Sources */,
 				38A00B2325FC2B55006BC0B0 /* LRUCache.swift in Sources */,

+ 16 - 0
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -79,6 +79,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         subscribe()
         coreDataObserver = CoreDataObserver()
         registerHandlers()
+        setupNotification()
     }
 
     private func subscribe() {
@@ -128,6 +129,21 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
+    func setupNotification() {
+        Foundation.NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(handleOverrideConfigurationUpdate),
+            name: .didUpdateOverrideConfiguration,
+            object: nil
+        )
+    }
+
+    @objc private func handleOverrideConfigurationUpdate() {
+        Task.detached {
+            await self.uploadOverrides()
+        }
+    }
+
     func sourceInfo() -> [String: Any]? {
         if let ping = ping {
             return [GlucoseSourceKey.nightscoutPing.rawValue: ping]

+ 14 - 0
FreeAPS/Sources/Shortcuts/AppShortcuts.swift

@@ -31,5 +31,19 @@ import Foundation
                 "\(.applicationName) allows to add carbs"
             ]
         )
+        AppShortcut(
+            intent: ApplyOverridePresetIntent(),
+            phrases: [
+                "Activate \(.applicationName) override",
+                "Activates an available \(.applicationName) override"
+            ]
+        )
+        AppShortcut(
+            intent: CancelOverrideIntent(),
+            phrases: [
+                "Cancel \(.applicationName) override",
+                "Cancels an active \(.applicationName) override"
+            ]
+        )
     }
 }

+ 2 - 0
FreeAPS/Sources/Shortcuts/BaseIntentsRequest.swift

@@ -13,10 +13,12 @@ import Swinject
     @Injected() var carbsStorage: CarbsStorage!
     @Injected() var glucoseStorage: GlucoseStorage!
     @Injected() var apsManager: APSManager!
+    @Injected() var overrideStorage: OverrideStorage!
 
     let resolver: Resolver
 
     let coredataContext = CoreDataStack.shared.newTaskContext()
+    let viewContext = CoreDataStack.shared.persistentContainer.viewContext
 
     override init() {
         resolver = FreeAPSApp.resolver

+ 88 - 0
FreeAPS/Sources/Shortcuts/Override/ApplyOverridePresetIntent.swift

@@ -0,0 +1,88 @@
+import AppIntents
+import Foundation
+
+@available(iOS 16.0, *) struct ApplyOverridePresetIntent: AppIntent {
+    // Title of the action in the Shortcuts app
+    static var title = LocalizedStringResource("Activate an override", table: "ShortcutsDetail")
+
+    // Description of the action in the Shortcuts app
+    static var description = IntentDescription(.init("Activate an override", table: "ShortcutsDetail"))
+
+    internal var intentRequest: OverridePresetsIntentRequest
+
+    init() {
+        intentRequest = OverridePresetsIntentRequest()
+    }
+
+    @Parameter(
+        title: LocalizedStringResource("Override", table: "ShortcutsDetail"),
+        description: LocalizedStringResource("Override choice", table: "ShortcutsDetail")
+    ) var preset: OverridePreset?
+
+    @Parameter(
+        title: LocalizedStringResource("Confirm Before applying", table: "ShortcutsDetail"),
+        description: LocalizedStringResource("If toggled, you will need to confirm before applying", table: "ShortcutsDetail"),
+        default: true
+    ) var confirmBeforeApplying: Bool
+
+    static var parameterSummary: some ParameterSummary {
+        When(\ApplyOverridePresetIntent.$confirmBeforeApplying, .equalTo, true, {
+            Summary("Applying \(\.$preset) override", table: "ShortcutsDetail") {
+                \.$confirmBeforeApplying
+            }
+        }, otherwise: {
+            Summary("Immediately applying \(\.$preset) override", table: "ShortcutsDetail") {
+                \.$confirmBeforeApplying
+            }
+        })
+    }
+
+    @MainActor func perform() async throws -> some ProvidesDialog {
+        do {
+            let presetToApply: OverridePreset
+            if let preset = preset {
+                presetToApply = preset
+            } else {
+                presetToApply = try await $preset.requestDisambiguation(
+                    among: await intentRequest.fetchAndProcessOverrides(),
+                    dialog: IntentDialog(LocalizedStringResource("Select override", table: "ShortcutsDetail"))
+                )
+            }
+
+            let displayName: String = presetToApply.name
+            if confirmBeforeApplying {
+                try await requestConfirmation(
+                    result: .result(
+                        dialog: IntentDialog(LocalizedStringResource(
+                            "Confirm to apply override '\(displayName)'",
+                            table: "ShortcutsDetail"
+                        ))
+                    )
+                )
+            }
+
+            if await intentRequest.enactOverride(presetToApply) {
+                return .result(
+                    dialog: IntentDialog(
+                        LocalizedStringResource(
+                            "Override '\(presetToApply.name)' applied",
+                            table: "ShortcutsDetail"
+                        )
+                    )
+                )
+            } else {
+                return .result(
+                    dialog: IntentDialog(
+                        LocalizedStringResource(
+                            "Override '\(presetToApply.name)' failed",
+                            table: "ShortcutsDetail"
+                        )
+                    )
+                )
+            }
+
+        } catch {
+            throw error
+        }
+    }
+}

+ 25 - 0
FreeAPS/Sources/Shortcuts/Override/CancelOverrideIntent.swift

@@ -0,0 +1,25 @@
+import AppIntents
+import Foundation
+
+@available(iOS 16.0, *) struct CancelOverrideIntent: AppIntent {
+    // Title of the action in the Shortcuts app
+    static var title = LocalizedStringResource("Cancel override", table: "ShortcutsDetail")
+
+    // Description of the action in the Shortcuts app
+    static var description = IntentDescription(.init("Cancel an active override", table: "ShortcutsDetail"))
+
+    internal var intentRequest: OverridePresetsIntentRequest
+
+    init() {
+        intentRequest = OverridePresetsIntentRequest()
+    }
+
+    @MainActor func perform() async throws -> some ProvidesDialog {
+        do {
+            await intentRequest.cancelOverride()
+            return .result(
+                dialog: IntentDialog(LocalizedStringResource("Override canceled", table: "ShortcutsDetail"))
+            )
+        }
+    }
+}

+ 30 - 0
FreeAPS/Sources/Shortcuts/Override/ListOverridePresetIntent.swift

@@ -0,0 +1,30 @@
+import AppIntents
+import Foundation
+
+@available(iOS 16.0, *) struct ListOverridePresetsIntent: AppIntent {
+    // Title of the action in the Shortcuts app
+    static var title = LocalizedStringResource("List overrides", table: "ShortcutsDetail")
+
+    // Description of the action in the Shortcuts app
+    static var description = IntentDescription(
+        .init(
+            "Allow to list and choose a specific override",
+            table: "ShortcutsDetail"
+        )
+    )
+
+    @Parameter(
+        title: LocalizedStringResource("Override", table: "ShortcutsDetail"),
+        description: LocalizedStringResource("Override choice", table: "ShortcutsDetail")
+    ) var preset: OverridePreset?
+
+    static var parameterSummary: some ParameterSummary {
+        Summary("Choose the override  \(\.$preset)", table: "ShortcutsDetail")
+    }
+
+    @MainActor func perform() async throws -> some ReturnsValue<OverridePreset> {
+        .result(
+            value: preset!
+        )
+    }
+}

+ 33 - 0
FreeAPS/Sources/Shortcuts/Override/OverridePresetEntity.swift

@@ -0,0 +1,33 @@
+import AppIntents
+import Foundation
+import Intents
+import Swinject
+
+@available(iOS 16.0, *) struct OverridePreset: AppEntity, Identifiable {
+    static var defaultQuery = OverridePresetsQuery()
+
+    var id: String
+    var name: String
+
+    var displayRepresentation: DisplayRepresentation {
+        DisplayRepresentation(title: "\(name)")
+    }
+
+    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Override"
+}
+
+@available(iOS 16.0, *) struct OverridePresetsQuery: EntityQuery {
+    internal var intentRequest: OverridePresetsIntentRequest
+
+    init() {
+        intentRequest = OverridePresetsIntentRequest()
+    }
+
+    func entities(for identifiers: [OverridePreset.ID]) async throws -> [OverridePreset] {
+        await intentRequest.fetchIDs(identifiers)
+    }
+
+    func suggestedEntities() async throws -> [OverridePreset] {
+        await intentRequest.fetchAndProcessOverrides()
+    }
+}

+ 171 - 0
FreeAPS/Sources/Shortcuts/Override/OverridePresetsIntentRequest.swift

@@ -0,0 +1,171 @@
+import CoreData
+import Foundation
+
+@available(iOS 16.0, *) final class OverridePresetsIntentRequest: BaseIntentsRequest {
+    enum overridePresetsError: Error {
+        case noTempOverrideFound
+        case noDurationDefined
+        case noActiveOverride
+    }
+
+    func fetchAndProcessOverrides() async -> [OverridePreset] {
+        // Fetch all Override Presets via OverrideStorage
+        let allOverridePresetsIDs = await overrideStorage.fetchForOverridePresets()
+
+        // Since we are fetching on a different background Thread we need to unpack the NSManagedObjectID on the correct Thread first
+        return await coredataContext.perform {
+            do {
+                let overrideObjects = try allOverridePresetsIDs.compactMap { id in
+                    try self.coredataContext.existingObject(with: id) as? OverrideStored
+                }
+
+                return overrideObjects.map { object in
+                    guard let id = object.id,
+                          let name = object.name else { return OverridePreset(id: UUID().uuidString, name: "") }
+                    return OverridePreset(id: id, name: name)
+                }
+
+            } catch {
+                debugPrint(
+                    "\(#file) \(#function) \(DebuggingIdentifiers.failed) error while fetching/ processing the overrides Array: \(error.localizedDescription)"
+                )
+                return [OverridePreset(id: UUID().uuidString, name: "")]
+            }
+        }
+    }
+
+    func fetchIDs(_ uuid: [OverridePreset.ID]) async -> [OverridePreset] {
+        await coredataContext.perform {
+            let fetchRequest: NSFetchRequest<OverrideStored> = OverrideStored.fetchRequest()
+            fetchRequest.predicate = NSPredicate(format: "id IN %@", uuid)
+
+            do {
+                let result = try self.coredataContext.fetch(fetchRequest)
+
+                if result.isEmpty {
+                    debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) No OverrideStored found for ids: \(uuid)")
+                    return [OverridePreset(id: UUID().uuidString, name: "")]
+                }
+
+                return result.map { overrideStored in
+                    OverridePreset(id: overrideStored.id ?? UUID().uuidString, name: overrideStored.name ?? "")
+                }
+            } catch let error as NSError {
+                debugPrint(
+                    "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch Override: \(error.localizedDescription)"
+                )
+                return [OverridePreset(id: UUID().uuidString, name: "")]
+            }
+        }
+    }
+
+    private func fetchOverrideID(_ preset: OverridePreset) async -> NSManagedObjectID? {
+        let fetchRequest: NSFetchRequest<OverrideStored> = OverrideStored.fetchRequest()
+        fetchRequest.predicate = NSPredicate(format: "id == %@", preset.id)
+        fetchRequest.fetchLimit = 1
+
+        return await coredataContext.perform {
+            do {
+                return try self.coredataContext.fetch(fetchRequest).first?.objectID
+            } catch {
+                debugPrint(
+                    "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch Override: \(error.localizedDescription)"
+                )
+                return nil
+            }
+        }
+    }
+
+    @MainActor func enactOverride(_ preset: OverridePreset) async -> Bool {
+        do {
+            guard let overrideID = await fetchOverrideID(preset),
+                  let overrideObject = try viewContext.existingObject(with: overrideID) as? OverrideStored else { return false }
+
+            overrideObject.enabled = true
+            overrideObject.date = Date()
+            overrideObject.isUploadedToNS = false
+
+            // Disable previous Overrides
+            /// do not create a OverrideRunEntry because we only want that if we cancel a running Override, not when enacting a Preset
+            await disableAllActiveOverrides(except: overrideID, createOverrideRunEntry: true)
+
+            if viewContext.hasChanges {
+                try viewContext.save()
+
+                // Update State variables in OverrideView
+                Foundation.NotificationCenter.default.post(name: .didUpdateOverrideConfiguration, object: nil)
+
+                return true
+            }
+        } catch let error as NSError {
+            debugPrint(
+                "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to enact Override: \(error.localizedDescription)"
+            )
+        }
+        return false
+    }
+
+    func cancelOverride() async {
+        await disableAllActiveOverrides(createOverrideRunEntry: true)
+    }
+
+    @MainActor func disableAllActiveOverrides(
+        except overrideID: NSManagedObjectID? = nil,
+        createOverrideRunEntry _: Bool
+    ) async {
+        // Get ALL NSManagedObject IDs of ALL active Overrides to cancel every single Override
+        let ids = await overrideStorage.loadLatestOverrideConfigurations(fetchLimit: 0) // 0 = no fetch limit
+
+        await viewContext.perform {
+            do {
+                // Fetch the existing OverrideStored objects from the context
+                let results = try ids.compactMap { id in
+                    try self.viewContext.existingObject(with: id) as? OverrideStored
+                }
+
+                // If there are no results, return early
+                guard !results.isEmpty else { return }
+
+                // Check if we also need to create a corresponding OverrideRunStored entry, i.e. when the User uses the Cancel Button in Override View
+                // Auggie - commented out this if statment, we always need to do this for overrides
+                // if createOverrideRunEntry {
+                // Use the first override to create a new OverrideRunStored entry
+                if let canceledOverride = results.first {
+                    let newOverrideRunStored = OverrideRunStored(context: self.viewContext)
+                    newOverrideRunStored.id = UUID()
+                    newOverrideRunStored.name = canceledOverride.name
+                    newOverrideRunStored.startDate = canceledOverride.date ?? .distantPast
+                    newOverrideRunStored.endDate = Date()
+                    newOverrideRunStored
+                        .target = NSDecimalNumber(
+                            decimal: self.overrideStorage
+                                .calculateTarget(override: canceledOverride)
+                        )
+                    newOverrideRunStored.override = canceledOverride
+                    newOverrideRunStored.isUploadedToNS = false
+                }
+                // }
+
+                // Disable all override except the one with overrideID
+                for overrideToCancel in results {
+                    if overrideToCancel.objectID != overrideID {
+                        overrideToCancel.enabled = false
+                        overrideToCancel.isUploadedToNS = false
+                    }
+                }
+
+                // Save the context if there are changes
+                if self.viewContext.hasChanges {
+                    try self.viewContext.save()
+
+                    // Update State variables in OverrideView
+                    Foundation.NotificationCenter.default.post(name: .didUpdateOverrideConfiguration, object: nil)
+                }
+            } catch {
+                debugPrint(
+                    "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to disable active Overrides with error: \(error.localizedDescription)"
+                )
+            }
+        }
+    }
+}