wip shopping dialog

This commit is contained in:
vabene1111
2024-12-22 18:36:56 +01:00
parent d611391bea
commit e0223e0c5c
13 changed files with 520 additions and 42 deletions

View File

@@ -1139,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','addshopping'
'meal_type_name', 'shopping', 'addshopping'
)
read_only_fields = ('created_by',)
@@ -1155,26 +1155,12 @@ class AutoMealPlanSerializer(serializers.Serializer):
class ShoppingListRecipeSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField('get_name') # should this be done at the front end?
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')
servings = CustomDecimalField()
@extend_schema_field(str)
def get_name(self, obj):
if not isinstance(value := obj.servings, Decimal):
value = Decimal(value)
value = value.quantize(
Decimal(1)) if value == value.to_integral() else value.normalize() # strips trailing zero
return (
obj.name
or getattr(obj.mealplan, 'title', None)
or (d := getattr(obj.mealplan, 'date', None)) and ': '.join([obj.mealplan.recipe.name, str(d)])
or obj.recipe.name
) + f' ({value:.2g})'
def update(self, instance, validated_data):
# TODO remove once old shopping list
if 'servings' in validated_data and self.context.get('view', None).__class__.__name__ != 'ShoppingListViewSet':
@@ -1252,6 +1238,16 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
read_only_fields = ('id', 'created_by', 'created_at')
class ShoppingListEntrySimpleCreateSerializer(serializers.Serializer):
amount = CustomDecimalField()
unit_id = serializers.IntegerField(allow_null=True)
food_id = serializers.IntegerField(allow_null=True)
class ShoppingListEntryBulkCreateSerializer(serializers.Serializer):
entries = serializers.ListField(child=ShoppingListEntrySimpleCreateSerializer())
class ShoppingListEntryBulkSerializer(serializers.Serializer):
ids = serializers.ListField()
checked = serializers.BooleanField()
@@ -1537,8 +1533,8 @@ class RecipeExportSerializer(WritableNestedModelSerializer):
class RecipeShoppingUpdateSerializer(serializers.ModelSerializer):
list_recipe = serializers.IntegerField(write_only=True, allow_null=True, required=False,
help_text=_("Existing shopping list to update"))
ingredients = serializers.IntegerField(write_only=True, allow_null=True, required=False, help_text=_(
"List of ingredient IDs from the recipe to add, if not provided all ingredients will be added."))
ingredients = serializers.ListField(child=serializers.IntegerField(write_only=True, allow_null=True, required=False, help_text=_(
"List of ingredient IDs from the recipe to add, if not provided all ingredients will be added.")))
servings = serializers.IntegerField(default=1, write_only=True, allow_null=True, required=False, help_text=_(
"Providing a list_recipe ID and servings of 0 will delete that shopping list."))
@@ -1627,9 +1623,10 @@ class SourceImportDuplicateSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
class RecipeFromSourceResponseSerializer(serializers.Serializer):
recipe = SourceImportRecipeSerializer(default=None)
images = serializers.ListField(child=serializers.CharField(),default=[], allow_null=False)
images = serializers.ListField(child=serializers.CharField(), default=[], allow_null=False)
error = serializers.BooleanField(default=False)
msg = serializers.CharField(max_length=1024, default='')
duplicates = serializers.ListField(child=SourceImportDuplicateSerializer(), default=[], allow_null=False)

View File

@@ -105,7 +105,7 @@ from cookbook.serializer import (AccessTokenSerializer, AutomationSerializer, Au
SupermarketSerializer, SyncLogSerializer, SyncSerializer,
UnitConversionSerializer, UnitSerializer, UserFileSerializer, UserPreferenceSerializer,
UserSerializer, UserSpaceSerializer, ViewLogSerializer, ImportImageSerializer,
LocalizationSerializer, ServerSettingsSerializer, RecipeFromSourceResponseSerializer
LocalizationSerializer, ServerSettingsSerializer, RecipeFromSourceResponseSerializer, ShoppingListEntryBulkCreateSerializer
)
from cookbook.version_info import TANDOOR_VERSION
from cookbook.views.import_export import get_integration
@@ -1289,7 +1289,8 @@ class RecipeViewSet(LoggingMixin, viewsets.ModelViewSet):
return Response(content, status=http_status)
@decorators.action(detail=True, methods=['GET'], serializer_class=RecipeSimpleSerializer)
@extend_schema(responses=RecipeSimpleSerializer(many=True))
@decorators.action(detail=True, pagination_class=None, methods=['GET'], serializer_class=RecipeSimpleSerializer)
def related(self, request, pk):
obj = self.get_object()
if obj.get_space() != request.space:
@@ -1371,8 +1372,34 @@ class ShoppingListRecipeViewSet(LoggingMixin, viewsets.ModelViewSet):
self.queryset = self.queryset.filter(Q(entries__space=self.request.space) | Q(recipe__space=self.request.space))
return self.queryset.filter(Q(entries__isnull=True)
| Q(entries__created_by=self.request.user)
| Q(
entries__created_by__in=list(self.request.user.get_shopping_share()))).distinct().all()
| Q(entries__created_by__in=list(self.request.user.get_shopping_share()))).distinct().all()
@decorators.action(detail=True, methods=['POST'], serializer_class=ShoppingListEntryBulkCreateSerializer, permission_classes=[CustomIsUser])
def bulk_create_entries(self, request, pk):
obj = self.get_object()
if obj.get_space() != request.space:
raise PermissionDenied(detail='You do not have the required permission to perform this action', code=403)
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
entries = []
for e in serializer.validated_data['entries']:
entries.append(
ShoppingListEntry(
list_recipe_id=obj.pk,
amount=e['amount'],
unit_id=e['unit_id'],
food_id=e['food_id'],
created_by_id=request.user.id,
space_id=request.space.id,
)
)
ShoppingListEntry.objects.bulk_create(entries)
return Response(serializer.validated_data)
else:
return Response(serializer.errors, 400)
@extend_schema_view(list=extend_schema(parameters=[