'Reverts an item to its last published version (recursively traversing all of its descendants).
If no published version exists, an InvalidVersionError is thrown.
If a published version exists but there is no draft version of this item or any of its descendants, this
method is a no-op. It is also a no-op if the root item is in DIRECT_ONLY_CATEGORIES.
:raises InvalidVersionError: if no published version exists for the location specified'

def revert_to_published(self, location, user_id=None):

    self._verify_branch_setting(ModuleStoreEnum.Branch.draft_preferred)
    _verify_revision_is_published(location)
    if (location.category in DIRECT_ONLY_CATEGORIES):
        return
    if (not self.has_item(location, revision=ModuleStoreEnum.RevisionOption.published_only)):
        raise InvalidVersionError(location)
    def delete_draft_only(root_location):
        '\n                                                Helper    function    that    calls    delete    on    the    specified    location    if    a    draft    version    of    the    item    exists.\n                                                If    no    draft    exists,    this    function    recursively    calls    itself    on    the    children    of    the    item.\n                                                '
        query = root_location.to_deprecated_son(prefix='_id.')
        del query['_id.revision']
        versions_found = self.collection.find(query, {'_id': True, 'definition.children': True}, sort=[SORT_REVISION_FAVOR_DRAFT])
        if (versions_found.count() > 1):
            published_version = [version for version in versions_found if (version.get('_id').get('revision') != MongoRevisionKey.draft)]
            if (len(published_version) > 0):
                self.update_parent_if_moved(root_location, published_version[0], delete_draft_only, user_id)
            self._delete_subtree(root_location, [as_draft], draft_only=True)
        elif (versions_found.count() == 1):
            item = versions_found[0]
            assert (item.get('_id').get('revision') != MongoRevisionKey.draft)
            for child in item.get('definition', {}).get('children', []):
                child_loc = Location.from_deprecated_string(child)
                delete_draft_only(child_loc)
    delete_draft_only(location)
