Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a filter to the workshop request view for requests where an active member did not use their code #2559

47 changes: 41 additions & 6 deletions amy/extrequests/filters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import date
import re

from django.db.models import Q
from django.db.models import Case, F, Q, QuerySet, When
from django.forms import widgets
from django.http import QueryDict
import django_filters
Expand Down Expand Up @@ -29,7 +30,7 @@ def __init__(self, data=None, *args, **kwargs):
# client-side unless the user deliberately chooses to do so.
# See https://github.com/carpentries/amy/issues/2314
if not data:
data = QueryDict("state=no_d&matched=u")
data = QueryDict("state=pa&matched=u")

super().__init__(data, *args, **kwargs)

Expand All @@ -39,12 +40,12 @@ def __init__(self, data=None, *args, **kwargs):
)

member_code = django_filters.CharFilter(
field_name="member_code", lookup_expr="icontains", label="Group"
field_name="member_code", lookup_expr="icontains", label="Member code"
)

state = django_filters.ChoiceFilter(
label="State",
choices=(("no_d", "Pending or accepted"),) + TrainingRequest.STATE_CHOICES,
choices=(("pa", "Pending or accepted"),) + TrainingRequest.STATE_CHOICES,
method="filter_training_requests_by_state",
)

Expand All @@ -65,6 +66,12 @@ def __init__(self, data=None, *args, **kwargs):
widget=widgets.CheckboxInput,
)

invalid_member_code = django_filters.BooleanFilter(
label="Member code marked as invalid",
field_name="member_code_override",
widget=widgets.CheckboxInput,
)

affiliation = django_filters.CharFilter(
method="filter_affiliation",
)
Expand Down Expand Up @@ -140,8 +147,8 @@ def filter_affiliation(self, queryset, name, affiliation):
return queryset.filter(q).distinct()

def filter_training_requests_by_state(self, queryset, name, choice):
if choice == "no_d":
return queryset.exclude(state="d")
if choice == "pa":
return queryset.filter(state__in=["p", "a"])
else:
return queryset.filter(state=choice)

Expand All @@ -165,6 +172,11 @@ class WorkshopRequestFilter(AMYFilterSet, StateFilterSet):
queryset=Curriculum.objects.all(),
widget=widgets.CheckboxSelectMultiple(),
)
unused_member_code = django_filters.BooleanFilter(
label="Institution has an active member code but did not provide it",
method="filter_unused_member_code",
widget=widgets.CheckboxInput(),
)

order_by = django_filters.OrderingFilter(
fields=("created_at",),
Expand All @@ -179,6 +191,29 @@ class Meta:
"country",
]

def filter_unused_member_code(
self, queryset: QuerySet, name: str, apply_filter: bool
) -> QuerySet:
if apply_filter:
# find requests where no member code was provided
requests_without_code = queryset.filter(member_code="")

# find requests where institution has an active membership
# ideally compare to workshop dates, but fall back on today
return requests_without_code.annotate(
date_to_check=Case(
When(
preferred_dates__isnull=False,
then=F("preferred_dates"),
),
default=date.today(),
)
).filter(
institution__memberships__agreement_end__gte=F("date_to_check"),
institution__memberships__agreement_start__lte=F("date_to_check"),
)
return queryset


# ------------------------------------------------------------
# WorkshopInquiryRequest related filter and filter methods
Expand Down
Loading