Projet

Général

Profil

0001-agendas-factorize-recurrent-event-update-code-57305.patch

Nicolas Roche (absent jusqu'au 3 avril), 05 octobre 2021 17:42

Télécharger (5,35 ko)

Voir les différences:

Subject: [PATCH 1/2] agendas: factorize recurrent event update code (#57305)

 chrono/agendas/models.py | 26 ++++++++++++++++++++++++++
 chrono/manager/forms.py  | 22 +++-------------------
 2 files changed, 29 insertions(+), 19 deletions(-)
chrono/agendas/models.py
17 17
import collections
18 18
import copy
19 19
import datetime
20 20
import functools
21 21
import itertools
22 22
import math
23 23
import sys
24 24
import uuid
25
from contextlib import contextmanager
25 26

  
26 27
import requests
27 28
import vobject
28 29
from dateutil.rrule import DAILY, WEEKLY, rrule, rruleset
29 30
from django.conf import settings
30 31
from django.contrib.auth.models import Group
31 32
from django.contrib.postgres.fields import ArrayField, JSONField
32 33
from django.core.exceptions import FieldDoesNotExist, ValidationError
......
1404 1405
    def save(self, seen_slugs=None, *args, **kwargs):
1405 1406
        assert self.agenda.kind != 'virtual', "an event can't reference a virtual agenda"
1406 1407
        assert not (self.slug and self.slug.isdigit()), 'slug cannot be a number'
1407 1408
        self.start_datetime = self.start_datetime.replace(second=0, microsecond=0)
1408 1409
        if not self.slug:
1409 1410
            self.slug = generate_slug(self, seen_slugs=seen_slugs, agenda=self.agenda)
1410 1411
        return super().save(*args, **kwargs)
1411 1412

  
1413
    @contextmanager
1414
    def update_recurrences(
1415
        self, changed_data=None, cleaned_data=None, protected_fields=None, more_protected_fields=None
1416
    ):
1417
        changed_data = changed_data or []
1418
        cleaned_data = cleaned_data or {}
1419
        protected_fields = protected_fields or []
1420
        more_protected_fields = more_protected_fields or []
1421

  
1422
        with transaction.atomic():
1423
            if any(field for field in changed_data if field in protected_fields):
1424
                self.recurrences.all().delete()
1425
            elif self.recurrence_days:
1426
                protected_fields = list(protected_fields) + more_protected_fields
1427
                update_fields = {
1428
                    field: value for field, value in cleaned_data.items() if field not in protected_fields
1429
                }
1430
                self.recurrences.update(**update_fields)
1431
            yield
1432

  
1433
            if self.recurrence_end_date:
1434
                self.recurrences.filter(start_datetime__gt=self.recurrence_end_date).delete()
1435
                excluded_datetimes = [evt.datetime_slug for evt in self.recurrences.all()]
1436
                self.create_all_recurrences(excluded_datetimes)
1437

  
1412 1438
    @property
1413 1439
    def base_slug(self):
1414 1440
        # label can be empty
1415 1441
        return slugify(self.label or ('%s-event' % self.agenda.label))
1416 1442

  
1417 1443
    def main_list_full(self):
1418 1444
        return bool(self.booked_places >= self.places)
1419 1445

  
chrono/manager/forms.py
19 19
import csv
20 20
import datetime
21 21

  
22 22
import django_filters
23 23
from django import forms
24 24
from django.conf import settings
25 25
from django.contrib.auth.models import Group
26 26
from django.core.exceptions import FieldDoesNotExist
27
from django.db import transaction
28 27
from django.forms import ValidationError
29 28
from django.utils.encoding import force_text
30 29
from django.utils.six import StringIO
31 30
from django.utils.timezone import make_aware, now
32 31
from django.utils.translation import ugettext_lazy as _
33 32

  
34 33
from chrono.agendas.models import (
35 34
    WEEKDAYS_LIST,
......
275 274
        ):
276 275
            raise ValidationError(_('Bookings exist after this date.'))
277 276

  
278 277
        if self.cleaned_data.get('frequency') == 'unique':
279 278
            self.cleaned_data['recurrence_days'] = None
280 279
            self.cleaned_data['recurrence_end_date'] = None
281 280

  
282 281
    def save(self, *args, **kwargs):
283
        with transaction.atomic():
284
            if any(field for field in self.changed_data if field in self.protected_fields):
285
                self.instance.recurrences.all().delete()
286
            elif self.instance.recurrence_days:
287
                protected_fields = list(self.protected_fields) + ['recurrence_end_date', 'frequency']
288
                update_fields = {
289
                    field: value
290
                    for field, value in self.cleaned_data.items()
291
                    if field not in protected_fields
292
                }
293
                self.instance.recurrences.update(**update_fields)
294

  
282
        with self.instance.update_recurrences(
283
            self.changed_data, self.cleaned_data, self.protected_fields, ['recurrence_end_date', 'frequency']
284
        ):
295 285
            super().save(*args, **kwargs)
296
            if self.instance.recurrence_end_date:
297
                self.instance.recurrences.filter(
298
                    start_datetime__gt=self.instance.recurrence_end_date
299
                ).delete()
300
                excluded_datetimes = [event.datetime_slug for event in self.instance.recurrences.all()]
301
                self.instance.create_all_recurrences(excluded_datetimes)
302 286
        return self.instance
303 287

  
304 288

  
305 289
class BookingCheckFilterSet(django_filters.FilterSet):
306 290
    class Meta:
307 291
        model = Booking
308 292
        fields = []
309 293

  
310
-