Getting all non published variations

I got a question from a colleague today: A customer has multiple languages (8 of them). They need to make sure all variants are published in all languages. That is of course a reasonable request, but there is no feature builtin for such requirement. But good news is that can be done with ease. If you want to try this as practice, go ahead – I think it’s a good exercise for your Episerver Commerce-fu skills.

To do this task, we need the snippet to traverse the catalog from hereĀ https://leanpub.com/epicommercerecipes/read_sample

Basically, we will start from one point. Get all children nodes from it and go recursive, and also get all children of the desired type and return:

public virtual IEnumerable<T> GetEntriesRecursive<T>(ContentReference parentLink, CultureInfo defaultCulture) where T : EntryContentBase
    {
        foreach (var nodeContent in LoadChildrenBatched<NodeContent>(parentLink, defaultCulture))
        {
            foreach (var entry in GetEntriesRecursive<T>(nodeContent.ContentLink, defaultCulture))
            {
                yield return entry;
            }
        }

        foreach (var entry in LoadChildrenBatched<T>(parentLink, defaultCulture))
        {
            yield return entry;
        }
    }

    private IEnumerable<T> LoadChildrenBatched<T>(ContentReference parentLink, CultureInfo defaultCulture) where T : IContent
    {
        var start = 0;

        while (true)
        {
            var batch = _contentLoader.GetChildren<T>(parentLink, defaultCulture, start, 50);
            if (!batch.Any())
            {
                yield break;
            }

            foreach (var content in batch)
            {
                // Don't include linked products to avoid including them multiple times when traversing the catalog
                if (!parentLink.CompareToIgnoreWorkID(content.ParentLink))
                {
                    continue;
                }

                yield return content;
            }
            start += 50;
        }
    }

Now we need to check if each and every variation has publish version in all languages or not. That can be done via IContentVersionRepository.List and a bit of LINQ: We need to load all versions of a variant, group by language, and check if any language has no published versions. We are going to check on all catalogs, but you can of course limit to one, or even, to just a category:

            foreach (var catalogContent in catalogContents)
            {
                foreach (var variant in GetEntriesRecursive<VariationContent>(catalogContent.ContentLink, catalogContent.MasterLanguage))
                {
                    var versions = _contentVersionRepository.List(variant.ContentLink.ToReferenceWithoutVersion());
                    var missingLanguages = versions.GroupBy(l => l.LanguageBranch)
                        .Where(g => g.All(v => v.Status != VersionStatus.Published)).Select(v => v.Key);
                    if (missingLanguages.Any())
                    {
                        _log.Information($"Variant {variant.Code} with content link {variant.ContentLink} is not published in {String.Join(",", missingLanguages)}");
                    }
                }
            }

This can be made to a scheduled job which you can run daily/weekly to make sure all of your variants are published in all languages. Of course, it is not limited to just variants. You can change it to ProductContent as well. And instead of logging, you can send mail to responsible people to correct it – if you don’t want to publish automatically!

I’ll leave that part to you!

Leave a Reply

Your email address will not be published. Required fields are marked *