فهرست منبع

pull in latest dev and solve merge conflicts

polscm32 2 سال پیش
والد
کامیت
a9142c5d4a

+ 2 - 0
Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents

@@ -68,7 +68,9 @@
     <entity name="Meals" representedClassName="Meals" syncable="YES" codeGenerationType="class">
         <attribute name="carbs" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
         <attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <attribute name="fat" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
+        <attribute name="fpuID" optional="YES" attributeType="String"/>
         <attribute name="id" optional="YES" attributeType="String"/>
         <attribute name="note" optional="YES" attributeType="String"/>
         <attribute name="protein" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>

+ 7 - 0
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -349,6 +349,9 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
         broadcaster.notify(PumpBatteryObserver.self, on: processQueue) {
             $0.pumpBatteryDidChange(battery)
         }
+        broadcaster.notify(PumpTimeZoneObserver.self, on: processQueue) {
+            $0.pumpTimeZoneDidChange(status.timeZone)
+        }
 
         if let omnipod = pumpManager as? OmnipodPumpManager {
             let reservoirVal = omnipod.state.podState?.lastInsulinMeasurements?.reservoirLevel ?? 0xDEAD_BEEF
@@ -652,3 +655,7 @@ protocol PumpReservoirObserver {
 protocol PumpBatteryObserver {
     func pumpBatteryDidChange(_ battery: Battery)
 }
+
+protocol PumpTimeZoneObserver {
+    func pumpTimeZoneDidChange(_ timezone: TimeZone)
+}

+ 41 - 14
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -12,7 +12,7 @@ protocol CarbsStorage {
     func syncDate() -> Date
     func recent() -> [CarbsEntry]
     func nightscoutTretmentsNotUploaded() -> [NigtscoutTreatment]
-    func deleteCarbs(at uniqueID: String)
+    func deleteCarbs(at uniqueID: String, fpuID: String, complex: Bool)
 }
 
 final class BaseCarbsStorage: CarbsStorage, Injectable {
@@ -71,7 +71,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 // New date for each carb equivalent
                 var useDate = entries.last?.createdAt ?? Date()
                 // Group and Identify all FPUs together
-                let fpuID = (entries.last?.collectionID ?? "") + ".fpu"
+                let fpuID = entries.last?.fpuID ?? ""
                 // Create an array of all future carb equivalents.
                 var futureCarbArray = [CarbsEntry]()
                 while carbEquivalents > 0, numberOfEquivalents > 0 {
@@ -81,7 +81,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                     } else { useDate = useDate.addingTimeInterval(interval.minutes.timeInterval) }
 
                     let eachCarbEntry = CarbsEntry(
-                        collectionID: fpuID, createdAt: useDate, carbs: equivalent, fat: 0, protein: 0, note: nil,
+                        id: UUID().uuidString, createdAt: useDate, carbs: equivalent, fat: 0, protein: 0, note: nil,
                         enteredBy: CarbsEntry.manual, isFPU: true,
                         fpuID: fpuID
                     )
@@ -100,10 +100,22 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 }
             } // ------------------------- END OF TPU ----------------------------------------
             // Store the actual (normal) carbs
-            if entries.last?.carbs ?? 0 > 0 {
+            if let entry = entries.last, entry.carbs > 0 {
                 // uniqEvents = []
+                let onlyCarbs = CarbsEntry(
+                    id: entry.id ?? "",
+                    createdAt: entry.createdAt,
+                    carbs: entry.carbs,
+                    fat: nil,
+                    protein: nil,
+                    note: entry.note ?? "",
+                    enteredBy: entry.enteredBy ?? "",
+                    isFPU: false,
+                    fpuID: ""
+                )
+
                 self.storage.transaction { storage in
-                    storage.append(entries, to: file, uniqBy: \.createdAt)
+                    storage.append(onlyCarbs, to: file, uniqBy: \.createdAt)
                     uniqEvents = storage.retrieve(file, as: [CarbsEntry].self)?
                         .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
                         .sorted { $0.createdAt > $1.createdAt } ?? []
@@ -143,17 +155,31 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
         storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self)?.reversed() ?? []
     }
 
-    func deleteCarbs(at uniqueID: String) {
+    func deleteCarbs(at uniqueID: String, fpuID: String, complex: Bool) {
         processQueue.sync {
             var allValues = storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self) ?? []
 
-            if allValues.firstIndex(where: { $0.collectionID == uniqueID }) == nil {
-                debug(.default, "Didn't find any carb entries to delete. ID to search for: " + uniqueID.description)
-            } else {
-                allValues.removeAll(where: { $0.collectionID == uniqueID })
-                storage.save(allValues, as: OpenAPS.Monitor.carbHistory)
-                broadcaster.notify(CarbsObserver.self, on: processQueue) {
-                    $0.carbsDidUpdate(allValues)
+            if fpuID != "" {
+                if allValues.firstIndex(where: { $0.fpuID == fpuID }) == nil {
+                    debug(.default, "Didn't find any carb equivalents to delete. ID to search for: " + fpuID.description)
+                } else {
+                    allValues.removeAll(where: { $0.fpuID == fpuID })
+                    storage.save(allValues, as: OpenAPS.Monitor.carbHistory)
+                    broadcaster.notify(CarbsObserver.self, on: processQueue) {
+                        $0.carbsDidUpdate(allValues)
+                    }
+                }
+            }
+
+            if fpuID == "" || complex {
+                if allValues.firstIndex(where: { $0.id == uniqueID }) == nil {
+                    debug(.default, "Didn't find any carb entries to delete. ID to search for: " + uniqueID.description)
+                } else {
+                    allValues.removeAll(where: { $0.id == uniqueID })
+                    storage.save(allValues, as: OpenAPS.Monitor.carbHistory)
+                    broadcaster.notify(CarbsObserver.self, on: processQueue) {
+                        $0.carbsDidUpdate(allValues)
+                    }
                 }
             }
         }
@@ -181,7 +207,8 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 foodType: $0.note,
                 targetTop: nil,
                 targetBottom: nil,
-                collectionID: $0.collectionID
+                id: $0.id,
+                fpuID: $0.fpuID
             )
         }
         return Array(Set(treatments).subtracting(Set(uploaded)))

+ 2 - 2
FreeAPS/Sources/Models/CarbsEntry.swift

@@ -1,7 +1,7 @@
 import Foundation
 
 struct CarbsEntry: JSON, Equatable, Hashable {
-    let collectionID: String?
+    let id: String?
     let createdAt: Date
     let carbs: Decimal
     let fat: Decimal?
@@ -25,7 +25,7 @@ struct CarbsEntry: JSON, Equatable, Hashable {
 
 extension CarbsEntry {
     private enum CodingKeys: String, CodingKey {
-        case collectionID = "_id"
+        case id = "_id"
         case createdAt = "created_at"
         case carbs
         case fat

+ 4 - 2
FreeAPS/Sources/Models/NightscoutTreatment.swift

@@ -21,7 +21,8 @@ struct NigtscoutTreatment: JSON, Hashable, Equatable {
     var glucoseType: String?
     var glucose: String?
     var units: String?
-    var collectionID: String?
+    var id: String?
+    var fpuID: String?
 
     static let local = "iAPS"
 
@@ -58,6 +59,7 @@ extension NigtscoutTreatment {
         case glucoseType
         case glucose
         case units
-        case collectionID
+        case id
+        case fpuID
     }
 }

+ 6 - 4
FreeAPS/Sources/Modules/AddCarbs/AddCarbsStateModel.swift

@@ -40,14 +40,14 @@ extension AddCarbs {
             id_ = UUID().uuidString
 
             let carbsToStore = [CarbsEntry(
-                collectionID: id_,
-                createdAt: date,
+                id: id_,
+                createdAt: Date.now,
                 carbs: carbs,
                 fat: fat,
                 protein: protein,
                 note: note,
                 enteredBy: CarbsEntry.manual,
-                isFPU: false, fpuID: nil
+                isFPU: false, fpuID: UUID().uuidString
             )]
             carbsStorage.storeCarbs(carbsToStore)
 
@@ -192,13 +192,15 @@ extension AddCarbs {
                 let save = Meals(context: coredataContext)
                 if let entry = stored.first {
                     save.createdAt = Date.now
-                    save.id = entry.collectionID ?? ""
+                    save.id = entry.id ?? ""
+                    save.fpuID = entry.fpuID ?? ""
                     save.carbs = Double(entry.carbs)
                     save.fat = Double(entry.fat ?? 0)
                     save.protein = Double(entry.protein ?? 0)
                     save.note = entry.note
                     try? coredataContext.save()
                 }
+                print("meals 1: ID: " + (save.id ?? "").description + " FPU ID: " + (save.fpuID ?? "").description)
             }
         }
     }

+ 23 - 14
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -271,25 +271,34 @@ extension Bolus {
             }
         }
 
-        func backToCarbsView(complexEntry: Bool, _ id: String, override: Bool) {
-            delete(deleteTwice: complexEntry, id: id)
+        func backToCarbsView(complexEntry: Bool, _ meal: FetchedResults<Meals>, override: Bool) {
+            delete(deleteTwice: complexEntry, meal: meal)
             showModal(for: .addCarbs(editMode: complexEntry, override: override))
         }
 
-        func delete(deleteTwice: Bool, id: String) {
+        func delete(deleteTwice: Bool, meal: FetchedResults<Meals>) {
+            guard let meals = meal.first else {
+                return
+            }
+
+            let mealArray = DataTable.Treatment(
+                units: units,
+                type: .carbs,
+                date: meals.createdAt ?? Date(),
+                id: meals.id ?? "",
+                isFPU: deleteTwice ? true : false,
+                fpuID: deleteTwice ? (meals.fpuID ?? "") : ""
+            )
+
+            print(
+                "meals 2: ID: " + (mealArray.id ?? "").description + " FPU ID: " + (mealArray.fpuID ?? "")
+                    .description
+            )
+
             if deleteTwice {
-                // DispatchQueue.safeMainSync {
-                nsManager.deleteCarbs(
-                    at: id, isFPU: nil, fpuID: nil, syncID: id
-                )
-                nsManager.deleteCarbs(
-                    at: id + ".fpu", isFPU: nil, fpuID: nil, syncID: id
-                )
-                // }
+                nsManager.deleteCarbs(mealArray, complexMeal: true)
             } else {
-                nsManager.deleteCarbs(
-                    at: id, isFPU: nil, fpuID: nil, syncID: id
-                )
+                nsManager.deleteCarbs(mealArray, complexMeal: false)
             }
         }
     }

+ 4 - 5
FreeAPS/Sources/Modules/Bolus/View/AlternativeBolusCalcRootView.swift

@@ -205,9 +205,9 @@ extension Bolus {
             }
             .onDisappear {
                 if fetch, hasFatOrProtein, !keepForNextWiew, state.useCalc {
-                    state.delete(deleteTwice: true, id: meal.first?.id ?? "")
+                    state.delete(deleteTwice: true, meal: meal)
                 } else if fetch, !keepForNextWiew, state.useCalc {
-                    state.delete(deleteTwice: false, id: meal.first?.id ?? "")
+                    state.delete(deleteTwice: false, meal: meal)
                 }
             }
             .popup(isPresented: showInfo) {
@@ -300,12 +300,11 @@ extension Bolus {
         }
 
         func carbsView() {
-            let id_ = meal.first?.id ?? ""
             if fetch {
                 keepForNextWiew = true
-                state.backToCarbsView(complexEntry: fetch, id_, override: false)
+                state.backToCarbsView(complexEntry: true, meal, override: false)
             } else {
-                state.backToCarbsView(complexEntry: false, id_, override: true)
+                state.backToCarbsView(complexEntry: false, meal, override: true)
             }
         }
 

+ 4 - 5
FreeAPS/Sources/Modules/Bolus/View/DefaultBolusCalcRootView.swift

@@ -143,9 +143,9 @@ extension Bolus {
 
             .onDisappear {
                 if fetch, hasFatOrProtein, !keepForNextWiew, !state.useCalc {
-                    state.delete(deleteTwice: true, id: meal.first?.id ?? "")
+                    state.delete(deleteTwice: true, meal: meal)
                 } else if fetch, !keepForNextWiew, !state.useCalc {
-                    state.delete(deleteTwice: false, id: meal.first?.id ?? "")
+                    state.delete(deleteTwice: false, meal: meal)
                 }
             }
 
@@ -191,12 +191,11 @@ extension Bolus {
         }
 
         func carbsView() {
-            let id_ = meal.first?.id ?? ""
             if fetch {
                 keepForNextWiew = true
-                state.backToCarbsView(complexEntry: fetch, id_, override: false)
+                state.backToCarbsView(complexEntry: fetch, meal, override: false)
             } else {
-                state.backToCarbsView(complexEntry: false, id_, override: true)
+                state.backToCarbsView(complexEntry: false, meal, override: true)
             }
         }
 

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

@@ -32,12 +32,7 @@ extension DataTable {
         }
 
         func deleteCarbs(_ treatement: Treatment) {
-            nightscoutManager.deleteCarbs(
-                at: treatement.id,
-                isFPU: treatement.isFPU,
-                fpuID: treatement.fpuID,
-                syncID: treatement.id
-            )
+            nightscoutManager.deleteCarbs(treatement, complexMeal: false)
         }
 
         func deleteInsulin(_ treatement: Treatment) {

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

@@ -40,13 +40,14 @@ extension DataTable {
                 let carbs = self.provider.carbs()
                     .filter { !($0.isFPU ?? false) }
                     .map {
-                        if let id = $0.collectionID {
+                        if let id = $0.id {
                             return Treatment(
                                 units: units,
                                 type: .carbs,
                                 date: $0.createdAt,
                                 amount: $0.carbs,
                                 id: id,
+                                fpuID: $0.fpuID,
                                 note: $0.note
                             )
                         } else {
@@ -62,7 +63,7 @@ extension DataTable {
                             type: .fpus,
                             date: $0.createdAt,
                             amount: $0.carbs,
-                            id: $0.collectionID,
+                            id: $0.id,
                             isFPU: $0.isFPU,
                             fpuID: $0.fpuID,
                             note: $0.note

+ 4 - 0
FreeAPS/Sources/Modules/Home/HomeProvider.swift

@@ -19,6 +19,10 @@ extension Home {
             storage.retrieve(OpenAPS.Enact.enacted, as: Suggestion.self)
         }
 
+        func pumpTimeZone() -> TimeZone? {
+            apsManager.pumpManager?.status.timeZone
+        }
+
         func heartbeatNow() {
             apsManager.heartbeat(date: Date())
         }

+ 12 - 1
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -60,6 +60,7 @@ extension Home {
         @Published var displayXgridLines: Bool = false
         @Published var displayYgridLines: Bool = false
         @Published var thresholdLines: Bool = false
+        @Published var timeZone: TimeZone?
 
         enum Scale: Int, CaseIterable, Identifiable {
             case one = 1
@@ -90,6 +91,7 @@ extension Home {
             setupBattery()
             setupReservoir()
             setupAnnouncements()
+            setupCurrentPumpTimezone()
 
             suggestion = provider.suggestion
             uploadStats = settingsManager.settings.uploadStats
@@ -390,6 +392,10 @@ extension Home {
             tempTarget = provider.tempTarget()
         }
 
+        private func setupCurrentPumpTimezone() {
+            timeZone = provider.pumpTimeZone()
+        }
+
         func openCGM() {
             guard var url = nightscoutManager.cgmURL else { return }
 
@@ -427,7 +433,8 @@ extension Home.StateModel:
     CarbsObserver,
     EnactedSuggestionObserver,
     PumpBatteryObserver,
-    PumpReservoirObserver
+    PumpReservoirObserver,
+    PumpTimeZoneObserver
 {
     func glucoseDidUpdate(_: [BloodGlucose]) {
         setupGlucose()
@@ -493,6 +500,10 @@ extension Home.StateModel:
     func pumpReservoirDidChange(_: Decimal) {
         setupReservoir()
     }
+
+    func pumpTimeZoneDidChange(_: TimeZone) {
+        setupCurrentPumpTimezone()
+    }
 }
 
 extension Home.StateModel: CompletionDelegate {

+ 32 - 33
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, isFPU: Bool?, fpuID: String?)
+    func deleteCarbs(syncID: String, fpuID: String)
     /// delete insulin with syncID
     func deleteInsulin(syncID: String)
 }
@@ -46,7 +46,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
         static let healthInsulinObject = HKObjectType.quantityType(forIdentifier: .insulinDelivery)
 
         // Meta-data key of FreeASPX data in HealthStore
-        static let freeAPSMetaKey = "fromFreeAPSX"
+        static let freeAPSMetaKey = "From iAPS"
     }
 
     @Injected() private var glucoseStorage: GlucoseStorage!
@@ -186,7 +186,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
         else { return }
 
         let carbsWithId = carbs.filter { c in
-            guard c.collectionID != nil else { return false }
+            guard c.id != nil else { return false }
             return true
         }
 
@@ -194,7 +194,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             let sampleIDs = samples.compactMap(\.syncIdentifier)
             let sampleDates = samples.map(\.startDate)
             let samplesToSave = carbsWithId
-                .filter { !sampleIDs.contains($0.collectionID!) } // id existing in AH
+                .filter { !sampleIDs.contains($0.id ?? "") } // id existing in AH
                 .filter { !sampleDates.contains($0.createdAt) } // not id but exaclty the same datetime
                 .map {
                     HKQuantitySample(
@@ -203,8 +203,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
                         start: $0.createdAt,
                         end: $0.createdAt,
                         metadata: [
-                            HKMetadataKeyExternalUUID: $0.collectionID ?? "_id",
-                            HKMetadataKeySyncIdentifier: $0.collectionID ?? "_id",
+                            HKMetadataKeySyncIdentifier: $0.id ?? "_id",
                             HKMetadataKeySyncVersion: 1,
                             Config.freeAPSMetaKey: true
                         ]
@@ -568,41 +567,41 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
 
     // - MARK Carbs function
 
-    func deleteCarbs(syncID: String, isFPU: Bool?, fpuID: String?) {
+    func deleteCarbs(syncID: String, fpuID: String) {
         guard settingsManager.settings.useAppleHealth,
               let sampleType = Config.healthCarbObject,
               checkAvailabilitySave(objectTypeToHealthStore: sampleType)
         else { return }
 
-        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 }
+        print("meals 4: ID: " + syncID + " FPU ID: " + fpuID)
 
-            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
-                )
+        if syncID != "" {
+            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 fpuID: \(fpuID)", error: error)
-                }
+            healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
+                guard let error = error else { return }
+                warning(.service, "Cannot delete sample with syncID: \(syncID)", error: error)
+            }
+        }
+
+        if fpuID != "" {
+            // processQueue.async {
+            let recentCarbs: [CarbsEntry] = carbsStorage.recent()
+            let ids = recentCarbs.filter { $0.fpuID == fpuID }.compactMap(\.id)
+            let predicate = HKQuery.predicateForObjects(
+                withMetadataKey: HKMetadataKeySyncIdentifier,
+                allowedValues: ids
+            )
+            print("found IDs: " + ids.description)
+            healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
+                guard let error = error else { return }
+                warning(.service, "Cannot delete sample with fpuID: \(fpuID)", error: error)
             }
+            // }
         }
     }
 

+ 10 - 3
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -141,18 +141,25 @@ extension NightscoutAPI {
             .eraseToAnyPublisher()
     }
 
-    func deleteCarbs(at uniqueID: String) -> AnyPublisher<Void, Swift.Error> {
+    func deleteCarbs(_ treatement: DataTable.Treatment) -> AnyPublisher<Void, Swift.Error> {
         var components = URLComponents()
         components.scheme = url.scheme
         components.host = url.host
         components.port = url.port
         components.path = Config.treatmentsPath
+
+        var arguments = "find[_id][$eq]"
+        if treatement.isFPU ?? false {
+            arguments = "find[fpuID][$eq]"
+        }
+        let value = !(treatement.isFPU ?? false) ? treatement.id : (treatement.fpuID ?? "")
+
         components.queryItems = [
             // Removed below because it prevented all futire entries to be deleted. Don't know why?
             /* URLQueryItem(name: "find[carbs][$exists]", value: "true"), */
             URLQueryItem(
-                name: "find[collectionID][$eq]",
-                value: uniqueID
+                name: arguments,
+                value: value
             )
         ]
 

+ 89 - 23
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 uniqueID: String, isFPU: Bool?, fpuID: String?, syncID: String)
+    func deleteCarbs(_ treatement: DataTable.Treatment, complexMeal: Bool)
     func deleteInsulin(at date: Date)
     func deleteManualGlucose(at: Date)
     func uploadStatus()
@@ -177,32 +177,98 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
             .eraseToAnyPublisher()
     }
 
-    func deleteCarbs(at uniqueID: String, isFPU: Bool?, fpuID: String?, syncID: String) {
-        // remove in AH
-        healthkitManager.deleteCarbs(syncID: syncID, isFPU: isFPU, fpuID: fpuID)
-
+    func deleteCarbs(_ treatement: DataTable.Treatment, complexMeal: Bool) {
         guard let nightscout = nightscoutAPI, isUploadEnabled else {
-            carbsStorage.deleteCarbs(at: uniqueID)
+            carbsStorage.deleteCarbs(at: treatement.id, fpuID: treatement.fpuID ?? "", complex: complexMeal)
             return
         }
 
-        nightscout.deleteCarbs(at: uniqueID)
-            .collect()
-            .sink { completion in
-                self.carbsStorage.deleteCarbs(at: uniqueID)
-                switch completion {
-                case .finished:
-                    debug(.nightscout, "Carbs deleted")
-                case let .failure(error):
-                    info(
-                        .nightscout,
-                        "Deletion of carbs in NightScout not done \n \(error.localizedDescription)",
-                        type: MessageType.warning
-                    )
-                }
-            } receiveValue: { _ in }
-            .store(in: &lifetime)
-        // }
+        print("meals 3: ID: " + (treatement.id ?? "").description + " FPU ID: " + (treatement.fpuID ?? "").description)
+
+        var arg1 = ""
+        var arg2 = ""
+        if complexMeal {
+            arg1 = treatement.id ?? ""
+            arg2 = treatement.fpuID ?? ""
+        } else if treatement.isFPU ?? false {
+            arg1 = ""
+            arg2 = treatement.fpuID ?? ""
+        } else {
+            arg1 = treatement.id
+            arg2 = ""
+        }
+        healthkitManager.deleteCarbs(syncID: arg1, fpuID: arg2)
+
+        if complexMeal {
+            nightscout.deleteCarbs(treatement)
+                .collect()
+                .sink { completion in
+                    self.carbsStorage.deleteCarbs(at: treatement.id ?? "", fpuID: treatement.fpuID ?? "", complex: true)
+                    switch completion {
+                    case .finished:
+                        debug(.nightscout, "Carbs deleted")
+                    case let .failure(error):
+                        info(
+                            .nightscout,
+                            "Deletion of carbs in NightScout not done \n \(error.localizedDescription)",
+                            type: MessageType.warning
+                        )
+                    }
+                } receiveValue: { _ in }
+                .store(in: &lifetime)
+
+            if (treatement.fpuID ?? "") != "" {
+                nightscout.deleteCarbs(treatement)
+                    .collect()
+                    .sink { completion in
+                        switch completion {
+                        case .finished:
+                            debug(.nightscout, "Carb equivalents deleted from NS")
+                        case let .failure(error):
+                            info(
+                                .nightscout,
+                                "Deletion of carb equivalents in NightScout not done \n \(error.localizedDescription)",
+                                type: MessageType.warning
+                            )
+                        }
+                    } receiveValue: { _ in }
+                    .store(in: &lifetime)
+            }
+        } else if treatement.isFPU ?? false {
+            nightscout.deleteCarbs(treatement)
+                .collect()
+                .sink { completion in
+                    self.carbsStorage.deleteCarbs(at: "", fpuID: treatement.fpuID ?? "", complex: false)
+                    switch completion {
+                    case .finished:
+                        debug(.nightscout, "Carb equivalents deleted")
+                    case let .failure(error):
+                        info(
+                            .nightscout,
+                            "Deletion of carb equivalents in NightScout not done \n \(error.localizedDescription)",
+                            type: MessageType.warning
+                        )
+                    }
+                } receiveValue: { _ in }
+                .store(in: &lifetime)
+        } else {
+            nightscout.deleteCarbs(treatement)
+                .collect()
+                .sink { completion in
+                    self.carbsStorage.deleteCarbs(at: treatement.id, fpuID: "", complex: false)
+                    switch completion {
+                    case .finished:
+                        debug(.nightscout, "Carbs deleted")
+                    case let .failure(error):
+                        info(
+                            .nightscout,
+                            "Deletion of carbs in NightScout not done \n \(error.localizedDescription)",
+                            type: MessageType.warning
+                        )
+                    }
+                } receiveValue: { _ in }
+                .store(in: &lifetime)
+        }
     }
 
     func deleteInsulin(at date: Date) {

+ 1 - 1
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -330,7 +330,7 @@ extension BaseWatchManager: WCSessionDelegate {
         {
             carbsStorage.storeCarbs(
                 [CarbsEntry(
-                    collectionID: UUID().uuidString,
+                    id: UUID().uuidString,
                     createdAt: Date(),
                     carbs: Decimal(carbs),
                     fat: Decimal(fat),

+ 1 - 1
FreeAPS/Sources/Shortcuts/Carbs/CarbPresetIntentRequest.swift

@@ -11,7 +11,7 @@ import Foundation
 
         carbsStorage.storeCarbs(
             [CarbsEntry(
-                collectionID: UUID().uuidString,
+                id: UUID().uuidString,
                 createdAt: dateAdded,
                 carbs: carbs,
                 fat: Decimal(quantityFat),