diff --git a/src/pretix/plugins/sendmail/tasks.py b/src/pretix/plugins/sendmail/tasks.py index bb090e4dff..c5b8792899 100644 --- a/src/pretix/plugins/sendmail/tasks.py +++ b/src/pretix/plugins/sendmail/tasks.py @@ -31,6 +31,8 @@ # Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under the License. +from datetime import datetime + from django.db.models import Exists, OuterRef, Q from i18nfield.strings import LazyI18nString @@ -45,6 +47,7 @@ from pretix.helpers.format import format_map @app.task(base=ProfiledEventTask, acks_late=True) def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, objects: list, items: list, + subevent: int, subevents_from: datetime, subevents_to: datetime, recipients: str, filter_checkins: bool, not_checked_in: bool, checkin_lists: list, attachments: list = None, attach_tickets: bool = False, attach_ical: bool = False) -> None: @@ -76,7 +79,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, list_id__in=checkin_lists or [] ) ), - ).prefetch_related('addons'): + ).prefetch_related('addons', 'subevent'): if p.addon_to_id is not None: continue @@ -99,6 +102,15 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, if p.attendee_email == o.email and send_to_order: continue + if subevent and p.subevent_id != subevent: + continue + + if subevents_from and p.subevent.date_from < subevents_from: + continue + + if subevents_to and p.subevent.date_from >= subevents_to: + continue + try: with language(o.locale, event.settings.region): email_context = get_email_context(event=event, order=o, invoice_address=ia, position=p) diff --git a/src/pretix/plugins/sendmail/views.py b/src/pretix/plugins/sendmail/views.py index 64100e186a..be5c18c688 100644 --- a/src/pretix/plugins/sendmail/views.py +++ b/src/pretix/plugins/sendmail/views.py @@ -429,6 +429,9 @@ class OrderSendView(BaseSenderView): kwargs.update({ 'recipients': form.cleaned_data['recipients'], 'items': [i.pk for i in form.cleaned_data.get('items')], + 'subevent': form.cleaned_data['subevent'].pk if form.cleaned_data.get('subevent') else None, + 'subevents_from': form.cleaned_data.get('subevents_from'), + 'subevents_to': form.cleaned_data.get('subevents_to'), 'not_checked_in': form.cleaned_data.get('not_checked_in'), 'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')], 'filter_checkins': form.cleaned_data.get('filter_checkins'), diff --git a/src/tests/plugins/sendmail/test_sendmail.py b/src/tests/plugins/sendmail/test_sendmail.py index fd302582e8..de4593caeb 100644 --- a/src/tests/plugins/sendmail/test_sendmail.py +++ b/src/tests/plugins/sendmail/test_sendmail.py @@ -406,6 +406,79 @@ def test_sendmail_attendee_product_filter(logged_in_client, sendmail_url, event, assert '/order/' not in djmail.outbox[0].body +@pytest.mark.django_db +def test_sendmail_attendee_subevent_filter(logged_in_client, sendmail_url, event, item, order, pos): + event.settings.attendee_emails_asked = True + event.has_subevents = True + event.save() + with scopes_disabled(): + se1 = event.subevents.create(name='Subevent FOO', date_from=now()) + se2 = event.subevents.create(name='Bar', date_from=now()) + pos.attendee_email = 'attendee1@dummy.test' + pos.subevent = se1 + pos.save() + with scopes_disabled(): + order.positions.create( + item=item, price=0, attendee_email='attendee2@dummy.test', subevent=se2 + ) + + djmail.outbox = [] + response = logged_in_client.post(sendmail_url + 'orders/', + {'sendto': 'na', + 'action': 'send', + 'recipients': 'attendees', + 'items': item.pk, + 'subject_0': 'Test subject', + 'message_0': 'This is a test file for sending mails.', + 'subevent': se2.pk, + }, + follow=True) + assert response.status_code == 200 + assert 'alert-success' in response.rendered_content + assert len(djmail.outbox) == 1 + assert djmail.outbox[0].to == ['attendee2@dummy.test'] + assert '/ticket/' in djmail.outbox[0].body + assert '/order/' not in djmail.outbox[0].body + + +@pytest.mark.django_db +def test_sendmail_attendee_subevent_range_filter(logged_in_client, sendmail_url, event, item, order, pos): + event.settings.attendee_emails_asked = True + event.has_subevents = True + event.save() + with scopes_disabled(): + se1 = event.subevents.create(name='Subevent FOO', date_from=datetime.datetime(2023, 7, 6, 1, 2, 3, tzinfo=event.timezone)) + se2 = event.subevents.create(name='Bar', date_from=datetime.datetime(2023, 8, 9, 1, 2, 3, tzinfo=event.timezone)) + pos.attendee_email = 'attendee1@dummy.test' + pos.subevent = se1 + pos.save() + with scopes_disabled(): + order.positions.create( + item=item, price=0, attendee_email='attendee2@dummy.test', subevent=se2 + ) + + djmail.outbox = [] + response = logged_in_client.post(sendmail_url + 'orders/', + {'sendto': 'na', + 'action': 'send', + 'recipients': 'attendees', + 'items': item.pk, + 'subject_0': 'Test subject', + 'message_0': 'This is a test file for sending mails.', + 'subevents_from_0': '2023-07-01', + 'subevents_from_1': '00:00:00', + 'subevents_to_0': '2023-08-01', + 'subevents_to_1': '00:00:00', + }, + follow=True) + assert response.status_code == 200 + assert 'alert-success' in response.rendered_content + assert len(djmail.outbox) == 1 + assert djmail.outbox[0].to == ['attendee1@dummy.test'] + assert '/ticket/' in djmail.outbox[0].body + assert '/order/' not in djmail.outbox[0].body + + @pytest.mark.django_db def test_sendmail_attendee_checkin_filter(logged_in_client, sendmail_url, event, order, checkin_list, item, pos): event.settings.attendee_emails_asked = True