diff --git a/cookbook/serializer.py b/cookbook/serializer.py index a843b56e..f7a004c4 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -4,7 +4,8 @@ from rest_framework import serializers from rest_framework.exceptions import APIException, ValidationError from rest_framework.fields import CurrentUserDefault -from cookbook.models import MealPlan, MealType, Recipe, ViewLog, UserPreference, Storage, Sync, SyncLog, Keyword, Unit, Ingredient, Comment, RecipeImport, RecipeBook, RecipeBookEntry, ShareLink, CookLog, Food, Step +from cookbook.models import MealPlan, MealType, Recipe, ViewLog, UserPreference, Storage, Sync, SyncLog, Keyword, Unit, Ingredient, Comment, RecipeImport, RecipeBook, RecipeBookEntry, ShareLink, CookLog, Food, Step, ShoppingList, \ + ShoppingListEntry, ShoppingListRecipe from cookbook.templatetags.custom_tags import markdown @@ -193,6 +194,34 @@ class MealPlanSerializer(serializers.ModelSerializer): fields = ('id', 'title', 'recipe', 'note', 'note_markdown', 'date', 'meal_type', 'created_by', 'shared', 'recipe_name', 'meal_type_name') +class ShoppingListRecipeSerializer(serializers.ModelSerializer): + recipe = RecipeSerializer(read_only=True) + + def create(self, validated_data): + return ShoppingListRecipe.objects.create(**validated_data) + + def update(self, instance, validated_data): + return super(ShoppingListRecipeSerializer, self).update(instance, validated_data) + + class Meta: + model = ShoppingListRecipe + fields = ('recipe', 'multiplier') + + +class ShoppingListEntrySerializer(serializers.ModelSerializer): + class Meta: + model = ShoppingListEntry + fields = ('list_recipe', 'food', 'unit', 'amount', 'order', 'checked') + + +class ShoppingListSerializer(serializers.ModelSerializer): + recipes = ShoppingListRecipeSerializer(many=True, allow_null=True, read_only=True) + + class Meta: + model = ShoppingList + fields = ('id', 'uuid', 'note', 'recipes', 'shared', 'created_by', 'created_at',) + + class ShareLinkSerializer(serializers.ModelSerializer): class Meta: model = ShareLink diff --git a/cookbook/templates/shopping_list.html b/cookbook/templates/shopping_list.html index 0b9628e7..2db45f28 100644 --- a/cookbook/templates/shopping_list.html +++ b/cookbook/templates/shopping_list.html @@ -7,11 +7,124 @@ {% block title %}{% trans "Shopping List" %}{% endblock %} {% block extra_head %} + {% include 'include/vue_base.html' %} + + + + + {% endblock %} {% block content %} +
+
+

{% trans 'Shopping List' %}

+
+
+ {% trans 'Edit' %} +
+
+
+
+
+ + +
    +
  • [[x.name]]
  • +
+
+ +
+
+
+ Non Edit +
+ + + +{% endblock %} +{% block script %} + + {% endblock %} \ No newline at end of file diff --git a/cookbook/urls.py b/cookbook/urls.py index b4e29d8f..ecf8ac20 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -23,6 +23,7 @@ router.register(r'recipe', api.RecipeViewSet) router.register(r'ingredient', api.IngredientViewSet) router.register(r'meal-plan', api.MealPlanViewSet) router.register(r'meal-type', api.MealTypeViewSet) +router.register(r'shopping-list', api.ShoppingListViewSet) router.register(r'view-log', api.ViewLogViewSet) urlpatterns = [ @@ -34,6 +35,7 @@ urlpatterns = [ path('plan/', views.meal_plan, name='view_plan'), path('plan/entry/', views.meal_plan_entry, name='view_plan_entry'), path('shopping/', views.shopping_list, name='view_shopping'), + path('shopping/', views.shopping_list, name='view_shopping'), path('settings/', views.user_settings, name='view_settings'), path('history/', views.history, name='view_history'), path('test/', views.test, name='view_test'), diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 7988fcce..079a04bd 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -28,11 +28,11 @@ from rest_framework.viewsets import ViewSetMixin from cookbook.helper.permission_helper import group_required, CustomIsOwner, CustomIsAdmin, CustomIsUser, CustomIsGuest, CustomIsShare from cookbook.helper.recipe_url_import import get_from_html -from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, ViewLog, UserPreference, RecipeBook, Ingredient, Food, Step, Keyword, Unit, SyncLog +from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, ViewLog, UserPreference, RecipeBook, Ingredient, Food, Step, Keyword, Unit, SyncLog, ShoppingListRecipe, ShoppingList from cookbook.provider.dropbox import Dropbox from cookbook.provider.nextcloud import Nextcloud from cookbook.serializer import MealPlanSerializer, MealTypeSerializer, RecipeSerializer, ViewLogSerializer, UserNameSerializer, UserPreferenceSerializer, RecipeBookSerializer, IngredientSerializer, FoodSerializer, StepSerializer, \ - KeywordSerializer, RecipeImageSerializer, StorageSerializer, SyncSerializer, SyncLogSerializer, UnitSerializer + KeywordSerializer, RecipeImageSerializer, StorageSerializer, SyncSerializer, SyncLogSerializer, UnitSerializer, ShoppingListSerializer class UserNameViewSet(viewsets.ReadOnlyModelViewSet): @@ -233,6 +233,16 @@ class RecipeViewSet(viewsets.ModelViewSet, StandardFilterMixin): return Response(serializer.errors, 400) +class ShoppingListViewSet(viewsets.ModelViewSet): + queryset = ShoppingList.objects.all() + serializer_class = ShoppingListSerializer + permission_classes = [CustomIsOwner] + + def get_queryset(self): + queryset = self.queryset.filter(created_by=self.request.user).all() + return queryset + + class ViewLogViewSet(viewsets.ModelViewSet): queryset = ViewLog.objects.all() serializer_class = ViewLogSerializer diff --git a/cookbook/views/lists.py b/cookbook/views/lists.py index 2869fad6..8ae428e7 100644 --- a/cookbook/views/lists.py +++ b/cookbook/views/lists.py @@ -50,7 +50,7 @@ def shopping_list(request): table = ShoppingListTable(ShoppingList.objects.filter(created_by=request.user).all()) RequestConfig(request, paginate={'per_page': 25}).configure(table) - return render(request, 'generic/list_template.html', {'title': _("Shopping Lists"), 'table': table, 'create_url': 'new_storage'}) + return render(request, 'generic/list_template.html', {'title': _("Shopping Lists"), 'table': table, 'create_url': 'view_shopping'}) @group_required('admin') diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 95b846cf..c3bd4806 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -164,44 +164,8 @@ def meal_plan_entry(request, pk): @group_required('user') -def shopping_list(request): - markdown_format = True - - if request.method == "POST": - form = ShoppingForm(request.POST) - if form.is_valid(): - recipes = form.cleaned_data['recipe'] - markdown_format = form.cleaned_data['markdown_format'] - else: - recipes = [] - else: - raw_list = request.GET.getlist('r') - - recipes = [] - for r in raw_list: - if re.match(r'^([1-9])+$', r): - if Recipe.objects.filter(pk=int(r)).exists(): - recipes.append(int(r)) - - markdown_format = False - form = ShoppingForm(initial={'recipe': recipes, 'markdown_format': False}) - - ingredients = [] - - for r in recipes: - for s in r.steps.all(): - for ri in s.ingredients.exclude(unit__name__contains='Special:').all(): - index = None - for x, ig in enumerate(ingredients): - if ri.food == ig.food and ri.unit == ig.unit: - index = x - - if index: - ingredients[index].amount = ingredients[index].amount + ri.amount - else: - ingredients.append(ri) - - return render(request, 'shopping_list.html', {'ingredients': ingredients, 'recipes': recipes, 'form': form, 'markdown_format': markdown_format}) +def shopping_list(request, pk=None): + return render(request, 'shopping_list.html', {}) @group_required('guest')