diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index 2ee1237ee..41f5a2d81 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -1271,6 +1271,9 @@ class OrderRefundView(OrderView): if offset_order.event.currency != self.request.event.currency: messages.error(self.request, _('You entered an order in an event with a different currency.')) is_valid = False + if not self.request.user.has_event_permission(self.request.organizer, offset_order.event, 'event.orders:write', request=self.request): + messages.error(self.request, _('You entered an order in an event that you do not have access to.')) + is_valid = False refunds.append(OrderRefund( order=order, payment=None, @@ -1342,7 +1345,12 @@ class OrderRefundView(OrderView): )) any_success = False - if refund_selected == full_refund and is_valid: + if refund_selected != full_refund: + messages.error(self.request, _('The refunds you selected do not match the selected total refund ' + 'amount.')) + is_valid = False + + if is_valid: for r in refunds: r.save() order.log_action('pretix.event.order.refund.created', { @@ -1414,9 +1422,6 @@ class OrderRefundView(OrderView): ) })) return redirect(self.get_order_url()) - else: - messages.error(self.request, _('The refunds you selected do not match the selected total refund ' - 'amount.')) def post(self, *args, **kwargs): if self.start_form.is_valid(): diff --git a/src/tests/control/test_orders.py b/src/tests/control/test_orders.py index f773c5be3..92e20a85e 100644 --- a/src/tests/control/test_orders.py +++ b/src/tests/control/test_orders.py @@ -2438,6 +2438,47 @@ def test_refund_paid_order_offsetting_to_wrong_currency(client, env): assert b'different currency' in r.content +@pytest.mark.django_db +def test_refund_paid_order_offsetting_to_wrong_permissions(client, env): + with scopes_disabled(): + p = env[2].payments.last() + p.confirm() + t = env[0].organizer.teams.get() + t.all_events = False + t.save() + t.limit_events.set([env[0]]) + client.login(email='dummy@dummy.dummy', password='dummy') + event2 = Event.objects.create( + organizer=env[0].organizer, name='Dummy', slug='dummy2', + date_from=now(), plugins='pretix.plugins.banktransfer,pretix.plugins.stripe,tests.testdummy', + currency='EUR', + ) + ticket2 = Item.objects.create(event=event2, name='Early-bird ticket', + category=None, default_price=23, + admission=True, personalized=True) + o = Order.objects.create( + code='BAZ', event=event2, email='dummy@dummy.test', + status=Order.STATUS_PENDING, + datetime=now(), expires=now() + timedelta(days=10), + sales_channel=event2.organizer.sales_channels.get(identifier="web"), + total=5, locale='en' + ) + o.positions.create(price=5, item=ticket2) + + r = client.post('/control/event/dummy/dummy/orders/ABC32/refund', { + 'start-partial_amount': '5.00', + 'start-mode': 'partial', + 'start-action': 'mark_pending', + 'refund-offsetting': '5.00', + 'order-offsetting': 'BAZ', + 'manual_state': 'pending', + 'last_known_refund_id': 0, + 'perform': 'on' + }, follow=True) + assert b'alert-danger' in r.content + assert b'do not have access' in r.content + + @pytest.mark.django_db def test_refund_paid_order_offsetting(client, env): with scopes_disabled():