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..077acb29 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 (à adapter) + }).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..02a98254 100644 --- a/apps/activity/views.py +++ b/apps/activity/views.py @@ -152,6 +152,21 @@ class ActivityUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): def get_success_url(self, **kwargs): return reverse_lazy('activity:activity_detail', kwargs={"pk": self.kwargs["pk"]}) +class ActivityDeleteView(View): + def delete(self, request, pk): + try: + activity = Activity.objects.get(pk=pk) + activity.delete() + return JsonResponse({"message": "Activity deleted"}) + except ProtectedError as e: + return JsonResponse({"error": "Cannot delete this activity because it is still referenced by guests."}, status=400) + except Activity.DoesNotExist: + return JsonResponse({"error": "Activity not found"}, status=404) + + def dispatch(self, *args, **kwargs): + # Optionnel : restreindre à utilisateur connecté ou permissions + return super().dispatch(*args, **kwargs) + class ActivityInviteView(ProtectQuerysetMixin, ProtectedCreateView): """