import graphene from graphene import relay, InputObjectType from graphql_relay import from_global_id from rest_framework.exceptions import PermissionDenied from api.utils import get_object from books.models import Module from books.schema.inputs import UserGroupBlockVisibility from core.utils import set_visible_for, set_hidden_for from objectives.inputs import AddObjectiveGroupArgument, UpdateObjectiveGroupArgument from objectives.models import ObjectiveProgressStatus, Objective, ObjectiveGroup from objectives.schema import ObjectiveNode, ObjectiveGroupNode class UpdateObjectiveProgress(relay.ClientIDMutation): class Input: id = graphene.ID(required=True, description="The ID of the objective") done = graphene.Boolean(required=True) errors = graphene.List(graphene.String) objective = graphene.Field(ObjectiveNode) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): objective_id = kwargs.get('id') done = kwargs.get('done') objective = get_object(Objective, objective_id) # info.context.user = django user objective_progress, created = ObjectiveProgressStatus.objects.get_or_create( objective=objective, user=info.context.user ) objective_progress.done = done objective_progress.save() return cls(objective=objective) class UpdateObjectiveGroupVisibility(relay.ClientIDMutation): class Input: id = graphene.ID(required=True, description='The ID of the objective group') visibility = graphene.List(UserGroupBlockVisibility) objective_group = graphene.Field(ObjectiveGroupNode) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): objective_group_id = kwargs.get('id') visibility_list = kwargs.get('visibility') objective_group = get_object(ObjectiveGroup, objective_group_id) # info.context.user = django user if visibility_list is not None: if objective_group.owner is not None: set_visible_for(objective_group, visibility_list) else: set_hidden_for(objective_group, visibility_list) objective_group.save() return cls(objective_group=objective_group) class AddObjectiveGroup(relay.ClientIDMutation): class Input: objective_group = graphene.Argument(AddObjectiveGroupArgument) objective_group = graphene.Field(ObjectiveGroupNode) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): owner = info.context.user if not owner.has_perm('users.can_manage_school_class_content'): raise PermissionDenied('Missing permissions') objective_group_data = kwargs.get('objective_group') title = objective_group_data.get('title') if title != 'society': title = 'language_communication' module_id = objective_group_data.get('module') module = get_object(Module, module_id) new_objective_group = ObjectiveGroup.objects.create(title=title, module=module, owner=owner) objectives = objective_group_data.get('objectives') for objective in objectives: Objective.objects.create(text=objective.get('text'), group=new_objective_group) return cls(objective_group=new_objective_group) class UpdateObjectiveGroup(relay.ClientIDMutation): class Input: objective_group = graphene.Argument(UpdateObjectiveGroupArgument) objective_group = graphene.Field(ObjectiveGroupNode) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): user = info.context.user if not user.has_perm('users.can_manage_school_class_content'): raise PermissionDenied('Missing permissions') objective_group_data = kwargs.get('objective_group') id = objective_group_data.get('id') objective_group = get_object(ObjectiveGroup, id) objectives = objective_group_data.get('objectives') existing_objective_ids = list(objective_group.objectives.values_list('id', flat=True)) for objective in objectives: if objective.get('id') is not None: objective_id = objective.get('id') updated_objective = get_object(Objective, objective_id) updated_objective.text = objective.get('text') updated_objective.save() existing_objective_ids.remove(int(from_global_id(objective_id)[1])) else: Objective.objects.create(text=objective.get('text'), group=objective_group) # remove existing items that are not in payload for objective_id in existing_objective_ids: objective = Objective.objects.get(pk=objective_id) objective.delete() return cls(objective_group=objective_group) class ObjectiveMutations: update_objective_progress = UpdateObjectiveProgress.Field() update_objective_group_visibility = UpdateObjectiveGroupVisibility.Field() add_objective_group = AddObjectiveGroup.Field() update_objective_group = UpdateObjectiveGroup.Field()