diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 01844c82f8..ceea5dd10c 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -2912,7 +2912,8 @@ class OrderPosition(AbstractPosition): def send_mail(self, subject: str, template: Union[str, LazyI18nString], context: Dict[str, Any]=None, log_entry_type: str='pretix.event.order.email.sent', user: User=None, headers: dict=None, sender: str=None, invoices: list=None, - auth=None, attach_tickets=False, attach_ical=False, attach_other_files: list=None): + auth=None, attach_tickets=False, attach_ical=False, attach_other_files: list = None, + diff_recipient=None): """ Sends an email to the attendee. Basically, this method does two things: @@ -2930,14 +2931,15 @@ class OrderPosition(AbstractPosition): :param sender: Custom email sender. :param attach_tickets: Attach tickets of this order, if they are existing and ready to download :param attach_ical: Attach relevant ICS files + :param diff_recipient: A different recipient in case of unpersonalized add-ons. """ from pretix.base.services.mail import mail - if not self.attendee_email: + if not self.attendee_email and not self.diff_recipient: return with language(self.order.locale, self.order.event.settings.region): - recipient = self.attendee_email + recipient = self.attendee_email if self.attendee_email else self.diff_recipient outgoing_mail = mail( recipient, subject, template, context, self.event, self.order.locale, order=self.order, headers=headers, sender=sender, diff --git a/src/pretix/plugins/sendmail/models.py b/src/pretix/plugins/sendmail/models.py index b68916c010..c98a19e1d2 100644 --- a/src/pretix/plugins/sendmail/models.py +++ b/src/pretix/plugins/sendmail/models.py @@ -194,7 +194,19 @@ class ScheduledMail(models.Model): for p in positions: if p.id in position_ids: - if p.attendee_email and (p.attendee_email != o.email or not o_sent): + email_to = p.attendee_email if p.attendee_email else None + + if not email_to and p.addon_to_id is not None: + try: + parent_op = o.positions.get( + id=p.addon_to_id) # should we rethink the whole positions logic here to reduce DB queries? + except OrderPosition.DoesNotExist: + raise OrderPosition.DoesNotExist # this should not happen, but just in case + if parent_op.attendee_email: + email_to = parent_op.attendee_email + mail_to_parent = True + + if email_to != o.email or not o_sent: email_ctx = get_email_context( event=e, order=o, @@ -204,7 +216,8 @@ class ScheduledMail(models.Model): ) p.send_mail(self.rule.subject, self.rule.template, email_ctx, attach_ical=self.rule.attach_ical, - log_entry_type='pretix.plugins.sendmail.rule.order.position.email.sent') + log_entry_type='pretix.plugins.sendmail.rule.order.position.email.sent', + diff_recipient=email_to if mail_to_parent else None) elif not o_sent and o.email: email_ctx = get_email_context( event=e, @@ -227,7 +240,8 @@ class Rule(models.Model, LoggingMixin): SEND_TO_CHOICES = [ (CUSTOMERS, _("Everyone who created a ticket order")), - (ATTENDEES, _("Every attendee (falling back to the order contact when no attendee email address is given)")), + (ATTENDEES, + _("Every attendee (falling back to the order contact when no attendee email address is given or the ticket's contact in the case of add-ons)")), (BOTH, _('Both (all order contact addresses and all attendee email addresses)')) ]