From ef0d03f6ea5df754c3ca543174ebf591eb6a068b Mon Sep 17 00:00:00 2001 From: Phin Wolkwitz Date: Thu, 6 Aug 2026 16:51:14 +0200 Subject: [PATCH] Fix and improve changed mail-rules logic --- src/pretix/plugins/sendmail/models.py | 51 +++++++++++++++++++-------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/pretix/plugins/sendmail/models.py b/src/pretix/plugins/sendmail/models.py index c98a19e1d2..8950e7fde6 100644 --- a/src/pretix/plugins/sendmail/models.py +++ b/src/pretix/plugins/sendmail/models.py @@ -187,26 +187,37 @@ class ScheduledMail(models.Model): o_sent = True if send_to_attendees: - if not self.rule.all_products: - positions = [p for p in positions if p.item_id in limit_products] if self.subevent_id: positions = [p for p in positions if p.subevent_id == self.subevent_id] + parent_op = None + sent_to_parent_positions = set() for p in positions: + + if p.addon_to_id is None: + parent_op = p + if not self.rule.all_products and p.item_id not in position_ids: + continue + else: + sent_to_parent_positions.add(p.id) + if p.id in position_ids: - email_to = p.attendee_email if p.attendee_email else None + mail_to_parent = False - 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 + # position is an add-on + if p.addon_to_id is not None: + # without attendee-email + if not p.attendee_email: + if p.addon_to_id in sent_to_parent_positions: + continue + elif parent_op.attendee_email: + sent_to_parent_positions.add(parent_op.id) + mail_to_parent = True + # with attendee-email but same as parent's and sent to parent + elif parent_op.attendee_email and p.attendee_email == parent_op.attendee_email and parent_op in sent_to_parent_positions: + continue - if email_to != o.email or not o_sent: + if p.attendee_email and (p.attendee_email != o.email or not o_sent): email_ctx = get_email_context( event=e, order=o, @@ -216,8 +227,18 @@ 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', - diff_recipient=email_to if mail_to_parent else None) + log_entry_type='pretix.plugins.sendmail.rule.order.position.email.sent') + elif mail_to_parent and (parent_op.attendee_email != o.email or not o_sent): + email_ctx = get_email_context( + event=e, + order=o, + invoice_address=ia, + position=parent_op, + event_or_subevent=self.subevent or e, + ) + parent_op.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') elif not o_sent and o.email: email_ctx = get_email_context( event=e,