Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions app/eventyay/api/serializers/organizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,13 @@ def _send_invite(self, instance):
try:
mail(
instance.email,
_('eventyay account invitation'),
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=instance.team.name,
organizer=self.context['organizer'].name,
),
'pretixcontrol/email/invitation.txt',
{
'user': self,
'user': instance,
'organizer': self.context['organizer'].name,
'team': instance.team.name,
'url': build_absolute_uri('control:auth.invite', kwargs={'token': instance.token}),
Expand Down Expand Up @@ -208,14 +211,33 @@ def create(self, validated_data):
else:
if self.context['team'].members.filter(pk=user.pk).exists():
raise ValidationError(_('This user already has permissions for this team.'))

try:
mail(
user.email,
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=self.context['team'].name,
organizer=self.context['organizer'].name,
),
'pretixcontrol/email/invitation.txt',
{
'user': user,
'organizer': self.context['organizer'].name,
'team': self.context['team'].name,
'url': build_absolute_uri('control:teams.detail', kwargs={'organizer': self.context['organizer'].slug, 'team': self.context['team'].pk}),
},
event=None,
locale=get_language_without_region(),
)
except SendMailException:
logger.warning(
"Failed to send invitation email to existing user: %s",
user.email,
exc_info=True
)
self.context['team'].members.add(user)
self.context['team'].log_action(
'eventyay.team.member.added',
data={
'email': user.email,
'user': user.pk,
},
data={'email': user.email, 'user': user.pk},
**self.context['log_kwargs'],
)
return TeamInvite(email=user.email)
Expand Down
18 changes: 13 additions & 5 deletions app/eventyay/base/models/organizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,19 +485,27 @@ def send(self):

invitation_link = self.invitation_url
invitation_text = _(
"""Hi!
You have been invited to the {name} event organizer team - Please click here to accept:
"""Hello,

You have been invited to join the team "{name}" for the organizer "{organizer}".

Please click the following link to accept the invitation:

{invitation_link}

See you there,
The {organizer} team"""
If you do not want to join, you can safely ignore or delete this email.

Best regards,
Your event team"""
).format(
name=str(self.team.name),
invitation_link=invitation_link,
organizer=str(self.team.organizer.name),
)
invitation_subject = _('You have been invited to an organizer team')
invitation_subject = _('You have been invited to join the team "{team}" for "{organizer}"').format(
team=str(self.team.name),
organizer=str(self.team.organizer.name),
)

mail = QueuedMail.objects.create(
to=self.email,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
{% load i18n %}{% blocktrans with url=url|safe %}Hello,
{% load i18n %}{% blocktrans with url=url|safe team=team organizer=organizer %}Hello,

you have been invited to the following event team
You have been invited to join the team "{{ team }}" for the organizer "{{ organizer }}".

Organizer: {{ organizer }}
Team: {{ team }}

If you want to join that team, just click on the following link:
Please click the following link to accept the invitation:
{{ url }}

If you are already logged in, you will be automatically added to the team. Otherwise, please log in or create an account to join.

If you do not want to join, you can safely ignore or delete this email.

Best regards,

Your event team
{% endblocktrans %}
{% endblocktrans %}
44 changes: 36 additions & 8 deletions app/eventyay/control/views/organizer_views/team_view.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import logging

logger = logging.getLogger(__name__)

from django.contrib import messages
from django.db import transaction
from django.db.models import Count, ManyToManyField
Expand Down Expand Up @@ -173,10 +177,13 @@ def _send_invite(self, instance):
try:
mail(
instance.email,
_('eventyay account invitation'),
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=instance.team.name,
organizer=self.request.organizer.name,
),
'pretixcontrol/email/invitation.txt',
{
'user': self,
'user': instance,
'organizer': self.request.organizer.name,
'team': instance.team.name,
'url': build_global_uri('eventyay_common:auth.invite', kwargs={'token': instance.token}),
Expand Down Expand Up @@ -304,16 +311,37 @@ def post(self, request, *args, **kwargs):
)
return self.get(request, *args, **kwargs)

# Send email to registered user and then add them
try:
mail(
user.email,
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=self.object.name,
organizer=self.request.organizer.name,
),
'pretixcontrol/email/invitation.txt',
{
'user': user,
'organizer': self.request.organizer.name,
'team': self.object.name,
'url': build_global_uri('eventyay_common:organizer.team', kwargs={'organizer': self.request.organizer.slug, 'team': self.object.pk}),
},
event=None,
locale=self.request.LANGUAGE_CODE,
)
except SendMailException:
logger.warning("Failed to send invitation to existing member %s", user.email, exc_info=True)
messages.warning(self.request, _('The new member was added to the team, but the invitation email could not be sent.'))
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tense in this error message is inconsistent. At the time this message is shown, the member has not been added yet (that happens on line 339). The message should say 'will be added' to match the actual timing, or the code should be restructured to add the member before sending the email.

Suggested change
messages.warning(self.request, _('The new member was added to the team, but the invitation email could not be sent.'))
messages.warning(self.request, _('The new member will be added to the team, but the invitation email could not be sent.'))

Copilot uses AI. Check for mistakes.

Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is trailing whitespace on this blank line. Remove the trailing whitespace to maintain code cleanliness.

Suggested change

Copilot uses AI. Check for mistakes.
else:
messages.success(self.request, _('The new member has been invited and added to the team.'))

self.object.members.add(user)
self.object.log_action(
'pretix.team.member.added',
'eventyay.team.member.added',
user=self.request.user,
data={
'email': user.email,
'user': user.pk,
},
data={'email': user.email, 'user': user.pk},
)
messages.success(self.request, _('The new member has been added to the team.'))
return redirect(self.get_success_url())

elif 'name' in self.request.POST and self.add_token_form.is_valid() and self.add_token_form.has_changed():
Expand Down
43 changes: 36 additions & 7 deletions app/eventyay/eventyay_common/views/team.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import logging
from urllib.parse import urljoin

logger = logging.getLogger(__name__)

from django.conf import settings
from django.contrib import messages
from django.db import transaction
Expand Down Expand Up @@ -67,10 +70,13 @@ def _send_invite(self, instance):
try:
mail(
instance.email,
_('eventyay account invitation'),
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=instance.team.name,
organizer=self.request.organizer.name,
),
'pretixcontrol/email/invitation.txt',
{
'user': self,
'user': instance,
'organizer': self.request.organizer.name,
'team': instance.team.name,
'url': build_global_uri('eventyay_common:auth.invite', kwargs={'token': instance.token}),
Expand Down Expand Up @@ -198,16 +204,39 @@ def post(self, request, *args, **kwargs):
)
return self.get(request, *args, **kwargs)

# Send email to registered user even if they exist
try:
mail(
user.email,
_('You have been invited to join the team "{team}" for "{organizer}"').format(
team=self.object.name,
organizer=self.request.organizer.name,
),
'pretixcontrol/email/invitation.txt',
{
'user': user,
'organizer': self.request.organizer.name,
'team': self.object.name,
'url': build_global_uri('eventyay_common:organizer.team', kwargs={'organizer': self.request.organizer.slug, 'team': self.object.pk}),
},
event=None,
locale=self.request.LANGUAGE_CODE,
)
except SendMailException:
logger.warning("Failed to send invitation email to existing user %s", user.email, exc_info=True)
messages.warning(
self.request,
_('The new member will be added to the team, but the invitation email could not be delivered.')
)
else:
messages.success(self.request, _('The new member has been invited and added to the team.'))

self.object.members.add(user)
self.object.log_action(
'eventyay.team.member.added',
user=self.request.user,
data={
'email': user.email,
'user': user.pk,
},
data={'email': user.email, 'user': user.pk},
)
messages.success(self.request, _('The new member has been added to the team.'))
return redirect(self.get_success_url())

elif 'name' in self.request.POST and self.add_token_form.is_valid() and self.add_token_form.has_changed():
Expand Down