def undo_mapping(project_id: int, task_id: int, user_id: int, preferred_locale: str = "en") -> TaskDTO: """ Allows a user to Undo the task state they updated """ task = MappingService.get_task(task_id, project_id) if not MappingService._is_task_undoable(user_id, task): raise MappingServiceError("Undo not allowed for this user") current_state = TaskStatus(task.task_status) undo_state = TaskHistory.get_last_status(project_id, task_id, True) # Refer to last action for user of it. last_action = TaskHistory.get_last_action(project_id, task_id) StatsService.update_stats_after_task_state_change( project_id, last_action.user_id, current_state, undo_state, "undo") task.unlock_task( user_id, undo_state, f"Undo state from {current_state.name} to {undo_state.name}", True, ) return task.as_dto_with_instructions(preferred_locale)
def _is_task_undoable(logged_in_user_id: int, task: Task) -> bool: """ Determines if the current task status can be undone by the logged in user """ # Test to see if user can undo status on this task if logged_in_user_id and TaskStatus(task.task_status) not in [ TaskStatus.LOCKED_FOR_MAPPING, TaskStatus.LOCKED_FOR_VALIDATION, TaskStatus.READY, ]: last_action = TaskHistory.get_last_action(task.project_id, task.id) # User requesting task made the last change, so they are allowed to undo it. if last_action.user_id == int( logged_in_user_id ) or ProjectService.is_user_permitted_to_validate( task.project_id, logged_in_user_id): return True return False