Skip to content
Snippets Groups Projects
Commit 51be0fbe authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

refactor: update schedule REST API attribute names and documentation

The following attribute names were marked as deprecated in the schedule
request and have been replaced by their new names:

  dstart → first_date
  until → last_date
  tstart → start_time
  tend → end_time
  byweekday → by_weekday

Apart from that this commit fixes a few documentation errors.
parent 26962973
No related branches found
No related tags found
1 merge request!22refactor schedule REST API
......@@ -323,25 +323,25 @@ class Schedule(models.Model):
True if sdl.get("add_business_days_only") is True else False
)
# TODO: replace `dstart` with `first_date` when the dashboard is updated
first_date = parse_date(str(sdl["dstart"]))
# TODO: replace `tstart` with `start_time` when the dashboard is updated
first_date = parse_date(str(sdl["first_date"]))
start_time = (
sdl["tstart"] + ":00" if len(str(sdl["tstart"])) == 5 else sdl["tstart"]
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"]
)
# TODO: replace `tend` with `end_time` when the dashboard is updated
end_time = sdl["tend"] + ":00" if len(str(sdl["tend"])) == 5 else sdl["tend"]
start_time = parse_time(str(start_time))
end_time = parse_time(str(end_time))
# TODO: replace `until` with `last_date` when the dashboard is updated
if sdl["until"]:
last_date = parse_date(str(sdl["until"]))
if sdl["last_date"]:
last_date = parse_date(str(sdl["last_date"]))
else:
# If no until date was set
# Set it to the end of the year
# Or add x days
# If last_date was not set, set it to the end of the year or add x days
if AUTO_SET_UNTIL_DATE_TO_END_OF_YEAR:
year = timezone.now().year
last_date = parse_date(f"{year}-12-31")
......@@ -350,10 +350,9 @@ class Schedule(models.Model):
days=+AUTO_SET_UNTIL_DATE_TO_DAYS_IN_FUTURE
)
# TODO: replace `byweekday` with `by_weekday` when the dashboard is updated
schedule = Schedule(
pk=pk,
by_weekday=sdl["byweekday"],
by_weekday=sdl["by_weekday"],
rrule=rrule,
first_date=first_date,
start_time=start_time,
......@@ -373,7 +372,7 @@ class Schedule(models.Model):
def generate_timeslots(schedule):
"""
Returns a list of timeslot objects based on a schedule and its rrule
Returns past timeslots as well, starting from dstart (not today)
Returns past timeslots as well, starting from first_date (not today)
"""
by_week_no = None
......@@ -696,7 +695,7 @@ class Schedule(models.Model):
# Generate schedule to be saved
schedule = Schedule.instantiate_upcoming(sdl, show_pk, schedule_pk)
# Copy if dstart changes for generating timeslots
# Copy if first_date changes for generating timeslots
gen_schedule = schedule
# Generate timeslots
......@@ -742,13 +741,13 @@ class Schedule(models.Model):
if schedule.rrule.freq > 0 and schedule.first_date == schedule.last_date:
raise ValidationError(
_("Start and until dates mustn't be the same"),
_("Start and end dates must not be the same."),
code="no-same-day-start-and-end",
)
if schedule.last_date < schedule.first_date:
raise ValidationError(
_("Until date mustn't be before start"),
_("End date mustn't be before start."),
code="no-start-after-end",
)
......
......@@ -36,7 +36,6 @@ from program.models import (
MusicFocus,
Note,
NoteLink,
RRule,
Schedule,
Show,
TimeSlot,
......@@ -405,35 +404,16 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer):
class ScheduleSerializer(serializers.ModelSerializer):
rrule = serializers.PrimaryKeyRelatedField(
queryset=RRule.objects.all(),
help_text=Schedule.rrule.field.help_text,
)
show = serializers.PrimaryKeyRelatedField(
queryset=Show.objects.all(),
help_text=Schedule.show.field.help_text,
)
# TODO: remove this when the dashboard is updated
byweekday = serializers.IntegerField(
source="by_weekday",
help_text=Schedule.by_weekday.field.help_text,
)
dstart = serializers.DateField(
source="first_date",
help_text=Schedule.first_date.field.help_text,
)
tstart = serializers.TimeField(
source="start_time",
help_text=Schedule.start_time.field.help_text,
)
tend = serializers.TimeField(
source="end_time",
help_text=Schedule.end_time.field.help_text,
)
until = serializers.DateField(
source="last_date",
help_text=Schedule.last_date.field.help_text,
)
class Meta:
model = Schedule
fields = "__all__"
class UnsavedScheduleSerializer(ScheduleSerializer):
id = serializers.IntegerField(allow_null=True)
class ScheduleInRequestSerializer(ScheduleSerializer):
dryrun = serializers.BooleanField(
write_only=True,
required=False,
......@@ -464,11 +444,11 @@ class ScheduleSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
"""Update and return an existing Schedule instance, given the validated data."""
instance.by_weekday = validated_data.get("byweekday", instance.by_weekday)
instance.first_date = validated_data.get("dstart", instance.first_date)
instance.start_time = validated_data.get("tstart", instance.start_time)
instance.end_time = validated_data.get("tend", instance.end_time)
instance.last_date = validated_data.get("until", instance.last_date)
instance.by_weekday = validated_data.get("by_weekday", instance.by_weekday)
instance.first_date = validated_data.get("first_date", instance.first_date)
instance.start_time = validated_data.get("start_time", instance.start_time)
instance.end_time = validated_data.get("end_time", instance.end_time)
instance.last_date = validated_data.get("last_date", instance.last_date)
instance.is_repetition = validated_data.get(
"is_repetition", instance.is_repetition
)
......@@ -525,41 +505,24 @@ class DryRunTimeSlotSerializer(serializers.Serializer):
class ScheduleCreateUpdateRequestSerializer(serializers.Serializer):
schedule = ScheduleSerializer()
solutions = serializers.DictField(child=serializers.ChoiceField(SOLUTION_CHOICES))
schedule = ScheduleInRequestSerializer()
solutions = serializers.DictField(
child=serializers.ChoiceField(SOLUTION_CHOICES), required=False
)
notes = serializers.DictField(child=serializers.IntegerField(), required=False)
playlists = serializers.DictField(child=serializers.IntegerField(), required=False)
# TODO: There shouldn’t be a separate ScheduleSerializer for use in responses.
# Instead the default serializer should be used. Unfortunately, the
# code that generates the data creates custom dicts with this particular format.
class ScheduleInResponseSerializer(serializers.Serializer):
# "Schedule schema type" is the rendered name of the ScheduleSerializer.
"""
For documentation on the individual fields see the
Schedule schema type.
"""
add_business_days_only = serializers.BooleanField()
add_days_no = serializers.IntegerField(allow_null=True)
by_weekday = serializers.IntegerField()
default_playlist_id = serializers.IntegerField(allow_null=True)
end_time = serializers.TimeField()
first_date = serializers.DateField()
id = serializers.PrimaryKeyRelatedField(queryset=Schedule.objects.all())
is_repetition = serializers.BooleanField()
last_date = serializers.DateField()
rrule = serializers.PrimaryKeyRelatedField(queryset=RRule.objects.all())
show = serializers.PrimaryKeyRelatedField(queryset=Note.objects.all())
start_time = serializers.TimeField()
class ScheduleConflictResponseSerializer(serializers.Serializer):
class ScheduleResponseSerializer(serializers.Serializer):
projected = ProjectedTimeSlotSerializer(many=True)
solutions = serializers.DictField(child=serializers.ChoiceField(SOLUTION_CHOICES))
notes = serializers.DictField(child=serializers.IntegerField())
playlists = serializers.DictField(child=serializers.IntegerField())
schedule = ScheduleInResponseSerializer()
schedule = ScheduleSerializer()
class ScheduleConflictResponseSerializer(ScheduleResponseSerializer):
schedule = UnsavedScheduleSerializer()
class ScheduleDryRunResponseSerializer(serializers.Serializer):
......
......@@ -58,6 +58,7 @@ from program.serializers import (
ScheduleConflictResponseSerializer,
ScheduleCreateUpdateRequestSerializer,
ScheduleDryRunResponseSerializer,
ScheduleResponseSerializer,
ScheduleSerializer,
ShowSerializer,
TimeSlotSerializer,
......@@ -344,9 +345,10 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet):
@extend_schema_view(
create=extend_schema(
summary="Create a new schedule.",
request=ScheduleCreateUpdateRequestSerializer,
responses={
status.HTTP_201_CREATED: OpenApiResponse(
response=ScheduleConflictResponseSerializer,
response=ScheduleResponseSerializer,
description=(
"Signals the successful creation of the schedule and of the projected "
"timeslots."
......@@ -366,9 +368,9 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet):
Returned in case the request contained invalid data.
This may happen if:
* the until date is before the start date (`no-start-after-end`),
* the last date is before the start date (`no-start-after-end`),
in which case you should correct either the start or until date.
* The start and until date are the same (`no-same-day-start-and-end`).
* The start and last date are the same (`no-same-day-start-and-end`).
This is only allowed for single timeslots with the recurrence rule
set to `once`. You should fix either the start or until date.
* The number of conflicts and solutions aren’t the same
......@@ -410,8 +412,14 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet):
},
),
retrieve=extend_schema(summary="Retrieve a single schedule."),
update=extend_schema(summary="Update an existing schedule."),
partial_update=extend_schema(summary="Partially update an existing schedule."),
update=extend_schema(
summary="Update an existing schedule.",
request=ScheduleCreateUpdateRequestSerializer,
),
partial_update=extend_schema(
summary="Partially update an existing schedule.",
request=ScheduleCreateUpdateRequestSerializer,
),
destroy=extend_schema(summary="Delete an existing schedule."),
list=extend_schema(summary="List all schedules."),
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment