Sometimes you may want to use an enum from Business Foundation on your product/variation. In my case the “Organization Customer Group” that can be set on an Organization.
For this you need a custom “SelectManyAttribute” and a “SelectionFactory”.
public sealed class MetaEnumSelectionAttribute : SelectManyAttribute, IMetadataAware
{
public string McDataTypeName { get; }
public MetaEnumSelectionAttribute(string mcDataTypeName)
{
this.McDataTypeName = mcDataTypeName;
}
public new void OnMetadataCreated(ModelMetadata metadata)
{
if (metadata == null)
{
return;
}
this.SelectionFactoryType = typeof(MetaEnumSelectionFactory);
base.OnMetadataCreated(metadata);
}
}
This attribute doe not do more than set the selection factory and the name of the enum you need.
public class MetaEnumSelectionFactory : ISelectionFactory
{
private static readonly ILogger Log = LogManager.GetLogger();
public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
try
{
MetaEnumSelectionAttribute metaEnumSelectionAttribute =
metadata.Attributes.OfType<MetaEnumSelectionAttribute>().SingleOrDefault();
MetaFieldType currentType = null;
if (metaEnumSelectionAttribute != null
&& !string.IsNullOrEmpty(metaEnumSelectionAttribute.McDataTypeName))
{
currentType =
DataContext.Current.MetaModel.RegisteredTypes.Cast<MetaFieldType>()
.FirstOrDefault(
type =>
type.McDataType == McDataType.Enum
&& type.Name.Equals(
metaEnumSelectionAttribute.McDataTypeName,
StringComparison.OrdinalIgnoreCase));
}
if (currentType == null)
{
return new List<ISelectItem>();
}
MetaEnumItem[] values = MetaEnum.GetItems(currentType);
return
values.Select(
metaEnumItem =>
new SelectItem
{
Text = MetaEnum.GetFriendlyName(currentType, metaEnumItem.Handle),
Value = metaEnumItem.Handle.ToString()
}).Cast<ISelectItem>().ToList();
}
catch (ArgumentNullException argumentNullException)
{
Log.Error(argumentNullException.Message, argumentNullException);
}
catch (ArgumentException argumentException)
{
Log.Error(argumentException.Message, argumentException);
}
catch (InvalidOperationException invalidOperationException)
{
Log.Error(invalidOperationException.Message, invalidOperationException);
}
catch (InvalidCastException invalidCastException)
{
Log.Error(invalidCastException.Message, invalidCastException);
}
return new List<ISelectItem>();
}
The selection factory gets the enum from the registered types in the context by the name specified in the attribute and returns a list of select items based on the items in the enum.
On your product/variation you can add property with the attribute, select the values and use them.
[MetaEnumSelection("ContactGroup")]
public virtual string Customergroups { get; set; }
The complete code can be found here