From ddbc965e8a4cb13a4f8d0638589ee5074db5c352 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Wed, 10 Apr 2024 19:46:09 -0400
Subject: [PATCH] feat: handle PATCH requests for schedules

---
 program/views.py | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/program/views.py b/program/views.py
index 42593a8a..23439554 100644
--- a/program/views.py
+++ b/program/views.py
@@ -593,12 +593,54 @@ class APIScheduleViewSet(viewsets.ModelViewSet):
         if not request.user.is_superuser:
             return Response(status=status.HTTP_401_UNAUTHORIZED)
 
+        if request.method == "PATCH":
+            # only these fields can be updated without generating conflicts
+            allowed = {"default_playlist_id", "is_repetition", "last_date"}
+
+            if set(request.data.keys()).issubset(allowed):
+                schedule = self.get_object()
+
+                if default_playlist_id := request.data.get("default_playlist_id"):
+                    if default_playlist_id == "":
+                        # "clear" the default_playlist_id if the field has no value
+                        schedule.default_playlist_id = None
+                    else:
+                        schedule.default_playlist_id = int(default_playlist_id)
+
+                if is_repetition := request.data.get("is_repetition"):
+                    if is_repetition == "true" or is_repetition == "1":
+                        schedule.is_repetition = True
+                    if is_repetition == "false" or is_repetition == "0":
+                        schedule.is_repetition = False
+
+                if last_date := request.data.get("last_date"):
+                    last_date = date.fromisoformat(last_date)
+
+                    if schedule.last_date is None or schedule.last_date > last_date:
+                        schedule.last_date = last_date
+
+                        last_end = timezone.make_aware(
+                            datetime.combine(last_date, schedule.end_time)
+                        )
+
+                        TimeSlot.objects.filter(schedule=schedule, start__gt=last_end).delete()
+                    else:
+                        return Response(status=status.HTTP_400_BAD_REQUEST)
+
+                schedule.save()
+                serializer = ScheduleSerializer(schedule)
+
+                return Response(serializer.data)
+            else:
+                return Response(status=status.HTTP_400_BAD_REQUEST)
+
         # Only allow updating when with the `schedule` JSON object
         if "schedule" not in request.data:
             return Response(status=status.HTTP_400_BAD_REQUEST)
 
         schedule = self.get_object()
 
+        # FIXME: this is redundant now and should be removed
         # If default playlist id or repetition are given, just update
         if default_playlist_id := request.data.get("schedule").get("default_playlist_id"):
             schedule.default_playlist_id = int(default_playlist_id)
-- 
GitLab