Packages and bundles
Describes how to work with bundles and packages with relation to the Optimizely Commerce Connect content model.
For an introduction to these concepts, see Packages and bundles in the user documentation.
- The
EPiServer.Commerce.Catalog.Linking.BundleEntry
class represents bundle entries. - The
EPiServer.Commerce.Catalog.Linking.PackageEntry
class represents package entries. - The
EPiServer.Commerce.Catalog.Linking.IRelationRepository
service administers each.
The Child
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 in the bundle/package.
EPiServer.Commerce.Catalog.Linking.EntryRelation
contains the following default values: DefaultGroupName
and DefaultQuantity
.
A BundleEntry
or PackageEntry
is uniquely defined by the ContentReference
in its Child
property together with its Parent
property (referencing the bundle or package itself). That is, you cannot add the same entry more than once to the same bundle or package.
Get the entries of a bundle/package
To get bundle/package entries, call the GetChildren
method of IRelationRepository
with the ContentReference
of a bundle/package.
Sample code
// Retrieve entries from a bundle
public IEnumerable<BundleEntry> ListBundleEntries(ContentReference referenceToBundle)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// Relations to bundle entries are of type BundleEntry
var bundleEntries = relationRepository.GetChildren<BundleEntry>(referenceToBundle);
return bundleEntries;
}
// Retrieve entries from a package
public IEnumerable<PackageEntry> ListPackageEntries(ContentReference referenceToPackage)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// Relations to package entries are of type PackageEntry
var packageEntries = relationRepository.GetChildren<PackageEntry>(referenceToPackage);
return packageEntries;
}
Or, you can get the bundle/package entry links from bundle/package content via bundle/package content extensions:
Sample code
public IEnumerable<ContentReference> ListBundleEntries(BundleContent bundleContent)
{
var bundleEntryLinks = bundleContent.GetEntries();
return bundleEntryLinks;
}
public IEnumerable<ContentReference> ListPackageEntries(PackageContent packageContent)
{
var packageEntryLinks = packageContent.GetEntries();
return packageEntryLinks;
}
Get the bundle/package by an entry
To get the packages/bundles, call the GetParents
method of IRelationRepository
with the ContentReference
of a catalog entry.
Sample code
public IEnumerable<BundleEntry> GetBundleByEntry(ContentReference entry)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// Relations between bundle and bundle entry is BundleEntry
var bundleRelations = relationRepository.GetParents<BundleEntry>(entry);
return bundleRelations;
}
public IEnumerable<PackageEntry> GetPackageByEntry(ContentReference entry)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// Relations between package and package entry is PackageEntry
var packageRelations = relationRepository.GetParents<PackageEntry>(entry);
return packageRelations;
}
Or, you can get the bundle/package links from a child item via entry content extensions:
Sample code
public IEnumerable<ContentReference> GetParentBundles(EntryContentBase entryContent)
{
var bundleLinks = entryContent.GetParentBundles();
return bundleLinks;
}
public IEnumerable<ContentReference> GetParentPackages(EntryContentBase entryContent)
{
var packageLinks = entryContent.GetParentPackages();
return packageLinks;
}
Add an entry to a bundle/package
To add BundleEntry
or PackageEntry
objects to a bundle or package, use the UpdateRelations
method or UpdateRelation
extension method of IRelationRepository
. The new entry must have a Child ContentReference
, a Parent ContentReference
, and you probably want to specify a Quantity
and Group
.
Sample code
public void AddBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
var newBundleEntry = new BundleEntry
{
GroupName = "GroupX",
Quantity = 1.0m,
SortOrder = 100,
Parent = referenceToBundle,
Child = referenceToProductOrVariation
};
relationRepository.UpdateRelation(newBundleEntry);
}
public void AddPackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
var newPackageEntry = new PackageEntry
{
GroupName = "GroupX",
Quantity = 1.0m,
SortOrder = 100,
Parent = referenceToPackage,
Child = referenceToPackageOrVariation
};
relationRepository.UpdateRelation(newPackageEntry);
}
Update an entry in a bundle/package
To update BundleEntry
or PackageEntry
objects, such as updating the Quantity
, use the UpdateRelations
method or the UpdateRelation
extension method of IRelationRepository
. You can construct a new object to replace the old one (matched by the Parent
and Child
properties). Or, use GetParents
to get the existing Relations
, filter out the object you want to update, and pass it to UpdateRelation
after changing the value.
Sample code
public void UpdateBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation, decimal newQuantity)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
var bundleEntries = relationRepository.GetChildren<BundleEntry>(referenceToBundle);
// Find the matching BundleEntry by comparing the child, ignoring versions since relations are not version specific
var matchingEntry = bundleEntries.FirstOrDefault(r => r.Child.CompareToIgnoreWorkID(referenceToProductOrVariation));
// Update if there was a matching entry
if (matchingEntry != null)
{
// Set new data
matchingEntry.Quantity = newQuantity;
relationRepository.UpdateRelation(matchingEntry);
}
}
public void UpdatePackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation, decimal newQuantity)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
var packageEntries = relationRepository.GetChildren<PackageEntry>(referenceToPackage);
// Find the matching PackageEntry by comparing the child, ignoring versions since relations are not version specific
var matchingEntry = packageEntries.FirstOrDefault(r => r.Child.CompareToIgnoreWorkID(referenceToPackageOrVariation));
// Update if there was a matching entry
if (matchingEntry != null)
{
// Set new data
matchingEntry.Quantity = newQuantity;
relationRepository.UpdateRelation(matchingEntry);
}
}
Remove an entry from a bundle/package
To remove an entry from a bundle/package, call the RemoveRelations
method or RemoveRelation
extension method of IRelationRepository
with a BundleEntry
or PackageEntry
object matching an existing bundle/package entry. You can construct a matching object, or use GetParents
to get the existing Relations
, to filter out the object you want to remove and pass it to RemoveRelation
.
Sample code
public void RemoveBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// 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
{
Parent = referenceToBundle,
Child = referenceToProductOrVariation
};
// Removes matching BundleEntry, or no action if no match exists
relationRepository.RemoveRelation(relationToRemove);
}
public void RemovePackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation)
{
var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
// 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 PackageEntry
{
Parent = referenceToPackage,
Child = referenceToPackageOrVariation
};
// Removes matching PackageEntry, or no action if no match exists
relationRepository.RemoveRelation(relationToRemove);
}
Updated 20 minutes ago