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):
                return True

        return False
    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)