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 @@
- useMealPlanStore().plans.set(arg.id, arg)">
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) }}
+
+
+
@@ -230,14 +226,13 @@ 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";
+import ShoppingListEntryInput from "@/components/inputs/ShoppingListEntryInput.vue";
+import {DateTime} from "luxon";
const {t} = useI18n()
const currentTab = ref("shopping")
-const ingredientInput = ref('')
-const ingredientInputIcon = ref('fa-solid fa-plus')
-
const shoppingLineItemDialog = ref(false)
const shoppingLineItemDialogFood = ref({} as IShoppingListFood)
@@ -273,29 +268,6 @@ onMounted(() => {
}
})
-/**
- * add new ingredient from ingredient text input
- */
-function addIngredient() {
- const api = new ApiApi()
-
- api.apiIngredientFromStringCreate({ingredientString: {text: ingredientInput.value} as IngredientString}).then(r => {
- useShoppingStore().createObject({
- amount: Math.max(r.amount, 1),
- unit: r.unit,
- food: r.food,
- } as ShoppingListEntry, true)
- ingredientInput.value = ''
-
- ingredientInputIcon.value = 'fa-solid fa-check'
- setTimeout(() => {
- ingredientInputIcon.value = 'fa-solid fa-plus'
- }, 1000)
- }).catch(err => {
- useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
- })
-}
-
/**
* determines if a category as entries that should be visible
* @param category
diff --git a/vue3/src/components/inputs/ShoppingListEntryInput.vue b/vue3/src/components/inputs/ShoppingListEntryInput.vue
new file mode 100644
index 0000000000..a65362d018
--- /dev/null
+++ b/vue3/src/components/inputs/ShoppingListEntryInput.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vue3/src/components/model_editors/MealPlanEditor.vue b/vue3/src/components/model_editors/MealPlanEditor.vue
index 580a04cda2..7c776f4c63 100644
--- a/vue3/src/components/model_editors/MealPlanEditor.vue
+++ b/vue3/src/components/model_editors/MealPlanEditor.vue
@@ -11,7 +11,7 @@
{{ $t('Meal_Plan') }}
- {{ $t('Shopping_list') }}
+ {{ $t('Shopping_list') }}
@@ -67,26 +67,23 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -99,7 +96,7 @@