From c1bfa563a33c6cc3de499ccb8dc2b34a87372fca Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 28 Dec 2024 23:26:22 +0100 Subject: [PATCH] shopping from meal plan edit --- cookbook/serializer.py | 26 ++++--- .../components/display/ClosableHelpAlert.vue | 2 +- vue3/src/components/display/MealPlanView.vue | 2 +- .../components/display/ShoppingLineItem.vue | 16 ++-- .../components/display/ShoppingListView.vue | 52 +++---------- .../inputs/ShoppingListEntryInput.vue | 73 +++++++++++++++++++ .../model_editors/MealPlanEditor.vue | 71 ++++++++++++------ .../composables/useModelEditorFunctions.ts | 7 ++ vue3/src/locales/ar.json | 1 + vue3/src/locales/bg.json | 1 + vue3/src/locales/ca.json | 1 + vue3/src/locales/cs.json | 1 + vue3/src/locales/da.json | 1 + vue3/src/locales/de.json | 1 + vue3/src/locales/el.json | 1 + vue3/src/locales/en.json | 1 + vue3/src/locales/es.json | 1 + vue3/src/locales/fi.json | 1 + vue3/src/locales/fr.json | 1 + vue3/src/locales/he.json | 1 + vue3/src/locales/hu.json | 1 + vue3/src/locales/hy.json | 1 + vue3/src/locales/id.json | 1 + vue3/src/locales/is.json | 1 + vue3/src/locales/it.json | 1 + vue3/src/locales/lt.json | 1 + vue3/src/locales/nb_NO.json | 1 + vue3/src/locales/nl.json | 1 + vue3/src/locales/pl.json | 1 + vue3/src/locales/pt.json | 1 + vue3/src/locales/pt_BR.json | 1 + vue3/src/locales/ro.json | 1 + vue3/src/locales/ru.json | 1 + vue3/src/locales/sl.json | 1 + vue3/src/locales/sv.json | 1 + vue3/src/locales/tr.json | 1 + vue3/src/locales/uk.json | 1 + vue3/src/locales/zh_Hans.json | 1 + vue3/src/locales/zh_Hant.json | 1 + vue3/src/openapi/apis/ApiApi.ts | 12 +-- .../models/PatchedShoppingListEntry.ts | 14 +++- .../models/PatchedShoppingListRecipe.ts | 49 +++++++------ vue3/src/openapi/models/ShoppingListEntry.ts | 16 +++- vue3/src/openapi/models/ShoppingListRecipe.ts | 55 +++++++------- vue3/src/stores/ShoppingStore.ts | 17 +++-- 45 files changed, 291 insertions(+), 152 deletions(-) create mode 100644 vue3/src/components/inputs/ShoppingListEntryInput.vue diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 46171c5312..0db3df6968 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -1155,10 +1155,8 @@ class AutoMealPlanSerializer(serializers.Serializer): class ShoppingListRecipeSerializer(serializers.ModelSerializer): - recipe_name = serializers.ReadOnlyField(source='recipe.name') - mealplan_note = serializers.ReadOnlyField(source='mealplan.note') - mealplan_from_date = serializers.ReadOnlyField(source='mealplan.from_date') - mealplan_type = serializers.ReadOnlyField(source='mealplan.meal_type.name') + recipe_data = RecipeOverviewSerializer(source='recipe', read_only=True, required=False) + meal_plan_data = MealPlanSerializer(source='mealplan', read_only=True, required=False) servings = CustomDecimalField() def update(self, instance, validated_data): @@ -1170,18 +1168,19 @@ def update(self, instance, validated_data): class Meta: model = ShoppingListRecipe - fields = ('id', 'recipe_name', 'name', 'recipe', 'mealplan', 'servings', 'mealplan_note', 'mealplan_from_date', - 'mealplan_type') + fields = ('id', 'name', 'recipe', 'recipe_data', 'mealplan', 'meal_plan_data', 'servings',) read_only_fields = ('id',) class ShoppingListEntrySerializer(WritableNestedModelSerializer): food = FoodSerializer(allow_null=True) unit = UnitSerializer(allow_null=True, required=False) - recipe_mealplan = ShoppingListRecipeSerializer(source='list_recipe', read_only=True) + list_recipe_data = ShoppingListRecipeSerializer(source='list_recipe', read_only=True) amount = CustomDecimalField() created_by = UserSerializer(read_only=True) completed_at = serializers.DateTimeField(allow_null=True, required=False) + mealplan_id = serializers.IntegerField(required=False, write_only=True, + help_text='If a mealplan id is given try to find existing or create new ShoppingListRecipe with that meal plan and link entry to it') def get_fields(self, *args, **kwargs): fields = super().get_fields(*args, **kwargs) @@ -1215,10 +1214,20 @@ def run_validation(self, data): def create(self, validated_data): validated_data['space'] = self.context['request'].space validated_data['created_by'] = self.context['request'].user + + if validated_data['mealplan_id']: + slr, created = ShoppingListRecipe.objects.get_or_create(mealplan_id=validated_data['mealplan_id'], mealplan__space=self.context['request'].space) + validated_data['list_recipe'] = slr + del validated_data['mealplan_id'] + return super().create(validated_data) def update(self, instance, validated_data): user = self.context['request'].user + + if validated_data['mealplan_id']: + del validated_data['mealplan_id'] + # update the onhand for food if shopping_add_onhand is True if user.userpreference.shopping_add_onhand: if checked := validated_data.get('checked', None): @@ -1232,8 +1241,7 @@ class Meta: model = ShoppingListEntry fields = ( 'id', 'list_recipe', 'food', 'unit', 'amount', 'order', 'checked', - 'recipe_mealplan', - 'created_by', 'created_at', 'updated_at', 'completed_at', 'delay_until' + 'list_recipe_data', 'created_by', 'created_at', 'updated_at', 'completed_at', 'delay_until', 'mealplan_id' ) read_only_fields = ('id', 'created_by', 'created_at') diff --git a/vue3/src/components/display/ClosableHelpAlert.vue b/vue3/src/components/display/ClosableHelpAlert.vue index ffa876c690..8db69f2bc4 100644 --- a/vue3/src/components/display/ClosableHelpAlert.vue +++ b/vue3/src/components/display/ClosableHelpAlert.vue @@ -5,7 +5,7 @@

{{ props.text}} - {{ actionText}} + {{ actionText}}

diff --git a/vue3/src/components/display/MealPlanView.vue b/vue3/src/components/display/MealPlanView.vue index a51826b84a..200a2b8144 100644 --- a/vue3/src/components/display/MealPlanView.vue +++ b/vue3/src/components/display/MealPlanView.vue @@ -34,7 +34,7 @@ - diff --git a/vue3/src/components/display/ShoppingLineItem.vue b/vue3/src/components/display/ShoppingLineItem.vue index 8a79255863..bb6a1948fa 100644 --- a/vue3/src/components/display/ShoppingLineItem.vue +++ b/vue3/src/components/display/ShoppingLineItem.vue @@ -154,7 +154,7 @@ const amounts = computed((): Map => { * compute the second (info) row of the line item based on the entries and the device settings */ const infoRow = computed(() => { - if(props.hideInfoRow){ + if (props.hideInfoRow) { return '' } @@ -171,14 +171,16 @@ const infoRow = computed(() => { authors.push(e.createdBy.displayName) } - if (e.recipeMealplan !== null) { - let recipe_name = e.recipeMealplan.recipeName - if (recipes.indexOf(recipe_name) === -1) { - recipes.push(recipe_name.substring(0, 14) + (recipe_name.length > 14 ? '..' : '')) + if (e.listRecipe != null) { + if (e.listRecipeData.recipe != null) { + let recipe_name = e.listRecipeData.recipeData.name + if (recipes.indexOf(recipe_name) === -1) { + recipes.push(recipe_name.substring(0, 14) + (recipe_name.length > 14 ? '..' : '')) + } } - if ('mealplan_from_date' in e.recipeMealplan) { - let meal_plan_entry = (e?.recipeMealplan?.mealplanType || '') + ' (' + DateTime.fromJSDate(e.recipeMealplan.mealplanFromDate).toLocaleString(DateTime.DATETIME_SHORT) + ')' + if (e.listRecipeData.mealplan != null) { + let meal_plan_entry = (e.listRecipeData.mealPlanData.mealType.name.substring(0, 8) || '') + ' (' + DateTime.fromJSDate(e.listRecipeData.mealPlanData.fromDate).toLocaleString(DateTime.DATE_SHORT) + ')' if (meal_pans.indexOf(meal_plan_entry) === -1) { meal_pans.push(meal_plan_entry) } diff --git a/vue3/src/components/display/ShoppingListView.vue b/vue3/src/components/display/ShoppingListView.vue index 6c29460022..c1a8d87784 100644 --- a/vue3/src/components/display/ShoppingListView.vue +++ b/vue3/src/components/display/ShoppingListView.vue @@ -83,16 +83,7 @@ - - - + @@ -168,7 +159,7 @@ - {{ $t('Recipes') }} + {{ $t('Recipes') }} / {{ $t('Meal_Plan') }} @@ -179,9 +170,14 @@ @confirm="(servings: number) => {updateRecipeServings(r, servings)}"> - - {{ r.recipeName }} - + +
+

{{ r.recipeData.name }}

+

+ {{ r.mealPlanData.mealType.name }} - {{ DateTime.fromJSDate(r.mealPlanData.fromDate).toLocaleString(DateTime.DATE_FULL) }} +

+
+