From 4c67995680fd18b9392afe4f5f101a22cb50b0bc Mon Sep 17 00:00:00 2001 From: Jens Kleineheismann Date: Wed, 5 Jun 2019 11:33:45 +0200 Subject: [PATCH] UPD: change grace period for purging registration and participant data. --- dav_events/models/participant.py | 20 ++++++++++-- dav_events/utils.py | 23 +++++++------- dav_events/workflow.py | 5 +-- dav_registration/models.py | 18 +++++++++-- dav_registration/tests/test_utils.py | 46 ++++++++++++---------------- 5 files changed, 66 insertions(+), 46 deletions(-) diff --git a/dav_events/models/participant.py b/dav_events/models/participant.py index ef0a7b6..7318042 100644 --- a/dav_events/models/participant.py +++ b/dav_events/models/participant.py @@ -9,7 +9,6 @@ from django.utils.translation import ugettext_lazy as _ from dav_base.validators import DAVNumberValidator midnight = datetime.time(00, 00, 00) -one_day = datetime.timedelta(1) @python_2_unicode_compatible @@ -54,7 +53,8 @@ class Participant(models.Model): ordering = ['event', 'position'] def __str__(self): - return '{position}. {name}'.format( + return '{eventnumber} - {position}. {name}'.format( + eventnumber=self.event.get_number(), position=self.position, name=self.get_full_name(), ) @@ -78,4 +78,18 @@ class Participant(models.Model): last_day = event.alt_first_day else: last_day = event.first_day - return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight)) + + april = datetime.date(last_day.year, 4, 1) + july = datetime.date(last_day.year, 7, 1) + july_nextyear = datetime.date(last_day.year + 1, 7, 1) + october = datetime.date(last_day.year, 10, 1) + january_nextyear = datetime.date(last_day.year + 1, 1, 1) + + if last_day < april: + purge_date = july + elif last_day < october: + purge_date = january_nextyear + else: + purge_date = july_nextyear + + return timezone.make_aware(datetime.datetime.combine(purge_date, midnight)) diff --git a/dav_events/utils.py b/dav_events/utils.py index 5c29594..6f072f4 100644 --- a/dav_events/utils.py +++ b/dav_events/utils.py @@ -2,11 +2,21 @@ import logging from django.apps import apps from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from django.db.models import Q +from django.utils import timezone + +# from .models import Participant app_config = apps.get_containing_app_config(__package__) logger = logging.getLogger(__name__) + +# def purge_participants(): +# now = timezone.now() +# for p in Participant.objects.filter(purge_at__lte=now): +# logger.info('Purge participant \'%s\'', p) +# p.delete() + + # TODO: most of the functions here are auth stuff. @@ -65,14 +75,3 @@ def has_role(user, role): if group_names and user.groups.filter(name__in=group_names).count(): return True return False - - -def get_users_by_permission(permission_name, include_superusers=False): - appname, codename = permission_name.split('.') - - query = Q(user_permissions__codename=codename, user_permissions__content_type__app_label=appname) - query |= Q(groups__permissions__codename=codename, groups__permissions__content_type__app_label=appname) - if include_superusers: - query |= Q(is_superuser=True) - - return get_user_model().objects.filter(query).distinct() diff --git a/dav_events/workflow.py b/dav_events/workflow.py index 3a9aa18..11f684c 100644 --- a/dav_events/workflow.py +++ b/dav_events/workflow.py @@ -3,6 +3,7 @@ import datetime import logging import re from django.apps import apps +from django.db.models.functions import Length from django.utils import timezone from django.utils.translation import ugettext_lazy as _ @@ -286,8 +287,8 @@ class BasicWorkflow(object): qs = event.__class__.objects.filter(number__isnull=False, sport=event.sport, first_day__gte=year_begin, - first_day__lte=year_end).order_by('number') - last = qs.last() + first_day__lte=year_end).annotate(number_length=Length('number')) + last = qs.order_by('number_length', 'number').last() if last: match = re.match(r'^(?P[A-Z])(?P[0-9][0-9]*)/(?P[0-9][0-9]*)', last.number) if match: diff --git a/dav_registration/models.py b/dav_registration/models.py index 39b0772..2376340 100644 --- a/dav_registration/models.py +++ b/dav_registration/models.py @@ -2,7 +2,6 @@ from __future__ import unicode_literals import datetime import logging -import uuid from django.db import models from django.urls import reverse from django.utils import timezone @@ -17,7 +16,6 @@ from . import signals logger = logging.getLogger(__name__) midnight = datetime.time(00, 00, 00) -one_day = datetime.timedelta(1) @python_2_unicode_compatible @@ -150,4 +148,18 @@ Anmerkung: last_day = event.alt_first_day else: last_day = event.first_day - return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight)) + + april = datetime.date(last_day.year, 4, 1) + july = datetime.date(last_day.year, 7, 1) + july_nextyear = datetime.date(last_day.year + 1, 7, 1) + october = datetime.date(last_day.year, 10, 1) + january_nextyear = datetime.date(last_day.year + 1, 1, 1) + + if last_day < april: + purge_date = july + elif last_day < october: + purge_date = january_nextyear + else: + purge_date = july_nextyear + + return timezone.make_aware(datetime.datetime.combine(purge_date, midnight)) diff --git a/dav_registration/tests/test_utils.py b/dav_registration/tests/test_utils.py index 329467f..81ff5d4 100644 --- a/dav_registration/tests/test_utils.py +++ b/dav_registration/tests/test_utils.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime from django.test import TestCase +from django.utils import timezone from dav_events.tests.generic import EventMixin @@ -13,9 +14,10 @@ from .generic import RegistrationMixin class UtilsTestCase(RegistrationMixin, EventMixin, TestCase): def test_purge(self): - today = datetime.date.today() + now = timezone.now() + today = now.date() one_day = datetime.timedelta(1) - purge_after_days = 7 + registrations_per_event = 1 common_event_data = { 'title': 'Daytrip', 'description': 'Test', @@ -28,21 +30,9 @@ class UtilsTestCase(RegistrationMixin, EventMixin, TestCase): 'trainer_email': 'trainer@localhost', } - # We will create 4 events with different dates in the past - # 1. an event, that is happening right now -> we would still need the participants data - # 2. an event that will be finished few days ago, but the grace period were we have to keep - # the participants data is not over right now -> do not purge registrations - # 3. an event that will be finished long enough, so that we can purge the registrations - # 4. event will be finished even longer ago - # To all events, we will create some registrations - event_data = ( - (True, today), - (True, today - one_day * (purge_after_days - 1)), - (False, today - one_day * purge_after_days), - (False, today - one_day * (purge_after_days + 1)), - ) - events = [] - for registrations_still_needed, first_day in event_data: + first_day = today - (one_day * 367) + while first_day < today: + first_day += one_day data = common_event_data.copy() data['first_day'] = first_day @@ -50,15 +40,19 @@ class UtilsTestCase(RegistrationMixin, EventMixin, TestCase): self.submit_event(event) self.accept_event(event) - self.create_registration({'event': event}) - self.create_registration({'event': event}) - self.create_registration({'event': event}) + for i in range(0, registrations_per_event): + self.create_registration({'event': event}) - events.append((event, registrations_still_needed)) - - # Now we purge obsolete registrations purge_registrations() - # Now we test for all 4 events, if there are still registrations - for event, registrations_still_needed in events: - self.assertEqual(Registration.objects.filter(event=event).exists(), registrations_still_needed) + registrations = Registration.objects.all() + n_registrations = registrations.count() + # We keep registrations at min three months (min 90 days) + # So there should be at least the registrations of the events in the last 90 days left. + self.assertGreater(n_registrations, registrations_per_event * 90) + # We keep registrations at max nine months (max 276 days) + # So there should be no more registrations left, than of the events from the last 276 days. + self.assertGreater(registrations_per_event * 276, n_registrations) + + for registration in registrations: + self.assertGreater(registration.purge_at, now)