related recipes included when adding mealplan to shopping list

This commit is contained in:
smilerz 2021-10-28 20:40:56 -05:00
parent 6135a6f26d
commit ecac3f3c2d
13 changed files with 519 additions and 594 deletions

View File

@ -490,8 +490,8 @@ class ShoppingPreferenceForm(forms.ModelForm):
'of mobile data. If lower than instance limit it is reset when saving.' # noqa: E501
),
'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'),
'mealplan_autoexclude_onhand': _('When automatically adding a meal plan to the shopping list, exclude ingredients that are on hand.'),
'mealplan_autoinclude_related': _('When automatically adding a meal plan to the shopping list, include all related recipes.'),
'mealplan_autoinclude_related': _('When adding a meal plan to the shopping list (manually or automatically), include all related recipes.'),
'mealplan_autoexclude_onhand': _('When adding a meal plan to the shopping list (manually or automatically), exclude ingredients that are on hand.'),
'default_delay': _('Default number of hours to delay a shopping list entry.'),
'filter_to_supermarket': _('Filter shopping list to only include supermarket categories.'),
}

View File

@ -1,11 +1,15 @@
from datetime import timedelta
from decimal import Decimal
from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import F, OuterRef, Q, Subquery, Value
from django.db.models.functions import Coalesce
from django.utils import timezone
from cookbook.models import UserPreference
from cookbook.helper.HelperFunctions import Round, str2bool
from cookbook.models import (Ingredient, ShoppingListEntry, ShoppingListRecipe,
SupermarketCategoryRelation)
from recipes import settings
def shopping_helper(qs, request):
@ -35,3 +39,77 @@ def shopping_helper(qs, request):
supermarket_order = ['checked'] + supermarket_order
return qs.order_by(*supermarket_order).select_related('unit', 'food', 'ingredient', 'created_by', 'list_recipe', 'list_recipe__mealplan', 'list_recipe__recipe')
def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None, append=False):
"""
Creates ShoppingListRecipe and associated ShoppingListEntrys from a recipe or a meal plan with a recipe
:param list_recipe: Modify an existing ShoppingListRecipe
:param recipe: Recipe to use as list of ingredients. One of [recipe, mealplan] are required
:param mealplan: alternatively use a mealplan recipe as source of ingredients
:param servings: Optional: Number of servings to use to scale shoppinglist. If servings = 0 an existing recipe list will be deleted
:param ingredients: Ingredients, list of ingredient IDs to include on the shopping list. When not provided all ingredients will be used
:param append: If False will remove any entries not included with ingredients, when True will append ingredients to the shopping list
"""
# TODO cascade to related recipes
r = recipe or getattr(mealplan, 'recipe', None) or getattr(list_recipe, 'recipe', None)
if not r:
raise ValueError(_("You must supply a recipe or mealplan"))
created_by = created_by or getattr(mealplan, 'created_by', None) or getattr(list_recipe, 'created_by', None)
if not created_by:
raise ValueError(_("You must supply a created_by"))
if type(servings) not in [int, float]:
servings = getattr(mealplan, 'servings', 1.0)
shared_users = list(created_by.get_shopping_share())
shared_users.append(created_by)
if list_recipe:
created = False
else:
list_recipe = ShoppingListRecipe.objects.create(recipe=r, mealplan=mealplan, servings=servings)
created = True
if servings == 0 and not created:
list_recipe.delete()
return []
elif ingredients:
ingredients = Ingredient.objects.filter(pk__in=ingredients, space=space)
else:
ingredients = Ingredient.objects.filter(step__recipe=r, space=space)
add_ingredients = ingredients.values_list('id', flat=True)
if not append:
existing_list = ShoppingListEntry.objects.filter(list_recipe=list_recipe)
# delete shopping list entries not included in ingredients
existing_list.exclude(ingredient__in=ingredients).delete()
# add shopping list entries that did not previously exist
add_ingredients = set(add_ingredients) - set(existing_list.values_list('ingredient__id', flat=True))
add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
# if servings have changed, update the ShoppingListRecipe and existing Entrys
if servings <= 0:
servings = 1
servings_factor = servings / r.servings
if not created and list_recipe.servings != servings:
update_ingredients = set(ingredients.values_list('id', flat=True)) - set(add_ingredients.values_list('id', flat=True))
for sle in ShoppingListEntry.objects.filter(list_recipe=list_recipe, ingredient__id__in=update_ingredients):
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
sle.save()
# add any missing Entrys
for i in [x for x in add_ingredients if not x.food.ignore_shopping]:
ShoppingListEntry.objects.create(
list_recipe=list_recipe,
food=i.food,
unit=i.unit,
ingredient=i,
amount=i.amount * Decimal(servings_factor),
created_by=created_by,
space=space,
)
# return all shopping list items
return list_recipe

View File

@ -783,17 +783,6 @@ class MealPlan(ExportModelOperationsMixin('meal_plan'), models.Model, Permission
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')
# TODO override create method to check if recipes are always added
# @classmethod
# def generate_shoppinglist(self, ingredients=None):
# recipe_list = ShoppingListRecipe.objects.create()
# if not ingredients:
# ingredients = Ingredient.objects.filter(step__recipe=self.recipe)
# for i in ingredients:
# ShoppingListEntry.objects.create(
# )
def get_label(self):
if self.title:
return self.title
@ -847,149 +836,6 @@ class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), model
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')
@classmethod
@atomic
def list_from_recipe(self, list_recipe=None, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None):
"""
Creates ShoppingListRecipe and associated ShoppingListEntrys from a recipe or a meal plan with a recipe
:param list_recipe: Modify an existing ShoppingListRecipe
:param recipe: Recipe to use as list of ingredients. One of [recipe, mealplan] are required
:param mealplan: alternatively use a mealplan recipe as source of ingredients
:param servings: Optional: Number of servings to use to scale shoppinglist. If servings = 0 an existing recipe list will be deleted
:param ingredients: Ingredients, list of ingredient IDs to include on the shopping list. When not provided all ingredients will be used
"""
# TODO cascade to related recipes
r = recipe or getattr(mealplan, 'recipe', None) or getattr(list_recipe, 'recipe', None)
if not r:
raise ValueError(_("You must supply a recipe or mealplan"))
created_by = created_by or getattr(mealplan, 'created_by', None) or getattr(list_recipe, 'created_by', None)
if not created_by:
raise ValueError(_("You must supply a created_by"))
if type(servings) not in [int, float]:
servings = getattr(mealplan, 'servings', 1.0)
shared_users = list(created_by.get_shopping_share())
shared_users.append(created_by)
if list_recipe:
created = False
else:
list_recipe = ShoppingListRecipe.objects.create(recipe=r, mealplan=mealplan, servings=servings)
created = True
if servings == 0 and not created:
list_recipe.delete()
return []
elif ingredients:
ingredients = Ingredient.objects.filter(pk__in=ingredients, space=space)
else:
ingredients = Ingredient.objects.filter(step__recipe=r, space=space)
existing_list = ShoppingListEntry.objects.filter(list_recipe=list_recipe)
# delete shopping list entries not included in ingredients
existing_list.exclude(ingredient__in=ingredients).delete()
# add shopping list entries that did not previously exist
add_ingredients = set(ingredients.values_list('id', flat=True)) - set(existing_list.values_list('ingredient__id', flat=True))
add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
# if servings have changed, update the ShoppingListRecipe and existing Entrys
if servings <= 0:
servings = 1
servings_factor = servings / r.servings
if not created and list_recipe.servings != servings:
update_ingredients = set(ingredients.values_list('id', flat=True)) - set(add_ingredients.values_list('id', flat=True))
for sle in ShoppingListEntry.objects.filter(list_recipe=list_recipe, ingredient__id__in=update_ingredients):
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
sle.save()
# add any missing Entrys
shoppinglist = [
ShoppingListEntry(
list_recipe=list_recipe,
food=i.food,
unit=i.unit,
ingredient=i,
amount=i.amount * Decimal(servings),
created_by=created_by,
space=space
)
for i in ingredients
]
return ShoppingListEntry.objects.bulk_create(shoppinglist)
@classmethod
@atomic
def list_from_recipe(self, list_recipe=None, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None):
"""
Creates ShoppingListRecipe and associated ShoppingListEntrys from a recipe or a meal plan with a recipe
:param list_recipe: Modify an existing ShoppingListRecipe
:param recipe: Recipe to use as list of ingredients. One of [recipe, mealplan] are required
:param mealplan: alternatively use a mealplan recipe as source of ingredients
:param servings: Optional: Number of servings to use to scale shoppinglist. If servings = 0 an existing recipe list will be deleted
:param ingredients: Ingredients, list of ingredient IDs to include on the shopping list. When not provided all ingredients will be used
"""
# TODO cascade to related recipes
r = recipe or getattr(mealplan, 'recipe', None) or getattr(list_recipe, 'recipe', None)
if not r:
raise ValueError(_("You must supply a recipe or mealplan"))
created_by = created_by or getattr(mealplan, 'created_by', None) or getattr(list_recipe, 'created_by', None)
if not created_by:
raise ValueError(_("You must supply a created_by"))
if type(servings) not in [int, float]:
servings = getattr(mealplan, 'servings', 1.0)
shared_users = list(created_by.get_shopping_share())
shared_users.append(created_by)
if list_recipe:
created = False
else:
list_recipe = ShoppingListRecipe.objects.create(recipe=r, mealplan=mealplan, servings=servings)
created = True
if servings == 0 and not created:
list_recipe.delete()
return []
elif ingredients:
ingredients = Ingredient.objects.filter(pk__in=ingredients, space=space)
else:
ingredients = Ingredient.objects.filter(step__recipe=r, space=space)
existing_list = ShoppingListEntry.objects.filter(list_recipe=list_recipe)
# delete shopping list entries not included in ingredients
existing_list.exclude(ingredient__in=ingredients).delete()
# add shopping list entries that did not previously exist
add_ingredients = set(ingredients.values_list('id', flat=True)) - set(existing_list.values_list('ingredient__id', flat=True))
add_ingredients = Ingredient.objects.filter(id__in=add_ingredients, space=space)
# if servings have changed, update the ShoppingListRecipe and existing Entrys
if servings <= 0:
servings = 1
servings_factor = servings / r.servings
if not created and list_recipe.servings != servings:
update_ingredients = set(ingredients.values_list('id', flat=True)) - set(add_ingredients.values_list('id', flat=True))
for sle in ShoppingListEntry.objects.filter(list_recipe=list_recipe, ingredient__id__in=update_ingredients):
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
sle.save()
# add any missing Entrys
shoppinglist = [
ShoppingListEntry(
list_recipe=list_recipe,
food=i.food,
unit=i.unit,
ingredient=i,
amount=i.amount * Decimal(servings_factor),
created_by=created_by,
space=space
)
for i in [x for x in add_ingredients if not x.food.ignore_shopping]
]
ShoppingListEntry.objects.bulk_create(shoppinglist)
# return all shopping list items
print('end of servings')
return ShoppingListEntry.objects.filter(list_recipe=list_recipe)
@ staticmethod
def get_space_key():
return 'shoppinglist', 'space'

View File

@ -12,6 +12,7 @@ from drf_writable_nested import UniqueFieldsMixin, WritableNestedModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import NotFound, ValidationError
from cookbook.helper.shopping_helper import list_from_recipe
from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Food,
FoodInheritField, ImportLog, Ingredient, Keyword, MealPlan, MealType,
NutritionInformation, Recipe, RecipeBook, RecipeBookEntry,
@ -616,7 +617,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
validated_data['created_by'] = self.context['request'].user
mealplan = super().create(validated_data)
if self.context['request'].data.get('addshopping', False):
ShoppingListEntry.list_from_recipe(mealplan=mealplan, space=validated_data['space'], created_by=validated_data['created_by'])
list_from_recipe(mealplan=mealplan, space=validated_data['space'], created_by=validated_data['created_by'])
return mealplan
class Meta:
@ -648,7 +649,7 @@ class ShoppingListRecipeSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
if 'servings' in validated_data:
ShoppingListEntry.list_from_recipe(
list_from_recipe(
list_recipe=instance,
servings=validated_data['servings'],
created_by=self.context['request'].user,

View File

@ -1,3 +1,4 @@
from decimal import Decimal
from functools import wraps
from django.contrib.postgres.search import SearchVector
@ -5,8 +6,10 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import translation
from cookbook.helper.shopping_helper import list_from_recipe
from cookbook.managers import DICTIONARY
from cookbook.models import Food, FoodInheritField, Recipe, Step
from cookbook.models import (Food, FoodInheritField, Ingredient, MealPlan, Recipe,
ShoppingListEntry, Step)
# wraps a signal with the ability to set 'skip_signal' to avoid creating recursive signals
@ -78,3 +81,52 @@ def update_food_inheritance(sender, instance=None, created=False, **kwargs):
# don't cascade empty supermarket category
if instance.supermarket_category:
instance.get_children().filter(inherit=True).exclude(ignore_inherit__field='supermarket_category').update(supermarket_category=instance.supermarket_category)
@receiver(post_save, sender=MealPlan)
def auto_add_shopping(sender, instance=None, created=False, weak=False, **kwargs):
user = instance.get_owner()
if not created or not user.userpreference.mealplan_autoadd_shopping:
return
# if creating a mealplan - perform shopping list activities
space = instance.space
if user.userpreference.mealplan_autoadd_shopping:
kwargs = {
'mealplan': instance,
'space': space,
'created_by': user,
'servings': instance.servings
}
recipe_ingredients = Ingredient.objects.filter(step__recipe=instance.recipe, space=space)
if exclude_onhand := user.userpreference.mealplan_autoexclude_onhand:
recipe_ingredients = recipe_ingredients.exclude(food__on_hand=True)
if related := user.userpreference.mealplan_autoinclude_related:
# TODO: add levels of related recipes to use when auto-adding mealplans
related_recipes = instance.recipe.get_related_recipes()
# dont' add recipes that are going to have their recipes added to the shopping list
kwargs['ingredients'] = recipe_ingredients.exclude(food__recipe__in=related_recipes).values_list('id', flat=True)
else:
kwargs['ingredients'] = recipe_ingredients.values_list('id', flat=True)
list_recipe = list_from_recipe(**kwargs)
if related:
servings_factor = Decimal(instance.servings / instance.recipe.servings)
kwargs['list_recipe'] = list_recipe
food_recipes = recipe_ingredients.filter(food__recipe__in=related_recipes).values('food__recipe', 'amount')
for recipe in related_recipes:
kwargs['ingredients'] = []
if exclude_onhand:
kwargs['ingredients'] = Ingredient.objects.filter(step__recipe=recipe, food__on_hand=False, space=space).values_list('id', flat=True)
kwargs['recipe'] = recipe
# assume related recipes are intended to be 'full sized' to parent recipe
# Recipe1 (servings:4) includes StepRecipe2(servings:2) a Meal Plan serving size of 8 would assume 4 servings of StepRecipe2
if recipe.id in [x['food__recipe'] for x in food_recipes if x['food__recipe'] == recipe.id]:
kwargs['servings'] = Decimal(recipe.servings) * sum([x['amount'] for x in food_recipes if x['food__recipe'] == recipe.id]) * servings_factor
else:
# TODO: When modifying step recipes to allow serving size - will need to update this
kwargs['servings'] = Decimal(recipe.servings) * servings_factor
list_from_recipe(**kwargs, append=True)

View File

@ -243,7 +243,7 @@
window.location.hash = e.target.hash;
})
// listen for events
$(document).ready(function(){
{% comment %} $(document).ready(function(){
hideShow()
// call hideShow when the user clicks on the mealplan_autoadd checkbox
$("#id_shopping-mealplan_autoadd_shopping").click(function(event){
@ -261,7 +261,7 @@
{
$('#div_id_shopping-mealplan_autoexclude_onhand').hide();
$('#div_id_shopping-mealplan_autoinclude_related').hide();
}
} {% endcomment %}
}
</script>
{% endblock %}

View File

@ -38,7 +38,7 @@ from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsGuest, Cus
from cookbook.helper.recipe_html_import import get_recipe_from_source
from cookbook.helper.recipe_search import get_facet, old_search, search_recipes
from cookbook.helper.recipe_url_import import get_from_scraper
from cookbook.helper.shopping_helper import shopping_helper
from cookbook.helper.shopping_helper import list_from_recipe, shopping_helper
from cookbook.models import (Automation, BookmarkletImport, CookLog, Food, FoodInheritField,
ImportLog, Ingredient, Keyword, MealPlan, MealType, Recipe, RecipeBook,
RecipeBookEntry, ShareLink, ShoppingList, ShoppingListEntry,
@ -658,7 +658,7 @@ class RecipeViewSet(viewsets.ModelViewSet):
list_recipe = request.data.get('list_recipe', None)
content = {'msg': _(f'{obj.name} was added to the shopping list.')}
# TODO: Consider if this should be a Recipe method
ShoppingListEntry.list_from_recipe(list_recipe=list_recipe, recipe=obj, ingredients=ingredients, servings=servings, space=request.space, created_by=request.user)
list_from_recipe(list_recipe=list_recipe, recipe=obj, ingredients=ingredients, servings=servings, space=request.space, created_by=request.user)
return Response(content, status=status.HTTP_204_NO_CONTENT)

View File

@ -81,18 +81,11 @@
<hr />
<div class="row">
<div class="col-md-8 order-md-1 col-sm-12 order-sm-2 col-12 order-2" v-if="recipe && ingredient_count > 0">
<ingredients-card
:steps="recipe.steps"
:recipe="recipe.id"
:ingredient_factor="ingredient_factor"
:servings="servings"
:header="true"
@checked-state-changed="updateIngredientCheckedState"
/>
<div class="col-md-6 order-md-1 col-sm-12 order-sm-2 col-12 order-2" v-if="recipe && ingredient_count > 0">
<ingredients-card :steps="recipe.steps" :ingredient_factor="ingredient_factor" :servings="servings" :header="true" @checked-state-changed="updateIngredientCheckedState" />
</div>
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-4 order-md-2">
<div class="col-12 order-1 col-sm-12 order-sm-1 col-md-6 order-md-2">
<div class="row">
<div class="col-12">
<img class="img img-fluid rounded" :src="recipe.image" style="max-height: 30vh" :alt="$t('Recipe_Image')" v-if="recipe.image !== null" />
@ -149,11 +142,11 @@ import { apiLoadRecipe } from "@/utils/api"
import Step from "@/components/Step"
import RecipeContextMenu from "@/components/ContextMenu/RecipeContextMenu"
import { ResolveUrlMixin, ToastMixin } from "@/utils/utils"
import IngredientsCard from "@/components/IngredientsCard"
import PdfViewer from "@/components/PdfViewer"
import ImageViewer from "@/components/ImageViewer"
import Nutrition from "@/components/Nutrition"
import IngredientsCard from "@/components/IngredientsCard"
import moment from "moment"
import Keywords from "@/components/Keywords"

View File

@ -1,34 +0,0 @@
<template>
<div>
<div style="position: static;" class=" btn-group">
<div class="dropdown b-dropdown position-static">
<li @click="$refs.submenu.open($event)" role="presentation" class="btn dropdown-toggle btn-link text-decoration-none text-body pr-1 dropdown-toggle-no-caret">
<slot />
</li>
</div>
</div>
<ContextMenu ref="submenu">
<template #menu="{ contextData }">
<ContextMenuItem
@click="
$refs.menu.close()
moveEntry(contextData)
"
>
<a class="dropdown-item p-2" href="#"><i class="fas fa-cubes"></i> submenu item</a>
</ContextMenuItem>
</template>
</ContextMenu>
</div>
</template>
<script>
import ContextMenu from "@/components/ContextMenu/ContextMenu"
import ContextMenuItem from "@/components/ContextMenu/ContextMenuItem"
export default {
name: "ContextSubmenu.vue",
components: { ContextMenu, ContextMenuItem },
}
</script>
<style scoped></style>

View File

@ -1,193 +1,189 @@
<template>
<div>
<div>
<div class="dropdown d-print-none">
<a class="btn shadow-none" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-lg"></i>
</a>
<div class="dropdown d-print-none">
<a class="btn shadow-none" href="javascript:void(0);" role="button" id="dropdownMenuLink"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-lg"></i>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item" :href="resolveDjangoUrl('edit_recipe', recipe.id)"><i class="fas fa-pencil-alt fa-fw"></i> {{ $t("Edit") }}</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item" :href="resolveDjangoUrl('edit_convert_recipe', recipe.id)" v-if="!recipe.internal"
><i class="fas fa-exchange-alt fa-fw"></i> {{ $t("convert_internal") }}</a
>
<a class="dropdown-item" :href="resolveDjangoUrl('edit_recipe', recipe.id)"><i
class="fas fa-pencil-alt fa-fw"></i> {{ $t('Edit') }}</a>
<a href="#">
<button class="dropdown-item" @click="$bvModal.show(`id_modal_add_book_${modal_id}`)"><i class="fas fa-bookmark fa-fw"></i> {{ $t("Manage_Books") }}</button>
</a>
<a class="dropdown-item" :href="resolveDjangoUrl('edit_convert_recipe', recipe.id)" v-if="!recipe.internal"><i
class="fas fa-exchange-alt fa-fw"></i> {{ $t('convert_internal') }}</a>
<a
class="dropdown-item"
:href="`${resolveDjangoUrl('view_shopping')}?r=[${recipe.id},${servings_value}]`"
v-if="recipe.internal"
target="_blank"
rel="noopener noreferrer"
>
<i class="fas fa-shopping-cart fa-fw"></i> {{ $t("Add_to_Shopping") }}
</a>
<a href="javascript:void(0);">
<button class="dropdown-item" @click="$bvModal.show(`id_modal_add_book_${modal_id}`)">
<i class="fas fa-bookmark fa-fw"></i> {{ $t('Manage_Books') }}
</button>
</a>
<a class="dropdown-item" v-if="recipe.internal" @click="addToShopping" href="#"> <i class="fas fa-shopping-cart fa-fw"></i> New {{ $t("Add_to_Shopping") }} </a>
<a class="dropdown-item" :href="`${resolveDjangoUrl('view_shopping') }?r=[${recipe.id},${servings_value}]`"
v-if="recipe.internal" target="_blank" rel="noopener noreferrer">
<i class="fas fa-shopping-cart fa-fw"></i> {{ $t('Add_to_Shopping') }}
</a>
<a class="dropdown-item" @click="createMealPlan" href="#"><i class="fas fa-calendar fa-fw"></i> {{ $t("Add_to_Plan") }} </a>
<a class="dropdown-item" v-if="recipe.internal" @click="addToShopping" href="#">
<i class="fas fa-shopping-cart fa-fw"></i> New {{ $t('Add_to_Shopping') }}
</a>
<a href="#">
<button class="dropdown-item" @click="$bvModal.show(`id_modal_cook_log_${modal_id}`)">
<i class="fas fa-clipboard-list fa-fw"></i> {{ $t("Log_Cooking") }}
</button>
</a>
<a class="dropdown-item" @click="createMealPlan" href="#"><i
class="fas fa-calendar fa-fw"></i> {{ $t('Add_to_Plan') }}
</a>
<a href="#">
<button class="dropdown-item" onclick="window.print()"><i class="fas fa-print fa-fw"></i> {{ $t("Print") }}</button>
</a>
<a href="javascript:void(0);">
<button class="dropdown-item" @click="$bvModal.show(`id_modal_cook_log_${modal_id}`)"><i
class="fas fa-clipboard-list fa-fw"></i> {{ $t('Log_Cooking') }}
</button>
</a>
<a class="dropdown-item" :href="resolveDjangoUrl('view_export') + '?r=' + recipe.id" target="_blank" rel="noopener noreferrer"
><i class="fas fa-file-export fa-fw"></i> {{ $t("Export") }}</a
>
<a href="javascript:void(0);">
<button class="dropdown-item" onclick="window.print()"><i
class="fas fa-print fa-fw"></i> {{ $t('Print') }}
</button>
</a>
<a class="dropdown-item" :href="resolveDjangoUrl('view_export') + '?r=' + recipe.id" target="_blank"
rel="noopener noreferrer"><i class="fas fa-file-export fa-fw"></i> {{ $t('Export') }}</a>
<a href="javascript:void(0);">
<button class="dropdown-item" @click="createShareLink()" v-if="recipe.internal"><i
class="fas fa-share-alt fa-fw"></i> {{ $t('Share') }}
</button>
</a>
</div>
</div>
<cook-log :recipe="recipe" :modal_id="modal_id"></cook-log>
<add-recipe-to-book :recipe="recipe" :modal_id="modal_id"></add-recipe-to-book>
<b-modal :id="`modal-share-link_${modal_id}`" v-bind:title="$t('Share')" hide-footer>
<div class="row">
<div class="col col-md-12">
<label v-if="recipe_share_link !== undefined">{{ $t('Public share link') }}</label>
<input ref="share_link_ref" class="form-control" v-model="recipe_share_link"/>
<b-button class="mt-2 mb-3 d-none d-md-inline" variant="secondary"
@click="$bvModal.hide(`modal-share-link_${modal_id}`)">{{ $t('Close') }}
</b-button>
<b-button class="mt-2 mb-3 ml-md-2" variant="primary" @click="copyShareLink()">{{ $t('Copy') }}</b-button>
<b-button class="mt-2 mb-3 ml-2 float-right" variant="success" @click="shareIntend()">{{ $t('Share') }} <i
class="fa fa-share-alt"></i></b-button>
<a href="#">
<button class="dropdown-item" @click="createShareLink()" v-if="recipe.internal"><i class="fas fa-share-alt fa-fw"></i> {{ $t("Share") }}</button>
</a>
</div>
</div>
</div>
</b-modal>
<meal-plan-edit-modal :entry="entryEditing" :entryEditing_initial_recipe="[recipe]"
:entry-editing_initial_meal_type="[]" @save-entry="saveMealPlan"
:modal_id="`modal-meal-plan_${modal_id}`" :allow_delete="false" :modal_title="$t('Create_Meal_Plan_Entry')"></meal-plan-edit-modal>
<shopping-modal :recipe="recipe" :servings="servings_value" :modal_id="modal_id"/>
</div>
<cook-log :recipe="recipe" :modal_id="modal_id"></cook-log>
<add-recipe-to-book :recipe="recipe" :modal_id="modal_id"></add-recipe-to-book>
<b-modal :id="`modal-share-link_${modal_id}`" v-bind:title="$t('Share')" hide-footer>
<div class="row">
<div class="col col-md-12">
<label v-if="recipe_share_link !== undefined">{{ $t("Public share link") }}</label>
<input ref="share_link_ref" class="form-control" v-model="recipe_share_link" />
<b-button class="mt-2 mb-3 d-none d-md-inline" variant="secondary" @click="$bvModal.hide(`modal-share-link_${modal_id}`)">{{ $t("Close") }} </b-button>
<b-button class="mt-2 mb-3 ml-md-2" variant="primary" @click="copyShareLink()">{{ $t("Copy") }}</b-button>
<b-button class="mt-2 mb-3 ml-2 float-right" variant="success" @click="shareIntend()">{{ $t("Share") }} <i class="fa fa-share-alt"></i></b-button>
</div>
</div>
</b-modal>
<meal-plan-edit-modal
:entry="entryEditing"
:entryEditing_initial_recipe="[recipe]"
:entryEditing_inital_servings="recipe.servings"
:entry-editing_initial_meal_type="[]"
@save-entry="saveMealPlan"
:modal_id="`modal-meal-plan_${modal_id}`"
:allow_delete="false"
:modal_title="$t('Create_Meal_Plan_Entry')"
></meal-plan-edit-modal>
<shopping-modal :recipe="recipe" :servings="servings_value" :modal_id="modal_id" />
</div>
</template>
<script>
import {makeToast, resolveDjangoUrl, ResolveUrlMixin, StandardToasts} from "@/utils/utils";
import CookLog from "@/components/CookLog";
import axios from "axios";
import AddRecipeToBook from "@/components/Modals/AddRecipeToBook";
import MealPlanEditModal from "@/components/Modals/MealPlanEditModal";
import ShoppingModal from "@/components/Modals/ShoppingModal";
import moment from "moment";
import Vue from "vue";
import {ApiApiFactory} from "@/utils/openapi/api";
import { makeToast, resolveDjangoUrl, ResolveUrlMixin, StandardToasts } from "@/utils/utils"
import CookLog from "@/components/CookLog"
import axios from "axios"
import AddRecipeToBook from "@/components/Modals/AddRecipeToBook"
import MealPlanEditModal from "@/components/Modals/MealPlanEditModal"
import ShoppingModal from "@/components/Modals/ShoppingModal"
import moment from "moment"
import Vue from "vue"
import { ApiApiFactory } from "@/utils/openapi/api"
Vue.prototype.moment = moment
export default {
name: 'RecipeContextMenu',
mixins: [
ResolveUrlMixin
],
components: {
AddRecipeToBook,
CookLog,
MealPlanEditModal,
ShoppingModal
},
data() {
return {
servings_value: 0,
recipe_share_link: undefined,
modal_id: this.recipe.id + Math.round(Math.random() * 100000),
options: {
entryEditing: {
date: null,
id: -1,
meal_type: null,
note: "",
note_markdown: "",
recipe: null,
servings: 1,
shared: [],
title: '',
title_placeholder: this.$t('Title'),
name: "RecipeContextMenu",
mixins: [ResolveUrlMixin],
components: {
AddRecipeToBook,
CookLog,
MealPlanEditModal,
ShoppingModal,
},
data() {
return {
servings_value: 0,
recipe_share_link: undefined,
modal_id: this.recipe.id + Math.round(Math.random() * 100000),
options: {
entryEditing: {
date: null,
id: -1,
meal_type: null,
note: "",
note_markdown: "",
recipe: null,
servings: 1,
shared: [],
title: "",
title_placeholder: this.$t("Title"),
},
},
entryEditing: {},
}
},
entryEditing: {},
}
},
props: {
recipe: Object,
servings: {
type: Number,
default: -1
}
},
mounted() {
this.servings_value = ((this.servings === -1) ? this.recipe.servings : this.servings)
},
methods: {
saveMealPlan: function (entry) {
entry.date = moment(entry.date).format("YYYY-MM-DD")
},
props: {
recipe: Object,
servings: {
type: Number,
default: -1,
},
},
mounted() {
this.servings_value = this.servings === -1 ? this.recipe.servings : this.servings
},
methods: {
saveMealPlan: function(entry) {
entry.date = moment(entry.date).format("YYYY-MM-DD")
let apiClient = new ApiApiFactory()
let apiClient = new ApiApiFactory()
apiClient.createMealPlan(entry).then(result => {
this.$bvModal.hide(`modal-meal-plan_${this.modal_id}`)
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
}).catch(error => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_CREATE)
})
apiClient
.createMealPlan(entry)
.then((result) => {
this.$bvModal.hide(`modal-meal-plan_${this.modal_id}`)
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
})
.catch((error) => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_CREATE)
})
},
createMealPlan(data) {
this.entryEditing = this.options.entryEditing
this.entryEditing.recipe = this.recipe
this.entryEditing.date = moment(new Date()).format("YYYY-MM-DD")
this.$bvModal.show(`modal-meal-plan_${this.modal_id}`)
},
createShareLink: function() {
axios
.get(resolveDjangoUrl("api_share_link", this.recipe.id))
.then((result) => {
this.$bvModal.show(`modal-share-link_${this.modal_id}`)
this.recipe_share_link = result.data.link
})
.catch((err) => {
if (err.response.status === 403) {
makeToast(this.$t("Share"), this.$t("Sharing is not enabled for this space."), "danger")
}
})
},
copyShareLink: function() {
let share_input = this.$refs.share_link_ref
share_input.select()
document.execCommand("copy")
},
shareIntend: function() {
let shareData = {
title: this.recipe.name,
text: `${this.$t("Check out this recipe: ")} ${this.recipe.name}`,
url: this.recipe_share_link,
}
navigator.share(shareData)
},
addToShopping() {
this.$bvModal.show(`shopping_${this.modal_id}`)
},
},
createMealPlan(data) {
this.entryEditing = this.options.entryEditing
this.entryEditing.recipe = this.recipe
this.entryEditing.date = moment(new Date()).format('YYYY-MM-DD')
this.$bvModal.show(`modal-meal-plan_${this.modal_id}`)
},
createShareLink: function () {
axios.get(resolveDjangoUrl('api_share_link', this.recipe.id)).then(result => {
this.$bvModal.show(`modal-share-link_${this.modal_id}`)
this.recipe_share_link = result.data.link
}).catch(err => {
if (err.response.status === 403) {
makeToast(this.$t('Share'), this.$t('Sharing is not enabled for this space.'), 'danger')
}
})
},
copyShareLink: function () {
let share_input = this.$refs.share_link_ref;
share_input.select();
document.execCommand("copy");
},
shareIntend: function () {
let shareData = {
title: this.recipe.name,
text: `${this.$t('Check out this recipe: ')} ${this.recipe.name}`,
url: this.recipe_share_link
}
navigator.share(shareData)
},
addToShopping() {
this.$bvModal.show(`shopping_${this.modal_id}`)
},
}
}
</script>

View File

@ -12,15 +12,11 @@
@change="missing_recipe = false"
></b-form-input>
<b-input-group-append class="d-none d-lg-block">
<b-button variant="primary" @click="entryEditing.title = ''"
><i class="fa fa-eraser"></i
></b-button>
<b-button variant="primary" @click="entryEditing.title = ''"><i class="fa fa-eraser"></i></b-button>
</b-input-group-append>
</b-input-group>
<span class="text-danger" v-if="missing_recipe">{{ $t("Title_or_Recipe_Required") }}</span>
<small tabindex="-1" class="form-text text-muted" v-if="!missing_recipe">{{
$t("Title")
}}</small>
<small tabindex="-1" class="form-text text-muted" v-if="!missing_recipe">{{ $t("Title") }}</small>
</div>
<div class="col-6 col-lg-3">
<input type="date" id="DateInput" class="form-control" v-model="entryEditing.date" />
@ -58,24 +54,13 @@
@new="createMealType"
></generic-multiselect>
<span class="text-danger" v-if="missing_meal_type">{{ $t("Meal_Type_Required") }}</span>
<small tabindex="-1" class="form-text text-muted" v-if="!missing_meal_type">{{
$t("Meal_Type")
}}</small>
<small tabindex="-1" class="form-text text-muted" v-if="!missing_meal_type">{{ $t("Meal_Type") }}</small>
</b-form-group>
<b-form-group label-for="NoteInput" :description="$t('Note')" class="mt-3">
<textarea
class="form-control"
id="NoteInput"
v-model="entryEditing.note"
:placeholder="$t('Note')"
></textarea>
<textarea class="form-control" id="NoteInput" v-model="entryEditing.note" :placeholder="$t('Note')"></textarea>
</b-form-group>
<b-input-group>
<b-form-input
id="ServingsInput"
v-model="entryEditing.servings"
:placeholder="$t('Servings')"
></b-form-input>
<b-form-input id="ServingsInput" v-model="entryEditing.servings" :placeholder="$t('Servings')"></b-form-input>
</b-input-group>
<small tabindex="-1" class="form-text text-muted">{{ $t("Servings") }}</small>
<!-- TODO: hide this checkbox if autoadding menuplans, but allow editing on-hand -->
@ -90,9 +75,7 @@
</div>
<div class="row mt-3 mb-3">
<div class="col-12">
<b-button variant="danger" @click="deleteEntry" v-if="allow_delete"
>{{ $t("Delete") }}
</b-button>
<b-button variant="danger" @click="deleteEntry" v-if="allow_delete">{{ $t("Delete") }} </b-button>
<b-button class="float-right" variant="primary" @click="editEntry">{{ $t("Save") }}</b-button>
</div>
</div>
@ -119,6 +102,7 @@ export default {
entry: Object,
entryEditing_initial_recipe: Array,
entryEditing_initial_meal_type: Array,
entryEditing_inital_servings: Number,
modal_title: String,
modal_id: {
type: String,
@ -145,6 +129,9 @@ export default {
entry: {
handler() {
this.entryEditing = Object.assign({}, this.entry)
if (this.entryEditing_inital_servings) {
this.entryEditing.servings = this.entryEditing_inital_servings
}
},
deep: true,
},

View File

@ -233,8 +233,8 @@
"shopping_share_desc": "Users will see all items you add to your shopping list. They must add you to see items on their list.",
"shopping_auto_sync_desc": "Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but will use mobile data.",
"mealplan_autoadd_shopping_desc": "Automatically add meal plan ingredients to shopping list.",
"mealplan_autoexclude_onhand_desc": "When automatically adding a meal plan to the shopping list, exclude ingredients that are on hand.",
"mealplan_autoinclude_related_desc": "When automatically adding a meal plan to the shopping list, include all related recipes.",
"mealplan_autoexclude_onhand_desc": "When adding a meal plan to the shopping list (manually or automatically), exclude ingredients that are on hand.",
"mealplan_autoinclude_related_desc": "When adding a meal plan to the shopping list (manually or automatically), include all related recipes.",
"default_delay_desc": "Default number of hours to delay a shopping list entry.",
"filter_to_supermarket": "Filter to Supermarket",
"filter_to_supermarket_desc": "Filter shopping list to only include supermarket categories.",

View File

@ -229,10 +229,10 @@ export interface Food {
parent?: string;
/**
*
* @type {boolean}
* @type {number}
* @memberof Food
*/
on_hand?: boolean;
numchild?: number;
/**
*
* @type {boolean}
@ -269,13 +269,13 @@ export interface FoodIgnoreInherit {
* @type {string}
* @memberof FoodIgnoreInherit
*/
name?: string;
name: string;
/**
*
* @type {string}
* @memberof FoodIgnoreInherit
*/
field?: string;
field: string;
}
/**
*
@ -294,13 +294,13 @@ export interface FoodInheritField {
* @type {string}
* @memberof FoodInheritField
*/
name?: string;
name: string;
/**
*
* @type {string}
* @memberof FoodInheritField
*/
field?: string;
field: string;
}
/**
*
@ -958,37 +958,6 @@ export interface InlineResponse2009 {
*/
results?: Array<ViewLog>;
}
/**
*
* @export
* @interface InlineResponse2009
*/
export interface InlineResponse2009 {
/**
*
* @type {number}
* @memberof InlineResponse2009
*/
count?: number;
/**
*
* @type {string}
* @memberof InlineResponse2009
*/
next?: string | null;
/**
*
* @type {string}
* @memberof InlineResponse2009
*/
previous?: string | null;
/**
*
* @type {Array<ViewLog>}
* @memberof InlineResponse2009
*/
results?: Array<ViewLog>;
}
/**
*
* @export
@ -1006,7 +975,13 @@ export interface Keyword {
* @type {string}
* @memberof Keyword
*/
parent?: string;
name: string;
/**
*
* @type {string}
* @memberof Keyword
*/
icon?: string | null;
/**
*
* @type {string}
@ -1018,13 +993,31 @@ export interface Keyword {
* @type {string}
* @memberof Keyword
*/
created_at?: string;
description?: string;
/**
*
* @type {string}
* @memberof Keyword
*/
parent?: string;
/**
*
* @type {number}
* @memberof Keyword
*/
numchild?: number;
/**
*
* @type {string}
* @memberof Keyword
*/
created_at?: string;
/**
*
* @type {string}
* @memberof Keyword
*/
updated_at?: string;
}
/**
*
@ -1632,61 +1625,6 @@ export interface RecipeIngredients {
*/
no_amount?: boolean;
}
/**
*
* @export
* @interface RecipeKeywords
*/
export interface RecipeIngredients {
/**
*
* @type {number}
* @memberof RecipeIngredients
*/
id?: number;
/**
*
* @type {IngredientFood}
* @memberof RecipeIngredients
*/
food: IngredientFood | null;
/**
*
* @type {FoodSupermarketCategory}
* @memberof RecipeIngredients
*/
unit: FoodSupermarketCategory | null;
/**
*
* @type {string}
* @memberof RecipeIngredients
*/
amount: string;
/**
*
* @type {string}
* @memberof RecipeIngredients
*/
note?: string | null;
/**
*
* @type {number}
* @memberof RecipeIngredients
*/
order?: number;
/**
*
* @type {boolean}
* @memberof RecipeIngredients
*/
is_header?: boolean;
/**
*
* @type {boolean}
* @memberof RecipeIngredients
*/
no_amount?: boolean;
}
/**
*
* @export
@ -1704,7 +1642,13 @@ export interface RecipeKeywords {
* @type {string}
* @memberof RecipeKeywords
*/
parent?: string;
name: string;
/**
*
* @type {string}
* @memberof RecipeKeywords
*/
icon?: string | null;
/**
*
* @type {string}
@ -1716,13 +1660,31 @@ export interface RecipeKeywords {
* @type {string}
* @memberof RecipeKeywords
*/
created_at?: string;
description?: string;
/**
*
* @type {string}
* @memberof RecipeKeywords
*/
parent?: string;
/**
*
* @type {number}
* @memberof RecipeKeywords
*/
numchild?: number;
/**
*
* @type {string}
* @memberof RecipeKeywords
*/
created_at?: string;
/**
*
* @type {string}
* @memberof RecipeKeywords
*/
updated_at?: string;
}
/**
*
@ -2129,10 +2091,10 @@ export interface ShoppingListEntries {
id?: number;
/**
*
* @type {string}
* @type {number}
* @memberof ShoppingListEntries
*/
list_recipe?: string;
list_recipe?: number | null;
/**
*
* @type {IngredientFood}
@ -2186,7 +2148,7 @@ export interface ShoppingListEntries {
* @type {ShoppingListCreatedBy}
* @memberof ShoppingListEntries
*/
created_by: ShoppingListCreatedBy;
created_by?: ShoppingListCreatedBy;
/**
*
* @type {string}
@ -2198,7 +2160,13 @@ export interface ShoppingListEntries {
* @type {string}
* @memberof ShoppingListEntries
*/
completed_at?: string | null;
completed_at: string | null;
/**
*
* @type {string}
* @memberof ShoppingListEntries
*/
delay_until?: string | null;
}
/**
*
@ -2214,10 +2182,10 @@ export interface ShoppingListEntry {
id?: number;
/**
*
* @type {string}
* @type {number}
* @memberof ShoppingListEntry
*/
list_recipe?: string;
list_recipe?: number | null;
/**
*
* @type {IngredientFood}
@ -2283,7 +2251,13 @@ export interface ShoppingListEntry {
* @type {string}
* @memberof ShoppingListEntry
*/
completed_at?: string;
completed_at: string | null;
/**
*
* @type {string}
* @memberof ShoppingListEntry
*/
delay_until?: string | null;
}
/**
*
@ -2297,6 +2271,12 @@ export interface ShoppingListRecipe {
* @memberof ShoppingListRecipe
*/
id?: number;
/**
*
* @type {string}
* @memberof ShoppingListRecipe
*/
recipe_name?: string;
/**
*
* @type {string}
@ -2312,7 +2292,7 @@ export interface ShoppingListRecipe {
/**
*
* @type {number}
* @memberof ShoppingListEntry
* @memberof ShoppingListRecipe
*/
ingredient?: number | null;
/**
@ -2333,79 +2313,6 @@ export interface ShoppingListRecipe {
* @memberof ShoppingListRecipe
*/
servings: string;
/**
*
* @type {string}
* @memberof ShoppingListRecipe
*/
checked?: boolean;
/**
*
* @type {ShoppingListRecipeMealplan}
* @memberof ShoppingListEntry
*/
recipe_mealplan?: ShoppingListRecipeMealplan;
/**
*
* @type {ShoppingListCreatedBy}
* @memberof ShoppingListEntry
*/
created_by: ShoppingListCreatedBy;
/**
*
* @type {string}
* @memberof ShoppingListEntry
*/
created_at?: string;
/**
*
* @type {string}
* @memberof ShoppingListEntry
*/
completed_at?: string | null;
}
/**
*
* @export
* @interface ShoppingListRecipeMealplan
*/
export interface ShoppingListRecipeMealplan {
/**
*
* @type {number}
* @memberof ShoppingListRecipeMealplan
*/
id?: number;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
*/
name?: string;
/**
*
* @type {number}
* @memberof ShoppingListRecipeMealplan
*/
recipe?: number | null;
/**
*
* @type {number}
* @memberof ShoppingListRecipe
*/
mealplan?: number | null;
/**
*
* @type {string}
* @memberof ShoppingListRecipe
*/
mealplan?: number | null;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
*/
servings: string;
/**
*
* @type {string}
@ -2428,7 +2335,13 @@ export interface ShoppingListRecipeMealplan {
/**
*
* @type {string}
* @memberof ShoppingListRecipes
* @memberof ShoppingListRecipeMealplan
*/
recipe_name?: string;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
*/
name?: string;
/**
@ -2437,6 +2350,61 @@ export interface ShoppingListRecipeMealplan {
* @memberof ShoppingListRecipeMealplan
*/
recipe?: number | null;
/**
*
* @type {number}
* @memberof ShoppingListRecipe
*/
mealplan?: number | null;
/**
*
* @type {string}
* @memberof ShoppingListRecipe
*/
mealplan?: number | null;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
*/
servings: string;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
*/
mealplan_note?: string;
}
/**
*
* @export
* @interface ShoppingListRecipes
*/
export interface ShoppingListRecipes {
/**
*
* @type {number}
* @memberof ShoppingListRecipes
*/
id?: number;
/**
*
* @type {string}
* @memberof ShoppingListRecipes
*/
recipe_name?: string;
/**
*
* @type {string}
* @memberof ShoppingListRecipes
*/
name?: string;
/**
*
* @type {number}
* @memberof ShoppingListRecipes
*/
recipe?: number | null;
/**
*
* @type {number}
@ -2452,13 +2420,13 @@ export interface ShoppingListRecipeMealplan {
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
* @memberof ShoppingListRecipes
*/
servings: string;
/**
*
* @type {string}
* @memberof ShoppingListRecipeMealplan
* @memberof ShoppingListRecipes
*/
mealplan_note?: string;
}
@ -3038,6 +3006,36 @@ export interface UserPreference {
* @memberof UserPreference
*/
mealplan_autoadd_shopping?: boolean;
/**
*
* @type {string}
* @memberof UserPreference
*/
food_ignore_default?: string;
/**
*
* @type {number}
* @memberof UserPreference
*/
default_delay?: number;
/**
*
* @type {boolean}
* @memberof UserPreference
*/
mealplan_autoinclude_related?: boolean;
/**
*
* @type {boolean}
* @memberof UserPreference
*/
mealplan_autoexclude_onhand?: boolean;
/**
*
* @type {Array<number>}
* @memberof UserPreference
*/
shopping_share?: Array<number>;
}
/**
@ -5359,12 +5357,13 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
},
/**
*
* @param {string} [checked] Filter shopping list entries on checked. Valid values are true, false, both and &lt;b&gt;false+&lt;/b&gt;.&lt;br&gt; - false+ includes unchecked items and recently completed items.
* @param {number} [id] Returns the shopping list entry with a primary key of id. Multiple values allowed.
* @param {string} [checked] Filter shopping list entries on checked. [true, false, both, &lt;b&gt;recent&lt;/b&gt;]&lt;br&gt; - recent includes unchecked items and recently completed items.
* @param {number} [supermarket] Returns the shopping list entries sorted by supermarket category order.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listShoppingListEntrys: async (checked?: string, id?: number, options: any = {}): Promise<RequestArgs> => {
listShoppingListEntrys: async (id?: number, checked?: string, supermarket?: number, options: any = {}): Promise<RequestArgs> => {
const localVarPath = `/api/shopping-list-entry/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -5377,12 +5376,16 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
if (id !== undefined) {
localVarQueryParameter['id'] = id;
}
if (checked !== undefined) {
localVarQueryParameter['checked'] = checked;
}
if (id !== undefined) {
localVarQueryParameter['id'] = id;
if (supermarket !== undefined) {
localVarQueryParameter['supermarket'] = supermarket;
}
@ -9663,13 +9666,14 @@ export const ApiApiFp = function(configuration?: Configuration) {
},
/**
*
* @param {string} [checked] Filter shopping list entries on checked. Valid values are true, false, both and &lt;b&gt;false+&lt;/b&gt;.&lt;br&gt; - false+ includes unchecked items and recently completed items.
* @param {number} [id] Returns the shopping list entry with a primary key of id. Multiple values allowed.
* @param {string} [checked] Filter shopping list entries on checked. [true, false, both, &lt;b&gt;recent&lt;/b&gt;]&lt;br&gt; - recent includes unchecked items and recently completed items.
* @param {number} [supermarket] Returns the shopping list entries sorted by supermarket category order.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async listShoppingListEntrys(checked?: string, id?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ShoppingListEntry>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.listShoppingListEntrys(checked, id, options);
async listShoppingListEntrys(id?: number, checked?: string, supermarket?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ShoppingListEntry>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.listShoppingListEntrys(id, checked, supermarket, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
@ -11345,13 +11349,14 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
},
/**
*
* @param {string} [checked] Filter shopping list entries on checked. Valid values are true, false, both and &lt;b&gt;false+&lt;/b&gt;.&lt;br&gt; - false+ includes unchecked items and recently completed items.
* @param {number} [id] Returns the shopping list entry with a primary key of id. Multiple values allowed.
* @param {string} [checked] Filter shopping list entries on checked. [true, false, both, &lt;b&gt;recent&lt;/b&gt;]&lt;br&gt; - recent includes unchecked items and recently completed items.
* @param {number} [supermarket] Returns the shopping list entries sorted by supermarket category order.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listShoppingListEntrys(checked?: string, id?: number, options?: any): AxiosPromise<Array<ShoppingListEntry>> {
return localVarFp.listShoppingListEntrys(checked, id, options).then((request) => request(axios, basePath));
listShoppingListEntrys(id?: number, checked?: string, supermarket?: number, options?: any): AxiosPromise<Array<ShoppingListEntry>> {
return localVarFp.listShoppingListEntrys(id, checked, supermarket, options).then((request) => request(axios, basePath));
},
/**
*
@ -13054,14 +13059,15 @@ export class ApiApi extends BaseAPI {
/**
*
* @param {string} [checked] Filter shopping list entries on checked. Valid values are true, false, both and &lt;b&gt;false+&lt;/b&gt;.&lt;br&gt; - false+ includes unchecked items and recently completed items.
* @param {number} [id] Returns the shopping list entry with a primary key of id. Multiple values allowed.
* @param {string} [checked] Filter shopping list entries on checked. [true, false, both, &lt;b&gt;recent&lt;/b&gt;]&lt;br&gt; - recent includes unchecked items and recently completed items.
* @param {number} [supermarket] Returns the shopping list entries sorted by supermarket category order.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public listShoppingListEntrys(checked?: string, id?: number, options?: any) {
return ApiApiFp(this.configuration).listShoppingListEntrys(checked, id, options).then((request) => request(this.axios, this.basePath));
public listShoppingListEntrys(id?: number, checked?: string, supermarket?: number, options?: any) {
return ApiApiFp(this.configuration).listShoppingListEntrys(id, checked, supermarket, options).then((request) => request(this.axios, this.basePath));
}
/**