From f98fa836482edcc376823da83e3beb22c842462c Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Tue, 4 Apr 2023 15:58:58 -0400
Subject: [PATCH] Extract instantiate_upcoming and make_conflicts as functions

---
 program/models.py   |  95 +----------------------------------------
 program/services.py | 101 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 98 insertions(+), 98 deletions(-)

diff --git a/program/models.py b/program/models.py
index dde3b044..0fafc80b 100644
--- a/program/models.py
+++ b/program/models.py
@@ -29,13 +29,11 @@ from django.contrib.auth.models import User
 from django.core.exceptions import ObjectDoesNotExist
 from django.db import models
 from django.db.models import Q, QuerySet
-from django.forms.models import model_to_dict
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
-from program.utils import parse_date, parse_datetime, parse_time
+
+from program.utils import parse_datetime
 from steering.settings import (
-    AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE,
-    AUTO_SET_LAST_DATE_TO_END_OF_YEAR,
     THUMBNAIL_SIZES,
 )
 
@@ -377,57 +375,6 @@ class Schedule(models.Model):
     class Meta:
         ordering = ("first_date", "start_time")
 
-    # FIXME: this does not belong here
-    @staticmethod
-    def instantiate_upcoming(sdl, show_pk, pk=None):
-        """Returns an upcoming schedule instance for conflict resolution"""
-        pk = int(pk) if pk is not None else None
-        rrule = RRule.objects.get(pk=int(sdl["rrule"]))
-        show = Show.objects.get(pk=int(show_pk))
-
-        is_repetition = True if sdl.get("is_repetition") is True else False
-        default_playlist_id = (
-            int(sdl["default_playlist_id"]) if sdl.get("default_playlist_id") else None
-        )
-        add_days_no = int(sdl["add_days_no"]) if sdl.get("add_days_no") else None
-        add_business_days_only = True if sdl.get("add_business_days_only") is True else False
-
-        first_date = parse_date(str(sdl["first_date"]))
-        start_time = (
-            sdl["start_time"] + ":00" if len(str(sdl["start_time"])) == 5 else sdl["start_time"]
-        )
-        end_time = sdl["end_time"] + ":00" if len(str(sdl["end_time"])) == 5 else sdl["end_time"]
-
-        start_time = parse_time(str(start_time))
-        end_time = parse_time(str(end_time))
-
-        if sdl["last_date"]:
-            last_date = parse_date(str(sdl["last_date"]))
-        else:
-            # If last_date was not set, set it to the end of the year or add x days
-            if AUTO_SET_LAST_DATE_TO_END_OF_YEAR:
-                year = timezone.now().year
-                last_date = parse_date(f"{year}-12-31")
-            else:
-                last_date = first_date + timedelta(days=+AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE)
-
-        schedule = Schedule(
-            pk=pk,
-            by_weekday=sdl["by_weekday"],
-            rrule=rrule,
-            first_date=first_date,
-            start_time=start_time,
-            end_time=end_time,
-            last_date=last_date,
-            is_repetition=is_repetition,
-            default_playlist_id=default_playlist_id,
-            show=show,
-            add_days_no=add_days_no,
-            add_business_days_only=add_business_days_only,
-        )
-
-        return schedule
-
     # FIXME: this does not belong here
     @staticmethod
     def generate_timeslots(schedule):
@@ -712,44 +659,6 @@ class Schedule(models.Model):
 
         return conflicts
 
-    # FIXME: this does not belong here
-    @staticmethod
-    def make_conflicts(sdl, schedule_pk, show_pk):
-        """
-        Retrieves POST vars
-        Generates a schedule
-        Generates conflicts: Returns timeslots, collisions, solutions as JSON
-        Returns conflicts dict
-        """
-
-        # Generate schedule to be saved
-        schedule = Schedule.instantiate_upcoming(sdl, show_pk, schedule_pk)
-
-        # Copy if first_date changes for generating timeslots
-        gen_schedule = schedule
-
-        # Generate timeslots
-
-        # If extending: Get last timeslot and start generating from that date on
-        if schedule_pk is not None:
-            existing_schedule = Schedule.objects.get(pk=int(schedule_pk))
-
-            if schedule.last_date > existing_schedule.last_date:
-                last_timeslot = (
-                    TimeSlot.objects.filter(schedule=existing_schedule)
-                    .order_by("start")
-                    .reverse()[0]
-                )
-                gen_schedule.first_date = last_timeslot.start.date() + timedelta(days=1)
-
-        timeslots = Schedule.generate_timeslots(gen_schedule)
-
-        # Generate conflicts and add schedule
-        conflicts = Schedule.generate_conflicts(timeslots)
-        conflicts["schedule"] = model_to_dict(schedule)
-
-        return conflicts
-
 
 class TimeSlotManager(models.Manager):
     @staticmethod
diff --git a/program/services.py b/program/services.py
index e7ead3cb..a6d509df 100644
--- a/program/services.py
+++ b/program/services.py
@@ -17,7 +17,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from datetime import datetime, time
+from datetime import datetime, time, timedelta
 
 from rest_framework.exceptions import ValidationError
 
@@ -25,8 +25,12 @@ from django.core.exceptions import ObjectDoesNotExist
 from django.forms.models import model_to_dict
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
-from program.models import Note, Schedule, ScheduleConflictError, TimeSlot
-from program.utils import parse_datetime
+from program.models import Note, RRule, Schedule, ScheduleConflictError, Show, TimeSlot
+from program.utils import parse_date, parse_datetime, parse_time
+from steering.settings import (
+    AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE,
+    AUTO_SET_LAST_DATE_TO_END_OF_YEAR,
+)
 
 
 # TODO: add type annotations
@@ -43,9 +47,9 @@ def resolve_conflicts(data, schedule_pk, show_pk):
     solutions = data.get("solutions", [])
 
     # Regenerate conflicts
-    schedule = Schedule.instantiate_upcoming(sdl, show_pk, schedule_pk)
+    schedule = instantiate_upcoming(sdl, show_pk, schedule_pk)
     show = schedule.show
-    conflicts = Schedule.make_conflicts(sdl, schedule_pk, show_pk)
+    conflicts = make_conflicts(sdl, schedule_pk, show_pk)
 
     if schedule.rrule.freq > 0 and schedule.first_date == schedule.last_date:
         raise ValidationError(
@@ -307,3 +311,90 @@ def resolve_conflicts(data, schedule_pk, show_pk):
         dl.delete()
 
     return model_to_dict(schedule)
+
+
+# TODO: add type annotations
+def instantiate_upcoming(sdl, show_pk, pk=None):
+    """Returns an upcoming schedule instance for conflict resolution"""
+    pk = int(pk) if pk is not None else None
+    rrule = RRule.objects.get(pk=int(sdl["rrule"]))
+    show = Show.objects.get(pk=int(show_pk))
+
+    is_repetition = True if sdl.get("is_repetition") is True else False
+    default_playlist_id = (
+        int(sdl["default_playlist_id"]) if sdl.get("default_playlist_id") else None
+    )
+    add_days_no = int(sdl["add_days_no"]) if sdl.get("add_days_no") else None
+    add_business_days_only = True if sdl.get("add_business_days_only") is True else False
+
+    first_date = parse_date(str(sdl["first_date"]))
+    start_time = (
+        sdl["start_time"] + ":00" if len(str(sdl["start_time"])) == 5 else sdl["start_time"]
+    )
+    end_time = sdl["end_time"] + ":00" if len(str(sdl["end_time"])) == 5 else sdl["end_time"]
+
+    start_time = parse_time(str(start_time))
+    end_time = parse_time(str(end_time))
+
+    if sdl["last_date"]:
+        last_date = parse_date(str(sdl["last_date"]))
+    else:
+        # If last_date was not set, set it to the end of the year or add x days
+        if AUTO_SET_LAST_DATE_TO_END_OF_YEAR:
+            year = timezone.now().year
+            last_date = parse_date(f"{year}-12-31")
+        else:
+            last_date = first_date + timedelta(days=+AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE)
+
+    schedule = Schedule(
+        pk=pk,
+        by_weekday=sdl["by_weekday"],
+        rrule=rrule,
+        first_date=first_date,
+        start_time=start_time,
+        end_time=end_time,
+        last_date=last_date,
+        is_repetition=is_repetition,
+        default_playlist_id=default_playlist_id,
+        show=show,
+        add_days_no=add_days_no,
+        add_business_days_only=add_business_days_only,
+    )
+
+    return schedule
+
+
+# TODO: add type annotations
+def make_conflicts(sdl, schedule_pk, show_pk):
+    """
+    Retrieves POST vars
+    Generates a schedule
+    Generates conflicts: Returns timeslots, collisions, solutions as JSON
+    Returns conflicts dict
+    """
+
+    # Generate schedule to be saved
+    schedule = instantiate_upcoming(sdl, show_pk, schedule_pk)
+
+    # Copy if first_date changes for generating timeslots
+    gen_schedule = schedule
+
+    # Generate timeslots
+
+    # If extending: Get last timeslot and start generating from that date on
+    if schedule_pk is not None:
+        existing_schedule = Schedule.objects.get(pk=int(schedule_pk))
+
+        if schedule.last_date > existing_schedule.last_date:
+            last_timeslot = (
+                TimeSlot.objects.filter(schedule=existing_schedule).order_by("start").reverse()[0]
+            )
+            gen_schedule.first_date = last_timeslot.start.date() + timedelta(days=1)
+
+    timeslots = Schedule.generate_timeslots(gen_schedule)
+
+    # Generate conflicts and add schedule
+    conflicts = Schedule.generate_conflicts(timeslots)
+    conflicts["schedule"] = model_to_dict(schedule)
+
+    return conflicts
-- 
GitLab