1
0
mirror of https://github.com/oliexdev/openScale.git synced 2025-08-17 22:11:35 +02:00

Recalculate derived values after CSV import

This commit is contained in:
oliexdev
2025-08-04 08:04:54 +02:00
parent c44080aa17
commit 646d5a8f0c
5 changed files with 40 additions and 14 deletions

View File

@@ -137,21 +137,25 @@ class DatabaseRepository(
}
/**
* Inserts a list of measurements, each with its associated values.
* Inserts a list of measurements, each with its associated values,
* and returns the IDs of the newly inserted main Measurement records.
*/
suspend fun insertMeasurementsWithValues(measurementsData: List<Pair<Measurement, List<MeasurementValue>>>) {
suspend fun insertMeasurementsWithValues(measurementsData: List<Pair<Measurement, List<MeasurementValue>>>) : List<Long> {
val insertedIds = mutableListOf<Long>()
LogManager.i(TAG, "Attempting to insert ${measurementsData.size} measurements with their values.")
withContext(Dispatchers.IO) {
measurementsData.forEachIndexed { index, (measurement, values) ->
try {
LogManager.d(TAG, "Inserting measurement ${index + 1}/${measurementsData.size}, userId: ${measurement.userId}, with ${values.size} values.")
measurementDao.insertSingleMeasurementWithItsValues(measurement, values)
val newMeasurementId = measurementDao.insertSingleMeasurementWithItsValues(measurement, values)
insertedIds.add(newMeasurementId)
} catch (e: Exception) {
LogManager.e(TAG, "Failed to insert measurement (userId: ${measurement.userId}, timestamp: ${measurement.timestamp}) and its values. Error: ${e.message}", e)
}
}
}
LogManager.i(TAG, "Finished inserting measurements with values.")
LogManager.i(TAG, "Finished inserting measurements. ${insertedIds.size} measurements successfully inserted.")
return insertedIds
}
suspend fun deleteMeasurementValueById(valueId: Int) {
@@ -204,7 +208,7 @@ class DatabaseRepository(
*
* @param measurementId The ID of the measurement for which to recalculate derived values.
*/
private suspend fun recalculateDerivedValuesForMeasurement(measurementId: Int) {
suspend fun recalculateDerivedValuesForMeasurement(measurementId: Int) {
LogManager.i(DERIVED_VALUES_TAG, "Starting recalculation of derived values for measurementId: $measurementId")
val measurement = measurementDao.getMeasurementById(measurementId) ?: run {

View File

@@ -61,9 +61,10 @@ interface MeasurementDao {
*
* @param measurement The measurement to insert.
* @param values The list of associated measurement values.
* @return The row ID of the newly inserted measurement.
*/
@Transaction
suspend fun insertSingleMeasurementWithItsValues(measurement: Measurement, values: List<MeasurementValue>) {
suspend fun insertSingleMeasurementWithItsValues(measurement: Measurement, values: List<MeasurementValue>) : Long {
val measurementId = insert(measurement) // Insert the main measurement to get its ID
// Update each MeasurementValue with the correct measurementId
@@ -75,6 +76,8 @@ interface MeasurementDao {
if (updatedValues.isNotEmpty()) {
insertMeasurementValues(updatedValues) // Insert the updated measurement values
}
return measurementId
}
/**

View File

@@ -72,7 +72,7 @@ interface UserSettingsRepository {
suspend fun setFileLoggingEnabled(enabled: Boolean)
val isFirstAppStart: Flow<Boolean>
suspend fun setFirstAppStartCompleted(completed: Boolean) // Renamed for clarity
suspend fun setFirstAppStartCompleted(completed: Boolean)
val appLanguageCode: Flow<String?>
suspend fun setAppLanguageCode(languageCode: String?)
@@ -134,7 +134,7 @@ class UserSettingsRepositoryImpl(context: Context) : UserSettingsRepository {
override suspend fun setFirstAppStartCompleted(completed: Boolean) {
LogManager.d(TAG, "Setting first app start completed to: $completed")
saveSetting(UserPreferenceKeys.IS_FIRST_APP_START.name, !completed)
saveSetting(UserPreferenceKeys.IS_FIRST_APP_START.name, completed)
}
override val appLanguageCode: Flow<String?> = dataStore.data

View File

@@ -96,7 +96,7 @@ fun MeasurementTypeSettingsScreen(
}.also { updatedList ->
// Persist the new display order for each type in the updated list
updatedList.forEachIndexed { index, type ->
settingsViewModel.updateMeasurementType(type.copy(displayOrder = index))
settingsViewModel.updateMeasurementType(type.copy(displayOrder = index), showSnackbar = false)
}
}
}

View File

@@ -473,10 +473,22 @@ class SettingsViewModel(
} ?: throw IOException("Could not open InputStream for Uri: $uri")
if (newMeasurementsToSave.isNotEmpty()) {
repository.insertMeasurementsWithValues(newMeasurementsToSave)
importedMeasurementsCount = newMeasurementsToSave.size
val insertedMeasurementIds = repository.insertMeasurementsWithValues(newMeasurementsToSave)
importedMeasurementsCount = insertedMeasurementIds.size
LogManager.i(TAG, "CSV Import for User ID $userId successful. $importedMeasurementsCount measurements imported.")
if (insertedMeasurementIds.isNotEmpty()) {
LogManager.d(TAG, "Starting derived value recalculation for ${insertedMeasurementIds.size} imported measurements.")
insertedMeasurementIds.forEach { measurementId ->
try {
repository.recalculateDerivedValuesForMeasurement(measurementId.toInt())
} catch (e: Exception) {
LogManager.e(TAG, "Error recalculating derived values for measurement ID $measurementId post-import.", e)
}
}
LogManager.i(TAG, "Derived value recalculation for ${insertedMeasurementIds.size} imported measurements completed.")
}
var detailsForMessage = ""
if (linesSkippedMissingDate > 0) {
detailsForMessage += " ($linesSkippedMissingDate rows skipped due to missing dates"
@@ -1070,13 +1082,20 @@ class SettingsViewModel(
*
* @param type The [MeasurementType] object with updated information.
*/
fun updateMeasurementType(type: MeasurementType) {
fun updateMeasurementType(type: MeasurementType, showSnackbar: Boolean = true) {
viewModelScope.launch {
LogManager.d(TAG, "Updating measurement type (ID: ${type.id})")
if (showSnackbar) {
LogManager.d(TAG, "Updating measurement type (ID: ${type.id})")
}
try {
repository.updateMeasurementType(type)
LogManager.i(TAG, "Measurement type (ID: ${type.id}) updated successfully.")
sharedViewModel.showSnackbar(R.string.measurement_type_updated_successfully, listOf(type.key.toString()))
if (showSnackbar) {
sharedViewModel.showSnackbar(
R.string.measurement_type_updated_successfully,
listOf(type.key.toString())
)
}
// sharedViewModel.refreshMeasurementTypes()
} catch (e: Exception) {
LogManager.e(TAG, "Error updating measurement type (ID: ${type.id})", e)