mirror of
https://github.com/pretix/pretix.git
synced 2025-12-09 00:42:28 +00:00
Compare commits
3 Commits
answer-exp
...
voucher-we
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
712463b259 | ||
|
|
78ad4f4979 | ||
|
|
8e106d2f85 |
@@ -60,6 +60,9 @@ The following values for ``action_types`` are valid with pretix core:
|
|||||||
* ``pretix.event.added``
|
* ``pretix.event.added``
|
||||||
* ``pretix.event.changed``
|
* ``pretix.event.changed``
|
||||||
* ``pretix.event.deleted``
|
* ``pretix.event.deleted``
|
||||||
|
* ``pretix.voucher.added``
|
||||||
|
* ``pretix.voucher.changed``
|
||||||
|
* ``pretix.voucher.deleted``
|
||||||
* ``pretix.subevent.added``
|
* ``pretix.subevent.added``
|
||||||
* ``pretix.subevent.changed``
|
* ``pretix.subevent.changed``
|
||||||
* ``pretix.subevent.deleted``
|
* ``pretix.subevent.deleted``
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ class WebhookEvent:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError() # NOQA
|
raise NotImplementedError() # NOQA
|
||||||
|
|
||||||
|
@property
|
||||||
|
def help_text(self) -> str:
|
||||||
|
"""
|
||||||
|
A human-readable description
|
||||||
|
"""
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def get_all_webhook_events():
|
def get_all_webhook_events():
|
||||||
global _ALL_EVENTS
|
global _ALL_EVENTS
|
||||||
@@ -97,9 +104,10 @@ def get_all_webhook_events():
|
|||||||
|
|
||||||
|
|
||||||
class ParametrizedWebhookEvent(WebhookEvent):
|
class ParametrizedWebhookEvent(WebhookEvent):
|
||||||
def __init__(self, action_type, verbose_name):
|
def __init__(self, action_type, verbose_name, help_text=""):
|
||||||
self._action_type = action_type
|
self._action_type = action_type
|
||||||
self._verbose_name = verbose_name
|
self._verbose_name = verbose_name
|
||||||
|
self._help_text = help_text
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -110,6 +118,10 @@ class ParametrizedWebhookEvent(WebhookEvent):
|
|||||||
def verbose_name(self):
|
def verbose_name(self):
|
||||||
return self._verbose_name
|
return self._verbose_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def help_text(self):
|
||||||
|
return self._help_text
|
||||||
|
|
||||||
|
|
||||||
class ParametrizedOrderWebhookEvent(ParametrizedWebhookEvent):
|
class ParametrizedOrderWebhookEvent(ParametrizedWebhookEvent):
|
||||||
def build_payload(self, logentry: LogEntry):
|
def build_payload(self, logentry: LogEntry):
|
||||||
@@ -161,6 +173,19 @@ class ParametrizedEventWebhookEvent(ParametrizedWebhookEvent):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ParametrizedVoucherWebhookEvent(ParametrizedWebhookEvent):
|
||||||
|
|
||||||
|
def build_payload(self, logentry: LogEntry):
|
||||||
|
# do not use content_object, this is also called in deletion
|
||||||
|
return {
|
||||||
|
'notification_id': logentry.pk,
|
||||||
|
'organizer': logentry.event.organizer.slug,
|
||||||
|
'event': logentry.event.slug,
|
||||||
|
'voucher': logentry.object_id,
|
||||||
|
'action': logentry.action_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ParametrizedSubEventWebhookEvent(ParametrizedWebhookEvent):
|
class ParametrizedSubEventWebhookEvent(ParametrizedWebhookEvent):
|
||||||
|
|
||||||
def build_payload(self, logentry: LogEntry):
|
def build_payload(self, logentry: LogEntry):
|
||||||
@@ -346,8 +371,9 @@ def register_default_webhook_events(sender, **kwargs):
|
|||||||
),
|
),
|
||||||
ParametrizedItemWebhookEvent(
|
ParametrizedItemWebhookEvent(
|
||||||
'pretix.event.item.*',
|
'pretix.event.item.*',
|
||||||
_('Product changed (including product added or deleted and including changes to nested objects like '
|
_('Product changed'),
|
||||||
'variations or bundles)'),
|
_('This includes product added or deleted and changes to nested objects like '
|
||||||
|
'variations or bundles.'),
|
||||||
),
|
),
|
||||||
ParametrizedEventWebhookEvent(
|
ParametrizedEventWebhookEvent(
|
||||||
'pretix.event.live.activated',
|
'pretix.event.live.activated',
|
||||||
@@ -381,6 +407,19 @@ def register_default_webhook_events(sender, **kwargs):
|
|||||||
'pretix.event.orders.waitinglist.voucher_assigned',
|
'pretix.event.orders.waitinglist.voucher_assigned',
|
||||||
_('Waiting list entry received voucher'),
|
_('Waiting list entry received voucher'),
|
||||||
),
|
),
|
||||||
|
ParametrizedVoucherWebhookEvent(
|
||||||
|
'pretix.voucher.added',
|
||||||
|
_('Voucher added'),
|
||||||
|
),
|
||||||
|
ParametrizedVoucherWebhookEvent(
|
||||||
|
'pretix.voucher.changed',
|
||||||
|
_('Voucher changed'),
|
||||||
|
_('Only includes explicit changes to the voucher, not e.g. an increase of the number of redemptions.')
|
||||||
|
),
|
||||||
|
ParametrizedVoucherWebhookEvent(
|
||||||
|
'pretix.voucher.deleted',
|
||||||
|
_('Voucher deleted'),
|
||||||
|
),
|
||||||
ParametrizedCustomerWebhookEvent(
|
ParametrizedCustomerWebhookEvent(
|
||||||
'pretix.customer.created',
|
'pretix.customer.created',
|
||||||
_('Customer account created'),
|
_('Customer account created'),
|
||||||
|
|||||||
@@ -207,16 +207,19 @@ class WaitingListEntry(LoggedModel):
|
|||||||
block_quota=True,
|
block_quota=True,
|
||||||
subevent=self.subevent,
|
subevent=self.subevent,
|
||||||
)
|
)
|
||||||
v.log_action('pretix.voucher.added.waitinglist', {
|
v.log_action('pretix.voucher.added', {
|
||||||
'item': self.item.pk,
|
'item': self.item.pk,
|
||||||
'variation': self.variation.pk if self.variation else None,
|
'variation': self.variation.pk if self.variation else None,
|
||||||
'tag': 'waiting-list',
|
'tag': 'waiting-list',
|
||||||
'block_quota': True,
|
'block_quota': True,
|
||||||
'valid_until': v.valid_until.isoformat(),
|
'valid_until': v.valid_until.isoformat(),
|
||||||
'max_usages': 1,
|
'max_usages': 1,
|
||||||
|
'subevent': self.subevent.pk if self.subevent else None,
|
||||||
|
'source': 'waitinglist',
|
||||||
|
}, user=user, auth=auth)
|
||||||
|
v.log_action('pretix.voucher.added.waitinglist', {
|
||||||
'email': self.email,
|
'email': self.email,
|
||||||
'waitinglistentry': self.pk,
|
'waitinglistentry': self.pk,
|
||||||
'subevent': self.subevent.pk if self.subevent else None,
|
|
||||||
}, user=user, auth=auth)
|
}, user=user, auth=auth)
|
||||||
self.voucher = v
|
self.voucher = v
|
||||||
self.save()
|
self.save()
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ from django.forms import formset_factory, inlineformset_factory
|
|||||||
from django.forms.utils import ErrorDict
|
from django.forms.utils import ErrorDict
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.html import conditional_escape
|
from django.utils.html import conditional_escape, format_html
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
from django_scopes.forms import SafeModelChoiceField
|
from django_scopes.forms import SafeModelChoiceField
|
||||||
@@ -695,7 +695,9 @@ class WebHookForm(forms.ModelForm):
|
|||||||
self.fields['events'].choices = [
|
self.fields['events'].choices = [
|
||||||
(
|
(
|
||||||
a.action_type,
|
a.action_type,
|
||||||
mark_safe('{} – <code>{}</code>'.format(a.verbose_name, a.action_type))
|
format_html('{} – <code>{}</code><br><span class="text-muted">{}</span>', a.verbose_name, a.action_type, a.help_text)
|
||||||
|
if a.help_text else
|
||||||
|
format_html('{} – <code>{}</code>', a.verbose_name, a.action_type)
|
||||||
) for a in get_all_webhook_events().values()
|
) for a in get_all_webhook_events().values()
|
||||||
]
|
]
|
||||||
if self.instance and self.instance.pk:
|
if self.instance and self.instance.pk:
|
||||||
|
|||||||
@@ -563,11 +563,11 @@ class CoreOrderLogEntryType(OrderLogEntryType):
|
|||||||
@log_entry_types.new_from_dict({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.voucher.added': _('The voucher has been created.'),
|
'pretix.voucher.added': _('The voucher has been created.'),
|
||||||
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
|
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
|
||||||
'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
|
|
||||||
'pretix.voucher.expired.waitinglist': _(
|
'pretix.voucher.expired.waitinglist': _(
|
||||||
'The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
|
'The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
|
||||||
'pretix.voucher.changed': _('The voucher has been changed.'),
|
'pretix.voucher.changed': _('The voucher has been changed.'),
|
||||||
'pretix.voucher.deleted': _('The voucher has been deleted.'),
|
'pretix.voucher.deleted': _('The voucher has been deleted.'),
|
||||||
|
'pretix.voucher.added.waitinglist': _('The voucher has been sent to {email} through the waiting list.'),
|
||||||
})
|
})
|
||||||
class CoreVoucherLogEntryType(VoucherLogEntryType):
|
class CoreVoucherLogEntryType(VoucherLogEntryType):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ class VoucherCreate(EventPermissionRequiredMixin, CreateView):
|
|||||||
messages.success(self.request, mark_safe(_('The new voucher has been created: {code}').format(
|
messages.success(self.request, mark_safe(_('The new voucher has been created: {code}').format(
|
||||||
code=format_html('<a href="{url}">{code}</a>', url=url, code=self.object.code)
|
code=format_html('<a href="{url}">{code}</a>', url=url, code=self.object.code)
|
||||||
)))
|
)))
|
||||||
form.instance.log_action('pretix.voucher.added', data=dict(form.cleaned_data), user=self.request.user)
|
form.instance.log_action('pretix.voucher.added', data={**dict(form.cleaned_data), "source": "control"}, user=self.request.user)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@@ -475,7 +475,7 @@ class VoucherBulkCreate(EventPermissionRequiredMixin, AsyncFormView):
|
|||||||
data['bulk'] = True
|
data['bulk'] = True
|
||||||
del data['codes']
|
del data['codes']
|
||||||
log_entries.append(
|
log_entries.append(
|
||||||
v.log_action('pretix.voucher.added', data=data, user=self.request.user, save=False)
|
v.log_action('pretix.voucher.added', data={**data, "source": "control_bulk"}, user=self.request.user, save=False)
|
||||||
)
|
)
|
||||||
LogEntry.bulk_create_and_postprocess(log_entries)
|
LogEntry.bulk_create_and_postprocess(log_entries)
|
||||||
form.post_bulk_save(batch_vouchers)
|
form.post_bulk_save(batch_vouchers)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ def test_waitinglist_shredder(event, item):
|
|||||||
)
|
)
|
||||||
wle.send_voucher()
|
wle.send_voucher()
|
||||||
assert '@' in wle.voucher.comment
|
assert '@' in wle.voucher.comment
|
||||||
assert '@' in wle.voucher.all_logentries().last().data
|
assert '@' in wle.voucher.all_logentries().get(action_type="pretix.voucher.added.waitinglist").data
|
||||||
s = WaitingListShredder(event)
|
s = WaitingListShredder(event)
|
||||||
f = list(s.generate_files())
|
f = list(s.generate_files())
|
||||||
assert json.loads(f[0][2]) == [
|
assert json.loads(f[0][2]) == [
|
||||||
@@ -166,7 +166,7 @@ def test_waitinglist_shredder(event, item):
|
|||||||
assert '@' not in wle.email
|
assert '@' not in wle.email
|
||||||
assert '+49' not in str(wle.phone)
|
assert '+49' not in str(wle.phone)
|
||||||
assert '@' not in wle.voucher.comment
|
assert '@' not in wle.voucher.comment
|
||||||
assert '@' not in wle.voucher.all_logentries().last().data
|
assert '@' not in wle.voucher.all_logentries().get(action_type="pretix.voucher.added.waitinglist").data
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
Reference in New Issue
Block a user