Allow attendees to modify their data (Z#23152886) (#4138)

* Allow attendees to modify their data

* Allow attendees to change ticket information

* Update src/pretix/control/templates/pretixcontrol/event/settings.html

Co-authored-by: Mira <weller@rami.io>

* Update src/pretix/presale/views/order.py

Co-authored-by: Mira <weller@rami.io>

* Update src/pretix/base/services/placeholders.py

Co-authored-by: Mira <weller@rami.io>

* Tests fix

* Fix test

---------

Co-authored-by: Mira <weller@rami.io>
This commit is contained in:
Raphael Michel
2024-05-08 15:18:33 +02:00
committed by GitHub
parent aa55eb2de2
commit e8f7cea1bf
12 changed files with 347 additions and 28 deletions

View File

@@ -1263,22 +1263,34 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.settings.set('invoice_address_asked', False)
self.event.settings.set('attendee_names_asked', True)
assert self.order.can_modify_answers
assert not self.op1.can_modify_answers
self.event.settings.set('allow_modifications', 'attendee')
assert self.op1.can_modify_answers
self.event.settings.set('attendee_names_asked', False)
assert not self.order.can_modify_answers
assert not self.op1.can_modify_answers
self.event.settings.set('invoice_address_asked', True)
assert self.order.can_modify_answers
assert not self.op1.can_modify_answers
self.event.settings.set('invoice_address_asked', False)
self.event.settings.set('invoice_name_required', True)
assert self.order.can_modify_answers
assert not self.op1.can_modify_answers
q = Question.objects.create(question='Foo', type=Question.TYPE_BOOLEAN, event=self.event)
self.item1.questions.add(q)
assert self.order.can_modify_answers
assert self.op1.can_modify_answers
self.order.status = Order.STATUS_CANCELED
assert not self.order.can_modify_answers
assert not self.op1.can_modify_answers
self.order.status = Order.STATUS_PAID
assert self.order.can_modify_answers
assert self.op1.can_modify_answers
self.event.settings.set('last_order_modification_date', now() - timedelta(days=1))
assert not self.order.can_modify_answers
assert not self.op1.can_modify_answers
@classscope(attr='o')
def test_can_modify_answers_subevent(self):

View File

@@ -191,6 +191,24 @@ class OrdersTest(BaseOrdersTest):
self.deleted_pos.positionid, self.deleted_pos.web_secret)
)
assert response.status_code == 404
response = self.client.get(
'/%s/%s/ticket/%s/1/123/modify' % (self.orga.slug, self.event.slug, self.not_my_order.code)
)
assert response.status_code == 404
response = self.client.get(
'/%s/%s/ticket/%s/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
self.deleted_pos.positionid, self.deleted_pos.web_secret)
)
assert response.status_code == 404
response = self.client.get(
'/%s/%s/ticket/%s/1/123/change' % (self.orga.slug, self.event.slug, self.not_my_order.code)
)
assert response.status_code == 404
response = self.client.get(
'/%s/%s/ticket/%s/%s/%s/change' % (self.orga.slug, self.event.slug, self.order.code,
self.deleted_pos.positionid, self.deleted_pos.web_secret)
)
assert response.status_code == 404
def test_orders_confirm_email(self):
response = self.client.get(
@@ -424,6 +442,49 @@ class OrdersTest(BaseOrdersTest):
with scopes_disabled():
assert self.order.invoices.count() == 3
def test_orders_attendee_modify_invalid(self):
self.order.status = Order.STATUS_CANCELED
self.order.save()
self.event.settings.set('allow_modifications', 'attendee')
r = self.client.get(
'/%s/%s/ticket/%s/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
self.ticket_pos.positionid, self.ticket_pos.web_secret)
)
assert r.status_code == 302
def test_orders_attendee_modify_forbidden(self):
self.event.settings.set('allow_modifications', 'order')
r = self.client.get(
'/%s/%s/ticket/%s/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
self.ticket_pos.positionid, self.ticket_pos.web_secret)
)
assert r.status_code == 302
def test_orders_attendee_modify_attendee_optional(self):
self.event.settings.set('allow_modifications', 'attendee')
self.event.settings.set('attendee_names_asked', True)
self.event.settings.set('attendee_names_required', False)
response = self.client.get(
'/%s/%s/ticket/%s/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
self.ticket_pos.positionid, self.ticket_pos.web_secret)
)
doc = BeautifulSoup(response.content.decode(), "lxml")
self.assertEqual(len(doc.select('input[name="%s-attendee_name_parts_0"]' % self.ticket_pos.id)), 1)
# Not all fields filled out, expect success
response = self.client.post(
'/%s/%s/ticket/%s/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
self.ticket_pos.positionid, self.ticket_pos.web_secret)
)
self.assertRedirects(response,
'/%s/%s/ticket/%s/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,
self.ticket_pos.positionid, self.ticket_pos.web_secret),
target_status_code=200)
with scopes_disabled():
self.ticket_pos = OrderPosition.objects.get(id=self.ticket_pos.id)
assert self.ticket_pos.attendee_name in (None, '')
def test_orders_cancel_invalid(self):
self.order.status = Order.STATUS_PAID
self.order.save()