From 0665bd443bdfbce4c1b47fee707754b21d1520a3 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sun, 22 Jan 2017 18:05:47 +0100 Subject: [PATCH] Add validate_cart hook --- doc/development/api/general.rst | 2 +- src/pretix/base/services/cart.py | 11 +++++++++++ src/pretix/base/signals.py | 13 +++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/development/api/general.rst b/doc/development/api/general.rst index 0e064551c..8fffe2771 100644 --- a/doc/development/api/general.rst +++ b/doc/development/api/general.rst @@ -19,7 +19,7 @@ Order events There are multiple signals that will be sent out in the ordering cycle: .. automodule:: pretix.base.signals - :members: order_paid, order_placed + :members: validate_cart, order_paid, order_placed Frontend -------- diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index d209102ad..1fac08175 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -12,6 +12,7 @@ from pretix.base.models import ( ) from pretix.base.services.async import ProfiledTask from pretix.base.services.locking import LockTimeoutException +from pretix.base.signals import validate_cart from pretix.celery_app import app @@ -207,6 +208,11 @@ def _add_items_to_cart(event: Event, items: List[dict], cart_id: str=None) -> No # TODO: i18n plurals raise CartError(error_messages['max_items'], (event.settings.max_items_per_order,)) + validate_cart.send( + sender=event, positions=CartPosition.objects.filter(Q(cart_id=cart_id) & Q(event=event)), + requested_add=items, requested_delete=[] + ) + expiry = now_dt + timedelta(minutes=event.settings.get('reservation_time', as_type=int)) _extend_existing(event, cart_id, expiry, now_dt) @@ -240,6 +246,11 @@ def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None) -> def _remove_items_from_cart(event: Event, items: List[dict], cart_id: str) -> None: with event.lock(): + validate_cart.send( + sender=event, positions=CartPosition.objects.filter(Q(cart_id=cart_id) & Q(event=event)), + requested_add=[], requested_delete=items + ) + for i in items: cw = Q(cart_id=cart_id) & Q(item_id=i['item']) & Q(event=event) if i['variation']: diff --git a/src/pretix/base/signals.py b/src/pretix/base/signals.py index 10f12f676..d9eafd956 100644 --- a/src/pretix/base/signals.py +++ b/src/pretix/base/signals.py @@ -94,6 +94,19 @@ subclass of pretix.base.exporter.BaseExporter As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ +validate_cart = EventPluginSignal( + providing_args=["positions", "requested_add", "requested_delete"] +) +""" +This signal is sent out every time a cart is about to be changed. It includes an iterable +with the current CartPosition objects as well as lists of dictionaries of the cart items +that the user wants to add. Those dictionaries can contain the keys ``item``, ``variation``, +``count``, ``price`` and ``voucher``. The response of receivers will be ignored, but you can +raise an OrderError with an appropriate exception message. + +As with all event-plugin signals, the ``sender`` keyword argument will contain the event. +""" + order_placed = EventPluginSignal( providing_args=["order"] )