diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index e01d95126..75459370b 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -602,7 +602,7 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet): order.status in (Order.STATUS_PAID, Order.STATUS_PENDING) and order.invoices.filter(is_cancellation=True).count() >= order.invoices.filter(is_cancellation=False).count() ) - if self.request.event.settings.get('invoice_generate') not in ('admin', 'user', 'paid', 'True') or not invoice_qualified(order): + if self.request.event.settings.get('invoice_generate') not in ('admin', 'user', 'paid', 'user_paid', 'True') or not invoice_qualified(order): return Response( {'detail': _('You cannot generate an invoice for this order.')}, status=status.HTTP_400_BAD_REQUEST diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 4b15237bf..5b48b75de 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -1040,6 +1040,7 @@ DEFAULTS = { ('False', _('Do not generate invoices')), ('admin', _('Only manually in admin panel')), ('user', _('Automatically on user request')), + ('user_paid', _('Automatically on user request for paid orders')), ('True', _('Automatically for all created orders')), ('paid', _('Automatically on payment or when required by payment method')), ), @@ -1052,6 +1053,7 @@ DEFAULTS = { ('paid', _('Automatically after payment or when required by payment method')), ('True', _('Automatically before payment for all created orders')), ('user', _('Automatically on user request')), + ('user_paid', _('Automatically on user request for paid orders')), ('admin', _('Only manually in admin panel')), ), help_text=_("Invoices will never be automatically generated for free orders.") diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index 079f0ce9a..82bd4ca60 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -479,7 +479,7 @@ class OrderView(EventPermissionRequiredMixin, DetailView): def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx['can_generate_invoice'] = invoice_qualified(self.order) and ( - self.request.event.settings.invoice_generate in ('admin', 'user', 'paid', 'True') + self.request.event.settings.invoice_generate in ('admin', 'user', 'paid', 'user_paid', 'True') ) and self.order.status in (Order.STATUS_PAID, Order.STATUS_PENDING) and ( not self.order.invoices.exists() or self.order.invoices.filter(is_cancellation=True).count() >= self.order.invoices.filter(is_cancellation=False).count() @@ -1584,7 +1584,7 @@ class OrderInvoiceCreate(OrderView): order.status in (Order.STATUS_PAID, Order.STATUS_PENDING) and order.invoices.filter(is_cancellation=True).count() >= order.invoices.filter(is_cancellation=False).count() ) - if self.request.event.settings.get('invoice_generate') not in ('admin', 'user', 'paid', 'True') or not invoice_qualified(order): + if self.request.event.settings.get('invoice_generate') not in ('admin', 'user', 'paid', 'user_paid', 'True') or not invoice_qualified(order): messages.error(self.request, _('You cannot generate an invoice for this order.')) elif has_inv: messages.error(self.request, _('An invoice for this order already exists.')) diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index eb6bd8512..c2a463890 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -710,7 +710,7 @@ def can_generate_invoice(event, order, ignore_payments=False): and ( event.settings.get('invoice_generate') in ('user', 'True') or ( - event.settings.get('invoice_generate') == 'paid' + event.settings.get('invoice_generate') in ('paid', 'user_paid') and order.status == Order.STATUS_PAID ) ) and ( diff --git a/src/tests/presale/test_orders.py b/src/tests/presale/test_orders.py index 9e41baf2a..3f9f926e3 100644 --- a/src/tests/presale/test_orders.py +++ b/src/tests/presale/test_orders.py @@ -874,6 +874,21 @@ class OrdersTest(BaseOrdersTest): {}, follow=True) assert 'alert-danger' in response.content.decode() + def test_invoice_create_onlypaid(self): + self.event.settings.set('invoice_generate', 'user_paid') + response = self.client.post( + '/%s/%s/order/%s/%s/invoice' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret), + {}, follow=True) + assert 'alert-danger' in response.content.decode() + self.order.status = Order.STATUS_PAID + self.order.save() + response = self.client.post( + '/%s/%s/order/%s/%s/invoice' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret), + {}, follow=True) + assert 'alert-success' in response.content.decode() + with scopes_disabled(): + assert self.order.invoices.exists() + def test_invoice_create_duplicate(self): self.event.settings.set('invoice_generate', 'user') with scopes_disabled():