Newer
Older
from django.utils.timezone import localdate, localtime
from graphene_django.types import DjangoObjectType
from guardian.shortcuts import get_objects_for_user

Jonathan Weth
committed
from aleksis.apps.alsijil.util.predicates import can_edit_documentation, is_in_allowed_time_range
from aleksis.apps.chronos.models import LessonEvent
from aleksis.apps.cursus.models import Subject
from aleksis.apps.cursus.schema import CourseType, SubjectType
from aleksis.core.models import Person
from aleksis.core.schema.base import (
DjangoFilterMixin,
PermissionsTypeMixin,
)
from aleksis.core.util.core_helpers import get_site_preferences
from ..models import Documentation
class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectType):
class Meta:
model = Documentation
fields = (
"id",
"course",
"lesson_event",
"subject",
"topic",
"homework",
"group_note",
"datetime_start",
"datetime_end",
"date_start",
"date_end",
filter_fields = {
"id": ["exact", "lte", "gte"],
"course__name": ["exact"],
}
course = graphene.Field(CourseType, required=False)
subject = graphene.Field(SubjectType, required=False)

Jonathan Weth
committed
future_notice = graphene.Boolean(required=False)
old_id = graphene.ID(required=False)
@staticmethod
def resolve_teachers(root: Documentation, info, **kwargs):
if not str(root.pk).startswith("DUMMY") and hasattr(root, "teachers"):
return root.lesson_event.teachers

Jonathan Weth
committed
@staticmethod
def resolve_future_notice(root: Documentation, info, **kwargs):
"""Show whether the user can't edit the documentation because it's in the future."""
return not is_in_allowed_time_range(info.context.user, root) and can_edit_documentation(
info.context.user, root
)
@classmethod
def get_queryset(cls, queryset, info):
return get_objects_for_user(info.context.user, "alsijil.view_documentation", queryset)
class DocumentationInputType(graphene.InputObjectType):
course = graphene.ID(required=False)
subject = graphene.ID(required=False)
teachers = graphene.List(graphene.ID, required=False)
topic = graphene.String(required=False)
homework = graphene.String(required=False)
group_note = graphene.String(required=False)
class DocumentationBatchCreateOrUpdateMutation(graphene.Mutation):
input = graphene.List(DocumentationInputType)
documentations = graphene.List(DocumentationType)
# Sadly, we can't use the update_or_create method since create_defaults
# is only introduced in Django 5.0
if _id.startswith("DUMMY"):
dummy, lesson_event_id, datetime_start_iso, datetime_end_iso = _id.split(";")
lesson_event = LessonEvent.objects.get(id=lesson_event_id)
datetime_start = datetime.fromisoformat(datetime_start_iso).astimezone(
lesson_event.timezone
)
datetime_end = datetime.fromisoformat(datetime_end_iso).astimezone(
lesson_event.timezone
)
if info.context.user.has_perm(
) and (
get_site_preferences()["alsijil__allow_edit_future_documentations"] == "all"
or (
get_site_preferences()["alsijil__allow_edit_future_documentations"]
== "current_day"
and datetime_start.date() <= localdate()
)
or (
get_site_preferences()["alsijil__allow_edit_future_documentations"]
== "current_time"
and datetime_start <= localtime()
)
# Timezone removal is necessary due to ISO style offsets are no valid timezones.
# Instead, we take the timezone from the lesson_event and save it in a dedicated field.
obj = Documentation.objects.create(
datetime_start=datetime_start,
datetime_end=datetime_end,
lesson_event=lesson_event,
course=lesson_event.course,
subject=lesson_event.subject,
topic=doc.topic or "",
homework=doc.homework or "",
group_note=doc.group_note or "",
)
if doc.teachers is not None:
obj.teachers.add(*doc.teachers)
else:
obj.teachers.set(lesson_event.teachers.all())
obj.save()
return obj
raise PermissionDenied()
if not info.context.user.has_perm("alsijil.edit_documentation_rule", obj):
raise PermissionDenied()
if doc.subject is not None:
obj.subject = Subject.objects.get(pk=doc.subject)
if doc.teachers is not None:
obj.teachers.set(Person.objects.filter(pk__in=doc.teachers))
obj.save()
return obj
@classmethod
objs = [cls.create_or_update(info, doc) for doc in input]
return DocumentationBatchCreateOrUpdateMutation(documentations=objs)