Просмотр исходного кода

Fat&Protein FPU : Add the deletion of FPU in AppleHealth and Nightscout. (#603)

* correction for the max FPU carbs

* Fat&Protein FPU : Add the deletion of FPU in AppleHealth and Nightscout.
Pierre L 3 лет назад
Родитель
Сommit
9081dfbb36

+ 7 - 1
FreeAPS/Sources/Modules/DataTable/DataTableDataFlow.swift

@@ -63,6 +63,8 @@ enum DataTable {
         let amount: Decimal?
         let secondAmount: Decimal?
         let duration: Decimal?
+        let isFPU: Bool?
+        let fpuID: String?
 
         private var numberFormater: NumberFormatter {
             let formatter = NumberFormatter()
@@ -79,7 +81,9 @@ enum DataTable {
             secondAmount: Decimal? = nil,
             duration: Decimal? = nil,
             id: String? = nil,
-            idPumpEvent: String? = nil
+            idPumpEvent: String? = nil,
+            isFPU: Bool? = false,
+            fpuID: String? = nil
         ) {
             self.units = units
             self.type = type
@@ -89,6 +93,8 @@ enum DataTable {
             self.duration = duration
             self.id = id ?? UUID().uuidString
             self.idPumpEvent = idPumpEvent
+            self.isFPU = isFPU
+            self.fpuID = fpuID
         }
 
         static func == (lhs: Treatment, rhs: Treatment) -> Bool {

+ 6 - 2
FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift

@@ -26,8 +26,12 @@ extension DataTable {
         }
 
         func deleteCarbs(_ treatement: Treatment) {
-            nightscoutManager.deleteCarbs(at: treatement.date)
-            healthkitManager.deleteCarbs(syncID: treatement.id)
+            nightscoutManager.deleteCarbs(
+                at: treatement.date,
+                isFPU: treatement.isFPU,
+                fpuID: treatement.fpuID,
+                syncID: treatement.id
+            )
         }
 
         func deleteInsulin(_ treatement: Treatment) {

+ 3 - 1
FreeAPS/Sources/Modules/DataTable/DataTableStateModel.swift

@@ -49,7 +49,9 @@ extension DataTable {
                             type: .fpus,
                             date: $0.createdAt,
                             amount: $0.carbs,
-                            id: $0.id
+                            id: $0.id,
+                            isFPU: $0.isFPU,
+                            fpuID: $0.fpuID
                         )
                     }
 

+ 30 - 11
FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

@@ -26,7 +26,7 @@ protocol HealthKitManager: GlucoseSource {
     /// Delete glucose with syncID
     func deleteGlucose(syncID: String)
     /// delete carbs with syncID
-    func deleteCarbs(syncID: String)
+    func deleteCarbs(syncID: String, isFPU: Bool?, fpuID: String?)
     /// delete insulin with syncID
     func deleteInsulin(syncID: String)
 }
@@ -53,6 +53,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver {
     @Injected() private var healthKitStore: HKHealthStore!
     @Injected() private var settingsManager: SettingsManager!
     @Injected() private var broadcaster: Broadcaster!
+    @Injected() var carbsStorage: CarbsStorage!
 
     private let processQueue = DispatchQueue(label: "BaseHealthKitManager.processQueue")
     private var lifetime = Lifetime()
@@ -517,22 +518,40 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver {
 
     // - MARK Carbs function
 
-    func deleteCarbs(syncID: String) {
+    func deleteCarbs(syncID: String, isFPU: Bool?, fpuID: String?) {
         guard settingsManager.settings.useAppleHealth,
               let sampleType = Config.healthCarbObject,
               checkAvailabilitySave(objectTypeToHealthStore: sampleType)
         else { return }
 
-        processQueue.async {
-            let predicate = HKQuery.predicateForObjects(
-                withMetadataKey: HKMetadataKeySyncIdentifier,
-                operatorType: .equalTo,
-                value: syncID
-            )
+        if let isFPU = isFPU, !isFPU {
+            processQueue.async {
+                let predicate = HKQuery.predicateForObjects(
+                    withMetadataKey: HKMetadataKeySyncIdentifier,
+                    operatorType: .equalTo,
+                    value: syncID
+                )
+                self.healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
+                    guard let error = error else { return }
+                    warning(.service, "Cannot delete sample with syncID: \(syncID)", error: error)
+                }
+            }
+        } else {
+            // need to find all syncID
+            guard let fpuID = fpuID else { return }
+
+            processQueue.async {
+                let recentCarbs: [CarbsEntry] = self.carbsStorage.recent()
+                let ids = recentCarbs.filter { $0.fpuID == fpuID }.compactMap(\.id)
+                let predicate = HKQuery.predicateForObjects(
+                    withMetadataKey: HKMetadataKeySyncIdentifier,
+                    allowedValues: ids
+                )
 
-            self.healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
-                guard let error = error else { return }
-                warning(.service, "Cannot delete sample with syncID: \(syncID)", error: error)
+                self.healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
+                    guard let error = error else { return }
+                    warning(.service, "Cannot delete sample with fpuID: \(fpuID)", error: error)
+                }
             }
         }
     }

+ 44 - 12
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -9,7 +9,7 @@ protocol NightscoutManager: GlucoseSource {
     func fetchCarbs() -> AnyPublisher<[CarbsEntry], Never>
     func fetchTempTargets() -> AnyPublisher<[TempTarget], Never>
     func fetchAnnouncements() -> AnyPublisher<[Announcement], Never>
-    func deleteCarbs(at date: Date)
+    func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID: String)
     func deleteInsulin(at date: Date)
     func uploadStatus()
     func uploadStatistics(dailystat: Statistics)
@@ -30,6 +30,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     @Injected() private var settingsManager: SettingsManager!
     @Injected() private var broadcaster: Broadcaster!
     @Injected() private var reachabilityManager: ReachabilityManager!
+    @Injected() var healthkitManager: HealthKitManager!
 
     private let processQueue = DispatchQueue(label: "BaseNetworkManager.processQueue")
     private var ping: TimeInterval?
@@ -173,23 +174,54 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
             .eraseToAnyPublisher()
     }
 
-    func deleteCarbs(at date: Date) {
+    func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID: String) {
+        // remove in AH
+        healthkitManager.deleteCarbs(syncID: syncID, isFPU: isFPU, fpuID: fpuID)
+
         guard let nightscout = nightscoutAPI, isUploadEnabled else {
             carbsStorage.deleteCarbs(at: date)
             return
         }
 
-        nightscout.deleteCarbs(at: date)
-            .sink { completion in
-                switch completion {
-                case .finished:
-                    self.carbsStorage.deleteCarbs(at: date)
-                    debug(.nightscout, "Carbs deleted")
-                case let .failure(error):
-                    debug(.nightscout, error.localizedDescription)
+        if let isFPU = isFPU, isFPU {
+            guard let fpuID = fpuID else { return }
+            let allValues = storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self) ?? []
+            let dates = allValues.filter { $0.fpuID == fpuID }.map(\.createdAt).removeDublicates()
+
+            let publishers = dates
+                .map { d -> AnyPublisher<Void, Swift.Error> in
+                    nightscout.deleteCarbs(
+                        at: d
+                    )
                 }
-            } receiveValue: {}
-            .store(in: &lifetime)
+
+            Publishers.MergeMany(publishers)
+                .collect()
+                .sink { completion in
+                    self.carbsStorage.deleteCarbs(at: date)
+                    switch completion {
+                    case .finished:
+                        self.carbsStorage.deleteCarbs(at: date)
+                        debug(.nightscout, "Carbs deleted")
+                    case let .failure(error):
+                        debug(.nightscout, error.localizedDescription)
+                    }
+                } receiveValue: { _ in }
+                .store(in: &lifetime)
+
+        } else {
+            nightscout.deleteCarbs(at: date)
+                .sink { completion in
+                    self.carbsStorage.deleteCarbs(at: date)
+                    switch completion {
+                    case .finished:
+                        debug(.nightscout, "Carbs deleted")
+                    case let .failure(error):
+                        debug(.nightscout, error.localizedDescription)
+                    }
+                } receiveValue: {}
+                .store(in: &lifetime)
+        }
     }
 
     func deleteInsulin(at date: Date) {