Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion tapir/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
from phonenumber_field.modelfields import PhoneNumberField

from tapir import utils, settings
from tapir.coop.config import get_ids_of_users_registered_to_a_shift_with_capability
from tapir.coop.config import (
get_ids_of_users_registered_to_a_shift_with_capability,
get_ids_of_users_recently_completed_a_shift_with_capability,
)
from tapir.core.config import help_text_displayed_name
from tapir.log.models import UpdateModelLogEntry
from tapir.settings import (
Expand Down Expand Up @@ -52,6 +55,12 @@ def has_capability(self, capability: str):
shift_user_data__capabilities__contains=[capability]
).distinct()

def has_recent_capability_experience(self, capability: str):
user_ids = get_ids_of_users_recently_completed_a_shift_with_capability[0](
capability
)
return self.filter(id__in=user_ids).distinct()


class TapirUserManager(UserManager.from_queryset(TapirUserQuerySet)):
use_in_migrations = True
Expand Down
1 change: 1 addition & 0 deletions tapir/coop/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# This is not very clean, we need a better solution to inject member filters from the shift app into the coop app
# without adding a dependency from the coop app to the shift app
Comment on lines 10 to 11

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I continued with this hack for now, otherwise I think #704 will grow into a non-beginner-friendly task :)

happy to refactor this, if you have ideas and can guide me

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a suggestion? I'm no big backend expert

get_ids_of_users_registered_to_a_shift_with_capability = []
get_ids_of_users_recently_completed_a_shift_with_capability = []

URL_MEMBER_MANUAL = "https://wiki.supercoop.de/wiki/Member_Manual"

Expand Down
16 changes: 16 additions & 0 deletions tapir/coop/views/shareowner.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,14 @@ def __init__(self, *args, **kwargs):
method="has_capability_filter",
label=_("Has qualification"),
)
has_recent_capability_experience = ChoiceFilter(
choices=[
(capability, capability_name)
for capability, capability_name in SHIFT_USER_CAPABILITY_CHOICES.items()
],
method="has_recent_capability_experience_filter",
label=_("Has completed a shift with this qualification in the last 6 months"),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • agree on label string, then add to translation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

)
not_has_capability = ChoiceFilter(
choices=[
(capability, capability_name)
Expand Down Expand Up @@ -734,6 +742,14 @@ def has_capability_filter(
user__in=TapirUser.objects.has_capability(value)
).distinct()

@staticmethod
def has_recent_capability_experience_filter(
queryset: ShareOwner.ShareOwnerQuerySet, name, value: str
):
return queryset.filter(
user__in=TapirUser.objects.has_recent_capability_experience(value)
).distinct()

@staticmethod
def not_has_capability_filter(
queryset: ShareOwner.ShareOwnerQuerySet, name, value: str
Expand Down
4 changes: 4 additions & 0 deletions tapir/shifts/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from tapir.coop.config import (
on_welcome_session_attendance_update,
get_ids_of_users_registered_to_a_shift_with_capability,
get_ids_of_users_recently_completed_a_shift_with_capability,
)
from tapir.core.config import sidebar_link_groups, feature_flag_solidarity_shifts
from tapir.settings import PERMISSION_SHIFTS_MANAGE
Expand All @@ -30,6 +31,9 @@ def ready(self):
get_ids_of_users_registered_to_a_shift_with_capability.append(
utils.get_ids_of_users_registered_to_a_shift_with_capability
)
get_ids_of_users_recently_completed_a_shift_with_capability.append(
utils.get_ids_of_users_recently_completed_a_shift_with_capability
)

@classmethod
def register_sidebar_links(cls):
Expand Down
17 changes: 16 additions & 1 deletion tapir/shifts/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from calendar import HTMLCalendar, month_name, day_abbr
from datetime import datetime, date
from datetime import datetime, date, timedelta

from django.utils import timezone
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -145,6 +145,21 @@ def get_ids_of_users_registered_to_a_shift_with_capability(
)


def get_ids_of_users_recently_completed_a_shift_with_capability(
capability: ShiftUserCapability,
):
six_months_ago = timezone.now().date() - timedelta(weeks=26)
return (
ShiftAttendance.objects.filter(
slot__required_capabilities__contains=[capability],
state__in=[ShiftAttendance.State.DONE],
slot__shift__start_time__gt=six_months_ago,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, but I would include the day and use gte, so you really have 6 months. slot__shift__start_time__date__gte

)
.distinct()

@crosspolar crosspolar May 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove distinct since user IDs are naturally unique

.values_list("user__id", flat=True)
)


def get_attendance_mode_display(attendance_mode: str) -> str:
for mode_choice in SHIFT_ATTENDANCE_MODE_CHOICES:
if mode_choice[0] == attendance_mode:
Expand Down