Skip to content

Commit

Permalink
Implement penalty group
Browse files Browse the repository at this point in the history
  • Loading branch information
Arashfa0301 committed Sep 27, 2023
1 parent a2295e2 commit b50f868
Show file tree
Hide file tree
Showing 18 changed files with 602 additions and 214 deletions.
5 changes: 3 additions & 2 deletions lego/api/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
PasswordResetPerformViewSet,
PasswordResetRequestViewSet,
)
from lego.apps.users.views.penalties import PenaltyViewSet
from lego.apps.users.views.penalties import PenaltyGroupViewSet
from lego.apps.users.views.registration import UserRegistrationRequestViewSet
from lego.apps.users.views.student_confirmation import (
StudentConfirmationPerformViewSet,
Expand Down Expand Up @@ -179,7 +179,8 @@
PasswordResetRequestViewSet,
basename="password-reset-request",
)
router.register(r"penalties", PenaltyViewSet)
router.register(r"penalties", PenaltyGroupViewSet)
router.register(r"penaltie", PenaltyGroupViewSet)
router.register(r"podcasts", PodcastViewSet, basename="podcasts")
router.register(r"polls", PollViewSet, basename="polls")
router.register(r"quotes", QuoteViewSet)
Expand Down
14 changes: 8 additions & 6 deletions lego/apps/events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from lego.apps.followers.models import FollowEvent
from lego.apps.permissions.models import ObjectPermissionsModel
from lego.apps.users.constants import AUTUMN, SPRING
from lego.apps.users.models import AbakusGroup, Penalty, User
from lego.apps.users.models import AbakusGroup, PenaltyGroup, User
from lego.utils.models import BasisModel
from lego.utils.youtube_validator import youtube_validator

Expand Down Expand Up @@ -389,8 +389,10 @@ def unregister(
and self.heed_penalties
and self.passed_unregistration_deadline
):
if not registration.user.penalties.filter(source_event=self).exists():
Penalty.objects.create(
if not registration.user.penalty_groups.filter(
source_event=self
).exists():
PenaltyGroup.objects.create(
user=registration.user,
reason=f"Meldte seg av {self.title} for sent.",
weight=1,
Expand Down Expand Up @@ -910,15 +912,15 @@ def handle_user_penalty(self, presence: constants.PRESENCE_CHOICES) -> None:
and presence == constants.PRESENCE_CHOICES.NOT_PRESENT
and self.event.penalty_weight_on_not_present
):
if not self.user.penalties.filter(source_event=self.event).exists():
Penalty.objects.create(
if not self.user.penalty_groups.filter(source_event=self.event).exists():
PenaltyGroup.objects.create(
user=self.user,
reason=f"Møtte ikke opp på {self.event.title}.",
weight=self.event.penalty_weight_on_not_present,
source_event=self.event,
)
else:
for penalty in self.user.penalties.filter(source_event=self.event):
for penalty in self.user.penalties_groups.filter(source_event=self.event):
penalty.delete()

def add_to_pool(self, pool: Pool) -> Registration:
Expand Down
10 changes: 5 additions & 5 deletions lego/apps/events/tests/test_async_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
set_all_events_ready_and_bump,
)
from lego.apps.events.tests.utils import get_dummy_users, make_penalty_expire
from lego.apps.users.models import AbakusGroup, Penalty
from lego.apps.users.models import AbakusGroup, Penalty, PenaltyGroup
from lego.utils.test_utils import BaseAPITestCase, BaseTestCase


Expand Down Expand Up @@ -350,7 +350,7 @@ def test_is_automatically_bumped_after_penalty_expiration(self):
user = get_dummy_users(1)[0]
AbakusGroup.objects.get(name="Abakus").add_user(user)

p1 = Penalty.objects.create(
penalty_group = PenaltyGroup.objects.create(
user=user, reason="test", weight=3, source_event=self.event
)

Expand All @@ -359,7 +359,7 @@ def test_is_automatically_bumped_after_penalty_expiration(self):
]
async_register(registration.id)

make_penalty_expire(p1)
make_penalty_expire(penalty_group)
check_events_for_registrations_with_expired_penalties.delay()

self.assertIsNotNone(Registration.objects.get(id=registration.id).pool)
Expand Down Expand Up @@ -448,7 +448,7 @@ def test_async_bump_post_merge(self):
for user in users:
AbakusGroup.objects.get(name="Abakus").add_user(user)

p1 = Penalty.objects.create(
penalty_group = PenaltyGroup.objects.create(
user=users[1], reason="test", weight=3, source_event=self.event
)

Expand All @@ -458,7 +458,7 @@ def test_async_bump_post_merge(self):
)[0]
async_register(registration.id)

make_penalty_expire(p1)
make_penalty_expire(penalty_group)
check_events_for_registrations_with_expired_penalties.delay()

self.assertIsNotNone(Registration.objects.get(user=users[1]).pool)
Expand Down
2 changes: 1 addition & 1 deletion lego/apps/events/tests/test_penalties.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import timedelta
from django.conf import settings

from django.conf import settings
from django.utils import timezone

from lego.apps.events import constants
Expand Down
7 changes: 3 additions & 4 deletions lego/apps/events/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import stripe

from lego.apps.users.models import AbakusGroup, User
from lego.apps.users.models import AbakusGroup, PenaltyGroup, User


def get_dummy_users(n):
Expand Down Expand Up @@ -33,6 +33,5 @@ def create_token(number, cvc, year=None):
)


def make_penalty_expire(penalty):
penalty.created_at = timezone.now() - timedelta(days=365)
penalty.save()
def make_penalty_expire(penalty_group: PenaltyGroup) -> None:
penalty_group.expire()
20 changes: 10 additions & 10 deletions lego/apps/users/action_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from lego.apps.feeds.models import NotificationFeed, PersonalFeed, UserFeed
from lego.apps.feeds.verbs import GroupJoinVerb, PenaltyVerb
from lego.apps.users.constants import PUBLIC_GROUPS
from lego.apps.users.models import Membership, Penalty
from lego.apps.users.models import Membership, PenaltyGroup
from lego.apps.users.notifications import PenaltyNotification


Expand Down Expand Up @@ -43,20 +43,20 @@ def get_activity(self, membership):


class PenaltyHandler(Handler):
model = Penalty
model = PenaltyGroup
manager = feed_manager

def get_activity(self, penalty):
def get_activity(self, penalty_group):
return Activity(
actor=penalty.source_event,
actor=penalty_group.source_event,
verb=PenaltyVerb,
object=penalty,
target=penalty.user,
time=penalty.created_at,
object=penalty_group,
target=penalty_group.user,
time=penalty_group.activation_time,
extra_context={
"reason": penalty.reason,
"weight": penalty.weight,
"expiration_date": penalty.exact_expiration.days,
"reason": penalty_group.reason,
"weight": penalty_group.weight,
"expiration_date": penalty_group.exact_expiration.day,
},
)

Expand Down
11 changes: 8 additions & 3 deletions lego/apps/users/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
from django.db.models.functions import Concat
from django_filters.rest_framework import CharFilter, FilterSet

from lego.apps.users.models import AbakusGroup, Membership, MembershipHistory, Penalty
from lego.apps.users.models import (
AbakusGroup,
Membership,
MembershipHistory,
PenaltyGroup,
)


class MembershipFilterSet(FilterSet):
Expand Down Expand Up @@ -43,7 +48,7 @@ class Meta:
fields = ("user", "abakus_group", "role")


class PenaltyFilterSet(FilterSet):
class PenaltyGroupFilterSet(FilterSet):
class Meta:
model = Penalty
model = PenaltyGroup
fields = ("user", "source_event")
68 changes: 62 additions & 6 deletions lego/apps/users/managers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
from __future__ import annotations

from datetime import timedelta
from typing import TYPE_CHECKING

from django.contrib.auth.models import UserManager
from django.db.models import Q, F, DateTimeField, ExpressionWrapper
from django.utils import timezone
from django.conf import settings
from django.db import models
from django.db.models import Q, QuerySet

if TYPE_CHECKING:
from lego.apps.users.models import Penalty, PenaltyGroup

from django.conf import settings
from django.utils import timezone

from mptt.managers import TreeManager

Expand Down Expand Up @@ -48,9 +57,56 @@ def get_by_natural_key(self, username, abakus_group_name):
)


class UserPenaltyManager(PersistentModelManager):
def valid(self):
class UserPenaltyManager(PersistentModelManager["Penalty"]):
def valid(self) -> QuerySet["Penalty"]:
from lego.apps.users.models import Penalty

offset = Penalty.penalty_offset(timezone.now(), False)
return super().filter(created_at__gt=timezone.now() - offset)
return super().filter(activation_time__gt=timezone.now() - offset)


class UserPenaltyGroupManager(PersistentModelManager["PenaltyGroup"]):
def create(self, weight: int = 1, *args, **kwargs) -> PenaltyGroup:
from lego.apps.users.models import Penalty

penalty_group = super().create(*args, **kwargs)

last_active_penalty = (
Penalty.objects.filter(
penalty_group__user=penalty_group.user,
)
.order_by("-activation_time")
.first()
)

new_activation_time = (
last_active_penalty.exact_expiration
if last_active_penalty
else penalty_group.created_at
)

penalties = []

for __i__ in range(weight):
penalty = Penalty(penalty_group=penalty_group)
penalty.activation_time = new_activation_time

new_activation_time = penalty.exact_expiration

penalties.append(penalty)

Penalty.objects.bulk_create(penalties)
return penalty_group

def valid(self) -> QuerySet["PenaltyGroup"]:
from django.db.models import F
from lego.apps.users.models import PenaltyGroup

filtered_result = [
pg
for pg in super().annotate(penalty_count=models.Count(F("penalties")))
if pg.activation_time
> timezone.now() - timedelta(days=settings.PENALTY_DURATION.days)
]

return PenaltyGroup.objects.filter(id__in=[pg.id for pg in filtered_result])
26 changes: 0 additions & 26 deletions lego/apps/users/migrations/0039_penalty_activation_time.py

This file was deleted.

Loading

0 comments on commit b50f868

Please sign in to comment.