forked from CGM_Public/pretix_original
Sendmail: Fix incorrect filtering of subevents when mailing to attendees (Z#23166274) (#4474)
This commit is contained in:
@@ -31,6 +31,8 @@
|
|||||||
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
|
# 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
|
# 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.
|
# 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 django.db.models import Exists, OuterRef, Q
|
||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ from pretix.helpers.format import format_map
|
|||||||
|
|
||||||
@app.task(base=ProfiledEventTask, acks_late=True)
|
@app.task(base=ProfiledEventTask, acks_late=True)
|
||||||
def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, objects: list, items: list,
|
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,
|
recipients: str, filter_checkins: bool, not_checked_in: bool, checkin_lists: list,
|
||||||
attachments: list = None, attach_tickets: bool = False,
|
attachments: list = None, attach_tickets: bool = False,
|
||||||
attach_ical: bool = False) -> None:
|
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 []
|
list_id__in=checkin_lists or []
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
).prefetch_related('addons'):
|
).prefetch_related('addons', 'subevent'):
|
||||||
if p.addon_to_id is not None:
|
if p.addon_to_id is not None:
|
||||||
continue
|
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:
|
if p.attendee_email == o.email and send_to_order:
|
||||||
continue
|
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:
|
try:
|
||||||
with language(o.locale, event.settings.region):
|
with language(o.locale, event.settings.region):
|
||||||
email_context = get_email_context(event=event, order=o, invoice_address=ia, position=p)
|
email_context = get_email_context(event=event, order=o, invoice_address=ia, position=p)
|
||||||
|
|||||||
@@ -429,6 +429,9 @@ class OrderSendView(BaseSenderView):
|
|||||||
kwargs.update({
|
kwargs.update({
|
||||||
'recipients': form.cleaned_data['recipients'],
|
'recipients': form.cleaned_data['recipients'],
|
||||||
'items': [i.pk for i in form.cleaned_data.get('items')],
|
'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'),
|
'not_checked_in': form.cleaned_data.get('not_checked_in'),
|
||||||
'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')],
|
'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')],
|
||||||
'filter_checkins': form.cleaned_data.get('filter_checkins'),
|
'filter_checkins': form.cleaned_data.get('filter_checkins'),
|
||||||
|
|||||||
@@ -406,6 +406,79 @@ def test_sendmail_attendee_product_filter(logged_in_client, sendmail_url, event,
|
|||||||
assert '/order/' not in djmail.outbox[0].body
|
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
|
@pytest.mark.django_db
|
||||||
def test_sendmail_attendee_checkin_filter(logged_in_client, sendmail_url, event, order, checkin_list, item, pos):
|
def test_sendmail_attendee_checkin_filter(logged_in_client, sendmail_url, event, order, checkin_list, item, pos):
|
||||||
event.settings.attendee_emails_asked = True
|
event.settings.attendee_emails_asked = True
|
||||||
|
|||||||
Reference in New Issue
Block a user