Add icons to show item's personalized / questions status

This commit is contained in:
Mira Weller committed 2026-11-06 17:49:06 +01:00
1 parent 6e0e8af974
commit 1247700cd2
4 files changed
+41 -6

No files matched your search

@@ -45,6 +45,7 @@
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="text-right flip">{% trans "Default price" %}</th>
<th class="action-col-2"><span class="sr-only">Edit</span></th>
</tr>
@@ -113,6 +114,20 @@
<span class="fa fa-gift fa-fw text-muted" data-toggle="tooltip" title="{% trans "Gift card" %}"></span>
{% endif %}
</td>
<td>
{% if i.attendee_data_required %}
<i class="fa-stack fa-stack-small fa-fw " data-toggle="tooltip_html" title="<div class='text-left'>{% trans "Personal data of attendees required" %}. {% if i.custom_questions_asked %}{% trans "Custom questions asked" %}. {% endif %}{% trans "Questionnaires" %}:<br>{{ i.questionnaire_names_html }}</div>">
<i class="fa text-muted fa-id-card-o fa-stack-1x"></i>
<i class="fa fa-stack-shifted fa-asterisk fa-stack-1x fa-stack-shift-up fa-stack-sm"></i>
</i>
{% elif i.attendee_data_asked %}
<i class="fa-stack fa-stack-small fa-fw" data-toggle="tooltip_html" title="<div class='text-left'>{% trans "Personal data of attendees asked" %}. {% if i.custom_questions_asked %}{% trans "Custom questions asked" %}. {% endif %}{% trans "Questionnaires" %}:<br>{{ i.questionnaire_names_html }}</div>">
<span class="fa fa-id-card-o fa-fw text-muted" ></span>
</i>
{% elif i.custom_questions_asked %}
<span class="fa fa-question-circle-o fa-fw text-muted" data-toggle="tooltip_html" title="<div class='text-left'>{% trans "Custom questions asked" %}. {% trans "Questionnaires" %}:<br>{{ i.questionnaire_names_html }}</div>"></span>
{% endif %}
</td>
<td>
{% if i.var_count %}
<span class="fa fa-bars fa-fw text-muted" data-toggle="tooltip" title="{% trans "Product with variations" %}"></span>
+17 -1
View File
@@ -53,6 +53,8 @@ from django.http import (
from django.shortcuts import redirect, render
from django.urls import resolve, reverse
from django.utils.functional import cached_property
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import gettext, gettext_lazy as _
from django.views.decorators.http import require_http_methods
@@ -100,6 +102,7 @@ from . import (
ChartContainingView, CreateView, PaginationMixin, TellParentFormMixin,
UpdateView,
)
from ...presale.views import prefetch_relevant_questionnaires
def has_truthy_attr(cls, attr):
@@ -125,7 +128,10 @@ class ItemList(ListView):
).select_related("tax_rule").annotate(
var_count=Count('variations'),
requires_seat=requires_seat,
).prefetch_related("category", "limit_sales_channels").order_by(
).prefetch_related(
"category", "limit_sales_channels",
prefetch_relevant_questionnaires(self.request.event, None, None, questionnaire_lookup='questionnaires'),
).order_by(
F('category__position').asc(nulls_first=True),
'category', 'position'
)
@@ -133,6 +139,16 @@ class ItemList(ListView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['sales_channels'] = self.request.organizer.sales_channels.all()
for item in ctx['items']:
qrows = [qc for qq in item.relevant_questionnaires for qc in qq.questionnairerowlist]
item.attendee_data_asked = any(row.system_datafield for row in qrows)
item.attendee_data_required = item.attendee_data_asked and any(row.system_datafield and row.required for row in qrows)
item.custom_questions_asked = any(row.user_datafield_id for row in qrows)
item.questionnaire_names_html = format_html_join('<br>', '• {} {}{}', ((
q.internal_name,
mark_safe("<i class='fa fa-check-square'></i>") if q.ask_during_checkin else '',
mark_safe("<i class='fa fa-eye-slash'></i>") if q.hidden else '',
) for q in item.relevant_questionnaires))
items_by_category = {cat: list(items) for cat, items in groupby(ctx['items'], lambda item: item.category)}
ctx['cat_list'] = [(cat, items_by_category.get(cat, [])) for cat in [None, *self.request.event.categories.all()]]
return ctx
+7 -5
View File
@@ -396,10 +396,12 @@ def cart_exists(request):
return bool(request._cart_cache)
def prefetch_relevant_questionnaires(event, sales_channel, questionnaire_type):
qqs = event.questionnaires.filter(
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=sales_channel),
)
def prefetch_relevant_questionnaires(event, sales_channel, questionnaire_type, questionnaire_lookup='item__questionnaires'):
qqs = event.questionnaires
if sales_channel:
qqs = qqs.filter(
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=sales_channel),
)
if questionnaire_type:
qqs = qqs.filter(type=questionnaire_type)
else:
@@ -412,7 +414,7 @@ def prefetch_relevant_questionnaires(event, sales_channel, questionnaire_type):
Question.objects.none(),
to_attr='dummy'
)
return Prefetch('item__questionnaires',
return Prefetch(questionnaire_lookup,
qqs.prefetch_related(
Prefetch('rows', QuestionnaireRow.objects.prefetch_related(
Prefetch('user_datafield', Question.objects.prefetch_related(
@@ -251,6 +251,8 @@ svg.svg-icon {
.fa-stack-shifted {
left: 0.5em;
}
.fa-stack-sm { font-size: 0.75em; }
.fa-stack-shift-up { top: -0.4em; }
.badge-primary { background: $brand-primary; }
.badge-success { background: $brand-success; }