diff --git a/src/agenda_culturel/forms.py b/src/agenda_culturel/forms.py index 93d2607..92c4abb 100644 --- a/src/agenda_culturel/forms.py +++ b/src/agenda_culturel/forms.py @@ -327,6 +327,7 @@ class EventForm(GroupFormMixin, ModelForm): is_authenticated = kwargs.pop("is_authenticated", False) self.cloning = kwargs.pop("is_cloning", False) self.simple_cloning = kwargs.pop("is_simple_cloning", False) + self.is_edit_from_moderation = kwargs.pop("is_edit_from_moderation", False) self.is_moderation_expert = kwargs.pop("is_moderation_expert", False) super().__init__(*args, **kwargs) if not is_authenticated: diff --git a/src/agenda_culturel/migrations/0158_event_editing_start.py b/src/agenda_culturel/migrations/0158_event_editing_start.py new file mode 100644 index 0000000..5b492b8 --- /dev/null +++ b/src/agenda_culturel/migrations/0158_event_editing_start.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-03-14 20:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("agenda_culturel", "0157_auto_20250314_1645"), + ] + + operations = [ + migrations.AddField( + model_name="event", + name="editing_start", + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/src/agenda_culturel/migrations/0159_event_editing_user.py b/src/agenda_culturel/migrations/0159_event_editing_user.py new file mode 100644 index 0000000..7b426d7 --- /dev/null +++ b/src/agenda_culturel/migrations/0159_event_editing_user.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.19 on 2025-03-14 21:19 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("agenda_culturel", "0158_event_editing_start"), + ] + + operations = [ + migrations.AddField( + model_name="event", + name="editing_user", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_DEFAULT, + related_name="in_edition_events", + to=settings.AUTH_USER_MODEL, + verbose_name="Author currently editing/moderating the event", + ), + ), + ] diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index 9520dee..64bbb86 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -714,6 +714,17 @@ class Event(models.Model): modified_date = models.DateTimeField(blank=True, null=True) moderated_date = models.DateTimeField(blank=True, null=True) + editing_start = models.DateTimeField(blank=True, null=True) + editing_user = models.ForeignKey( + User, + verbose_name=_("Author currently editing/moderating the event"), + null=True, + blank=True, + default=None, + on_delete=models.SET_DEFAULT, + related_name="in_edition_events", + ) + created_by_user = models.ForeignKey( User, verbose_name=_("Author of the event creation"), @@ -920,6 +931,34 @@ class Event(models.Model): else: return self.end_day if self.end_day else self.start_day + def is_modification_locked(self, now=None): + if now is None: + now = timezone.now() + limit = timezone.now() + timedelta(minutes=-10) + + return self.editing_start is not None and self.editing_start > limit + + def get_modification_lock(self, user): + now = timezone.now() + + if not self.is_modification_locked(now): + self.editing_start = now + self.editing_user = user + self.save(update_fields=["editing_start", "editing_user"]) + return True + else: + return False + + def free_modification_lock(self, user, save=True): + if user != self.editing_user: + return False + else: + self.editing_start = None + self.editing_user = None + if save: + self.save(update_fields=["editing_start", "editing_user"]) + return True + def get_dates(self): first = self.start_day last = self.get_consolidated_end_day() @@ -1351,6 +1390,10 @@ class Event(models.Model): self.moderated_date = now self.moderated_by_user = self.processing_user + # release editing lock + if self.processing_user is not None: + self.free_modification_lock(self.processing_user, False) + def get_recurrence_at_date(self, year, month, day): dtstart = timezone.make_aware( datetime(year, month, day, 0, 0), timezone.get_default_timezone() diff --git a/src/agenda_culturel/templates/agenda_culturel/event_form.html b/src/agenda_culturel/templates/agenda_culturel/event_form.html index 8a5024f..6a575cd 100644 --- a/src/agenda_culturel/templates/agenda_culturel/event_form.html +++ b/src/agenda_culturel/templates/agenda_culturel/event_form.html @@ -2,6 +2,7 @@ {% load static %} {% load cat_extra %} {% load utils_extra %} +{% load event_extra %} {% block title %} {% block og_title %} {% if object %} @@ -86,6 +87,21 @@
{% endif %} + {% if not form.is_clone_from_url and not form.is_simple_clone_from_url and not object|get_modification_lock:user %} + {% if object.editing_user == user %} + + {% else %} + + {% endif %} + {% endif %}