mirror of
https://github.com/pretix/pretix.git
synced 2025-12-05 21:32:28 +00:00
Compare commits
5 Commits
subevent-e
...
release/4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4c8446cd5 | ||
|
|
84fdcacb17 | ||
|
|
2c7c04ae88 | ||
|
|
5e3f9178f5 | ||
|
|
03ea47715d |
@@ -19,4 +19,4 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
__version__ = "4.4.0.dev0"
|
__version__ = "4.4.1"
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Command(BaseCommand):
|
|||||||
order=OuterRef('pk')
|
order=OuterRef('pk')
|
||||||
).order_by().values('order').annotate(p=Sum('price')).values('p'),
|
).order_by().values('order').annotate(p=Sum('price')).values('p'),
|
||||||
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
), Value(Decimal(0)), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
), Value(0), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
),
|
),
|
||||||
fee_total=Coalesce(
|
fee_total=Coalesce(
|
||||||
Subquery(
|
Subquery(
|
||||||
@@ -51,7 +51,7 @@ class Command(BaseCommand):
|
|||||||
order=OuterRef('pk')
|
order=OuterRef('pk')
|
||||||
).order_by().values('order').annotate(p=Sum('value')).values('p'),
|
).order_by().values('order').annotate(p=Sum('value')).values('p'),
|
||||||
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
), Value(Decimal(0)), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
), Value(0), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
),
|
),
|
||||||
tx_total=Coalesce(
|
tx_total=Coalesce(
|
||||||
Subquery(
|
Subquery(
|
||||||
@@ -59,12 +59,12 @@ class Command(BaseCommand):
|
|||||||
order=OuterRef('pk')
|
order=OuterRef('pk')
|
||||||
).order_by().values('order').annotate(p=Sum(F('price') * F('count'))).values('p'),
|
).order_by().values('order').annotate(p=Sum(F('price') * F('count'))).values('p'),
|
||||||
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
), Value(Decimal(0)), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
), Value(0), output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
),
|
),
|
||||||
).annotate(
|
).annotate(
|
||||||
correct_total=Case(
|
correct_total=Case(
|
||||||
When(Q(status=Order.STATUS_CANCELED) | Q(status=Order.STATUS_EXPIRED) | Q(require_approval=True),
|
When(Q(status=Order.STATUS_CANCELED) | Q(status=Order.STATUS_EXPIRED) | Q(require_approval=True),
|
||||||
then=Value(Decimal(0))),
|
then=Value(0)),
|
||||||
default=F('position_total') + F('fee_total'),
|
default=F('position_total') + F('fee_total'),
|
||||||
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
output_field=models.DecimalField(decimal_places=2, max_digits=10)
|
||||||
),
|
),
|
||||||
@@ -73,6 +73,9 @@ class Command(BaseCommand):
|
|||||||
tx_total=F('correct_total')
|
tx_total=F('correct_total')
|
||||||
).select_related('event')
|
).select_related('event')
|
||||||
for o in qs:
|
for o in qs:
|
||||||
|
if abs(o.tx_total - o.correct_total) < Decimal('0.00001') and abs(o.position_total + o.fee_total - o.total) < Decimal('0.00001'):
|
||||||
|
# Ignore SQLite which treats Decimals like floats…
|
||||||
|
continue
|
||||||
print(f"Error in order {o.full_code}: status={o.status}, sum(positions)+sum(fees)={o.position_total + o.fee_total}, "
|
print(f"Error in order {o.full_code}: status={o.status}, sum(positions)+sum(fees)={o.position_total + o.fee_total}, "
|
||||||
f"order.total={o.total}, sum(transactions)={o.tx_total}, expected={o.correct_total}")
|
f"order.total={o.total}, sum(transactions)={o.tx_total}, expected={o.correct_total}")
|
||||||
|
|
||||||
|
|||||||
26
src/pretix/base/templates/pretixbase/redirect.html
Normal file
26
src/pretix/base/templates/pretixbase/redirect.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{% extends "error.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load rich_text %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}{% trans "Redirect" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<i class="fa fa-link fa-fw big-icon"></i>
|
||||||
|
<div class="error-details">
|
||||||
|
<h1>{% trans "Redirect" %}</h1>
|
||||||
|
<h3>
|
||||||
|
{% blocktrans trimmed with host="<strong>"|add:hostname|add:"</strong>"|safe %}
|
||||||
|
The link you clicked on wants to redirect you to a destination on the website {{ host }}.
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
Please only proceed if you trust this website to be safe.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<a href="{{ url }}" class="btn btn-primary btn-lg">
|
||||||
|
{% blocktrans trimmed with host=hostname %}
|
||||||
|
Proceed to {{ host }}
|
||||||
|
{% endblocktrans %}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -24,6 +24,21 @@ import urllib.parse
|
|||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.http import HttpResponseBadRequest, HttpResponseRedirect
|
from django.http import HttpResponseBadRequest, HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
||||||
|
def _is_samesite_referer(request):
|
||||||
|
referer = request.META.get('HTTP_REFERER')
|
||||||
|
if referer is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
referer = urllib.parse.urlparse(referer)
|
||||||
|
|
||||||
|
# Make sure we have a valid URL for Referer.
|
||||||
|
if '' in (referer.scheme, referer.netloc):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return (referer.scheme, referer.netloc) == (request.scheme, request.get_host())
|
||||||
|
|
||||||
|
|
||||||
def redir_view(request):
|
def redir_view(request):
|
||||||
@@ -32,6 +47,14 @@ def redir_view(request):
|
|||||||
url = signer.unsign(request.GET.get('url', ''))
|
url = signer.unsign(request.GET.get('url', ''))
|
||||||
except signing.BadSignature:
|
except signing.BadSignature:
|
||||||
return HttpResponseBadRequest('Invalid parameter')
|
return HttpResponseBadRequest('Invalid parameter')
|
||||||
|
|
||||||
|
if not _is_samesite_referer(request):
|
||||||
|
u = urllib.parse.urlparse(url)
|
||||||
|
return render(request, 'pretixbase/redirect.html', {
|
||||||
|
'hostname': u.hostname,
|
||||||
|
'url': url,
|
||||||
|
})
|
||||||
|
|
||||||
r = HttpResponseRedirect(url)
|
r = HttpResponseRedirect(url)
|
||||||
r['X-Robots-Tag'] = 'noindex'
|
r['X-Robots-Tag'] = 'noindex'
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -74,17 +74,17 @@
|
|||||||
{{ c.datetime|date:"SHORT_DATETIME_FORMAT" }}
|
{{ c.datetime|date:"SHORT_DATETIME_FORMAT" }}
|
||||||
{% if c.type == "exit" %}
|
{% if c.type == "exit" %}
|
||||||
{% if c.auto_checked_in %}
|
{% if c.auto_checked_in %}
|
||||||
<span class="fa fa-fw fa-hourglass-end" data-toggle="tooltip_html"
|
<span class="fa fa-fw fa-hourglass-end" data-toggle="tooltip"
|
||||||
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically marked not present: {{ date }}{% endblocktrans %}"></span>
|
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically marked not present: {{ date }}{% endblocktrans %}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif c.forced and c.successful %}
|
{% elif c.forced and c.successful %}
|
||||||
<span class="fa fa-fw fa-warning" data-toggle="tooltip_html"
|
<span class="fa fa-fw fa-warning" data-toggle="tooltip"
|
||||||
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}"></span>
|
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}"></span>
|
||||||
{% elif c.forced and not c.successful %}
|
{% elif c.forced and not c.successful %}
|
||||||
<br>
|
<br>
|
||||||
<small class="text-muted">{% trans "Failed in offline mode" %}</small>
|
<small class="text-muted">{% trans "Failed in offline mode" %}</small>
|
||||||
{% elif c.auto_checked_in %}
|
{% elif c.auto_checked_in %}
|
||||||
<span class="fa fa-fw fa-magic" data-toggle="tooltip_html"
|
<span class="fa fa-fw fa-magic" data-toggle="tooltip"
|
||||||
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}"></span>
|
title="{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="quotabox availability" data-toggle="tooltip_html" data-placement="top"
|
<div class="quotabox availability" data-toggle="tooltip_html" data-placement="top"
|
||||||
title="{% trans "Quota:" %} {{ q.name }}<br>{% blocktrans with date=q.cached_availability_time|date:"SHORT_DATETIME_FORMAT" %}Numbers as of {{ date }}{% endblocktrans %}">
|
title="{% trans "Quota:" %} {{ q.name|force_escape|force_escape }}<br>{% blocktrans with date=q.cached_availability_time|date:"SHORT_DATETIME_FORMAT" %}Numbers as of {{ date }}{% endblocktrans %}">
|
||||||
{% if q.size|default_if_none:"NONE" == "NONE" %}
|
{% if q.size|default_if_none:"NONE" == "NONE" %}
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div class="progress-bar progress-bar-success progress-bar-100">
|
<div class="progress-bar progress-bar-success progress-bar-100">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<a class="quotabox" data-toggle="tooltip_html" data-placement="top"
|
<a class="quotabox" data-toggle="tooltip_html" data-placement="top"
|
||||||
title="{% trans "Quota:" %} {{ q.name }}{% if q.cached_avail.1 is not None %}<br>{% blocktrans with num=q.cached_avail.1 %}Currently available: {{ num }}{% endblocktrans %}{% endif %}"
|
title="{% trans "Quota:" %} {{ q.name|force_escape|force_escape }}{% if q.cached_avail.1 is not None %}<br>{% blocktrans with num=q.cached_avail.1 %}Currently available: {{ num }}{% endblocktrans %}{% endif %}"
|
||||||
href="{% url "control:event.items.quotas.show" event=q.event.slug organizer=q.event.organizer.slug quota=q.pk %}">
|
href="{% url "control:event.items.quotas.show" event=q.event.slug organizer=q.event.organizer.slug quota=q.pk %}">
|
||||||
{% if q.size|default_if_none:"NONE" == "NONE" %}
|
{% if q.size|default_if_none:"NONE" == "NONE" %}
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
|
|||||||
@@ -360,19 +360,19 @@
|
|||||||
{% if line.checkins.all %}
|
{% if line.checkins.all %}
|
||||||
{% for c in line.all_checkins.all %}
|
{% for c in line.all_checkins.all %}
|
||||||
{% if not c.successful %}
|
{% if not c.successful %}
|
||||||
<span class="fa fa-fw fa-exclamation-circle text-danger" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Denied scan: {{ date }}{% endblocktrans %}<br>{{ c.get_error_reason_display }}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
<span class="fa fa-fw fa-exclamation-circle text-danger" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Denied scan: {{ date }}{% endblocktrans %}<br>{{ c.get_error_reason_display }}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||||
{% elif c.type == "exit" %}
|
{% elif c.type == "exit" %}
|
||||||
{% if c.auto_checked_in %}
|
{% if c.auto_checked_in %}
|
||||||
<span class="fa fa-fw text-success fa-hourglass-end" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically marked not present: {{ date }}{% endblocktrans %}"></span>
|
<span class="fa fa-fw text-success fa-hourglass-end" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically marked not present: {{ date }}{% endblocktrans %}"></span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fa fa-fw text-success fa-sign-out" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Exit scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
<span class="fa fa-fw text-success fa-sign-out" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Exit scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif c.forced %}
|
{% elif c.forced %}
|
||||||
<span class="fa fa-fw fa-warning text-warning" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
<span class="fa fa-fw fa-warning text-warning" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||||
{% elif c.auto_checked_in %}
|
{% elif c.auto_checked_in %}
|
||||||
<span class="fa fa-fw fa-magic text-success" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
<span class="fa fa-fw fa-magic text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fa fa-fw fa-check text-success" data-toggle="tooltip_html" title="{{ c.list.name }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
<span class="fa fa-fw fa-check text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="form-horizontal stripe-container">
|
<div class="form-horizontal stripe-container">
|
||||||
{% if is_moto %}
|
{% if is_moto %}
|
||||||
<h1>
|
<h1>
|
||||||
<span class="label label-info pull-right flip" data-toggle="tooltip_html" title="{% trans "This transaction will be marked as Mail Order/Telephone Order, exempting it from Strong Customer Authentication (SCA) whenever possible" %}">MOTO</span>
|
<span class="label label-info pull-right flip" data-toggle="tooltip" title="{% trans "This transaction will be marked as Mail Order/Telephone Order, exempting it from Strong Customer Authentication (SCA) whenever possible" %}">MOTO</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -675,7 +675,21 @@ $(function () {
|
|||||||
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
$('[data-toggle="tooltip_html"]').tooltip({
|
$('[data-toggle="tooltip_html"]').tooltip({
|
||||||
'html': true
|
'html': true,
|
||||||
|
'whiteList': {
|
||||||
|
// Global attributes allowed on any supplied element below.
|
||||||
|
'*': ['class', 'dir', 'id', 'lang', 'role'],
|
||||||
|
b: [],
|
||||||
|
br: [],
|
||||||
|
code: [],
|
||||||
|
div: [], // required for template
|
||||||
|
h3: ['class', 'role'], // required for template
|
||||||
|
i: [],
|
||||||
|
small: [],
|
||||||
|
span: [],
|
||||||
|
strong: [],
|
||||||
|
u: [],
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var url = document.location.toString();
|
var url = document.location.toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user