mirror of
https://github.com/pretix/pretix.git
synced 2026-10-09 20:34:42 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9639688c5a |
@@ -92,9 +92,9 @@ from pretix.base.services.invoices import (
|
||||
regenerate_invoice, transmit_invoice,
|
||||
)
|
||||
from pretix.base.services.orders import (
|
||||
OrderChangeManager, OrderError, _order_placed_email,
|
||||
_order_placed_email_attendee, approve_order, cancel_order, deny_order,
|
||||
extend_order, mark_order_expired, mark_order_refunded, reactivate_order,
|
||||
OrderChangeManager, OrderError, _attendee_mail_send_helper,
|
||||
_order_placed_email, approve_order, cancel_order, deny_order, extend_order,
|
||||
mark_order_expired, mark_order_refunded, reactivate_order,
|
||||
)
|
||||
from pretix.base.services.pricing import get_price
|
||||
from pretix.base.services.tickets import generate
|
||||
@@ -805,17 +805,42 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
|
||||
log_entry, invoice, [payment] if payment else [], is_free=free_flow
|
||||
)
|
||||
if email_attendees:
|
||||
for p in order.positions.all():
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
_order_placed_email_attendee(request.event, order, p, email_attendees_template, subject_attendees_template,
|
||||
log_entry, is_free=free_flow)
|
||||
ev = request.event
|
||||
# todo re note: order_placed_email for attendees (formerly services/orders _order_placed_email_attendee)
|
||||
_attendee_mail_send_helper(
|
||||
event=ev,
|
||||
order=order,
|
||||
positions=order.positions.all(),
|
||||
template=email_attendees_template,
|
||||
subject=subject_attendees_template,
|
||||
log_entry_type=log_entry,
|
||||
attach_tickets=True,
|
||||
attach_ical=ev.settings.mail_attach_ical and (
|
||||
not ev.settings.mail_attach_ical_paid_only or
|
||||
free_flow or
|
||||
order.valid_if_pending
|
||||
),
|
||||
attach_other_files=[a for a in [
|
||||
ev.settings.get('mail_attachment_new_order', as_type=str, default='')[len('file://'):]
|
||||
] if a],
|
||||
)
|
||||
|
||||
if not free_flow and order.status == Order.STATUS_PAID and payment:
|
||||
payment._send_paid_mail(invoice, None, '')
|
||||
if self.request.event.settings.mail_send_order_paid_attendee:
|
||||
for p in order.positions.all():
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
payment._send_paid_mail_attendee(p, None)
|
||||
ev = request.event
|
||||
# todo re note: paid_mail for attendees (formerly models/orders _send_paid_mail_attendee)
|
||||
_attendee_mail_send_helper(
|
||||
event=ev,
|
||||
order=order,
|
||||
positions=order.positions.all(),
|
||||
template=ev.settings.mail_text_order_paid_attendee,
|
||||
subject=ev.settings.mail_subject_order_paid_attendee,
|
||||
log_entry_type='pretix.event.order.email.order_paid',
|
||||
invoices=[],
|
||||
attach_tickets=True,
|
||||
attach_ical=ev.settings.mail_attach_ical
|
||||
)
|
||||
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
@@ -2021,9 +2021,23 @@ class OrderPayment(models.Model):
|
||||
if send_mail and self.order.sales_channel.identifier in self.order.event.settings.mail_sales_channel_placed_paid:
|
||||
self._send_paid_mail(invoice if transmit_invoice_mail else None, user, mail_text)
|
||||
if self.order.event.settings.mail_send_order_paid_attendee:
|
||||
for p in self.order.positions.all():
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != self.order.email:
|
||||
self._send_paid_mail_attendee(p, user)
|
||||
# todo re note: paid_mail for attendees (formerly models/orders _send_paid_mail_attendee)
|
||||
from pretix.base.services.orders import (
|
||||
_attendee_mail_send_helper,
|
||||
)
|
||||
|
||||
_attendee_mail_send_helper(
|
||||
event=self.order.event,
|
||||
order=self.order,
|
||||
positions=self.order.positions.all(),
|
||||
template=self.order.event.settings.mail_text_order_paid_attendee,
|
||||
subject=self.order.event.settings.mail_subject_order_paid_attendee,
|
||||
log_entry_type='pretix.event.order.email.order_paid',
|
||||
user=user,
|
||||
invoices=[],
|
||||
attach_tickets=True,
|
||||
attach_ical=self.order.event.settings.mail_attach_ical,
|
||||
)
|
||||
|
||||
if invoice and not transmit_invoice_mail:
|
||||
transmit_invoice.apply_async(args=(self.order.event_id, invoice.pk, False))
|
||||
|
||||
@@ -39,7 +39,8 @@ from pretix.base.models import (
|
||||
from pretix.base.services.locking import LockTimeoutException
|
||||
from pretix.base.services.mail import mail
|
||||
from pretix.base.services.orders import (
|
||||
OrderChangeManager, OrderError, _cancel_order, _try_auto_refund,
|
||||
OrderChangeManager, OrderError, _attendee_mail_send_helper, _cancel_order,
|
||||
_try_auto_refund,
|
||||
)
|
||||
from pretix.base.services.tasks import ProfiledEventTask
|
||||
from pretix.base.services.tax import split_fee_for_taxes
|
||||
@@ -79,22 +80,38 @@ def _send_mail(order: Order, subject: LazyI18nString, message: LazyI18nString, s
|
||||
user,
|
||||
)
|
||||
|
||||
for p in positions:
|
||||
if subevent and p.subevent_id != subevent.id:
|
||||
continue
|
||||
# todo before pr ready: (aka note to myself)
|
||||
# check if we use a checkbox in the form here
|
||||
# (because before, we didn't check for it and maybe we don't want to here)
|
||||
# also: do we really want to inform attendees about the refund_amount
|
||||
# or do we need to because else the template does not work?
|
||||
_attendee_mail_send_helper(
|
||||
event=order.event,
|
||||
order=order,
|
||||
positions=positions,
|
||||
template=message,
|
||||
subject=subject,
|
||||
log_entry_type='pretix.event.order.email.event_canceled',
|
||||
user=user,
|
||||
subevent=subevent,
|
||||
)
|
||||
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
email_context = get_email_context(event_or_subevent=p.subevent or order.event,
|
||||
event=order.event,
|
||||
refund_amount=refund_amount,
|
||||
position_or_address=p,
|
||||
order=order, position=p)
|
||||
order.send_mail(
|
||||
subject, message, email_context,
|
||||
'pretix.event.order.email.event_canceled',
|
||||
position=p,
|
||||
user=user
|
||||
)
|
||||
# for p in positions:
|
||||
# if subevent and p.subevent_id != subevent.id:
|
||||
# continue
|
||||
#
|
||||
# if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
# email_context = get_email_context(event_or_subevent=p.subevent or order.event,
|
||||
# event=order.event,
|
||||
# refund_amount=refund_amount,
|
||||
# position_or_address=p,
|
||||
# order=order, position=p)
|
||||
# order.send_mail(
|
||||
# subject, message, email_context,
|
||||
# 'pretix.event.order.email.event_canceled',
|
||||
# position=p,
|
||||
# user=user
|
||||
# )
|
||||
|
||||
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
|
||||
|
||||
@@ -114,6 +114,76 @@ from pretix.presale.productlist import prepare_item_list_for_shop
|
||||
from pretix.testutils.middleware import debugflags_var
|
||||
|
||||
|
||||
# todo before pr ready: (aka note to myself)
|
||||
# think about placing this helper function somewhere better
|
||||
# also: check those mail send functions, instead of replacing
|
||||
# maybe we still want to use them here instead of generic send_mail
|
||||
# and/or maybe we want to generalize this thing to also include order mails
|
||||
# (let's maybe not rewrite the whole mail logic?!)
|
||||
# but also, remember to write tests - a whole bunch of tests
|
||||
def _attendee_mail_send_helper(
|
||||
event: Event,
|
||||
order: Order,
|
||||
positions: list,
|
||||
template,
|
||||
subject,
|
||||
user,
|
||||
invoices: list = None,
|
||||
log_entry_type: str = 'pretix.event.order.email.sent',
|
||||
attach_tickets: bool = False,
|
||||
attach_ical: bool = False,
|
||||
attach_other_files: list = None,
|
||||
subevent: SubEvent = None,
|
||||
):
|
||||
parent_op = None
|
||||
sent_to_positions = set()
|
||||
for p in positions:
|
||||
if subevent and p.subevent_id != subevent.id:
|
||||
continue
|
||||
|
||||
if p.addon_to_id is None:
|
||||
# this op might have matching add-ons, so save for later
|
||||
parent_op = p
|
||||
elif not parent_op or p.addon_to_id != parent_op.id:
|
||||
# this op is an add-on, but not to the current parent_op
|
||||
# something got mixed up as add-ons should always come directly after their parent
|
||||
logger.warning(f"Add-ons are mixed up for position #{p.positionid} in order {order.full_code}")
|
||||
continue
|
||||
|
||||
if p.addon_to_id and (
|
||||
not p.attendee_email or p.attendee_email == parent_op.attendee_email
|
||||
):
|
||||
# if op is addon and either has no mail or the same as parent => send to parent
|
||||
p = parent_op
|
||||
|
||||
if p.pk in sent_to_positions:
|
||||
# this position already got an email
|
||||
continue
|
||||
|
||||
if not p.attendee_email or p.attendee_email == order.email:
|
||||
# no email or same as order
|
||||
continue
|
||||
|
||||
email_ctx = get_email_context(event=order.event, order=order, position=p)
|
||||
|
||||
p.send_mail(
|
||||
subject=subject,
|
||||
template=template,
|
||||
context=email_ctx,
|
||||
log_entry_type=log_entry_type,
|
||||
user=user if user else None,
|
||||
invoices=invoices,
|
||||
attach_tickets=attach_tickets,
|
||||
attach_ical=attach_ical,
|
||||
attach_other_files=attach_other_files,
|
||||
# possible, as of yet unused here, parameters:
|
||||
# headers: dict=None,
|
||||
# sender: str=None,
|
||||
# auth=None,
|
||||
)
|
||||
sent_to_positions.add(p.pk)
|
||||
|
||||
|
||||
class OrderError(Exception):
|
||||
def __init__(self, *args):
|
||||
msg = args[0]
|
||||
@@ -461,14 +531,21 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False
|
||||
)
|
||||
|
||||
if email_attendees:
|
||||
for p in order.positions.all():
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
email_attendee_context = get_email_context(event=order.event, order=order, position=p)
|
||||
p.send_mail(
|
||||
email_attendee_subject, email_attendee_template, email_attendee_context,
|
||||
'pretix.event.order.email.order_approved', user,
|
||||
attach_tickets=True,
|
||||
)
|
||||
_attendee_mail_send_helper(
|
||||
event=order.event,
|
||||
order=order,
|
||||
positions=order.positions.all(),
|
||||
template=email_attendee_template,
|
||||
subject=email_attendee_subject,
|
||||
log_entry_type='pretix.event.order.email.order_approved',
|
||||
user=user,
|
||||
attach_tickets=True,
|
||||
attach_ical=order.event.settings.mail_attach_ical and (
|
||||
not order.event.settings.mail_attach_ical_paid_only or
|
||||
order.total == Decimal('0.00') or
|
||||
order.valid_if_pending
|
||||
),
|
||||
)
|
||||
|
||||
return order.pk
|
||||
|
||||
@@ -1399,10 +1476,20 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
||||
is_free=free_order_flow
|
||||
)
|
||||
if email_attendees:
|
||||
for p in order.positions.all():
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||
_order_placed_email_attendee(event, order, p, email_attendees_template, subject_attendees_template, log_entry,
|
||||
is_free=free_order_flow)
|
||||
# todo re note: order_placed_email for attendees (formerly services/orders _order_placed_email_attendee)
|
||||
_attendee_mail_send_helper(
|
||||
event=event,
|
||||
order=order,
|
||||
positions=order.positions.all(),
|
||||
template=email_attendees_template,
|
||||
subject=subject_attendees_template,
|
||||
log_entry_type=log_entry,
|
||||
attach_ical=event.settings.mail_attach_ical and (
|
||||
not event.settings.mail_attach_ical_paid_only or
|
||||
free_order_flow or
|
||||
order.valid_if_pending
|
||||
),
|
||||
)
|
||||
|
||||
if not any_payment_failed:
|
||||
for p in payment_objs:
|
||||
@@ -1601,6 +1688,7 @@ def send_download_reminders(sender, **kwargs):
|
||||
)
|
||||
|
||||
if event.settings.mail_send_download_reminder_attendee:
|
||||
send_to_positions = []
|
||||
for p in positions:
|
||||
if p.subevent_id:
|
||||
reminder_date = (p.subevent.date_from - timedelta(days=event.reminder_days)).replace(
|
||||
@@ -1608,15 +1696,22 @@ def send_download_reminders(sender, **kwargs):
|
||||
)
|
||||
if now() < reminder_date:
|
||||
continue
|
||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != o.email:
|
||||
email_template = event.settings.mail_text_download_reminder_attendee
|
||||
email_subject = event.settings.mail_subject_download_reminder_attendee
|
||||
email_context = get_email_context(event=event, order=o, position=p)
|
||||
o.send_mail(
|
||||
email_subject, email_template, email_context,
|
||||
'pretix.event.order.email.download_reminder_sent',
|
||||
attach_tickets=True, position=p
|
||||
)
|
||||
else:
|
||||
send_to_positions.append(p)
|
||||
# todo before pr ready (aka note to myself):
|
||||
# order's send_mail used before, check if there was a good reason to not
|
||||
# use postion's send_mail
|
||||
# if not, look for a way to not use double iteration over positions (see above)
|
||||
# otherwise: rewrite this without this helper function anyway
|
||||
_attendee_mail_send_helper(
|
||||
event=event,
|
||||
order=o,
|
||||
positions=send_to_positions,
|
||||
email_template=event.settings.mail_text_download_reminder_attendee,
|
||||
email_subject=event.settings.mail_subject_download_reminder_attendee,
|
||||
log_entry_type='pretix.event.order.email.download_reminder_sent',
|
||||
attach_tickets=True,
|
||||
)
|
||||
|
||||
|
||||
def notify_user_changed_order(order, user=None, auth=None, invoices=[]):
|
||||
|
||||
Reference in New Issue
Block a user