forked from CGM_Public/pretix_original
Add order lifecycle signals
This commit is contained in:
@@ -20,7 +20,7 @@ Order events
|
|||||||
There are multiple signals that will be sent out in the ordering cycle:
|
There are multiple signals that will be sent out in the ordering cycle:
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
:members: validate_cart, order_fee_calculation, order_paid, order_placed, order_fee_type_name, allow_ticket_download
|
:members: validate_cart, order_fee_calculation, order_paid, order_placed, order_canceled, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download
|
||||||
|
|
||||||
Frontend
|
Frontend
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ from pretix.base.services.orders import (
|
|||||||
extend_order, mark_order_expired, mark_order_refunded,
|
extend_order, mark_order_expired, mark_order_refunded,
|
||||||
)
|
)
|
||||||
from pretix.base.services.tickets import generate
|
from pretix.base.services.tickets import generate
|
||||||
from pretix.base.signals import order_placed, register_ticket_outputs
|
from pretix.base.signals import (
|
||||||
|
order_modified, order_placed, register_ticket_outputs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OrderFilter(FilterSet):
|
class OrderFilter(FilterSet):
|
||||||
@@ -451,8 +453,8 @@ class OrderViewSet(viewsets.ModelViewSet):
|
|||||||
)
|
)
|
||||||
return super().update(request, *args, **kwargs)
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def perform_update(self, serializer):
|
def perform_update(self, serializer):
|
||||||
|
with transaction.atomic():
|
||||||
if 'comment' in self.request.data and serializer.instance.comment != self.request.data.get('comment'):
|
if 'comment' in self.request.data and serializer.instance.comment != self.request.data.get('comment'):
|
||||||
serializer.instance.log_action(
|
serializer.instance.log_action(
|
||||||
'pretix.event.order.comment',
|
'pretix.event.order.comment',
|
||||||
@@ -507,6 +509,9 @@ class OrderViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
if 'invoice_address' in self.request.data:
|
||||||
|
order_modified.send(sender=serializer.instance.event, order=serializer.instance)
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ from pretix.base.services.mail import SendMailException
|
|||||||
from pretix.base.services.pricing import get_price
|
from pretix.base.services.pricing import get_price
|
||||||
from pretix.base.services.tasks import ProfiledTask
|
from pretix.base.services.tasks import ProfiledTask
|
||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
allow_ticket_download, order_fee_calculation, order_placed, periodic_task,
|
allow_ticket_download, order_approved, order_canceled, order_changed,
|
||||||
|
order_denied, order_expired, order_fee_calculation, order_placed,
|
||||||
|
periodic_task,
|
||||||
)
|
)
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.helpers.models import modelcopy
|
from pretix.helpers.models import modelcopy
|
||||||
@@ -134,13 +136,13 @@ def mark_order_refunded(order, user=None, auth=None, api_token=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def mark_order_expired(order, user=None, auth=None):
|
def mark_order_expired(order, user=None, auth=None):
|
||||||
"""
|
"""
|
||||||
Mark this order as expired. This sets the payment status and returns the order object.
|
Mark this order as expired. This sets the payment status and returns the order object.
|
||||||
:param order: The order to change
|
:param order: The order to change
|
||||||
:param user: The user that performed the change
|
:param user: The user that performed the change
|
||||||
"""
|
"""
|
||||||
|
with transaction.atomic():
|
||||||
if isinstance(order, int):
|
if isinstance(order, int):
|
||||||
order = Order.objects.get(pk=order)
|
order = Order.objects.get(pk=order)
|
||||||
if isinstance(user, int):
|
if isinstance(user, int):
|
||||||
@@ -154,16 +156,17 @@ def mark_order_expired(order, user=None, auth=None):
|
|||||||
if i:
|
if i:
|
||||||
generate_cancellation(i)
|
generate_cancellation(i)
|
||||||
|
|
||||||
|
order_expired.send(order.event, order=order)
|
||||||
return order
|
return order
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def approve_order(order, user=None, send_mail: bool=True, auth=None):
|
def approve_order(order, user=None, send_mail: bool=True, auth=None):
|
||||||
"""
|
"""
|
||||||
Mark this order as approved
|
Mark this order as approved
|
||||||
:param order: The order to change
|
:param order: The order to change
|
||||||
:param user: The user that performed the change
|
:param user: The user that performed the change
|
||||||
"""
|
"""
|
||||||
|
with transaction.atomic():
|
||||||
if not order.require_approval or not order.status == Order.STATUS_PENDING:
|
if not order.require_approval or not order.status == Order.STATUS_PENDING:
|
||||||
raise OrderError(_('This order is not pending approval.'))
|
raise OrderError(_('This order is not pending approval.'))
|
||||||
|
|
||||||
@@ -184,6 +187,8 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None):
|
|||||||
except Quota.QuotaExceededException:
|
except Quota.QuotaExceededException:
|
||||||
raise OrderError(error_messages['unavailable'])
|
raise OrderError(error_messages['unavailable'])
|
||||||
|
|
||||||
|
order_approved.send(order.event, order=order)
|
||||||
|
|
||||||
invoice = order.invoices.last() # Might be generated by plugin already
|
invoice = order.invoices.last() # Might be generated by plugin already
|
||||||
if order.event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
if order.event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
||||||
if not invoice:
|
if not invoice:
|
||||||
@@ -234,13 +239,13 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None):
|
|||||||
return order.pk
|
return order.pk
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
||||||
"""
|
"""
|
||||||
Mark this order as canceled
|
Mark this order as canceled
|
||||||
:param order: The order to change
|
:param order: The order to change
|
||||||
:param user: The user that performed the change
|
:param user: The user that performed the change
|
||||||
"""
|
"""
|
||||||
|
with transaction.atomic():
|
||||||
if not order.require_approval or not order.status == Order.STATUS_PENDING:
|
if not order.require_approval or not order.status == Order.STATUS_PENDING:
|
||||||
raise OrderError(_('This order is not pending approval.'))
|
raise OrderError(_('This order is not pending approval.'))
|
||||||
|
|
||||||
@@ -259,6 +264,8 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
|||||||
if position.voucher:
|
if position.voucher:
|
||||||
Voucher.objects.filter(pk=position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1))
|
Voucher.objects.filter(pk=position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1))
|
||||||
|
|
||||||
|
order_denied.send(order.event, order=order)
|
||||||
|
|
||||||
if send_mail:
|
if send_mail:
|
||||||
try:
|
try:
|
||||||
invoice_name = order.invoice_address.name
|
invoice_name = order.invoice_address.name
|
||||||
@@ -294,7 +301,6 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
|||||||
return order.pk
|
return order.pk
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None,
|
def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None,
|
||||||
cancellation_fee=None):
|
cancellation_fee=None):
|
||||||
"""
|
"""
|
||||||
@@ -302,6 +308,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
|||||||
:param order: The order to change
|
:param order: The order to change
|
||||||
:param user: The user that performed the change
|
:param user: The user that performed the change
|
||||||
"""
|
"""
|
||||||
|
with transaction.atomic():
|
||||||
if isinstance(order, int):
|
if isinstance(order, int):
|
||||||
order = Order.objects.get(pk=order)
|
order = Order.objects.get(pk=order)
|
||||||
if isinstance(user, int):
|
if isinstance(user, int):
|
||||||
@@ -381,6 +388,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
|||||||
except SendMailException:
|
except SendMailException:
|
||||||
logger.exception('Order canceled email could not be sent')
|
logger.exception('Order canceled email could not be sent')
|
||||||
|
|
||||||
|
order_canceled.send(order.event, order=order)
|
||||||
return order.pk
|
return order.pk
|
||||||
|
|
||||||
|
|
||||||
@@ -1377,6 +1385,8 @@ class OrderChangeManager:
|
|||||||
if self.split_order:
|
if self.split_order:
|
||||||
self._notify_user(self.split_order)
|
self._notify_user(self.split_order)
|
||||||
|
|
||||||
|
order_changed.send(self.order.event, order=self.order)
|
||||||
|
|
||||||
def _clear_tickets_cache(self):
|
def _clear_tickets_cache(self):
|
||||||
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
||||||
CachedCombinedTicket.objects.filter(order=self.order).delete()
|
CachedCombinedTicket.objects.filter(order=self.order).delete()
|
||||||
|
|||||||
@@ -275,6 +275,66 @@ because an already-paid order has been split.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
order_canceled = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order is canceled. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
order_expired = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order is marked as expired. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
order_modified = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order's information is modified. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
order_changed = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order's content is changed. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
order_approved = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order is being approved. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
order_denied = EventPluginSignal(
|
||||||
|
providing_args=["order"]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal is sent out every time an order is being denied. The order object is given
|
||||||
|
as the first argument.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
"""
|
||||||
|
|
||||||
logentry_display = EventPluginSignal(
|
logentry_display = EventPluginSignal(
|
||||||
providing_args=["logentry"]
|
providing_args=["logentry"]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ from pretix.base.services.orders import (
|
|||||||
from pretix.base.services.stats import order_overview
|
from pretix.base.services.stats import order_overview
|
||||||
from pretix.base.services.tickets import generate
|
from pretix.base.services.tickets import generate
|
||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
register_data_exporters, register_ticket_outputs,
|
order_modified, register_data_exporters, register_ticket_outputs,
|
||||||
)
|
)
|
||||||
from pretix.base.templatetags.money import money_filter
|
from pretix.base.templatetags.money import money_filter
|
||||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||||
@@ -1321,6 +1321,8 @@ class OrderModifyInformation(OrderQuestionsViewMixin, OrderView):
|
|||||||
|
|
||||||
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
||||||
CachedCombinedTicket.objects.filter(order=self.order).delete()
|
CachedCombinedTicket.objects.filter(order=self.order).delete()
|
||||||
|
|
||||||
|
order_modified.send(sender=self.request.event, order=self.order)
|
||||||
return redirect(self.get_order_url())
|
return redirect(self.get_order_url())
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ from pretix.base.services.invoices import (
|
|||||||
from pretix.base.services.mail import SendMailException
|
from pretix.base.services.mail import SendMailException
|
||||||
from pretix.base.services.orders import cancel_order, change_payment_provider
|
from pretix.base.services.orders import cancel_order, change_payment_provider
|
||||||
from pretix.base.services.tickets import generate
|
from pretix.base.services.tickets import generate
|
||||||
from pretix.base.signals import allow_ticket_download, register_ticket_outputs
|
from pretix.base.signals import (
|
||||||
|
allow_ticket_download, order_modified, register_ticket_outputs,
|
||||||
|
)
|
||||||
from pretix.base.views.mixins import OrderQuestionsViewMixin
|
from pretix.base.views.mixins import OrderQuestionsViewMixin
|
||||||
from pretix.base.views.tasks import AsyncAction
|
from pretix.base.views.tasks import AsyncAction
|
||||||
from pretix.helpers.safedownload import check_token
|
from pretix.helpers.safedownload import check_token
|
||||||
@@ -540,6 +542,7 @@ class OrderModify(EventViewMixin, OrderDetailMixin, OrderQuestionsViewMixin, Tem
|
|||||||
for k in f.changed_data
|
for k in f.changed_data
|
||||||
} for f in self.forms]
|
} for f in self.forms]
|
||||||
})
|
})
|
||||||
|
order_modified.send(sender=self.request.event, order=self.order)
|
||||||
if self.invoice_form.has_changed():
|
if self.invoice_form.has_changed():
|
||||||
success_message = ('Your invoice address has been updated. Please contact us if you need us '
|
success_message = ('Your invoice address has been updated. Please contact us if you need us '
|
||||||
'to regenerate your invoice.')
|
'to regenerate your invoice.')
|
||||||
|
|||||||
Reference in New Issue
Block a user