Add event meta data fields to order search form

This commit is contained in:
Raphael Michel
2020-06-04 18:39:30 +02:00
parent cd5f6b66a1
commit effc9723f1
3 changed files with 81 additions and 21 deletions

View File

@@ -349,16 +349,34 @@ class OrderSearchFilterForm(OrderFilterForm):
)
def __init__(self, *args, **kwargs):
request = kwargs.pop('request')
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
if request.user.has_active_staff_session(request.session.session_key):
if self.request.user.has_active_staff_session(self.request.session.session_key):
self.fields['organizer'].queryset = Organizer.objects.all()
else:
self.fields['organizer'].queryset = Organizer.objects.filter(
pk__in=request.user.teams.values_list('organizer', flat=True)
pk__in=self.request.user.teams.values_list('organizer', flat=True)
)
self.fields['provider'].choices += get_all_payment_providers()
seen = set()
for p in self.meta_properties.all():
if p.name in seen:
continue
seen.add(p.name)
self.fields['meta_{}'.format(p.name)] = forms.CharField(
label=p.name,
required=False,
widget=forms.TextInput(
attrs={
'data-typeahead-url': reverse('control:events.meta.typeahead') + '?' + urlencode({
'property': p.name,
'organizer': ''
})
}
)
)
def filter_qs(self, qs):
fdata = self.cleaned_data
qs = super().filter_qs(qs)
@@ -366,8 +384,42 @@ class OrderSearchFilterForm(OrderFilterForm):
if fdata.get('organizer'):
qs = qs.filter(event__organizer=fdata.get('organizer'))
filters_by_property_name = {}
for i, p in enumerate(self.meta_properties):
d = fdata.get('meta_{}'.format(p.name))
if d:
emv_with_value = EventMetaValue.objects.filter(
event=OuterRef('event_id'),
property__pk=p.pk,
value=d
)
emv_with_any_value = EventMetaValue.objects.filter(
event=OuterRef('event_id'),
property__pk=p.pk,
)
qs = qs.annotate(**{'attr_{}'.format(i): Exists(emv_with_value)})
if p.name in filters_by_property_name:
filters_by_property_name[p.name] |= Q(**{'attr_{}'.format(i): True})
else:
filters_by_property_name[p.name] = Q(**{'attr_{}'.format(i): True})
if p.default == d:
qs = qs.annotate(**{'attr_{}_any'.format(i): Exists(emv_with_any_value)})
filters_by_property_name[p.name] |= Q(**{
'attr_{}_any'.format(i): False, 'event__organizer_id': p.organizer_id
})
for f in filters_by_property_name.values():
qs = qs.filter(f)
return qs
@cached_property
def meta_properties(self):
# We ignore superuser permissions here. This is intentional we do not want to show super
# users a form with all meta properties ever assigned.
return EventMetaProperty.objects.filter(
organizer_id__in=self.request.user.teams.values_list('organizer', flat=True)
)
class SubEventFilterForm(FilterForm):
orders = {

View File

@@ -7,25 +7,30 @@
{% block title %}{% trans "Order search" %}{% endblock %}
{% block content %}
<h1>{% trans "Order search" %}</h1>
<form class="row filter-form" action="" method="get">
<div class="col-md-3 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.query layout='inline' %}
<form class="" action="" method="get">
<div class="row filter-form">
<div class="col-md-3 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.query layout='inline' %}
</div>
<div class="col-md-2 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.status layout='inline' %}
</div>
<div class="col-md-3 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.organizer layout='inline' %}
</div>
<div class="col-md-2 col-xs-6">
{% bootstrap_field filter_form.provider layout='inline' %}
</div>
{% for mf in meta_fields %}
<div class="col-md-2 col-sm-6 col-xs-12">
{% bootstrap_field mf layout='inline' %}
</div>
{% endfor %}
</div>
<div class="col-md-2 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.status layout='inline' %}
</div>
<div class="col-md-3 col-sm-6 col-xs-12">
{% bootstrap_field filter_form.organizer layout='inline' %}
</div>
<div class="col-md-2 col-xs-6">
{% bootstrap_field filter_form.provider layout='inline' %}
</div>
<div class="col-md-2 col-sm-6 col-xs-12">
<button class="btn btn-primary btn-block" type="submit">
<div class="text-right">
<button class="btn btn-primary" type="submit">
<span class="fa fa-filter"></span>
<span class="hidden-md">
{% trans "Filter" %}
</span>
<span class="hidden-md">{% trans "Filter" %}</span>
</button>
</div>
</form>
@@ -84,7 +89,7 @@
{% endif %}
{% if o.is_overpaid %}
<span class="label label-warning">{% trans "OVERPAID" %}</span>
{% elif o.is_underpaid %}
{% elif o.is_underpaid %}
<span class="label label-danger">{% trans "UNDERPAID" %}</span>
{% elif o.is_pending_with_full_payment %}
<span class="label label-danger">{% trans "FULLY PAID" %}</span>

View File

@@ -22,6 +22,9 @@ class OrderSearch(PaginationMixin, ListView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data()
ctx['filter_form'] = self.filter_form
ctx['meta_fields'] = [
self.filter_form[k] for k in self.filter_form.fields if k.startswith('meta_')
]
# Only compute this annotations for this page (query optimization)
s = OrderPosition.objects.filter(