mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Add lifetime spending to customer details (#2934)
Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
@@ -22,54 +22,72 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form action="" method="post">
|
<form action="" method="post" class="row">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<dl class="dl-horizontal">
|
<dl class="dl-horizontal col-lg-6 col-sm-12">
|
||||||
<dt>{% trans "Customer ID" %}</dt>
|
<dt>{% trans "Customer ID" %}</dt>
|
||||||
<dd>#{{ customer.identifier }}</dd>
|
<dd>#{{ customer.identifier }}</dd>
|
||||||
{% if customer.provider %}
|
{% if customer.provider %}
|
||||||
<dt>{% trans "SSO provider" %}</dt>
|
<dt>{% trans "SSO provider" %}</dt>
|
||||||
<dd>{{ customer.provider.name }}</dd>
|
<dd>{{ customer.provider.name }}</dd>
|
||||||
{% endif %}
|
|
||||||
{% if customer.external_identifier %}
|
|
||||||
<dt>{% trans "External identifier" %}</dt>
|
|
||||||
<dd>{{ customer.external_identifier }}</dd>
|
|
||||||
{% endif %}
|
|
||||||
<dt>{% trans "Status" %}</dt>
|
|
||||||
<dd>
|
|
||||||
{% if not customer.is_active %}
|
|
||||||
{% trans "disabled" %}
|
|
||||||
{% elif not customer.is_verified %}
|
|
||||||
{% trans "not yet activated" %}
|
|
||||||
{% else %}
|
|
||||||
{% trans "active" %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
{% if customer.external_identifier %}
|
||||||
<dt>{% trans "E-mail" %}</dt>
|
<dt>{% trans "External identifier" %}</dt>
|
||||||
<dd>
|
<dd>{{ customer.external_identifier }}</dd>
|
||||||
{{ customer.email|default_if_none:"" }}
|
|
||||||
{% if customer.email and not customer.provider %}
|
|
||||||
<button type="submit" name="action" value="pwreset" class="btn btn-xs btn-default">
|
|
||||||
{% trans "Send password reset link" %}
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
<dt>{% trans "Status" %}</dt>
|
||||||
<dt>{% trans "Name" %}</dt>
|
<dd>
|
||||||
<dd>{{ customer.name }}</dd>
|
{% if not customer.is_active %}
|
||||||
{% if customer.phone %}
|
{% trans "disabled" %}
|
||||||
<dt>{% trans "Phone" %}</dt>
|
{% elif not customer.is_verified %}
|
||||||
<dd>{{ customer.phone }}</dd>
|
{% trans "not yet activated" %}
|
||||||
{% endif %}
|
{% else %}
|
||||||
<dt>{% trans "Locale" %}</dt>
|
{% trans "active" %}
|
||||||
<dd>{{ display_locale }}</dd>
|
{% endif %}
|
||||||
<dt>{% trans "Registration date" %}</dt>
|
</dd>
|
||||||
<dd>{{ customer.date_joined|date:"SHORT_DATETIME_FORMAT" }}</dd>
|
<dt>{% trans "E-mail" %}</dt>
|
||||||
<dt>{% trans "Last login" %}</dt>
|
<dd>
|
||||||
<dd>{% if customer.last_login %}{{ customer.last_login|date:"SHORT_DATETIME_FORMAT" }}{% else %}
|
{{ customer.email|default_if_none:"" }}
|
||||||
–{% endif %}</dd>
|
{% if customer.email and not customer.provider %}
|
||||||
{% if customer.notes %}
|
<button type="submit" name="action" value="pwreset" class="btn btn-xs btn-default">
|
||||||
<dt>{% trans "Notes" %}</dt>
|
{% trans "Send password reset link" %}
|
||||||
<dd>{{ customer.notes|linebreaks }}</dd>
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
<dt>{% trans "Name" %}</dt>
|
||||||
|
<dd>{{ customer.name }}</dd>
|
||||||
|
{% if customer.phone %}
|
||||||
|
<dt>{% trans "Phone" %}</dt>
|
||||||
|
<dd>{{ customer.phone }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
<dt>{% trans "Locale" %}</dt>
|
||||||
|
<dd>{{ display_locale }}</dd>
|
||||||
|
<dt>{% trans "Registration date" %}</dt>
|
||||||
|
<dd>{{ customer.date_joined|date:"SHORT_DATETIME_FORMAT" }}</dd>
|
||||||
|
<dt>{% trans "Last login" %}</dt>
|
||||||
|
<dd>{% if customer.last_login %}{{ customer.last_login|date:"SHORT_DATETIME_FORMAT" }}{% else %}
|
||||||
|
–{% endif %}</dd>
|
||||||
|
{% if customer.notes %}
|
||||||
|
<dt>{% trans "Notes" %}</dt>
|
||||||
|
<dd>{{ customer.notes|linebreaks }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
</dl>
|
||||||
|
<dl class="col-lg-6 col-sm-12 text-right">
|
||||||
|
<dt class="text-muted"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
title="{% trans "This includes all paid orders by this customer across all your events." %}">
|
||||||
|
{% trans "Lifetime spending" %}
|
||||||
|
</dt>
|
||||||
|
{% if lifetime_spending %}
|
||||||
|
{% for s in lifetime_spending %}
|
||||||
|
{% if s.spending >= 0 %}
|
||||||
|
<dd class="text-success text-h3">{{ s.spending|money:s.currency }}</dd>
|
||||||
|
{% elif s.spending < 0 %}
|
||||||
|
<dd class="text-error text-h3">{{ s.spending|money:s.currency }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<dd class="text-muted text-h3">{{ 0|floatformat:2 }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ from django.core.exceptions import PermissionDenied, ValidationError
|
|||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
from django.db import connections, transaction
|
from django.db import connections, transaction
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Count, Exists, IntegerField, Max, Min, OuterRef, Prefetch, ProtectedError,
|
Count, Exists, F, IntegerField, Max, Min, OuterRef, Prefetch,
|
||||||
Q, Subquery, Sum,
|
ProtectedError, Q, Subquery, Sum,
|
||||||
)
|
)
|
||||||
from django.db.models.functions import Coalesce, Greatest
|
from django.db.models.functions import Coalesce, Greatest
|
||||||
from django.forms import DecimalField
|
from django.forms import DecimalField
|
||||||
@@ -2312,6 +2312,14 @@ class CustomerDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
|
|||||||
o.icnt = annotated.get(o.pk)['icnt']
|
o.icnt = annotated.get(o.pk)['icnt']
|
||||||
o.sales_channel_obj = scs[o.sales_channel]
|
o.sales_channel_obj = scs[o.sales_channel]
|
||||||
|
|
||||||
|
ctx["lifetime_spending"] = (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(status=Order.STATUS_PAID)
|
||||||
|
.values(currency=F("event__currency"))
|
||||||
|
.order_by("currency")
|
||||||
|
.annotate(spending=Sum("total"))
|
||||||
|
)
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ p.bigger {
|
|||||||
.helper-space-below {
|
.helper-space-below {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.text-h1 { font-size: $font-size-h1; }
|
||||||
|
.text-h2 { font-size: $font-size-h2; }
|
||||||
|
.text-h3 { font-size: $font-size-h3; }
|
||||||
|
.text-h4 { font-size: $font-size-h4; }
|
||||||
|
.text-h5 { font-size: $font-size-h5; }
|
||||||
|
.text-h6 { font-size: $font-size-h6; }
|
||||||
|
|
||||||
.section-moved {
|
.section-moved {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user