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