Description
When importing a JSON recipe with a totalWeight value, the JSON importer correctly reads the value and passes it to the nutrition calculation as totalWeightOverride.
However, when the imported recipe is subsequently saved, the JSON import use case calls SaveRecipeUseCase without setting totalWeightOverridden. SaveRecipeUseCase defaults this flag to false, so the explicit total weight is not used during the final nutrition recalculation.
Relevant source:
-
json_recipe_importer.dart#L233-L249
|
final description = _asString(entry[_kDescription])?.trim(); |
|
final servingsCount = _asInt(entry[_kServings]); |
|
final totalWeightOverride = _asDouble(entry[_kTotalWeight]); |
|
|
|
final tags = <String>[]; |
|
final rawTags = entry[_kTags]; |
|
if (rawTags is List) { |
|
for (final t in rawTags) { |
|
final s = _asString(t)?.trim(); |
|
if (s != null && s.isNotEmpty) tags.add(s); |
|
} |
|
} |
|
|
|
final result = compute.compute( |
|
ingredients, |
|
totalWeightOverride: totalWeightOverride, |
|
); |
-
import_recipes_json_usecase.dart#L44-L48
|
|
|
for (final recipe in parseResult.recipes) { |
|
// SaveRecipeUseCase recomputes nutrition on save, matching the CSV |
|
// and recipe-builder paths so values land identical regardless of |
|
// entry point. |
-
save_recipe_usecase.dart#L15-L21
|
RecipeEntity recipe, { |
|
bool totalWeightOverridden = false, |
|
}) async { |
|
final result = _computeUseCase.compute( |
|
recipe.ingredients, |
|
totalWeightOverride: totalWeightOverridden ? recipe.totalWeightG : null, |
|
); |
-
compute_recipe_nutrition_usecase.dart#L54-L69
|
|
|
ComputeRecipeNutritionResult compute( |
|
List<RecipeIngredientEntity> ingredients, { |
|
double? totalWeightOverride, |
|
}) { |
|
if (ingredients.isEmpty) { |
|
return ComputeRecipeNutritionResult( |
|
perHundredG: MealNutrimentsEntity.empty(), |
|
totalWeightG: 0, |
|
); |
|
} |
|
|
|
final totalWeightG = totalWeightOverride ?? |
|
ingredients.fold<double>( |
|
0, |
|
(sum, i) => sum + i.convertedAmountG, |
-
recipe_builder_bloc.dart#L164-L181
|
void _onUpdateTotalWeight( |
|
UpdateTotalWeightEvent event, |
|
Emitter<RecipeBuilderState> emit, |
|
) { |
|
emit( |
|
state.copyWith( |
|
totalWeightG: event.totalWeightG, |
|
totalWeightOverridden: true, |
|
), |
|
); |
|
_recompute(emit); |
|
} |
|
|
|
void _recompute(Emitter<RecipeBuilderState> emit) { |
|
final result = _computeUseCase.compute( |
|
state.ingredients, |
|
totalWeightOverride: |
|
state.totalWeightOverridden ? state.totalWeightG : null, |
-
recipe_builder_bloc.dart#L227-L230
|
await _saveUseCase.save( |
|
recipe, |
|
totalWeightOverridden: state.totalWeightOverridden, |
|
); |
The normal recipe-builder path explicitly preserves and passes the totalWeightOverridden state, whereas the JSON import path does not.
Steps to reproduce
- Import a JSON recipe containing an ingredient weighing 110 g at 360 kcal/100 g and
"totalWeight": 300.
- Open the imported recipe and log 240 g.
- Observe that the recipe is calculated as approximately 864 kcal instead of approximately 317 kcal because the 300 g finished weight was not retained during saving.
Expected behaviour
The totalWeight specified in the imported JSON should be preserved as the recipe's explicit total-weight override through the save operation. Nutritional values per 100 g should therefore be calculated using the specified finished recipe weight.
Actual behaviour
The JSON importer initially uses totalWeight as an override, but the JSON import save path does not pass totalWeightOverridden to SaveRecipeUseCase. The flag therefore defaults to false, causing the recipe to be recalculated using the sum of ingredient weights instead of the specified finished weight. This can substantially inflate the nutritional values per 100 g and the values recorded when portions are logged.
Platform
Android
OS version
Android 12
App version
2.2.0
Install source
GitHub Release
Feature area
Export / import
Screenshots / recordings
No response
Logs or stack trace
Additional context
No response
Checklist
Description
When importing a JSON recipe with a
totalWeightvalue, the JSON importer correctly reads the value and passes it to the nutrition calculation astotalWeightOverride.However, when the imported recipe is subsequently saved, the JSON import use case calls
SaveRecipeUseCasewithout settingtotalWeightOverridden.SaveRecipeUseCasedefaults this flag tofalse, so the explicit total weight is not used during the final nutrition recalculation.Relevant source:
json_recipe_importer.dart#L233-L249
OpenNutriTracker/lib/core/utils/json_recipe_importer.dart
Lines 233 to 249 in 5a02d85
import_recipes_json_usecase.dart#L44-L48
OpenNutriTracker/lib/features/settings/domain/usecase/import_recipes_json_usecase.dart
Lines 44 to 48 in 5a02d85
save_recipe_usecase.dart#L15-L21
OpenNutriTracker/lib/core/domain/usecase/save_recipe_usecase.dart
Lines 15 to 21 in 5a02d85
compute_recipe_nutrition_usecase.dart#L54-L69
OpenNutriTracker/lib/core/domain/usecase/compute_recipe_nutrition_usecase.dart
Lines 54 to 69 in 5a02d85
recipe_builder_bloc.dart#L164-L181
OpenNutriTracker/lib/features/recipes/presentation/bloc/recipe_builder_bloc.dart
Lines 164 to 181 in 5a02d85
recipe_builder_bloc.dart#L227-L230
OpenNutriTracker/lib/features/recipes/presentation/bloc/recipe_builder_bloc.dart
Lines 227 to 230 in 5a02d85
The normal recipe-builder path explicitly preserves and passes the
totalWeightOverriddenstate, whereas the JSON import path does not.Steps to reproduce
"totalWeight": 300.Expected behaviour
The
totalWeightspecified in the imported JSON should be preserved as the recipe's explicit total-weight override through the save operation. Nutritional values per 100 g should therefore be calculated using the specified finished recipe weight.Actual behaviour
The JSON importer initially uses
totalWeightas an override, but the JSON import save path does not passtotalWeightOverriddentoSaveRecipeUseCase. The flag therefore defaults tofalse, causing the recipe to be recalculated using the sum of ingredient weights instead of the specified finished weight. This can substantially inflate the nutritional values per 100 g and the values recorded when portions are logged.Platform
Android
OS version
Android 12
App version
2.2.0
Install source
GitHub Release
Feature area
Export / import
Screenshots / recordings
No response
Logs or stack trace
Additional context
No response
Checklist