Membership invitations and order emails #47

Merged
valberg merged 10 commits from benjaoming/membersystem:membership-invite into main 2024-08-14 09:17:30 +00:00
5 changed files with 34 additions and 29 deletions
Showing only changes of commit e519383741 - Show all commits

View file

@ -148,21 +148,21 @@ class MemberAdmin(UserAdmin):
class WaitingListEntryAdmin(admin.ModelAdmin): class WaitingListEntryAdmin(admin.ModelAdmin):
"""Admin for WaitingList model.""" """Admin for WaitingList model."""
list_display = ("email", "has_user") list_display = ("email", "member")
actions = ("create_user",) actions = ("create_member",)
@admin.action(description="Create user account for entries") @admin.action(description="Create member account for entries")
def create_user(self, request: HttpRequest, queryset: QuerySet[WaitingListEntry]) -> None: def create_member(self, request: HttpRequest, queryset: QuerySet[WaitingListEntry]) -> None:
"""Create a user account for this entry. """Create a user account for this entry.
Note that actions can soon be made available from the edit page, too: Note that actions can soon be made available from the edit page, too:
https://github.com/django/django/pull/16012 https://github.com/django/django/pull/16012
""" """
for entry in queryset: for entry in queryset:
Member.objects.create_user(email=entry.email, username=slugify(entry.email), is_active=False) member = Member.objects.create_user(email=entry.email, username=slugify(entry.email), is_active=False)
entry.has_user = True entry.member = member
entry.save() entry.save()
messages.info( messages.info(
request, request,
f"Added user for f{entry.email} - ensure they have a membership and send an invite email.", f"Added user for {entry.email} - ensure they have a membership and send an invite email.",
) )

View file

@ -23,6 +23,7 @@ class InviteForm(SetPasswordForm):
Taken from the allauth Signup form - we should consider that data can be leaked here. Taken from the allauth Signup form - we should consider that data can be leaked here.
""" """
value = self.cleaned_data["username"] value = self.cleaned_data["username"]
# The allauth adapter ensures the username is unique.
return get_allauth_adapter().clean_username(value) return get_allauth_adapter().clean_username(value)
def save(self) -> None: def save(self) -> None:

View file

@ -1,18 +0,0 @@
# Generated by Django 5.1rc1 on 2024-08-11 21:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0009_membership_referral_code'),
]
operations = [
migrations.AddField(
model_name='waitinglistentry',
name='has_user',
field=models.BooleanField(default=False, help_text='Once a user account is generated (use the admin action), this field will be marked.', verbose_name='has user'),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 5.1rc1 on 2024-08-14 08:05
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('membership', '0009_membership_referral_code'),
]
operations = [
migrations.AddField(
model_name='waitinglistentry',
name='member',
field=models.ForeignKey(help_text='Once a member account is generated (use the admin action), this field will be marked.', null=True, blank=True, on_delete=django.db.models.deletion.CASCADE, to='membership.member', verbose_name='has member'),
),
]

View file

@ -230,10 +230,13 @@ class WaitingListEntry(CreatedModifiedAbstract):
email = models.EmailField() email = models.EmailField()
geography = models.CharField(verbose_name=_("geography"), blank=True, default="") geography = models.CharField(verbose_name=_("geography"), blank=True, default="")
comment = models.TextField(blank=True) comment = models.TextField(blank=True)
has_user = models.BooleanField( member = models.ForeignKey(
default=False, Member,
verbose_name=_("has user"), null=True,
help_text=_("Once a user account is generated (use the admin action), this field will be marked."), blank=True,
verbose_name=_("has member"),
help_text=_("Once a member account is generated (use the admin action), this field will be marked."),
on_delete=models.CASCADE,
) )
def __str__(self) -> str: def __str__(self) -> str: