def post(self, task_type_id): permissions.check_manager_permissions() criterions = query.get_query_criterions_from_request(request) shots = shots_service.get_shots(criterions) task_type = tasks_service.get_task_type(task_type_id) tasks = [tasks_service.create_task(task_type, shot) for shot in shots] return tasks, 201
def get(self, task_id): task = tasks_service.get_task(task_id) if not permissions.has_manager_permissions(): user_service.check_has_task_related(task["project_id"]) result = task task_type = tasks_service.get_task_type(task["task_type_id"]) result["task_type"] = task_type assigner = persons_service.get_person(task["assigner_id"]) result["assigner"] = assigner project = projects_service.get_project(task["project_id"]) result["project"] = project task_status = tasks_service.get_task_status(task["task_status_id"]) result["task_status"] = task_status entity = tasks_service.get_entity(task["entity_id"]) result["entity"] = entity if entity["parent_id"] is not None: sequence = shots_service.get_sequence(entity["parent_id"]) result["sequence"] = sequence if sequence["parent_id"] is not None: episode = shots_service.get_episode(sequence["parent_id"]) result["episode"] = episode entity_type = tasks_service.get_entity_type(entity["entity_type_id"]) result["entity_type"] = entity_type assignees = [] for assignee_id in task["assignees"]: assignees.append(persons_service.get_person(assignee_id)) result["persons"] = assignees result["type"] = "Task" return result, 200
def get_task_descriptors(person_id, task): """ Build task information needed to write notification emails: author object, full task name and task URL. """ author = persons_service.get_person(person_id) project = projects_service.get_project(task["project_id"]) task_type = tasks_service.get_task_type(task["task_type_id"]) entity = entities_service.get_entity(task["entity_id"]) (entity_name, episode_id) = names_service.get_full_entity_name(entity["id"]) episode_segment = "" entity_type = "assets" if task_type["for_shots"]: entity_type = "shots" if project["production_type"] == "tvshow": episode_segment = "/episodes/%s" % episode_id task_name = "%s / %s / %s" % ( project["name"], entity_name, task_type["name"], ) task_url = "%s://%s/productions/%s%s/%s/tasks/%s" % ( config.DOMAIN_PROTOCOL, config.DOMAIN_NAME, task["project_id"], episode_segment, entity_type, task["id"], ) return (author, task_name, task_url)
def put(self, preview_file_id): preview_file = files_service.get_preview_file(preview_file_id) task = tasks_service.get_task(preview_file["task_id"]) user_service.check_project_access(task["project_id"]) is_manager = permissions.has_manager_permissions() is_client = permissions.has_client_permissions() is_supervisor_allowed = False if permissions.has_supervisor_permissions(): user_departments = persons_service.get_current_user( relations=True)["departments"] if (user_departments == [] or tasks_service.get_task_type( task["task_type_id"])["department_id"] in user_departments): is_supervisor_allowed = True if not (is_manager or is_client or is_supervisor_allowed): raise permissions.PermissionDenied additions = request.json.get("additions", []) updates = request.json.get("updates", []) deletions = request.json.get("deletions", []) user = persons_service.get_current_user() return preview_files_service.update_preview_file_annotations( user["id"], task["project_id"], preview_file_id, additions=additions, updates=updates, deletions=deletions, )
def get_preview_file_name(preview_file_id): """ Build unique and human readable file name for preview downloads. The convention followed is: [project_name]_[entity_name]_[task_type_name]_v[revivision].[extension]. """ organisation = Organisation.query.first() preview_file = files_service.get_preview_file(preview_file_id) task = tasks_service.get_task(preview_file["task_id"]) task_type = tasks_service.get_task_type(task["task_type_id"]) project = projects_service.get_project(task["project_id"]) (entity_name, _) = get_full_entity_name(task["entity_id"]) if (organisation.use_original_file_name and preview_file.get("original_name", None) is not None): name = preview_file["original_name"] else: name = "%s_%s_%s_v%s" % ( project["name"], entity_name, task_type["name"], preview_file["revision"], ) name = slugify.slugify(name, separator="_") return "%s.%s" % (name, preview_file["extension"])
def post(self, asset_instance_id): args = self.get_arguments() try: revision = int(args["revision"]) try: working_file = files_service.get_working_file( args["working_file_id"] ) working_file_id = working_file["id"] except WorkingFileNotFoundException: pass asset_instance = assets_service.get_asset_instance( asset_instance_id ) entity = assets_service.get_asset(asset_instance["asset_id"]) if not permissions.has_manager_permissions(): user_service.check_has_task_related(entity["project_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if args["person_id"] is None: person = persons_service.get_current_user() else: person = persons_service.get_person(args["person_id"]) output_file = files_service.create_new_output_revision( asset_instance["asset_id"], working_file_id, output_type["id"], person["id"], task_type["id"], asset_instance_id=asset_instance["id"], revision=revision, name=args["name"], representation=args["representation"], comment=args["comment"], extension=args["extension"] ) output_file_dict = self.add_path_info( output_file, "output", asset_instance, output_type, task_type=task_type, name=args["name"], extension=args["extension"], representation=args["representation"], separator=args["sep"] ) except OutputTypeNotFoundException: return {"message": "Cannot find given output type."}, 400 except PersonNotFoundException: return {"message": "Cannot find given person."}, 400 except EntryAlreadyExistsException: return {"message": "The given output file already exists."}, 400 return output_file_dict, 201
def check_supervisor_schedule_item_access(schedule_item, new_data={}): """ Return true if current user is a manager and has a task assigned related to the project of this task or is a supervisor and can modify data accorded to his departments """ is_allowed = False if permissions.has_admin_permissions() or ( permissions.has_manager_permissions() and check_belong_to_project(schedule_item["project_id"]) ): is_allowed = True elif permissions.has_supervisor_permissions() and check_belong_to_project( schedule_item["project_id"] ): user_departments = persons_service.get_current_user(relations=True)[ "departments" ] if ( user_departments == [] or tasks_service.get_task_type(schedule_item["task_type_id"])[ "department_id" ] in user_departments ): is_allowed = True if not is_allowed: raise permissions.PermissionDenied return is_allowed
def post(self, entity_id): args = self.get_arguments() try: revision = int(args["revision"]) try: working_file = files_service.get_working_file( args["working_file_id"] ) working_file_id = working_file["id"] except WorkingFileNotFoundException: working_file_id = None entity = entities_service.get_entity(entity_id) user_service.check_project_access(entity["project_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if args["person_id"] is None: person = persons_service.get_current_user() else: person = persons_service.get_person(args["person_id"]) output_file = files_service.create_new_output_revision( entity_id, working_file_id, output_type["id"], person["id"], args["task_type_id"], revision=revision, name=args["name"], comment=args["comment"], representation=args["representation"], extension=args["extension"], nb_elements=int(args["nb_elements"]), file_status_id=args['file_status_id'], ) output_file_dict = self.add_path_info( output_file, "output", entity, output_type, task_type=task_type, name=args["name"], extension=args["extension"], representation=args["representation"], separator=args["sep"], nb_elements=int(args["nb_elements"]), ) except OutputTypeNotFoundException: return {"error": "Cannot find given output type."}, 400 except PersonNotFoundException: return {"error": "Cannot find given person."}, 400 except EntryAlreadyExistsException: return {"error": "The given output file already exists."}, 400 return output_file_dict, 201
def post(self, asset_instance_id, temporal_entity_id): args = self.get_arguments() try: revision = int(args["revision"]) try: working_file = files_service.get_working_file( args["working_file_id"]) working_file_id = working_file["id"] except WorkingFileNotFoundException: working_file_id = None asset_instance = assets_service.get_asset_instance( asset_instance_id) entity = assets_service.get_asset(asset_instance["asset_id"]) user_service.check_project_access(entity["project_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if args["person_id"] is None: person = persons_service.get_current_user() else: person = persons_service.get_person(args["person_id"]) output_file_dict = files_service.create_new_output_revision( asset_instance["asset_id"], working_file_id, output_type["id"], person["id"], task_type["id"], asset_instance_id=asset_instance["id"], temporal_entity_id=temporal_entity_id, revision=revision, name=args["name"], path=args["path"], render_info=args["render_info"], representation=args["representation"], comment=args["comment"], nb_elements=int(args["nb_elements"]), extension=args["extension"], file_status_id=args['file_status_id'], ) if args["path"]: folder_path, file_name = os.path.split(args["path"]) output_file_dict.update({ "folder_path": folder_path, "file_name": file_name }) except OutputTypeNotFoundException: return {"message": "Cannot find given output type."}, 400 except PersonNotFoundException: return {"message": "Cannot find given person."}, 400 except EntryAlreadyExistsException: return {"message": "The given output file already exists."}, 400 return output_file_dict, 201
def get_folder_from_task_type(task, task_type, field="name"): folder = "" if task_type is None and task is not None: task_type = tasks_service.get_task_type(task["task_type_id"]) if task_type is not None: folder = task_type[field] elif task_type is not None: folder = task_type[field] return folder
def post(self, project_id, task_type_id): user_service.check_manager_project_access(project_id) task_type = tasks_service.get_task_type(task_type_id) shot_ids = request.json shots = [] if type(shot_ids) == list and len(shot_ids) > 0: for shot_id in shot_ids: shot = shots_service.get_shot(shot_id) if shot["project_id"] == project_id: shots.append(shot) else: criterions = query.get_query_criterions_from_request(request) criterions["project_id"] = project_id shots = shots_service.get_shots(criterions) task_type = tasks_service.get_task_type(task_type_id) tasks = tasks_service.create_tasks(task_type, shots) return tasks, 201
def post(self, task_type_id): criterions = query.get_query_criterions_from_request(request) if "project_id" not in criterions: return {"error": True, "message": "Project ID is missing"}, 400 user_service.check_manager_project_access(criterions["project_id"]) shots = shots_service.get_shots(criterions) task_type = tasks_service.get_task_type(task_type_id) tasks = [tasks_service.create_task(task_type, shot) for shot in shots] return tasks, 201
def post(self, entity_id): args = self.get_arguments() entity = entities_service.get_entity(entity_id) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) user_service.check_project_access(entity["project_id"]) next_revision_number = files_service.get_next_output_file_revision( entity["id"], output_type["id"], task_type["id"], args["name"]) return {"next_revision": next_revision_number}, 200
def post(self, project_id, task_type_id): """ Create a new task for given shot and task type. --- tags: - Tasks parameters: - in: path name: project_id required: True schema: type: UUID example: a24a6ea4-ce75-4665-a070-57453082c25 - in: path name: task_type_id required: True schema: type: UUID example: a24a6ea4-ce75-4665-a070-57453082c25 responses: 201: description: New task for given shot and task type created """ user_service.check_manager_project_access(project_id) task_type = tasks_service.get_task_type(task_type_id) shot_ids = request.json shots = [] if type(shot_ids) == list and len(shot_ids) > 0: for shot_id in shot_ids: shot = shots_service.get_shot(shot_id) if shot["project_id"] == project_id: shots.append(shot) else: criterions = query.get_query_criterions_from_request(request) criterions["project_id"] = project_id shots = shots_service.get_shots(criterions) task_type = tasks_service.get_task_type(task_type_id) tasks = tasks_service.create_tasks(task_type, shots) return tasks, 201
def get_preview_file_name(preview_file_id): """ Build unique and human readable file name for preview downloads. The convention followed is: [project_name]_[entity_name]_[task_type_name]_v[revivision].[extension]. """ preview_file = files_service.get_preview_file(preview_file_id) task = tasks_service.get_task(preview_file["task_id"]) task_type = tasks_service.get_task_type(task["task_type_id"]) project = projects_service.get_project(task["project_id"]) (entity_name, _) = get_full_entity_name(task["entity_id"]) name = "%s_%s_%s_v%s" % (project["name"], entity_name, task_type["name"], preview_file["revision"]) return "%s.%s" % (slugify.slugify( name, separator="_"), preview_file["extension"])
def _run_status_automation(automation, task, person_id): is_automation_to_run = ( task["task_type_id"] == automation["in_task_type_id"] and task["task_status_id"] == automation["in_task_status_id"]) if not is_automation_to_run: return priorities = projects_service.get_task_type_priority_map( task["project_id"], automation["entity_type"].capitalize()) in_priority = priorities.get(automation["in_task_type_id"], 0) or 0 out_priority = priorities.get(automation["out_task_type_id"], 0) or 0 is_rollback = (priorities is not None and automation["out_field_type"] != "ready_for" and in_priority > out_priority) if is_rollback: # Do not apply rollback to avoid change cycles. return if automation["out_field_type"] == "status": tasks_to_update = tasks_service.get_tasks_for_entity_and_task_type( task["entity_id"], automation["out_task_type_id"]) if len(tasks_to_update) > 0: task_to_update = tasks_to_update[0] task_type = tasks_service.get_task_type( automation["in_task_type_id"]) task_status = tasks_service.get_task_status( automation["in_task_status_id"]) create_comment( person_id, task_to_update["id"], automation["out_task_status_id"], "Change triggered by %s set to %s" % ( task_type["name"], task_status["name"], ), [], {}, None, ) elif automation["out_field_type"] == "ready_for": try: asset = assets_service.update_asset( task["entity_id"], {"ready_for": automation["out_task_type_id"]}, ) breakdown_service.refresh_casting_stats(asset) except AssetNotFoundException: pass
def post(self, entity_id): args = self.get_arguments() entity = entities_service.get_entity(entity_id) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if not permissions.has_manager_permissions(): user_service.check_has_task_related(entity["project_id"]) next_revision_number = \ files_service.get_next_output_file_revision( entity["id"], output_type["id"], task_type["id"], args["name"] ) return {"next_revision": next_revision_number}, 200
def check_project_departement_access(task_id, person_id): """ Return true if current user is admin or is manager and is in team or is artist in the task department. """ user = persons_service.get_current_user(relations=True) task = tasks_service.get_task(task_id) task_type = tasks_service.get_task_type(task["task_type_id"]) is_allowed = (permissions.has_admin_permissions() or (permissions.has_manager_permissions() and check_belong_to_project(task["project_id"])) or (check_belong_to_project(task["project_id"]) and task_type["department_id"] in user["departments"] and person_id == user["id"])) if not is_allowed: raise permissions.PermissionDenied return is_allowed
def post(self, entity_id): args = self.get_arguments() try: entity = entities_service.get_entity(entity_id) if not permissions.has_manager_permissions(): user_service.check_has_task_related(entity["project_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) entity = entities_service.get_entity(entity_id) is_revision_set_by_user = args["revision"] != 0 if not is_revision_set_by_user: revision = files_service.get_next_output_file_revision( entity_id, args["name"] ) else: revision = args["revision"] folder_path = file_tree_service.get_output_folder_path( entity, mode=args["mode"], output_type=output_type, task_type=task_type, name=args["name"], representation=args["representation"], sep=args["separator"], revision=args["revision"] ) file_name = file_tree_service.get_output_file_name( entity, mode=args["mode"], revision=revision, output_type=output_type, task_type=task_type, name=args["name"] ) except MalformedFileTreeException: return { "error": "Tree is not properly written, check modes and variables", "received_data": request.json, }, 400 return {"folder_path": folder_path, "file_name": file_name}, 200
def post(self, entity_id): args = self.get_arguments() try: entity = entities_service.get_entity(entity_id) user_service.check_project_access(entity["project_id"]) user_service.check_entity_access(entity_id) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) entity = entities_service.get_entity(entity_id) is_revision_set_by_user = args["revision"] != 0 if not is_revision_set_by_user: revision = files_service.get_next_output_file_revision( entity_id, args["name"]) else: revision = args["revision"] folder_path = file_tree_service.get_output_folder_path( entity, mode=args["mode"], output_type=output_type, task_type=task_type, name=args["name"], representation=args["representation"], sep=args["separator"], revision=args["revision"], ) file_name = file_tree_service.get_output_file_name( entity, mode=args["mode"], revision=revision, output_type=output_type, task_type=task_type, name=args["name"], ) except MalformedFileTreeException as exception: return ( { "message": str(exception), "received_data": request.json }, 400, ) return {"folder_path": folder_path, "file_name": file_name}, 200
def post(self, project_id, task_type_id): user_service.check_manager_project_access(project_id) task_type = tasks_service.get_task_type(task_type_id) asset_ids = request.json assets = [] if type(asset_ids) == list and len(asset_ids) > 0: for asset_id in asset_ids: asset = assets_service.get_asset(asset_id) if asset["project_id"] == project_id: assets.append(asset) else: criterions = query.get_query_criterions_from_request(request) criterions["project_id"] = project_id assets = assets_service.get_assets(criterions) tasks = tasks_service.create_tasks(task_type, assets) return tasks, 201
def create_and_update_tasks(self, tasks_update, entity, asset_creation=False): if tasks_update: tasks_map = {} if asset_creation: task_type_ids = self.get_task_types_for_asset_type( entity.entity_type_id) for task_type_id in task_type_ids: task = tasks_service.create_task({"id": task_type_id}, entity.serialize()) tasks_map[task_type_id] = task else: for task in tasks_service.get_tasks_for_asset(str(entity.id)): tasks_map[task["task_type_id"]] = task for task_update in tasks_update: if task_update["task_type_id"] not in tasks_map: task = tasks_service.create_task( tasks_service.get_task_type( task_update["task_type_id"]), entity.serialize(), ) tasks_map[task_update["task_type_id"]] = task task = tasks_map[task_update["task_type_id"]] if (task_update["comment"] is not None or task_update["task_status_id"] != task["task_status_id"]): try: comments_service.create_comment( self.current_user_id, task["id"], task_update["task_status_id"] or task["task_status_id"], task_update["comment"] or "", [], {}, "", ) except WrongParameterException: pass elif asset_creation: self.created_assets.append(entity.serialize())
def check_task_departement_access(task_id, person_id): """ Return true if current user is an admin or is a manager and is in team or is a supervisor in the department of the task or is an artist assigning himself in the department of the task. """ user = persons_service.get_current_user(relations=True) task = tasks_service.get_task(task_id) task_type = tasks_service.get_task_type(task["task_type_id"]) is_allowed = ( permissions.has_admin_permissions() or ( permissions.has_manager_permissions() and check_belong_to_project(task["project_id"]) ) or ( permissions.has_supervisor_permissions() and check_belong_to_project(task["project_id"]) and ( user["departments"] == [] or ( task_type["department_id"] in user["departments"] and len( set( persons_service.get_person(person_id)[ "departments" ] ) & set(user["departments"]) ) > 0 ) ) ) or ( check_belong_to_project(task["project_id"]) and task_type["department_id"] in user["departments"] and person_id == user["id"] ) ) if not is_allowed: raise permissions.PermissionDenied return is_allowed
def post(self, asset_instance_id, temporal_entity_id): args = self.get_arguments() asset_instance = assets_service.get_asset_instance(asset_instance_id) asset = entities_service.get_entity(asset_instance["asset_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) user_service.check_project_access(asset["project_id"]) next_revision_number = files_service.get_next_output_file_revision( asset["id"], output_type["id"], task_type["id"], args["name"], asset_instance_id=asset_instance["id"], temporal_entity_id=temporal_entity_id, ) return {"next_revision": next_revision_number}, 200
def create_and_update_tasks( self, tasks_update, entity, shot_creation=False ): if tasks_update: if shot_creation: tasks_map = { str(task_type.id): create_task( task_type.serialize(), entity.serialize() ) for task_type in self.task_types_in_project_for_shots } else: tasks_map = { task["task_type_id"]: task for task in get_tasks_for_shot(str(entity.id)) } for task_update in tasks_update: if task_update["task_type_id"] not in tasks_map: tasks_map[task_update["task_type_id"]] = create_task( get_task_type(task_update["task_type_id"]), entity.serialize(), ) task = tasks_map[task_update["task_type_id"]] if ( task_update["comment"] is not None or task_update["task_status_id"] != task["task_status_id"] ): try: create_comment( self.current_user_id, task["id"], task_update["task_status_id"] or task["task_status_id"], task_update["comment"] or "", [], {}, "", ) except WrongParameterException: pass elif shot_creation: self.created_shots.append(entity.serialize())
def post(self, asset_instance_id, temporal_entity_id): args = self.get_arguments() try: asset_instance = assets_service.get_asset_instance( asset_instance_id) entity = entities_service.get_entity(temporal_entity_id) asset = assets_service.get_asset(asset_instance["asset_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) user_service.check_project_access(asset["project_id"]) user_service.check_entity_access(asset["id"]) folder_path = file_tree_service.get_instance_folder_path( asset_instance, entity, output_type=output_type, task_type=task_type, mode=args["mode"], name=args["name"], representation=args["representation"], revision=args["revision"], sep=args["separator"], ) file_name = file_tree_service.get_instance_file_name( asset_instance, entity, output_type=output_type, task_type=task_type, mode=args["mode"], name=args["name"], revision=args["revision"], ) except MalformedFileTreeException as exception: return ( { "message": str(exception), "received_data": request.json }, 400, ) return {"folder_path": folder_path, "file_name": file_name}, 200
def post(self, asset_instance_id, temporal_entity_id): args = self.get_arguments() asset_instance = assets_service.get_asset_instance(asset_instance_id) asset = entities_service.get_entity(asset_instance["asset_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if not permissions.has_manager_permissions(): user_service.check_has_task_related(asset["project_id"]) next_revision_number = \ files_service.get_next_output_file_revision( asset["id"], output_type["id"], task_type["id"], args["name"], asset_instance_id=asset_instance["id"], temporal_entity_id=temporal_entity_id ) return {"next_revision": next_revision_number}, 200
def post(self, asset_instance_id): args = self.get_arguments() try: asset_instance = assets_service.get_asset_instance( asset_instance_id) asset = assets_service.get_asset(asset_instance["asset_id"]) output_type = files_service.get_output_type(args["output_type_id"]) task_type = tasks_service.get_task_type(args["task_type_id"]) if not permissions.has_manager_permissions(): user_service.check_has_task_related(asset["project_id"]) folder_path = file_tree_service.get_instance_folder_path( asset_instance, output_type=output_type, task_type=task_type, mode=args["mode"], name=args["name"], representation=args["representation"], revision=args["revision"], sep=args["separator"] ) file_name = file_tree_service.get_instance_file_name( asset_instance, output_type=output_type, task_type=task_type, mode=args["mode"], name=args["name"], revision=args["revision"] ) except MalformedFileTreeException as e: current_app.logger.error(e) return { "error": "Tree is not properly written, check modes and variables", "received_data": request.json, }, 400 return {"path": folder_path, "name": file_name}, 200
def get(self, task_id): task = tasks_service.get_task(task_id) if not permissions.has_manager_permissions(): user_service.check_has_task_related(task["project_id"]) task_type = tasks_service.get_task_type(task["task_type_id"]) project = projects_service.get_project(task["project_id"]) task_status = tasks_service.get_task_status(task["task_status_id"]) entity = entities_service.get_entity(task["entity_id"]) entity_type = entities_service.get_entity_type( entity["entity_type_id"]) assignees = [] for assignee_id in task["assignees"]: assignees.append(persons_service.get_person(assignee_id)) task.update({ "entity": entity, "task_type": task_type, "task_status": task_status, "project": project, "entity_type": entity_type, "persons": assignees, "type": "Task" }) try: assigner = persons_service.get_person(task["assigner_id"]) task["assigner"] = assigner except PersonNotFoundException: pass if entity["parent_id"] is not None: sequence = shots_service.get_sequence(entity["parent_id"]) task["sequence"] = sequence if sequence["parent_id"] is not None: episode = shots_service.get_episode(sequence["parent_id"]) task["episode"] = episode return task, 200
def check_supervisor_task_access(task, new_data={}): """ Return true if current user is a manager and has a task assigned related to the project of this task or is a supervisor and can modify data accorded to his departments """ is_allowed = False if permissions.has_admin_permissions() or ( permissions.has_manager_permissions() and check_belong_to_project(task["project_id"]) ): is_allowed = True elif permissions.has_supervisor_permissions() and check_belong_to_project( task["project_id"] ): # checks that the supervisor only modifies columns # for which he is authorized allowed_columns = set( ["priority", "start_date", "due_date", "estimation"] ) if len(set(new_data.keys()) - allowed_columns) == 0: user_departments = persons_service.get_current_user( relations=True )["departments"] if ( user_departments == [] or tasks_service.get_task_type(task["task_type_id"])[ "department_id" ] in user_departments ): is_allowed = True if not is_allowed: raise permissions.PermissionDenied return is_allowed