Browse Source

Allow future and past dates for meals (#361)

Now saves both real dates of meals and the date of creation. 
Health store issue is only partly fixed. Will continue with this later.
Jon B Mårtensson 2 năm trước cách đây
mục cha
commit
2dbf718e85

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

@@ -66,6 +66,7 @@
         <attribute name="start" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
     </entity>
     <entity name="Meals" representedClassName="Meals" syncable="YES" codeGenerationType="class">
+        <attribute name="actualDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
         <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"/>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
FreeAPS/Resources/javascript/bundle/meal.js


+ 8 - 6
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -69,7 +69,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 // Only use delay in first loop
                 var firstIndex = true
                 // New date for each carb equivalent
-                var useDate = entries.last?.createdAt ?? Date()
+                var useDate = entries.last?.actualDate ?? Date()
                 // Group and Identify all FPUs together
                 let fpuID = entries.last?.fpuID ?? ""
                 // Create an array of all future carb equivalents.
@@ -81,7 +81,8 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                     } else { useDate = useDate.addingTimeInterval(interval.minutes.timeInterval) }
 
                     let eachCarbEntry = CarbsEntry(
-                        id: UUID().uuidString, createdAt: useDate, carbs: equivalent, fat: 0, protein: 0, note: nil,
+                        id: UUID().uuidString, createdAt: entries.last?.createdAt ?? Date(), actualDate: useDate,
+                        carbs: equivalent, fat: 0, protein: 0, note: nil,
                         enteredBy: CarbsEntry.manual, isFPU: true,
                         fpuID: fpuID
                     )
@@ -91,7 +92,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 // Save the array
                 if carbEquivalents > 0 {
                     self.storage.transaction { storage in
-                        storage.append(futureCarbArray, to: file, uniqBy: \.createdAt)
+                        storage.append(futureCarbArray, to: file, uniqBy: \.id)
                         uniqEvents = storage.retrieve(file, as: [CarbsEntry].self)?
                             .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
                             .sorted { $0.createdAt > $1.createdAt } ?? []
@@ -105,6 +106,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 let onlyCarbs = CarbsEntry(
                     id: entry.id ?? "",
                     createdAt: entry.createdAt,
+                    actualDate: entry.actualDate ?? entry.createdAt,
                     carbs: entry.carbs,
                     fat: nil,
                     protein: nil,
@@ -115,7 +117,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 )
 
                 self.storage.transaction { storage in
-                    storage.append(onlyCarbs, to: file, uniqBy: \.createdAt)
+                    storage.append(onlyCarbs, to: file, uniqBy: \.id)
                     uniqEvents = storage.retrieve(file, as: [CarbsEntry].self)?
                         .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
                         .sorted { $0.createdAt > $1.createdAt } ?? []
@@ -129,7 +131,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
             var carbDate = Date()
             if entries.isNotEmpty {
                 cbs = entries[0].carbs
-                carbDate = entries[0].createdAt
+                carbDate = entries[0].actualDate ?? entries[0].createdAt
             }
             if cbs != 0 {
                 self.coredataContext.perform {
@@ -197,7 +199,7 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
                 absolute: nil,
                 rate: nil,
                 eventType: .nsCarbCorrection,
-                createdAt: $0.createdAt,
+                createdAt: $0.actualDate ?? $0.createdAt,
                 enteredBy: CarbsEntry.manual,
                 bolus: nil,
                 insulin: nil,

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

@@ -3,6 +3,7 @@ import Foundation
 struct CarbsEntry: JSON, Equatable, Hashable {
     let id: String?
     let createdAt: Date
+    let actualDate: Date?
     let carbs: Decimal
     let fat: Decimal?
     let protein: Decimal?
@@ -27,6 +28,7 @@ extension CarbsEntry {
     private enum CodingKeys: String, CodingKey {
         case id = "_id"
         case createdAt = "created_at"
+        case actualDate
         case carbs
         case fat
         case protein

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

@@ -22,6 +22,8 @@ extension AddCarbs {
         @Published var summary: String = ""
         @Published var skipBolus: Bool = false
 
+        let now = Date.now
+
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
 
         override func subscribe() {
@@ -41,7 +43,8 @@ extension AddCarbs {
 
             let carbsToStore = [CarbsEntry(
                 id: id_,
-                createdAt: Date.now,
+                createdAt: now,
+                actualDate: date,
                 carbs: carbs,
                 fat: fat,
                 protein: protein,
@@ -191,7 +194,8 @@ extension AddCarbs {
             coredataContext.performAndWait {
                 let save = Meals(context: coredataContext)
                 if let entry = stored.first {
-                    save.createdAt = Date.now
+                    save.createdAt = now
+                    save.actualDate = entry.actualDate ?? Date.now
                     save.id = entry.id ?? ""
                     save.fpuID = entry.fpuID ?? ""
                     save.carbs = Double(entry.carbs)

+ 2 - 5
FreeAPS/Sources/Modules/AddCarbs/View/AddCarbsRootView.swift

@@ -82,19 +82,16 @@ extension AddCarbs {
                                 pushed = true
                             } label: { Text("Now") }.buttonStyle(.borderless).foregroundColor(.secondary).padding(.trailing, 5)
                         } else {
-                            Button { state.date = state.date.addingTimeInterval(-10.minutes.timeInterval) }
+                            Button { state.date = state.date.addingTimeInterval(-15.minutes.timeInterval) }
                             label: { Image(systemName: "minus.circle") }.tint(.blue).buttonStyle(.borderless)
                             DatePicker(
                                 "Time",
                                 selection: $state.date,
-                                in: ...now,
                                 displayedComponents: [.hourAndMinute]
                             ).controlSize(.mini)
                                 .labelsHidden()
                             Button {
-                                if state.date.addingTimeInterval(5.minutes.timeInterval) < now {
-                                    state.date = state.date.addingTimeInterval(10.minutes.timeInterval)
-                                }
+                                state.date = state.date.addingTimeInterval(15.minutes.timeInterval)
                             }
                             label: { Image(systemName: "plus.circle") }.tint(.blue).buttonStyle(.borderless)
                         }

+ 10 - 2
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -233,17 +233,25 @@ extension Bolus {
                 return
             }
 
+            var date = Date()
+
+            if let mealDate = meals.actualDate {
+                date = mealDate
+            } else if let mealdate = meals.createdAt {
+                date = mealdate
+            }
+
             let mealArray = DataTable.Treatment(
                 units: units,
                 type: .carbs,
-                date: meals.createdAt ?? Date(),
+                date: date,
                 id: meals.id ?? "",
                 isFPU: deleteTwice ? true : false,
                 fpuID: deleteTwice ? (meals.fpuID ?? "") : ""
             )
 
             print(
-                "meals 2: ID: " + (mealArray.id ?? "").description + " FPU ID: " + (mealArray.fpuID ?? "")
+                "meals 2: ID: " + mealArray.id.description + " FPU ID: " + (mealArray.fpuID ?? "")
                     .description
             )
 

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

@@ -36,7 +36,7 @@ extension DataTable {
         private func setupTreatments() {
             DispatchQueue.global().async {
                 let units = self.settingsManager.settings.units
-
+                var date = Date.now
                 let carbs = self.provider.carbs()
                     .filter { !($0.isFPU ?? false) }
                     .map {
@@ -44,14 +44,20 @@ extension DataTable {
                             return Treatment(
                                 units: units,
                                 type: .carbs,
-                                date: $0.createdAt,
+                                date: $0.actualDate ?? $0.createdAt,
                                 amount: $0.carbs,
                                 id: id,
                                 fpuID: $0.fpuID,
                                 note: $0.note
                             )
                         } else {
-                            return Treatment(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs, note: $0.note)
+                            return Treatment(
+                                units: units,
+                                type: .carbs,
+                                date: $0.actualDate ?? $0.createdAt,
+                                amount: $0.carbs,
+                                note: $0.note
+                            )
                         }
                     }
 
@@ -61,7 +67,7 @@ extension DataTable {
                         Treatment(
                             units: units,
                             type: .fpus,
-                            date: $0.createdAt,
+                            date: $0.actualDate ?? $0.createdAt,
                             amount: $0.carbs,
                             id: $0.id,
                             isFPU: $0.isFPU,

+ 10 - 2
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -710,7 +710,11 @@ extension MainChartView {
         calculationQueue.async {
             let realCarbs = carbs.filter { !($0.isFPU ?? false) }
             let dots = realCarbs.map { value -> DotInfo in
-                let center = timeToInterpolatedPoint(value.createdAt.timeIntervalSince1970, fullSize: fullSize)
+                let center = timeToInterpolatedPoint(
+                    value.actualDate != nil ? (value.actualDate ?? Date()).timeIntervalSince1970 : value.createdAt
+                        .timeIntervalSince1970,
+                    fullSize: fullSize
+                )
                 let size = Config.carbsSize + CGFloat(value.carbs) * Config.carbsScale
                 let rect = CGRect(x: center.x - size / 2, y: center.y - size / 2, width: size, height: size)
                 return DotInfo(rect: rect, value: value.carbs)
@@ -733,7 +737,11 @@ extension MainChartView {
         calculationQueue.async {
             let fpus = carbs.filter { $0.isFPU ?? false }
             let dots = fpus.map { value -> DotInfo in
-                let center = timeToInterpolatedPoint(value.createdAt.timeIntervalSince1970, fullSize: fullSize)
+                let center = timeToInterpolatedPoint(
+                    value.actualDate != nil ? (value.actualDate ?? Date()).timeIntervalSince1970 : value.createdAt
+                        .timeIntervalSince1970,
+                    fullSize: fullSize
+                )
                 let size = Config.fpuSize + CGFloat(value.carbs) * Config.fpuScale
                 let rect = CGRect(x: center.x - size / 2, y: center.y - size / 2, width: size, height: size)
                 return DotInfo(rect: rect, value: value.carbs)

+ 3 - 3
FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

@@ -195,13 +195,13 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             let sampleDates = samples.map(\.startDate)
             let samplesToSave = carbsWithId
                 .filter { !sampleIDs.contains($0.id ?? "") } // id existing in AH
-                .filter { !sampleDates.contains($0.createdAt) } // not id but exaclty the same datetime
+                .filter { !sampleDates.contains($0.actualDate ?? $0.createdAt) } // not id but exaclty the same datetime
                 .map {
                     HKQuantitySample(
                         type: sampleType,
                         quantity: HKQuantity(unit: .gram(), doubleValue: Double($0.carbs)),
-                        start: $0.createdAt,
-                        end: $0.createdAt,
+                        start: $0.actualDate ?? $0.createdAt,
+                        end: $0.actualDate ?? $0.createdAt,
                         metadata: [
                             HKMetadataKeySyncIdentifier: $0.id ?? "_id",
                             HKMetadataKeySyncVersion: 1,

+ 1 - 1
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -148,7 +148,7 @@ extension NightscoutAPI {
         components.port = url.port
         components.path = Config.treatmentsPath
 
-        var arguments = "find[_id][$eq]"
+        var arguments = "find[id][$eq]"
         if treatement.isFPU ?? false {
             arguments = "find[fpuID][$eq]"
         }

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

@@ -332,6 +332,7 @@ extension BaseWatchManager: WCSessionDelegate {
                 [CarbsEntry(
                     id: UUID().uuidString,
                     createdAt: Date(),
+                    actualDate: nil,
                     carbs: Decimal(carbs),
                     fat: Decimal(fat),
                     protein: Decimal(protein), note: nil,

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

@@ -13,6 +13,7 @@ import Foundation
             [CarbsEntry(
                 id: UUID().uuidString,
                 createdAt: dateAdded,
+                actualDate: dateAdded,
                 carbs: carbs,
                 fat: Decimal(quantityFat),
                 protein: Decimal(quantityProtein),