Преглед изворни кода

Refactor deletion handling + some cleanup/fixes

Deniz Cengiz пре 1 година
родитељ
комит
2692bca703

+ 4 - 3
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -169,7 +169,8 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 fat: 0,
                 fat: 0,
                 protein: 0,
                 protein: 0,
                 note: nil,
                 note: nil,
-                enteredBy: CarbsEntry.manual, isFPU: true,
+                enteredBy: CarbsEntry.manual,
+                isFPU: true,
                 fpuID: fpuID
                 fpuID: fpuID
             )
             )
             futureCarbArray.append(eachCarbEntry)
             futureCarbArray.append(eachCarbEntry)
@@ -442,7 +443,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                     fat: Decimal(result.fat),
                     fat: Decimal(result.fat),
                     protein: Decimal(result.protein),
                     protein: Decimal(result.protein),
                     note: result.note,
                     note: result.note,
-                    enteredBy: "Trio",
+                    enteredBy: CarbsEntry.manual,
                     isFPU: result.isFPU,
                     isFPU: result.isFPU,
                     fpuID: result.fpuID?.uuidString
                     fpuID: result.fpuID?.uuidString
                 )
                 )
@@ -473,7 +474,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                     fat: Decimal(result.fat),
                     fat: Decimal(result.fat),
                     protein: Decimal(result.protein),
                     protein: Decimal(result.protein),
                     note: result.note,
                     note: result.note,
-                    enteredBy: "Trio",
+                    enteredBy: CarbsEntry.manual,
                     isFPU: result.isFPU,
                     isFPU: result.isFPU,
                     fpuID: result.fpuID?.uuidString
                     fpuID: result.fpuID?.uuidString
                 )
                 )

+ 1 - 1
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -294,7 +294,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
                     rate: nil,
                     rate: nil,
                     eventType: .capillaryGlucose,
                     eventType: .capillaryGlucose,
                     createdAt: result.date,
                     createdAt: result.date,
-                    enteredBy: "Trio",
+                    enteredBy: CarbsEntry.manual,
                     bolus: nil,
                     bolus: nil,
                     insulin: nil,
                     insulin: nil,
                     notes: "Trio User",
                     notes: "Trio User",

+ 3 - 1
FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift

@@ -495,7 +495,9 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
                         id: event.id ?? UUID().uuidString,
                         id: event.id ?? UUID().uuidString,
                         type: .bolus,
                         type: .bolus,
                         timestamp: event.timestamp ?? Date(),
                         timestamp: event.timestamp ?? Date(),
-                        amount: event.bolus?.amount as Decimal?
+                        amount: event.bolus?.amount as Decimal?,
+                        isSMB: event.bolus?.isSMB ?? true,
+                        isExternal: event.bolus?.isExternal ?? false
                     )
                     )
                 case PumpEvent.tempBasal.rawValue:
                 case PumpEvent.tempBasal.rawValue:
                     return PumpHistoryEvent(
                     return PumpHistoryEvent(

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

@@ -49,7 +49,7 @@ extension CarbsEntry {
             grams: Double(carbs),
             grams: Double(carbs),
             startDate: createdAt,
             startDate: createdAt,
             uuid: UUID(uuidString: id!),
             uuid: UUID(uuidString: id!),
-            provenanceIdentifier: enteredBy ?? "",
+            provenanceIdentifier: enteredBy ?? "Trio",
             syncIdentifier: id,
             syncIdentifier: id,
             syncVersion: nil,
             syncVersion: nil,
             userCreatedDate: nil,
             userCreatedDate: nil,

+ 8 - 0
FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift

@@ -55,5 +55,13 @@ extension DataTable {
                 await self.healthkitManager.deleteMealData(byID: id, sampleType: sampleType)
                 await self.healthkitManager.deleteMealData(byID: id, sampleType: sampleType)
             }
             }
         }
         }
+
+        func deleteInsulinFromTidepool(withSyncId id: String, amount: Decimal, at: Date) {
+            tidepoolManager.deleteInsulin(withSyncId: id, amount: amount, at: at)
+        }
+
+        func deleteCarbsFromTidepool(withSyncId id: UUID, carbs: Decimal, at: Date, enteredBy: String) {
+            tidepoolManager.deleteCarbs(withSyncId: id, carbs: carbs, at: at, enteredBy: enteredBy)
+        }
     }
     }
 }
 }

+ 14 - 4
FreeAPS/Sources/Modules/DataTable/DataTableStateModel.swift

@@ -145,13 +145,20 @@ extension DataTable {
                         }
                         }
                     } else {
                     } else {
                         // Delete carbs from Nightscout
                         // Delete carbs from Nightscout
-                        if let id = carbEntry.id?.uuidString {
-                            self.provider.deleteCarbsFromNightscout(withID: id)
+                        if let id = carbEntry.id, let entryDate = carbEntry.date {
+                            self.provider.deleteCarbsFromNightscout(withID: id.uuidString)
 
 
                             // Delete carbs from Apple Health
                             // Delete carbs from Apple Health
                             if let sampleType = AppleHealthConfig.healthCarbObject {
                             if let sampleType = AppleHealthConfig.healthCarbObject {
-                                self.provider.deleteMealDataFromHealth(byID: id, sampleType: sampleType)
+                                self.provider.deleteMealDataFromHealth(byID: id.uuidString, sampleType: sampleType)
                             }
                             }
+
+                            self.provider.deleteCarbsFromTidepool(
+                                withSyncId: id,
+                                carbs: Decimal(carbEntry.carbs),
+                                at: entryDate,
+                                enteredBy: CarbsEntry.manual
+                            )
                         }
                         }
                     }
                     }
 
 
@@ -214,9 +221,12 @@ extension DataTable {
                     }
                     }
 
 
                     // Delete Insulin from Nightscout and Apple Health
                     // Delete Insulin from Nightscout and Apple Health
-                    if let id = treatmentToDelete.id {
+                    if let id = treatmentToDelete.id, let timestamp = treatmentToDelete.timestamp,
+                       let bolus = treatmentToDelete.bolus, let bolusAmount = bolus.amount
+                    {
                         self.provider.deleteInsulinFromNightscout(withID: id)
                         self.provider.deleteInsulinFromNightscout(withID: id)
                         self.provider.deleteInsulinFromHealth(withSyncID: id)
                         self.provider.deleteInsulinFromHealth(withSyncID: id)
+                        self.provider.deleteInsulinFromTidepool(withSyncId: id, amount: bolusAmount as Decimal, at: timestamp)
                     }
                     }
 
 
                     taskContext.delete(treatmentToDelete)
                     taskContext.delete(treatmentToDelete)

+ 36 - 39
FreeAPS/Sources/Services/Network/TidepoolManager.swift

@@ -11,9 +11,9 @@ protocol TidepoolManager {
     func getTidepoolServiceUI() -> ServiceUI?
     func getTidepoolServiceUI() -> ServiceUI?
     func getTidepoolPluginHost() -> PluginHost?
     func getTidepoolPluginHost() -> PluginHost?
     func uploadCarbs() async
     func uploadCarbs() async
-    func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID: String)
+    func deleteCarbs(withSyncId id: UUID, carbs: Decimal, at: Date, enteredBy: String)
     func uploadInsulin() async
     func uploadInsulin() async
-    func deleteInsulin(at date: Date)
+    func deleteInsulin(withSyncId id: String, amount: Decimal, at: Date)
     func uploadGlucose(device: HKDevice?) async
     func uploadGlucose(device: HKDevice?) async
     func forceTidepoolDataUpload(device: HKDevice?)
     func forceTidepoolDataUpload(device: HKDevice?)
 }
 }
@@ -128,7 +128,7 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
                     case let .failure(error):
                     case let .failure(error):
                         debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))")
                         debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))")
                     case .success:
                     case .success:
-                        debug(.nightscout, "Success synchronizing carbs data:")
+                        debug(.nightscout, "Success synchronizing carbs data")
                         // After successful upload, update the isUploadedToTidepool flag in Core Data
                         // After successful upload, update the isUploadedToTidepool flag in Core Data
                         Task {
                         Task {
                             await self.updateCarbsAsUploaded(carbs)
                             await self.updateCarbsAsUploaded(carbs)
@@ -161,30 +161,34 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
         }
         }
     }
     }
 
 
-    func deleteCarbs(at date: Date, isFPU: Bool?, fpuID: String?, syncID _: String) {
+    func deleteCarbs(withSyncId id: UUID, carbs: Decimal, at: Date, enteredBy: String) {
         guard let tidepoolService = self.tidepoolService else { return }
         guard let tidepoolService = self.tidepoolService else { return }
 
 
         processQueue.async {
         processQueue.async {
-            var carbsToDelete: [CarbsEntry] = []
-            let allValues = self.storage.retrieve(OpenAPS.Monitor.carbHistory, as: [CarbsEntry].self) ?? []
-
-            if let isFPU = isFPU, isFPU {
-                guard let fpuID = fpuID else { return }
-                carbsToDelete = allValues.filter { $0.fpuID == fpuID }.removeDublicates()
-            } else {
-                carbsToDelete = allValues.filter { $0.createdAt == date }.removeDublicates()
-            }
-
-            let syncCarb = carbsToDelete.map { d in
-                d.convertSyncCarb(operation: .delete)
-            }
+            let syncCarb: [SyncCarbObject] = [SyncCarbObject(
+                absorptionTime: nil,
+                createdByCurrentApp: true,
+                foodType: nil,
+                grams: Double(carbs),
+                startDate: at,
+                uuid: id,
+                provenanceIdentifier: enteredBy,
+                syncIdentifier: id.uuidString,
+                syncVersion: nil,
+                userCreatedDate: nil,
+                userUpdatedDate: nil,
+                userDeletedDate: nil,
+                operation: LoopKit.Operation.delete,
+                addedDate: nil,
+                supercededDate: nil
+            )]
 
 
             tidepoolService.uploadCarbData(created: [], updated: [], deleted: syncCarb) { result in
             tidepoolService.uploadCarbData(created: [], updated: [], deleted: syncCarb) { result in
                 switch result {
                 switch result {
                 case let .failure(error):
                 case let .failure(error):
                     debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))")
                     debug(.nightscout, "Error synchronizing carbs data: \(String(describing: error))")
                 case .success:
                 case .success:
-                    debug(.nightscout, "Success synchronizing carbs data:")
+                    debug(.nightscout, "Success synchronizing carbs data.")
                 }
                 }
             }
             }
         }
         }
@@ -317,7 +321,7 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
                 case let .failure(error):
                 case let .failure(error):
                     debug(.nightscout, "Error synchronizing Dose data: \(String(describing: error))")
                     debug(.nightscout, "Error synchronizing Dose data: \(String(describing: error))")
                 case .success:
                 case .success:
-                    debug(.nightscout, "Success synchronizing Dose data:")
+                    debug(.nightscout, "Success synchronizing Dose data")
                     // After successful upload, update the isUploadedToTidepool flag in Core Data
                     // After successful upload, update the isUploadedToTidepool flag in Core Data
                     Task {
                     Task {
                         let insulinEvents = events
                         let insulinEvents = events
@@ -334,7 +338,7 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
                 case let .failure(error):
                 case let .failure(error):
                     debug(.nightscout, "Error synchronizing Pump Event data: \(String(describing: error))")
                     debug(.nightscout, "Error synchronizing Pump Event data: \(String(describing: error))")
                 case .success:
                 case .success:
-                    debug(.nightscout, "Success synchronizing Pump Event data:")
+                    debug(.nightscout, "Success synchronizing Pump Event data")
                     // After successful upload, update the isUploadedToTidepool flag in Core Data
                     // After successful upload, update the isUploadedToTidepool flag in Core Data
                     Task {
                     Task {
                         let pumpEventType = events.map({ $0.type.mapEventTypeToPumpEventType()
                         let pumpEventType = events.map({ $0.type.mapEventTypeToPumpEventType()
@@ -370,24 +374,17 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
         }
         }
     }
     }
 
 
-    func deleteInsulin(at d: Date) {
-        let allValues = storage.retrieve(OpenAPS.Monitor.pumpHistory, as: [PumpHistoryEvent].self) ?? []
-
-        guard !allValues.isEmpty, let tidepoolService = self.tidepoolService else { return }
-
-        var doseDataToDelete: [DoseEntry] = []
+    func deleteInsulin(withSyncId id: String, amount: Decimal, at: Date) {
+        guard let tidepoolService = self.tidepoolService else { return }
 
 
-        guard let entry = allValues.first(where: { $0.timestamp == d }) else {
-            return
-        }
-        doseDataToDelete
-            .append(DoseEntry(
-                type: .bolus,
-                startDate: entry.timestamp,
-                value: Double(entry.amount!),
-                unit: .units,
-                syncIdentifier: entry.id
-            ))
+        // must be an array here, because `tidepoolService.uploadDoseData` expects a `deleted` array
+        let doseDataToDelete: [DoseEntry] = [DoseEntry(
+            type: .bolus,
+            startDate: at,
+            value: Double(amount),
+            unit: .units,
+            syncIdentifier: id
+        )]
 
 
         processQueue.async {
         processQueue.async {
             tidepoolService.uploadDoseData(created: [], deleted: doseDataToDelete) { result in
             tidepoolService.uploadDoseData(created: [], deleted: doseDataToDelete) { result in
@@ -395,7 +392,7 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
                 case let .failure(error):
                 case let .failure(error):
                     debug(.nightscout, "Error synchronizing Dose delete data: \(String(describing: error))")
                     debug(.nightscout, "Error synchronizing Dose delete data: \(String(describing: error))")
                 case .success:
                 case .success:
-                    debug(.nightscout, "Success synchronizing Dose delete data:")
+                    debug(.nightscout, "Success synchronizing Dose delete data")
                 }
                 }
             }
             }
         }
         }
@@ -419,7 +416,7 @@ final class BaseTidepoolManager: TidepoolManager, Injectable, CarbsStoredDelegat
                 tidepoolService.uploadGlucoseData(chunkStoreGlucose) { result in
                 tidepoolService.uploadGlucoseData(chunkStoreGlucose) { result in
                     switch result {
                     switch result {
                     case .success:
                     case .success:
-                        debug(.nightscout, "Success synchronizing glucose data:")
+                        debug(.nightscout, "Success synchronizing glucose data")
                         // After successful upload, update the isUploadedToTidepool flag in Core Data
                         // After successful upload, update the isUploadedToTidepool flag in Core Data
                         Task {
                         Task {
                             await self.updateGlucoseAsUploaded(glucose)
                             await self.updateGlucoseAsUploaded(glucose)

+ 1 - 1
Model/Helper/CarbEntryStored+helper.swift

@@ -89,7 +89,7 @@ extension CarbEntryStored: Encodable {
         try container.encode(formattedDate, forKey: .created_at)
         try container.encode(formattedDate, forKey: .created_at)
 
 
         // TODO: handle this conditionally; pass in the enteredBy string (manual entry or via NS or Apple Health)
         // TODO: handle this conditionally; pass in the enteredBy string (manual entry or via NS or Apple Health)
-        try container.encode("Open-iAPS", forKey: .enteredBy)
+        try container.encode("Trio", forKey: .enteredBy)
 
 
         try container.encode(carbs, forKey: .carbs)
         try container.encode(carbs, forKey: .carbs)
         try container.encode(fat, forKey: .fat)
         try container.encode(fat, forKey: .fat)