This content is archived. See latest version here

Last updated: Oct 21 2014

This document describes how to work with bundles and packages, in relation to the content model.

How it works

Bundle entries are represented by the EPiServer.Commerce.Linking.BundleEntry class and package entries are represented by the EPiServer.Commerce.Linking.PackageEntry class. Both are administered using the EPiServer.Commerce.Linking.ILinksRepository service.

The Target property of the BundleEntry or PackageEntry contains the ContentReference of the entry included in the bundle/package. The class also has a SortOrder property for ordering the entries, a GroupName property for grouping entries and a Quantity property containing the quantity of the entry included in the bundle/package. EPiServer.Commerce.Linking.EntryRelation contains default values that can be used: DefaultGroupName and DefaultQuantity.

A BundleEntry or PackageEntry is uniquely defined by the ContentReference in its Target property together with its Source property (referencing the bundle or package itself), i.e. the same entry can not be added more than once to the same bundle or package. Use the Quantity property to set the quantity of an entry in the bundle or package.

Getting the entries of a bundle/package

By calling the GetRelationsBySource method of ILinksRepository with the ContentReference of a bundle/package, and filtering for either BundleEntry or PackageEntry, you get the bundle/package entries:

C#
public IEnumerable<BundleEntry> ListBundleEntries(ContentReference referenceToBundle)
{
    var linksRepository = ServiceLocator.Current.GetInstance<ILinksRepository>();
    var allRelations = linksRepository.GetRelationsBySource(referenceToBundle);

    // Relations to bundle entries are of type BundleEntry
    var variations = allRelations.OfType<BundleEntry>().ToList();
    return variations;
}

Getting the bundle/package by an entry

By calling the GetRelationsByTarget method of ILinksRepository with the ContentReference of a catalog entry, and filtering for PackageEntry or BundleEntry you get the packages/bundles:

C#
public IEnumerable<BundleEntry> GetBundleByEntry(ContentReference entry)
{
    var linksRepository = ServiceLocator.Current.GetInstance<ILinksRepository>();
    var allRelations = linksRepository.GetRelationsByTarget(entry);

    // Relations to Product is ProductVariation
    return allRelations.OfType<BundleEntry>().ToList();
}

Adding an entry to a bundle/package

The UpdateRelations method or UpdateRelation extension method of ILinksRepository can be used to add new BundleEntry or PackageEntry objects to a bundle or package. The new entry has to have a Target ContentReference, a Source ContentReference and you probably want to specify a Quantity and Group.

C#
public void AddBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
{
    var linksRepository = ServiceLocator.Current.GetInstance<ILinksRepository>();

    var newBundleEntry = new BundleEntry
    {
        GroupName = "GroupX",
        Quantity = 1.0m,
        SortOrder = 100,
        Source = referenceToBundle,
        Target = referenceToProductOrVariation
    };

    linksRepository.UpdateRelation(newBundleEntry);
}

Updating an entry in a bundle/package

The UpdateRelations method or UpdateRelation extension method of ILinksRepository can also be used to update BundleEntry or PackageEntry objects, for example to update the Quantity. You can either construct a new object to replace the old (matched by the Source and Target properties), or use GetRelationsBySource to get the existing Relations, filter out the object you want to update, and pass it to UpdateRelation after changing the value.

C#
public void UpdateBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation, decimal newQuantity)
{
    var linksRepository = ServiceLocator.Current.GetInstance<ILinksRepository>();
    var allRelations = linksRepository.GetRelationsBySource(referenceToBundle);

    // Find the matching BundleEntry by comparing the target, ignoring versions since relations are not version specific
    var matchingEntry =
        allRelations.OfType<BundleEntry>()
                    .FirstOrDefault(r => r.Target.CompareToIgnoreWorkID(referenceToProductOrVariation));

    // Update if there was a matching entry
    if (matchingEntry != null)
    {
        // Set new data
        matchingEntry.Quantity = newQuantity;

        linksRepository.UpdateRelation(matchingEntry);
    }
}

Removing an entry from a bundle/package

By calling the RemoveRelations method or RemoveRelation extension method method of ILinksRepository with a BundleEntry or PackageEntry object matching an existing bundle/package entry, that entry will be removed from the bundle/package. You can either construct a matching object, or use GetRelationsBySource to get the existing Relations, filter out the object you want to remove, and pass it to RemoveRelation.

C#
public void RemoveBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
{
    var linksRepository = ServiceLocator.Current.GetInstance<ILinksRepository>();

    // Define a relation matching the one to remove, or use
    // GetRelations to find the one you want to remove and pass that to
    // RemoveRelation
    var relationToRemove = new BundleEntry
    {
        // Source is required here to match the correct relation
        Source = referenceToBundle,
        Target = referenceToProductOrVariation
    };

    // Removes matching BundleEntry, or no action if no match exists
    linksRepository.RemoveRelation(relationToRemove);
}

Do you have feedback on this documentation? Send an email to documentation@episerver.com. For development-related questions and discussions, refer to our Forums on https://world.episerver.com/forum/