diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 6e7994148..9fd4e133b 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -1104,6 +1104,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer): servings = CustomDecimalField() shared = UserSerializer(many=True, required=False, allow_null=True) shopping = serializers.SerializerMethodField('in_shopping') + addshopping = serializers.BooleanField(write_only=True) to_date = serializers.DateTimeField(required=False) @@ -1121,8 +1122,14 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer): if 'to_date' not in validated_data or validated_data['to_date'] is None: validated_data['to_date'] = validated_data['from_date'] + add_to_shopping = False + try: + add_to_shopping = validated_data.pop('addshopping', False) + except KeyError: + pass + mealplan = super().create(validated_data) - if self.context['request'].data.get('addshopping', False) and self.context['request'].data.get('recipe', None): + if add_to_shopping and self.context['request'].data.get('recipe', None): SLR = RecipeShoppingEditor(user=validated_data['created_by'], space=validated_data['space']) SLR.create(mealplan=mealplan, servings=validated_data['servings']) return mealplan @@ -1132,7 +1139,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer): fields = ( 'id', 'title', 'recipe', 'servings', 'note', 'note_markdown', 'from_date', 'to_date', 'meal_type', 'created_by', 'shared', 'recipe_name', - 'meal_type_name', 'shopping' + 'meal_type_name', 'shopping','addshopping' ) read_only_fields = ('created_by',) diff --git a/cookbook/signals.py b/cookbook/signals.py index a93ffba1e..11c464e93 100644 --- a/cookbook/signals.py +++ b/cookbook/signals.py @@ -120,37 +120,6 @@ def update_food_inheritance(sender, instance=None, created=False, **kwargs): child.save() -@receiver(post_save, sender=MealPlan) -def auto_add_shopping(sender, instance=None, created=False, weak=False, **kwargs): - print("MEAL_AUTO_ADD Signal trying to auto add to shopping") - if not instance: - print("MEAL_AUTO_ADD Instance is none") - return - - try: - space = instance.get_space() - user = instance.get_owner() - with scope(space=space): - slr_exists = instance.shoppinglistrecipe_set.exists() - - if not created and slr_exists: - for x in instance.shoppinglistrecipe_set.all(): - # assuming that permissions checks for the MealPlan have happened upstream - if instance.servings != x.servings: - SLR = RecipeShoppingEditor(id=x.id, user=user, space=instance.space) - SLR.edit_servings(servings=instance.servings) - elif not user.userpreference.mealplan_autoadd_shopping or not instance.recipe: - print("MEAL_AUTO_ADD No recipe or no setting") - return - - if created: - SLR = RecipeShoppingEditor(user=user, space=space) - SLR.create(mealplan=instance, servings=instance.servings) - print("MEAL_AUTO_ADD Created SLR") - except AttributeError: - pass - - @receiver(post_save, sender=Unit) def clear_unit_cache(sender, instance=None, created=False, **kwargs): if instance: diff --git a/vue3/src/components/display/HorizontalRecipeWindow.vue b/vue3/src/components/display/HorizontalRecipeWindow.vue index 6fbfa98e4..a6dcfa52e 100644 --- a/vue3/src/components/display/HorizontalRecipeWindow.vue +++ b/vue3/src/components/display/HorizontalRecipeWindow.vue @@ -130,6 +130,8 @@ function loadRecipes() { keyword.value = r.results[0] requestParameters.keywords = [keyword.value.id!] doRecipeRequest(requestParameters) + } else { + loading.value = false } }) return; diff --git a/vue3/src/components/display/ShoppingListView.vue b/vue3/src/components/display/ShoppingListView.vue index d97d92aa1..b09e5c4ba 100644 --- a/vue3/src/components/display/ShoppingListView.vue +++ b/vue3/src/components/display/ShoppingListView.vue @@ -178,8 +178,10 @@ {{ r.recipeName }} @@ -211,7 +213,7 @@ import {computed, onMounted, ref} from "vue"; import {useShoppingStore} from "@/stores/ShoppingStore"; -import {ApiApi, Food, IngredientString, ResponseError, ShoppingListEntry, ShoppingListRecipe, Supermarket, Unit} from "@/openapi"; +import {ApiApi, IngredientString, ResponseError, ShoppingListEntry, ShoppingListRecipe, Supermarket} from "@/openapi"; import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore"; import ShoppingLineItem from "@/components/display/ShoppingLineItem.vue"; import {useUserPreferenceStore} from "@/stores/UserPreferenceStore"; @@ -221,6 +223,7 @@ import {IShoppingListCategory, IShoppingListFood, ShoppingGroupingOptions} from import {useI18n} from "vue-i18n"; import NumberScalerDialog from "@/components/inputs/NumberScalerDialog.vue"; import SupermarketEditor from "@/components/model_editors/SupermarketEditor.vue"; +import DeleteConfirmDialog from "@/components/dialogs/DeleteConfirmDialog.vue"; const {t} = useI18n() @@ -340,6 +343,20 @@ function autoSyncLoop() { }, timeout) } +/** + * delete shopping list recipe + */ +function deleteListRecipe(slr: ShoppingListRecipe){ + let api = new ApiApi() + + api.apiShoppingListRecipeDestroy({id: slr.id!}).then(r => { + useShoppingStore().refreshFromAPI() + useMessageStore().addPreparedMessage(PreparedMessage.DELETE_SUCCESS) + }).catch(err => { + useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err) + }) +} +