diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt
index d5779d2e05..04845c27b5 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt
@@ -214,6 +214,34 @@ class NSClientAddUpdateWorker(
}
} ?: aapsLogger.error("Error parsing EffectiveProfileSwitch json $json")
}
+ eventType == TherapyEvent.Type.BOLUS_WIZARD.text ->
+ if (config.NSCLIENT) {
+ bolusCalculatorResultFromJson(json)?.let { bolusCalculatorResult ->
+ repository.runTransactionForResult(SyncNsBolusCalculatorResultTransaction(bolusCalculatorResult))
+ .doOnError {
+ aapsLogger.error(LTag.DATABASE, "Error while saving BolusCalculatorResult", it)
+ ret = Result.failure(workDataOf("Error" to it.toString()))
+ }
+ .blockingGet()
+ .also { result ->
+ result.inserted.forEach {
+ uel.log(Action.BOLUS_CALCULATOR_RESULT, Sources.NSClient,
+ ValueWithUnit.Timestamp(it.timestamp),
+ )
+ aapsLogger.debug(LTag.DATABASE, "Inserted BolusCalculatorResult $it")
+ }
+ result.invalidated.forEach {
+ uel.log(Action.BOLUS_CALCULATOR_RESULT_REMOVED, Sources.NSClient,
+ ValueWithUnit.Timestamp(it.timestamp),
+ )
+ aapsLogger.debug(LTag.DATABASE, "Invalidated BolusCalculatorResult $it")
+ }
+ result.updatedNsId.forEach {
+ aapsLogger.debug(LTag.DATABASE, "Updated nsId BolusCalculatorResult $it")
+ }
+ }
+ } ?: aapsLogger.error("Error parsing BolusCalculatorResult json $json")
+ }
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
diff --git a/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt b/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt
index b1f49b603c..a07e789856 100644
--- a/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt
+++ b/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt
@@ -1,10 +1,12 @@
package info.nightscout.androidaps.extensions
import com.google.gson.Gson
+import com.google.gson.JsonSyntaxException
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.utils.DateUtil
+import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
@@ -18,3 +20,23 @@ fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject
.put("units", Constants.MGDL)
.put("notes", note)
.also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) }
+
+fun bolusCalculatorResultFromJson(jsonObject: JSONObject): BolusCalculatorResult? {
+ val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
+ val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
+ val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null) ?: return null
+ val bcrString = JsonHelper.safeGetStringAllowNull(jsonObject, "bolusCalculatorResult", null) ?: return null
+
+ if (timestamp == 0L) return null
+
+ return try {
+ Gson().fromJson(bcrString, BolusCalculatorResult::class.java)
+ .also {
+ it.id = 0
+ it.isValid = isValid
+ it.interfaceIDs.nightscoutId = id
+ }
+ } catch (e: JsonSyntaxException) {
+ null
+ }
+}
diff --git a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt
index b62acc246d..f24e0f5edc 100644
--- a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt
+++ b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt
@@ -17,89 +17,91 @@ class Translator @Inject internal constructor(
) {
fun translate(action: Action): String = when (action) {
- Action.BOLUS -> resourceHelper.gs(R.string.uel_bolus)
- Action.SMB -> resourceHelper.gs(R.string.smb_shortname)
- Action.BOLUS_ADVISOR -> resourceHelper.gs(R.string.uel_bolus_advisor)
- Action.EXTENDED_BOLUS -> resourceHelper.gs(R.string.uel_extended_bolus)
- Action.SUPERBOLUS_TBR -> resourceHelper.gs(R.string.uel_superbolus_tbr)
- Action.CARBS -> resourceHelper.gs(R.string.uel_carbs)
- Action.EXTENDED_CARBS -> resourceHelper.gs(R.string.uel_extended_carbs)
- Action.TEMP_BASAL -> resourceHelper.gs(R.string.uel_temp_basal)
- Action.TT -> resourceHelper.gs(R.string.uel_tt)
- Action.NEW_PROFILE -> resourceHelper.gs(R.string.uel_new_profile)
- Action.CLONE_PROFILE -> resourceHelper.gs(R.string.uel_clone_profile)
- Action.STORE_PROFILE -> resourceHelper.gs(R.string.uel_store_profile)
- Action.PROFILE_SWITCH -> resourceHelper.gs(R.string.uel_profile_switch)
- Action.PROFILE_SWITCH_CLONED -> resourceHelper.gs(R.string.uel_profile_switch_cloned)
- Action.CLOSED_LOOP_MODE -> resourceHelper.gs(R.string.uel_closed_loop_mode)
- Action.LGS_LOOP_MODE -> resourceHelper.gs(R.string.uel_lgs_loop_mode)
- Action.OPEN_LOOP_MODE -> resourceHelper.gs(R.string.uel_open_loop_mode)
- Action.LOOP_DISABLED -> resourceHelper.gs(R.string.uel_loop_disabled)
- Action.LOOP_ENABLED -> resourceHelper.gs(R.string.uel_loop_enabled)
- Action.RECONNECT -> resourceHelper.gs(R.string.uel_reconnect)
- Action.DISCONNECT -> resourceHelper.gs(R.string.uel_disconnect)
- Action.RESUME -> resourceHelper.gs(R.string.uel_resume)
- Action.SUSPEND -> resourceHelper.gs(R.string.uel_suspend)
- Action.HW_PUMP_ALLOWED -> resourceHelper.gs(R.string.uel_hw_pump_allowed)
- Action.CLEAR_PAIRING_KEYS -> resourceHelper.gs(R.string.uel_clear_pairing_keys)
- Action.ACCEPTS_TEMP_BASAL -> resourceHelper.gs(R.string.uel_accepts_temp_basal)
- Action.CANCEL_TEMP_BASAL -> resourceHelper.gs(R.string.uel_cancel_temp_basal)
- Action.CANCEL_BOLUS -> resourceHelper.gs(R.string.uel_cancel_bolus)
- Action.CANCEL_EXTENDED_BOLUS -> resourceHelper.gs(R.string.uel_cancel_extended_bolus)
- Action.CANCEL_TT -> resourceHelper.gs(R.string.uel_cancel_tt)
- Action.CAREPORTAL -> resourceHelper.gs(R.string.uel_careportal)
- Action.SITE_CHANGE -> resourceHelper.gs(R.string.uel_site_change)
- Action.RESERVOIR_CHANGE -> resourceHelper.gs(R.string.uel_reservoir_change)
- Action.CALIBRATION -> resourceHelper.gs(R.string.uel_calibration)
- Action.PRIME_BOLUS -> resourceHelper.gs(R.string.uel_prime_bolus)
- Action.TREATMENT -> resourceHelper.gs(R.string.uel_treatment)
- Action.CAREPORTAL_NS_REFRESH -> resourceHelper.gs(R.string.uel_careportal_ns_refresh)
- Action.PROFILE_SWITCH_NS_REFRESH -> resourceHelper.gs(R.string.uel_profile_switch_ns_refresh)
- Action.TREATMENTS_NS_REFRESH -> resourceHelper.gs(R.string.uel_treatments_ns_refresh)
- Action.TT_NS_REFRESH -> resourceHelper.gs(R.string.uel_tt_ns_refresh)
- Action.AUTOMATION_REMOVED -> resourceHelper.gs(R.string.uel_automation_removed)
- Action.BG_REMOVED -> resourceHelper.gs(R.string.uel_bg_removed)
- Action.CAREPORTAL_REMOVED -> resourceHelper.gs(R.string.uel_careportal_removed)
- Action.BOLUS_REMOVED -> resourceHelper.gs(R.string.uel_bolus_removed)
- Action.CARBS_REMOVED -> resourceHelper.gs(R.string.uel_carbs_removed)
- Action.TEMP_BASAL_REMOVED -> resourceHelper.gs(R.string.uel_temp_basal_removed)
- Action.EXTENDED_BOLUS_REMOVED -> resourceHelper.gs(R.string.uel_extended_bolus_removed)
- Action.FOOD -> resourceHelper.gs(R.string.uel_food)
- Action.FOOD_REMOVED -> resourceHelper.gs(R.string.uel_food_removed)
- Action.PROFILE_REMOVED -> resourceHelper.gs(R.string.uel_profile_removed)
- Action.PROFILE_SWITCH_REMOVED -> resourceHelper.gs(R.string.uel_profile_switch_removed)
- Action.RESTART_EVENTS_REMOVED -> resourceHelper.gs(R.string.uel_restart_events_removed)
- Action.TREATMENT_REMOVED -> resourceHelper.gs(R.string.uel_treatment_removed)
- Action.TT_REMOVED -> resourceHelper.gs(R.string.uel_tt_removed)
- Action.NS_PAUSED -> resourceHelper.gs(R.string.uel_ns_paused)
- Action.NS_RESUME -> resourceHelper.gs(R.string.uel_ns_resume)
- Action.NS_QUEUE_CLEARED -> resourceHelper.gs(R.string.uel_ns_queue_cleared)
- Action.NS_SETTINGS_COPIED -> resourceHelper.gs(R.string.uel_ns_settings_copied)
- Action.ERROR_DIALOG_OK -> resourceHelper.gs(R.string.uel_error_dialog_ok)
- Action.ERROR_DIALOG_MUTE -> resourceHelper.gs(R.string.uel_error_dialog_mute)
- Action.ERROR_DIALOG_MUTE_5MIN -> resourceHelper.gs(R.string.uel_error_dialog_mute_5min)
- Action.OBJECTIVE_STARTED -> resourceHelper.gs(R.string.uel_objective_started)
- Action.OBJECTIVE_UNSTARTED -> resourceHelper.gs(R.string.uel_objective_unstarted)
- Action.OBJECTIVES_SKIPPED -> resourceHelper.gs(R.string.uel_objectives_skipped)
- Action.STAT_RESET -> resourceHelper.gs(R.string.uel_stat_reset)
- Action.DELETE_LOGS -> resourceHelper.gs(R.string.uel_delete_logs)
- Action.DELETE_FUTURE_TREATMENTS -> resourceHelper.gs(R.string.uel_delete_future_treatments)
- Action.EXPORT_SETTINGS -> resourceHelper.gs(R.string.uel_export_settings)
- Action.IMPORT_SETTINGS -> resourceHelper.gs(R.string.uel_import_settings)
- Action.RESET_DATABASES -> resourceHelper.gs(R.string.uel_reset_databases)
- Action.EXPORT_DATABASES -> resourceHelper.gs(R.string.uel_export_databases)
- Action.IMPORT_DATABASES -> resourceHelper.gs(R.string.uel_import_databases)
- Action.OTP_EXPORT -> resourceHelper.gs(R.string.uel_otp_export)
- Action.OTP_RESET -> resourceHelper.gs(R.string.uel_otp_reset)
- Action.EXPORT_CSV -> resourceHelper.gs(R.string.uel_export_csv)
- Action.STOP_SMS -> resourceHelper.gs(R.string.uel_stop_sms)
- Action.START_AAPS -> resourceHelper.gs(R.string.uel_start_aaps)
- Action.EXIT_AAPS -> resourceHelper.gs(R.string.uel_exit_aaps)
- Action.PLUGIN_ENABLED -> resourceHelper.gs(R.string.uel_plugin_enabled)
- Action.PLUGIN_DISABLED -> resourceHelper.gs(R.string.uel_plugin_disabled)
- Action.LOOP_CHANGE -> resourceHelper.gs(R.string.uel_loop_change)
- Action.LOOP_REMOVED -> resourceHelper.gs(R.string.uel_loop_removed)
- Action.UNKNOWN -> resourceHelper.gs(R.string.unknown)
+ Action.BOLUS -> resourceHelper.gs(R.string.uel_bolus)
+ Action.BOLUS_CALCULATOR_RESULT -> resourceHelper.gs(R.string.uel_bolus_calculator)
+ Action.BOLUS_CALCULATOR_RESULT_REMOVED -> resourceHelper.gs(R.string.uel_bolus_calculator)
+ Action.SMB -> resourceHelper.gs(R.string.smb_shortname)
+ Action.BOLUS_ADVISOR -> resourceHelper.gs(R.string.uel_bolus_advisor)
+ Action.EXTENDED_BOLUS -> resourceHelper.gs(R.string.uel_extended_bolus)
+ Action.SUPERBOLUS_TBR -> resourceHelper.gs(R.string.uel_superbolus_tbr)
+ Action.CARBS -> resourceHelper.gs(R.string.uel_carbs)
+ Action.EXTENDED_CARBS -> resourceHelper.gs(R.string.uel_extended_carbs)
+ Action.TEMP_BASAL -> resourceHelper.gs(R.string.uel_temp_basal)
+ Action.TT -> resourceHelper.gs(R.string.uel_tt)
+ Action.NEW_PROFILE -> resourceHelper.gs(R.string.uel_new_profile)
+ Action.CLONE_PROFILE -> resourceHelper.gs(R.string.uel_clone_profile)
+ Action.STORE_PROFILE -> resourceHelper.gs(R.string.uel_store_profile)
+ Action.PROFILE_SWITCH -> resourceHelper.gs(R.string.uel_profile_switch)
+ Action.PROFILE_SWITCH_CLONED -> resourceHelper.gs(R.string.uel_profile_switch_cloned)
+ Action.CLOSED_LOOP_MODE -> resourceHelper.gs(R.string.uel_closed_loop_mode)
+ Action.LGS_LOOP_MODE -> resourceHelper.gs(R.string.uel_lgs_loop_mode)
+ Action.OPEN_LOOP_MODE -> resourceHelper.gs(R.string.uel_open_loop_mode)
+ Action.LOOP_DISABLED -> resourceHelper.gs(R.string.uel_loop_disabled)
+ Action.LOOP_ENABLED -> resourceHelper.gs(R.string.uel_loop_enabled)
+ Action.RECONNECT -> resourceHelper.gs(R.string.uel_reconnect)
+ Action.DISCONNECT -> resourceHelper.gs(R.string.uel_disconnect)
+ Action.RESUME -> resourceHelper.gs(R.string.uel_resume)
+ Action.SUSPEND -> resourceHelper.gs(R.string.uel_suspend)
+ Action.HW_PUMP_ALLOWED -> resourceHelper.gs(R.string.uel_hw_pump_allowed)
+ Action.CLEAR_PAIRING_KEYS -> resourceHelper.gs(R.string.uel_clear_pairing_keys)
+ Action.ACCEPTS_TEMP_BASAL -> resourceHelper.gs(R.string.uel_accepts_temp_basal)
+ Action.CANCEL_TEMP_BASAL -> resourceHelper.gs(R.string.uel_cancel_temp_basal)
+ Action.CANCEL_BOLUS -> resourceHelper.gs(R.string.uel_cancel_bolus)
+ Action.CANCEL_EXTENDED_BOLUS -> resourceHelper.gs(R.string.uel_cancel_extended_bolus)
+ Action.CANCEL_TT -> resourceHelper.gs(R.string.uel_cancel_tt)
+ Action.CAREPORTAL -> resourceHelper.gs(R.string.uel_careportal)
+ Action.SITE_CHANGE -> resourceHelper.gs(R.string.uel_site_change)
+ Action.RESERVOIR_CHANGE -> resourceHelper.gs(R.string.uel_reservoir_change)
+ Action.CALIBRATION -> resourceHelper.gs(R.string.uel_calibration)
+ Action.PRIME_BOLUS -> resourceHelper.gs(R.string.uel_prime_bolus)
+ Action.TREATMENT -> resourceHelper.gs(R.string.uel_treatment)
+ Action.CAREPORTAL_NS_REFRESH -> resourceHelper.gs(R.string.uel_careportal_ns_refresh)
+ Action.PROFILE_SWITCH_NS_REFRESH -> resourceHelper.gs(R.string.uel_profile_switch_ns_refresh)
+ Action.TREATMENTS_NS_REFRESH -> resourceHelper.gs(R.string.uel_treatments_ns_refresh)
+ Action.TT_NS_REFRESH -> resourceHelper.gs(R.string.uel_tt_ns_refresh)
+ Action.AUTOMATION_REMOVED -> resourceHelper.gs(R.string.uel_automation_removed)
+ Action.BG_REMOVED -> resourceHelper.gs(R.string.uel_bg_removed)
+ Action.CAREPORTAL_REMOVED -> resourceHelper.gs(R.string.uel_careportal_removed)
+ Action.BOLUS_REMOVED -> resourceHelper.gs(R.string.uel_bolus_removed)
+ Action.CARBS_REMOVED -> resourceHelper.gs(R.string.uel_carbs_removed)
+ Action.TEMP_BASAL_REMOVED -> resourceHelper.gs(R.string.uel_temp_basal_removed)
+ Action.EXTENDED_BOLUS_REMOVED -> resourceHelper.gs(R.string.uel_extended_bolus_removed)
+ Action.FOOD -> resourceHelper.gs(R.string.uel_food)
+ Action.FOOD_REMOVED -> resourceHelper.gs(R.string.uel_food_removed)
+ Action.PROFILE_REMOVED -> resourceHelper.gs(R.string.uel_profile_removed)
+ Action.PROFILE_SWITCH_REMOVED -> resourceHelper.gs(R.string.uel_profile_switch_removed)
+ Action.RESTART_EVENTS_REMOVED -> resourceHelper.gs(R.string.uel_restart_events_removed)
+ Action.TREATMENT_REMOVED -> resourceHelper.gs(R.string.uel_treatment_removed)
+ Action.TT_REMOVED -> resourceHelper.gs(R.string.uel_tt_removed)
+ Action.NS_PAUSED -> resourceHelper.gs(R.string.uel_ns_paused)
+ Action.NS_RESUME -> resourceHelper.gs(R.string.uel_ns_resume)
+ Action.NS_QUEUE_CLEARED -> resourceHelper.gs(R.string.uel_ns_queue_cleared)
+ Action.NS_SETTINGS_COPIED -> resourceHelper.gs(R.string.uel_ns_settings_copied)
+ Action.ERROR_DIALOG_OK -> resourceHelper.gs(R.string.uel_error_dialog_ok)
+ Action.ERROR_DIALOG_MUTE -> resourceHelper.gs(R.string.uel_error_dialog_mute)
+ Action.ERROR_DIALOG_MUTE_5MIN -> resourceHelper.gs(R.string.uel_error_dialog_mute_5min)
+ Action.OBJECTIVE_STARTED -> resourceHelper.gs(R.string.uel_objective_started)
+ Action.OBJECTIVE_UNSTARTED -> resourceHelper.gs(R.string.uel_objective_unstarted)
+ Action.OBJECTIVES_SKIPPED -> resourceHelper.gs(R.string.uel_objectives_skipped)
+ Action.STAT_RESET -> resourceHelper.gs(R.string.uel_stat_reset)
+ Action.DELETE_LOGS -> resourceHelper.gs(R.string.uel_delete_logs)
+ Action.DELETE_FUTURE_TREATMENTS -> resourceHelper.gs(R.string.uel_delete_future_treatments)
+ Action.EXPORT_SETTINGS -> resourceHelper.gs(R.string.uel_export_settings)
+ Action.IMPORT_SETTINGS -> resourceHelper.gs(R.string.uel_import_settings)
+ Action.RESET_DATABASES -> resourceHelper.gs(R.string.uel_reset_databases)
+ Action.EXPORT_DATABASES -> resourceHelper.gs(R.string.uel_export_databases)
+ Action.IMPORT_DATABASES -> resourceHelper.gs(R.string.uel_import_databases)
+ Action.OTP_EXPORT -> resourceHelper.gs(R.string.uel_otp_export)
+ Action.OTP_RESET -> resourceHelper.gs(R.string.uel_otp_reset)
+ Action.EXPORT_CSV -> resourceHelper.gs(R.string.uel_export_csv)
+ Action.STOP_SMS -> resourceHelper.gs(R.string.uel_stop_sms)
+ Action.START_AAPS -> resourceHelper.gs(R.string.uel_start_aaps)
+ Action.EXIT_AAPS -> resourceHelper.gs(R.string.uel_exit_aaps)
+ Action.PLUGIN_ENABLED -> resourceHelper.gs(R.string.uel_plugin_enabled)
+ Action.PLUGIN_DISABLED -> resourceHelper.gs(R.string.uel_plugin_disabled)
+ Action.LOOP_CHANGE -> resourceHelper.gs(R.string.uel_loop_change)
+ Action.LOOP_REMOVED -> resourceHelper.gs(R.string.uel_loop_removed)
+ Action.UNKNOWN -> resourceHelper.gs(R.string.unknown)
}
fun translate(units: ValueWithUnit?): String = when (units) {
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 73adf3e02b..b653a9bc23 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -397,6 +397,7 @@
BOLUS
+ BOLUS CALCULATOR
BOLUS ADVISOR
EXTENDED BOLUS
SUPERBOLUS TBR
diff --git a/database/src/main/java/info/nightscout/androidaps/database/daos/BolusCalculatorResultDao.kt b/database/src/main/java/info/nightscout/androidaps/database/daos/BolusCalculatorResultDao.kt
index 0b192849e1..0b7e4dff8e 100644
--- a/database/src/main/java/info/nightscout/androidaps/database/daos/BolusCalculatorResultDao.kt
+++ b/database/src/main/java/info/nightscout/androidaps/database/daos/BolusCalculatorResultDao.kt
@@ -2,7 +2,6 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
-import info.nightscout.androidaps.database.TABLE_APS_RESULTS
import info.nightscout.androidaps.database.TABLE_BOLUS_CALCULATOR_RESULTS
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import io.reactivex.Maybe
@@ -22,6 +21,12 @@ internal interface BolusCalculatorResultDao : TraceableDao
+ @Query("SELECT * FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE timestamp = :timestamp AND referenceId IS NULL")
+ fun findByTimestamp(timestamp: Long): BolusCalculatorResult?
+
+ @Query("SELECT * FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE nightscoutId = :nsId AND referenceId IS NULL")
+ fun findByNSId(nsId: String): BolusCalculatorResult?
+
@Query("SELECT * FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE isValid = 1 AND timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC")
fun getBolusCalculatorResultsFromTime(timestamp: Long): Single>
diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt
index e7a753713a..a0981c1b56 100644
--- a/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt
+++ b/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt
@@ -25,6 +25,8 @@ data class UserEntry(
) : DBEntry, DBEntryWithTime {
enum class Action (val colorGroup: ColorGroup) {
BOLUS (ColorGroup.InsulinTreatment),
+ BOLUS_CALCULATOR_RESULT (ColorGroup.InsulinTreatment),
+ BOLUS_CALCULATOR_RESULT_REMOVED (ColorGroup.Aaps),
SMB (ColorGroup.InsulinTreatment),
BOLUS_ADVISOR (ColorGroup.InsulinTreatment),
EXTENDED_BOLUS (ColorGroup.InsulinTreatment),
diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsBolusCalculatorResultTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsBolusCalculatorResultTransaction.kt
new file mode 100644
index 0000000000..7ac50e32d2
--- /dev/null
+++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsBolusCalculatorResultTransaction.kt
@@ -0,0 +1,51 @@
+package info.nightscout.androidaps.database.transactions
+
+import info.nightscout.androidaps.database.entities.BolusCalculatorResult
+
+/**
+ * Sync the BolusCalculatorResult from NS
+ */
+class SyncNsBolusCalculatorResultTransaction(private val bolusCalculatorResult: BolusCalculatorResult) :
+ Transaction() {
+
+ override fun run(): TransactionResult {
+ val result = TransactionResult()
+
+ val current: BolusCalculatorResult? =
+ bolusCalculatorResult.interfaceIDs.nightscoutId?.let {
+ database.bolusCalculatorResultDao.findByNSId(it)
+ }
+
+ if (current != null) {
+ // nsId exists, allow only invalidation
+ if (current.isValid && !bolusCalculatorResult.isValid) {
+ current.isValid = false
+ database.bolusCalculatorResultDao.updateExistingEntry(current)
+ result.invalidated.add(current)
+ }
+ return result
+ }
+
+ // not known nsId
+ val existing = database.bolusCalculatorResultDao.findByTimestamp(bolusCalculatorResult.timestamp)
+ if (existing != null && existing.interfaceIDs.nightscoutId == null) {
+ // the same record, update nsId only
+ existing.interfaceIDs.nightscoutId = bolusCalculatorResult.interfaceIDs.nightscoutId
+ existing.isValid = bolusCalculatorResult.isValid
+ database.bolusCalculatorResultDao.updateExistingEntry(existing)
+ result.updatedNsId.add(existing)
+ } else {
+ database.bolusCalculatorResultDao.insertNewEntry(bolusCalculatorResult)
+ result.inserted.add(bolusCalculatorResult)
+ }
+ return result
+
+ }
+
+ class TransactionResult {
+
+ val updatedNsId = mutableListOf()
+ val inserted = mutableListOf()
+ val invalidated = mutableListOf()
+ }
+}
\ No newline at end of file