Projet

Général

Profil

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

Nicolas Roche, 06 octobre 2021 13:50

Télécharger (5,31 ko)

Voir les différences:

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

 chrono/agendas/models.py | 25 +++++++++++++++++++++++++
 chrono/manager/forms.py  | 25 ++++++-------------------
 2 files changed, 31 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, exclude_fields=None
1416
    ):
1417
        changed_data = changed_data or []
1418
        cleaned_data = cleaned_data or {}
1419
        protected_fields = protected_fields or []
1420
        exclude_fields = exclude_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
                update_fields = {
1427
                    field: value for field, value in cleaned_data.items() if field not in exclude_fields
1428
                }
1429
                self.recurrences.update(**update_fields)
1430
            yield
1431

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

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

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

  
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,
284
            self.cleaned_data,
285
            self.protected_fields,
286
            list(self.protected_fields) + ['recurrence_end_date', 'frequency'],
287
        ):
295 288
            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 289
        return self.instance
303 290

  
304 291

  
305 292
class BookingCheckFilterSet(django_filters.FilterSet):
306 293
    class Meta:
307 294
        model = Booking
308 295
        fields = []
309 296

  
310
-