Projet

Général

Profil

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

Nicolas Roche, 06 octobre 2021 14:56

Télécharger (5,09 ko)

Voir les différences:

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

 chrono/agendas/models.py | 18 ++++++++++++++++++
 chrono/manager/forms.py  | 25 ++++++-------------------
 2 files changed, 24 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(self, changed_data, cleaned_data, protected_fields, exclude_fields):
1415
        with transaction.atomic():
1416
            if any(field for field in changed_data if field in protected_fields):
1417
                self.recurrences.all().delete()
1418
            elif self.recurrence_days:
1419
                update_fields = {
1420
                    field: value for field, value in cleaned_data.items() if field not in exclude_fields
1421
                }
1422
                self.recurrences.update(**update_fields)
1423
            yield
1424

  
1425
            if self.recurrence_end_date:
1426
                self.recurrences.filter(start_datetime__gt=self.recurrence_end_date).delete()
1427
                excluded_datetimes = [evt.datetime_slug for evt in self.recurrences.all()]
1428
                self.create_all_recurrences(excluded_datetimes)
1429

  
1412 1430
    @property
1413 1431
    def base_slug(self):
1414 1432
        # label can be empty
1415 1433
        return slugify(self.label or ('%s-event' % self.agenda.label))
1416 1434

  
1417 1435
    def main_list_full(self):
1418 1436
        return bool(self.booked_places >= self.places)
1419 1437

  
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
-