Projet

Général

Profil

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

Nicolas Roche, 30 septembre 2021 18:39

Télécharger (5,81 ko)

Voir les différences:

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

 chrono/agendas/models.py | 23 +++++++++++++++++++++++
 chrono/api/views.py      | 15 ++-------------
 chrono/manager/forms.py  | 24 +++++++-----------------
 3 files changed, 32 insertions(+), 30 deletions(-)
chrono/agendas/models.py
1389 1389
    def save(self, seen_slugs=None, *args, **kwargs):
1390 1390
        assert self.agenda.kind != 'virtual', "an event can't reference a virtual agenda"
1391 1391
        assert not (self.slug and self.slug.isdigit()), 'slug cannot be a number'
1392 1392
        self.start_datetime = self.start_datetime.replace(second=0, microsecond=0)
1393 1393
        if not self.slug:
1394 1394
            self.slug = generate_slug(self, seen_slugs=seen_slugs, agenda=self.agenda)
1395 1395
        return super().save(*args, **kwargs)
1396 1396

  
1397
    def pre_update(
1398
        self, changed_data=None, cleaned_data=None, protected_fields=None, more_protected_fields=None
1399
    ):
1400
        changed_data = changed_data or []
1401
        cleaned_data = cleaned_data or {}
1402
        protected_fields = protected_fields or []
1403
        more_protected_fields = more_protected_fields or []
1404

  
1405
        if any(field for field in changed_data if field in protected_fields):
1406
            self.recurrences.all().delete()
1407
        elif self.recurrence_days:
1408
            protected_fields = list(protected_fields) + more_protected_fields
1409
            update_fields = {
1410
                field: value for field, value in cleaned_data.items() if field not in protected_fields
1411
            }
1412
            self.recurrences.update(**update_fields)
1413

  
1414
    def post_update(self):
1415
        if self.recurrence_end_date:
1416
            self.recurrences.filter(start_datetime__gt=self.recurrence_end_date).delete()
1417
            excluded_datetimes = [evt.datetime_slug for evt in self.recurrences.all()]
1418
            self.create_all_recurrences(excluded_datetimes)
1419

  
1397 1420
    @property
1398 1421
    def base_slug(self):
1399 1422
        # label can be empty
1400 1423
        return slugify(self.label or ('%s-event' % self.agenda.label))
1401 1424

  
1402 1425
    def main_list_full(self):
1403 1426
        return bool(self.booked_places >= self.places)
1404 1427

  
chrono/api/views.py
2223 2223
                raise APIError(
2224 2224
                    _('invalid payload'),
2225 2225
                    err_class='invalid payload',
2226 2226
                    errors=errors,
2227 2227
                    http_status=status.HTTP_400_BAD_REQUEST,
2228 2228
                )
2229 2229

  
2230 2230
        with transaction.atomic():
2231
            if any(field for field in changed_data if field in protected_fields):
2232
                event.recurrences.all().delete()
2233
            elif event.recurrence_days:
2234
                protected_fields.append('recurrence_end_date')
2235
                update_fields = {
2236
                    field: value for field, value in payload.items() if field not in protected_fields
2237
                }
2238
                event.recurrences.update(**update_fields)
2239

  
2231
            event.pre_update(changed_data, payload, protected_fields, ['recurrence_end_date'])
2240 2232
            event = serializer.save()
2241
            if event.recurrence_end_date:
2242
                event.recurrences.filter(start_datetime__gt=event.recurrence_end_date).delete()
2243
                excluded_datetimes = [evt.datetime_slug for evt in event.recurrences.all()]
2244
                event.create_all_recurrences(excluded_datetimes)
2233
            event.post_update()
2245 2234

  
2246 2235
        return Response({'err': 0, 'data': get_event_detail(request, event)})
2247 2236

  
2248 2237

  
2249 2238
events = Events.as_view()
2250 2239

  
2251 2240

  
2252 2241
class EventStatus(APIView):
chrono/manager/forms.py
276 276
            raise ValidationError(_('Bookings exist after this date.'))
277 277

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

  
282 282
    def save(self, *args, **kwargs):
283 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

  
284
            self.instance.pre_update(
285
                self.changed_data,
286
                self.cleaned_data,
287
                self.protected_fields,
288
                ['recurrence_end_date', 'frequency'],
289
            )
295 290
            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)
291
            self.instance.post_update()
302 292
        return self.instance
303 293

  
304 294

  
305 295
class BookingCheckFilterSet(django_filters.FilterSet):
306 296
    class Meta:
307 297
        model = Booking
308 298
        fields = []
309 299

  
310
-