Add a simple test mode (#1181)

- [x] Provide data model and configuration toggle
- [x] Allow to delete individual test orders
- [x] Add tests
- [x] Add a prominent warning message to the backend if test mode orders exist (even though test mode is off), as this leads to wrong statistics
- [x] Decide if and how to generate invoices for test orders as invoice numbers cannot be repeated or should not have gaps.
- [x] Decide if and how we expose test orders through the API, since our difference pull mechanism relies on the fact that orders cannot be deleted.
- [x] Decide if and how we want to couple test modes of payment providers?
- [ ] pretix.eu: Ignore test orders for billing
- [ ] Adjust payment providers: Mollie, bitpay, cash, fakepayment, sepadebit

![download](https://user-images.githubusercontent.com/64280/53009081-fe420d80-343a-11e9-8361-b8511c988598.png)
This commit is contained in:
Raphael Michel
2019-02-20 17:51:26 +01:00
committed by GitHub
parent 8ffc96bf31
commit 67059fe323
49 changed files with 759 additions and 91 deletions

View File

@@ -101,6 +101,11 @@ class BankTransfer(BasePaymentProvider):
def public_name(self):
return str(self.settings.get('public_name', as_type=LazyI18nString) or self.verbose_name)
@property
def test_mode_message(self):
return _('In test mode, you can just manually mark this order as paid in the backend after it has been '
'created.')
@property
def settings_form_fields(self):
d = OrderedDict(

View File

@@ -36,6 +36,18 @@ class Paypal(BasePaymentProvider):
super().__init__(event)
self.settings = SettingsSandbox('payment', 'paypal', event)
@property
def test_mode_message(self):
if self.settings.connect_client_id and not self.settings.secret:
# in OAuth mode, sandbox mode needs to be set global
is_sandbox = self.settings.connect_endpoint == 'sandbox'
else:
is_sandbox = self.settings.get('endpoint') == 'sandbox'
if is_sandbox:
return _('The PayPal sandbox is being used, you can test without actually sending money but you will need a '
'PayPal sandbox user to log in.')
return None
@property
def settings_form_fields(self):
if self.settings.connect_client_id and not self.settings.secret:

View File

@@ -63,6 +63,11 @@
</p>
<h2>{% trans "3. Start scanning tickets" %}</h2>
<script type="text/javascript" src="{% static "pretixplugins/pretixdroid/pretixdroid.js" %}"></script>
{% if request.event.testmode %}
<div class="alert-info">
{% trans "Test mode orders will only be scanned if you scan online. If you scan in asynchronous mode, test mode orders won't be there." %}
</div>
{% endif %}
{% endif %}
{% endblock %}

View File

@@ -332,6 +332,7 @@ class ApiDownloadView(ApiView):
order__event=self.event,
order__status__in=[Order.STATUS_PAID] + ([Order.STATUS_PENDING] if self.config.list.include_pending else
[]),
order__testmode=False,
subevent=self.config.list.subevent
).annotate(
last_checked_in=Subquery(cqs)

View File

@@ -14,6 +14,7 @@ from django.template.loader import get_template
from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.http import urlquote
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import pgettext, ugettext, ugettext_lazy as _
from django_countries import countries
@@ -111,6 +112,8 @@ class StripeSettingsHolder(BasePaymentProvider):
('live', pgettext('stripe', 'Live')),
('test', pgettext('stripe', 'Testing')),
),
help_text=_('If your event is in test mode, we will always use Stripe\'s test API, '
'regardless of this setting.')
)),
]
else:
@@ -230,6 +233,21 @@ class StripeMethod(BasePaymentProvider):
super().__init__(event)
self.settings = SettingsSandbox('payment', 'stripe', event)
@property
def test_mode_message(self):
if self.settings.connect_client_id and not self.settings.secret_key:
is_testmode = True
else:
is_testmode = '_test_' in self.settings.secret_key
if is_testmode:
return mark_safe(
_('The Stripe plugin is operating in test mode. You can use one of <a {args}>many test '
'cards</a> to perform a transaction. No money will actually be transferred.').format(
args='href="https://stripe.com/docs/testing#cards" target="_blank"'
)
)
return None
@property
def settings_form_fields(self):
return {}
@@ -262,7 +280,7 @@ class StripeMethod(BasePaymentProvider):
@property
def api_kwargs(self):
if self.settings.connect_client_id and self.settings.connect_user_id:
if self.settings.get('endpoint', 'live') == 'live':
if self.settings.get('endpoint', 'live') == 'live' and not self.event.testmode:
kwargs = {
'api_key': self.settings.connect_secret_key,
'stripe_account': self.settings.connect_user_id