Related to https://github.com/grafana/oncall-private/issues/2994 - Extend gaps/empty shift checks to consider 30 days (customizable via param, eventually make it customizable per schedule?); ie. every week (per beat schedule), check the schedule next 30 days - Trigger checks via async task on schedule API updates (instead of a sync call) - Update notifications wording / link to schedule
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
from apps.api.serializers.schedule_base import ScheduleBaseSerializer
|
|
from apps.schedules.models import OnCallScheduleICal
|
|
from apps.schedules.tasks import (
|
|
check_gaps_and_empty_shifts_in_schedule,
|
|
refresh_ical_final_schedule,
|
|
schedule_notify_about_empty_shifts_in_schedule,
|
|
schedule_notify_about_gaps_in_schedule,
|
|
)
|
|
from apps.slack.models import SlackChannel, SlackUserGroup
|
|
from common.api_helpers.custom_fields import OrganizationFilteredPrimaryKeyRelatedField
|
|
from common.api_helpers.utils import validate_ical_url
|
|
|
|
|
|
class ScheduleICalSerializer(ScheduleBaseSerializer):
|
|
class Meta:
|
|
model = OnCallScheduleICal
|
|
fields = [
|
|
*ScheduleBaseSerializer.Meta.fields,
|
|
"ical_url_primary",
|
|
"ical_url_overrides",
|
|
"slack_channel",
|
|
]
|
|
|
|
def validate_ical_url_primary(self, url):
|
|
return validate_ical_url(url)
|
|
|
|
def validate_ical_url_overrides(self, url):
|
|
return validate_ical_url(url)
|
|
|
|
|
|
class ScheduleICalCreateSerializer(ScheduleICalSerializer):
|
|
slack_channel_id = OrganizationFilteredPrimaryKeyRelatedField(
|
|
filter_field="slack_team_identity__organizations",
|
|
queryset=SlackChannel.objects,
|
|
required=False,
|
|
allow_null=True,
|
|
write_only=True,
|
|
)
|
|
user_group = OrganizationFilteredPrimaryKeyRelatedField(
|
|
filter_field="slack_team_identity__organizations",
|
|
queryset=SlackUserGroup.objects,
|
|
required=False,
|
|
allow_null=True,
|
|
)
|
|
|
|
class Meta:
|
|
model = OnCallScheduleICal
|
|
fields = [
|
|
*ScheduleBaseSerializer.Meta.fields,
|
|
"ical_url_primary",
|
|
"ical_url_overrides",
|
|
"slack_channel_id",
|
|
]
|
|
extra_kwargs = {
|
|
"ical_url_primary": {"required": True, "allow_null": False},
|
|
"ical_url_overrides": {"required": False, "allow_null": True},
|
|
}
|
|
|
|
def create(self, validated_data):
|
|
created_schedule = super().create(validated_data)
|
|
# for iCal-based schedules we need to refresh final schedule information
|
|
refresh_ical_final_schedule.apply_async((created_schedule.pk,))
|
|
return created_schedule
|
|
|
|
|
|
class ScheduleICalUpdateSerializer(ScheduleICalCreateSerializer):
|
|
class Meta:
|
|
model = OnCallScheduleICal
|
|
fields = [
|
|
*ScheduleBaseSerializer.Meta.fields,
|
|
"ical_url_primary",
|
|
"ical_url_overrides",
|
|
"slack_channel_id",
|
|
]
|
|
extra_kwargs = {
|
|
"ical_url_primary": {"required": False, "allow_null": False},
|
|
"ical_url_overrides": {"required": False, "allow_null": True},
|
|
}
|
|
|
|
def update(self, instance, validated_data):
|
|
old_ical_url_primary = instance.ical_url_primary
|
|
old_ical_url_overrides = instance.ical_url_overrides
|
|
|
|
updated_schedule = super().update(instance, validated_data)
|
|
|
|
updated_ical_url_primary = updated_schedule.ical_url_primary
|
|
updated_ical_url_overrides = updated_schedule.ical_url_overrides
|
|
|
|
if old_ical_url_primary != updated_ical_url_primary or old_ical_url_overrides != updated_ical_url_overrides:
|
|
updated_schedule.drop_cached_ical()
|
|
check_gaps_and_empty_shifts_in_schedule.apply_async((instance.pk,))
|
|
schedule_notify_about_empty_shifts_in_schedule.apply_async((instance.pk,))
|
|
schedule_notify_about_gaps_in_schedule.apply_async((instance.pk,))
|
|
# for iCal-based schedules we need to refresh final schedule information
|
|
refresh_ical_final_schedule.apply_async((instance.pk,))
|
|
return updated_schedule
|