added ability to use invite link more than once

This commit is contained in:
vabene1111
2022-07-14 11:28:13 +02:00
parent 98a54ef38f
commit ba473123ba
7 changed files with 59 additions and 15 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0.6 on 2022-07-14 09:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0179_recipe_private_recipe_shared'),
]
operations = [
migrations.AddField(
model_name='invitelink',
name='reusable',
field=models.BooleanField(default=False),
),
]

View File

@ -601,7 +601,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
# remove all inherited fields from food # remove all inherited fields from food
trough = Food.inherit_fields.through trough = Food.inherit_fields.through
trough.objects.all().delete() trough.objects.all().delete()
# food is going to inherit attributes # food is going to inherit attributes
if len(inherit) > 0: if len(inherit) > 0:
# ManyToMany cannot be updated through an UPDATE operation # ManyToMany cannot be updated through an UPDATE operation
@ -1008,9 +1008,8 @@ class InviteLink(ExportModelOperationsMixin('invite_link'), models.Model, Permis
email = models.EmailField(blank=True) email = models.EmailField(blank=True)
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)
valid_until = models.DateField(default=default_valid_until) valid_until = models.DateField(default=default_valid_until)
used_by = models.ForeignKey( used_by = models.ForeignKey(User, null=True, on_delete=models.CASCADE, related_name='used_by')
User, null=True, on_delete=models.CASCADE, related_name='used_by' reusable = models.BooleanField(default=False)
)
created_by = models.ForeignKey(User, on_delete=models.CASCADE) created_by = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)

View File

@ -821,7 +821,7 @@ class RecipeBookEntrySerializer(serializers.ModelSerializer):
book = validated_data['book'] book = validated_data['book']
recipe = validated_data['recipe'] recipe = validated_data['recipe']
if not book.get_owner() == self.context['request'].user and not self.context[ if not book.get_owner() == self.context['request'].user and not self.context[
'request'].user in book.get_shared(): 'request'].user in book.get_shared():
raise NotFound(detail=None, code=None) raise NotFound(detail=None, code=None)
obj, created = RecipeBookEntry.objects.get_or_create(book=book, recipe=recipe) obj, created = RecipeBookEntry.objects.get_or_create(book=book, recipe=recipe)
return obj return obj
@ -877,11 +877,11 @@ class ShoppingListRecipeSerializer(serializers.ModelSerializer):
value = value.quantize( value = value.quantize(
Decimal(1)) if value == value.to_integral() else value.normalize() # strips trailing zero Decimal(1)) if value == value.to_integral() else value.normalize() # strips trailing zero
return ( return (
obj.name obj.name
or getattr(obj.mealplan, 'title', None) or getattr(obj.mealplan, 'title', None)
or (d := getattr(obj.mealplan, 'date', None)) and ': '.join([obj.mealplan.recipe.name, str(d)]) or (d := getattr(obj.mealplan, 'date', None)) and ': '.join([obj.mealplan.recipe.name, str(d)])
or obj.recipe.name or obj.recipe.name
) + f' ({value:.2g})' ) + f' ({value:.2g})'
def update(self, instance, validated_data): def update(self, instance, validated_data):
# TODO remove once old shopping list # TODO remove once old shopping list
@ -1105,7 +1105,7 @@ class InviteLinkSerializer(WritableNestedModelSerializer):
class Meta: class Meta:
model = InviteLink model = InviteLink
fields = ( fields = (
'id', 'uuid', 'email', 'group', 'valid_until', 'used_by', 'created_by', 'created_at',) 'id', 'uuid', 'email', 'group', 'valid_until', 'used_by', 'reusable', 'created_by', 'created_at',)
read_only_fields = ('id', 'uuid', 'created_by', 'created_at',) read_only_fields = ('id', 'uuid', 'created_by', 'created_at',)

View File

@ -431,8 +431,9 @@ def invite_link(request, token):
if link := InviteLink.objects.filter(valid_until__gte=datetime.today(), used_by=None, uuid=token).first(): if link := InviteLink.objects.filter(valid_until__gte=datetime.today(), used_by=None, uuid=token).first():
if request.user.is_authenticated and not request.user.userspace_set.filter(space=link.space).exists(): if request.user.is_authenticated and not request.user.userspace_set.filter(space=link.space).exists():
link.used_by = request.user if not link.reusable:
link.save() link.used_by = request.user
link.save()
user_space = UserSpace.objects.create(user=request.user, space=link.space, active=False) user_space = UserSpace.objects.create(user=request.user, space=link.space, active=False)

View File

@ -71,7 +71,7 @@
"Private_Recipe": "Private Recipe", "Private_Recipe": "Private Recipe",
"Private_Recipe_Help": "Recipe is only shown to you and people its shared with.", "Private_Recipe_Help": "Recipe is only shown to you and people its shared with.",
"reusable_help_text": "Should the invite link be usable for more than one user.",
"Add_Step": "Add Step", "Add_Step": "Add Step",
"Keywords": "Keywords", "Keywords": "Keywords",
"Books": "Books", "Books": "Books",

View File

@ -669,7 +669,7 @@ export class Models {
apiName: "InviteLink", apiName: "InviteLink",
paginated: false, paginated: false,
create: { create: {
params: [["email", "group", "valid_until"]], params: [["email", "group", "valid_until", "reusable"]],
form: { form: {
email: { email: {
form_field: true, form_field: true,
@ -694,6 +694,14 @@ export class Models {
label: "Valid Until", label: "Valid Until",
placeholder: "", placeholder: "",
}, },
reusable: {
form_field: true,
type: "checkbox",
field: "reusable",
label: "Reusable",
help_text: "reusable_help_text",
placeholder: "",
},
}, },
}, },
} }

View File

@ -1357,6 +1357,12 @@ export interface InviteLink {
* @memberof InviteLink * @memberof InviteLink
*/ */
used_by?: number | null; used_by?: number | null;
/**
*
* @type {boolean}
* @memberof InviteLink
*/
reusable?: boolean;
/** /**
* *
* @type {string} * @type {string}
@ -1893,6 +1899,18 @@ export interface Recipe {
* @memberof Recipe * @memberof Recipe
*/ */
last_cooked?: string; last_cooked?: string;
/**
*
* @type {boolean}
* @memberof Recipe
*/
_private?: boolean;
/**
*
* @type {Array<CustomFilterShared>}
* @memberof Recipe
*/
shared?: Array<CustomFilterShared>;
} }
/** /**
* *