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(
benjaoming marked this conversation as resolved Outdated

Why not have this as a ForeignKey("Member")?

Why not have this as a `ForeignKey("Member")`?

It's sensitive really. I suppose that once this turns into an application, we have to consider that people give out details that are 100% associated with their membership activity and if we want to keep that on record, we should make sure it's either very consistent with the functionality or write a privacy statement.

I was leaning a bit more towards deleting these records... but on that note, "right to be forgotten" is way easier to invoke when we ensure that we use FKs between personal data (or PII).

Changing.......

It's sensitive really. I suppose that once this turns into an application, we have to consider that people give out details that are 100% associated with their membership activity and if we want to keep that on record, we should make sure it's either very consistent with the functionality or write a privacy statement. I was leaning a bit more towards deleting these records... but on that note, "right to be forgotten" is way easier to invoke when we ensure that we use FKs between personal data (or PII). Changing.......
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: