diff --git a/apps/activity/models.py b/apps/activity/models.py index c7c92e8d..4e313a57 100644 --- a/apps/activity/models.py +++ b/apps/activity/models.py @@ -234,7 +234,7 @@ class Guest(models.Model): """ activity = models.ForeignKey( Activity, - on_delete=models.PROTECT, + on_delete=models.CASCADE, related_name='+', ) diff --git a/apps/activity/templates/activity/activity_detail.html b/apps/activity/templates/activity/activity_detail.html index a94d1e37..1a8d01ee 100644 --- a/apps/activity/templates/activity/activity_detail.html +++ b/apps/activity/templates/activity/activity_detail.html @@ -95,5 +95,23 @@ SPDX-License-Identifier: GPL-3.0-or-later errMsg(xhr.responseJSON); }); }); + $("#delete_activity").click(function () { + if (!confirm("{% trans 'Are you sure you want to delete this activity?' %}")) { + return; + } + + $.ajax({ + url: "/api/activity/activity/{{ activity.pk }}/", + type: "DELETE", + headers: { + "X-CSRFTOKEN": CSRF_TOKEN + } + }).done(function () { + addMsg("{% trans 'Activity deleted' %}", "success"); + window.location.href = "/activity/"; // Redirige vers la liste des activités + }).fail(function (xhr) { + errMsg(xhr.responseJSON); + }); + }); {% endblock %} diff --git a/apps/activity/templates/activity/includes/activity_info.html b/apps/activity/templates/activity/includes/activity_info.html index a16ad33b..f9ea634b 100644 --- a/apps/activity/templates/activity/includes/activity_info.html +++ b/apps/activity/templates/activity/includes/activity_info.html @@ -70,7 +70,10 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if ".change_"|has_perm:activity %} {% trans "edit"|capfirst %} {% endif %} - {% if activity.activity_type.can_invite and not activity_started %} + {% if not activity.valid and ".delete_"|has_perm:activity %} + {% trans "delete"|capfirst %} + {% endif %} + {% if activity.activity_type.can_invite and not activity_started and activity.valid %} {% trans "Invite" %} {% endif %} {% endif %} diff --git a/apps/activity/urls.py b/apps/activity/urls.py index 962be72a..63a3a169 100644 --- a/apps/activity/urls.py +++ b/apps/activity/urls.py @@ -15,4 +15,5 @@ urlpatterns = [ path('/update/', views.ActivityUpdateView.as_view(), name='activity_update'), path('new/', views.ActivityCreateView.as_view(), name='activity_create'), path('calendar.ics', views.CalendarView.as_view(), name='calendar_ics'), + path('/delete', views.ActivityDeleteView.as_view(), name='delete_activity'), ] diff --git a/apps/activity/views.py b/apps/activity/views.py index 80bc1506..3081c45b 100644 --- a/apps/activity/views.py +++ b/apps/activity/views.py @@ -9,7 +9,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.db import transaction from django.db.models import F, Q -from django.http import HttpResponse +from django.http import HttpResponse, JsonResponse from django.urls import reverse_lazy from django.utils import timezone from django.utils.decorators import method_decorator @@ -153,6 +153,34 @@ class ActivityUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): return reverse_lazy('activity:activity_detail', kwargs={"pk": self.kwargs["pk"]}) +class ActivityDeleteView(View): + """ + Deletes an Activity + """ + def delete(self, request, pk): + try: + activity = Activity.objects.get(pk=pk) + activity.delete() + return JsonResponse({"message": "Activity deleted"}) + except Activity.DoesNotExist: + return JsonResponse({"error": "Activity not found"}, status=404) + + def dispatch(self, *args, **kwargs): + """ + Don't display the delete button if the user has no right to delete. + """ + if not self.request.user.is_authenticated: + return self.handle_no_permission() + + activity = Activity.objects.get(pk=self.kwargs["pk"]) + if not PermissionBackend.check_perm(self.request, "activity.delete_activity", activity): + raise PermissionDenied(_("You are not allowed to delete this activity.")) + + if activity.valid: + raise PermissionDenied(_("This activity is valid.")) + return super().dispatch(*args, **kwargs) + + class ActivityInviteView(ProtectQuerysetMixin, ProtectedCreateView): """ Invite a Guest, The rules to invites someone are defined in `forms:activity.GuestForm`