public override async Task <EntityViewConditionsArgument> Run(EntityViewConditionsArgument arg, CommercePipelineExecutionContext context)
        {
            arg.ValidateEntity(ent => ent is EntityType);
            arg.ValidateDisplayView(viewName => viewName.Equals(GetMasterViewName(context), StringComparison.OrdinalIgnoreCase));
            arg.ValidateEditView(action => action.StartsWith("Edit-", StringComparison.OrdinalIgnoreCase));

            return(await Task.FromResult(arg));
        }
        public async override Task <EntityView> Run(EntityView entityView, CommercePipelineExecutionContext context)
        {
            Condition.Requires(entityView).IsNotNull($"{Name}: The argument cannot be null.");
            var request = this.viewCommander.CurrentEntityViewArgument(context.CommerceContext);

            if (request.Entity == null)
            {
                return(entityView);
            }

            var entityViewConditionsArgument = new EntityViewConditionsArgument(request.Entity, request.ViewName, entityView.Action);
            var result = await commander.Pipeline <IGetApplicableViewConditionsPipeline>().Run(entityViewConditionsArgument, context);

            // Only proceed if the current entity is supported
            if (!result.IsSupportedEntity)
            {
                return(entityView);
            }

            // Check if this is an edit view or display view
            if (!result.IsEditView && !result.IsDisplayView)
            {
                return(entityView);
            }

            var commerceEntity = request.Entity;
            var components     = commerceEntity.Components;

            // Get a list of all the component types that have been registered
            var viewableComponentTypes = this.commander.GetViewableComponentTypes(commerceEntity, request.ItemId, context.CommerceContext);

            if (!string.IsNullOrWhiteSpace(entityView.ItemId) && commerceEntity is SellableItem)
            {
                var variation = ((SellableItem)commerceEntity).GetVariation(entityView.ItemId);
                if (variation != null)
                {
                    components = variation.ChildComponents;
                }
            }

            CreateEntityViews(entityView, result, components, viewableComponentTypes);

            return(entityView);
        }
        private static void CreateEntityViews(EntityView entityView, EntityViewConditionsArgument result, IList <Sitecore.Commerce.Core.Component> components, IEnumerable <Type> viewableComponentTypes)
        {
            var targetView = entityView;

            foreach (var componentType in viewableComponentTypes)
            {
                System.Attribute[] attrs = System.Attribute.GetCustomAttributes(componentType);

                var component = components.SingleOrDefault(comp => comp.GetType() == componentType);

                if (attrs.SingleOrDefault(attr => attr is EntityViewAttribute) is EntityViewAttribute entityViewAttribute)
                {
                    // Check if the edit action was requested for this specific component type
                    var isEditViewForThisComponent = !string.IsNullOrEmpty(entityView.Action) && entityView.Action.Equals($"Edit-{componentType.FullName}", StringComparison.OrdinalIgnoreCase);

                    if (result.IsDisplayView)
                    {
                        // Create a new view and add it to the current entity view.
                        var view = new EntityView
                        {
                            Name          = componentType.FullName,
                            DisplayName   = entityViewAttribute?.ViewName ?? componentType.Name,
                            EntityId      = entityView.EntityId,
                            ItemId        = entityView.ItemId,
                            EntityVersion = entityView.EntityVersion
                        };

                        entityView.ChildViews.Add(view);

                        targetView = view;
                    }
                    else
                    {
                        targetView.DisplayName = entityViewAttribute?.ViewName ?? componentType.Name;
                    }

                    if (result.IsDisplayView || (result.IsEditView && isEditViewForThisComponent))
                    {
                        AddPropertiesToView(targetView, componentType, component, isEditViewForThisComponent);
                    }
                }
            }
        }
        public async override Task <EntityView> Run(EntityView entityView, CommercePipelineExecutionContext context)
        {
            Condition.Requires(entityView).IsNotNull($"{Name}: The argument cannot be null.");
            var request = this.viewCommander.CurrentEntityViewArgument(context.CommerceContext);

            if (request.Entity == null)
            {
                return(entityView);
            }

            var entityViewConditionsArgument = new EntityViewConditionsArgument(request.Entity, request.ViewName, entityView.Action);
            var result = await commander.Pipeline <IGetApplicableViewConditionsPipeline>().Run(entityViewConditionsArgument, context);

            // Only proceed if the current entity is supported
            if (!result.IsSupportedEntity)
            {
                return(entityView);
            }

            // Check if this is an edit view or display view
            if (!result.IsEditView && !result.IsDisplayView)
            {
                return(entityView);
            }

            List <Type> applicableComponentTypes = this.commander.GetApplicableComponentTypes(request.Entity, request.ItemId, context.CommerceContext);

            var targetView = entityView;

            var commerceEntity = request.Entity;
            var components     = request.Entity.Components;

            if (!string.IsNullOrWhiteSpace(entityView.ItemId) && commerceEntity is SellableItem)
            {
                var variation = ((SellableItem)commerceEntity).GetVariation(entityView.ItemId);
                if (variation != null)
                {
                    components = variation.ChildComponents;
                }
            }

            foreach (var componentType in applicableComponentTypes)
            {
                System.Attribute[] attrs = System.Attribute.GetCustomAttributes(componentType);

                var component = components.SingleOrDefault(comp => comp.GetType() == componentType);

                if (attrs.SingleOrDefault(attr => attr is EntityViewAttribute) is EntityViewAttribute entityViewAttribute)
                {
                    // Check if the edit action was requested for this specific component type
                    var isEditViewForThisComponent = !string.IsNullOrEmpty(entityView.Action) && entityView.Action.Equals($"Edit-{componentType.FullName}", StringComparison.OrdinalIgnoreCase);

                    if (result.IsDisplayView)
                    {
                        // Create a new view and add it to the current entity view.
                        var view = new EntityView
                        {
                            Name          = componentType.FullName,
                            DisplayName   = entityViewAttribute?.ViewName ?? componentType.Name,
                            EntityId      = entityView.EntityId,
                            ItemId        = entityView.ItemId,
                            EntityVersion = entityView.EntityVersion
                        };

                        entityView.ChildViews.Add(view);

                        targetView = view;
                    }
                    else
                    {
                        targetView.DisplayName = entityViewAttribute?.ViewName ?? componentType.Name;
                    }

                    if (result.IsDisplayView || (result.IsEditView && isEditViewForThisComponent))
                    {
                        var props = componentType.GetProperties();

                        foreach (var prop in props)
                        {
                            System.Attribute[] propAttributes = System.Attribute.GetCustomAttributes(prop);

                            if (propAttributes.SingleOrDefault(attr => attr is PropertyAttribute) is PropertyAttribute propAttr)
                            {
                                if (isEditViewForThisComponent || (!isEditViewForThisComponent && propAttr.ShowInList))
                                {
                                    var viewProperty = new ViewProperty
                                    {
                                        Name        = prop.Name,
                                        DisplayName = propAttr.DisplayName,
                                        RawValue    = component != null?prop.GetValue(component) : "",
                                                          IsReadOnly = !isEditViewForThisComponent && propAttr.IsReadOnly,
                                                          IsRequired = propAttr.IsRequired
                                    };

                                    targetView.Properties.Add(viewProperty);
                                }
                            }
                        }
                    }
                }
            }

            return(entityView);
        }