private void AddEntryRelationElement(StructureEntity structureEntity,
                                             string skuCode,
                                             LinkType linkType)
        {
            var parentProduct = _entityService.GetParentProduct(structureEntity);

            if (parentProduct == null)
            {
                return;
            }

            var parentCode = _catalogCodeGenerator.GetEpiserverCode(parentProduct);

            if (skuCode == parentCode)
            {
                return;
            }

            var addedRelationsName = "EntryRelation_" + _catalogCodeGenerator.GetRelationName(skuCode, parentCode);

            if (_epiElementContainer.HasRelation(addedRelationsName))
            {
                return;
            }

            var entryRelationElement = _catalogElementFactory.CreateEntryRelationElement(parentCode, linkType.SourceEntityTypeId, skuCode, structureEntity.SortOrder);

            _epiElementContainer.AddRelation(entryRelationElement, addedRelationsName);

            IntegrationLogger.Write(LogLevel.Debug, $"Added EntryRelation for {skuCode} to product {parentCode}. Relation name: {addedRelationsName}.");
        }
        private void AddNormalAssociations(StructureEntity structureEntity)
        {
            var entityCode = _catalogCodeGenerator.GetEpiserverCode(structureEntity.EntityId);
            var parentCode = _catalogCodeGenerator.GetEpiserverCode(structureEntity.ParentId);

            var associationName = _epiMappingHelper.GetAssociationName(structureEntity);

            var associationKey = _catalogCodeGenerator.GetAssociationKey(entityCode, parentCode, associationName);

            if (_epiElementContainer.HasAssociation(associationKey))
            {
                return;
            }

            XElement existingAssociation = GetExistingAssociation(associationName, parentCode);

            if (existingAssociation != null)
            {
                XElement newElement = _catalogElementFactory.CreateAssociationElement(structureEntity);

                if (!existingAssociation.Descendants().Any(e => e.Name.LocalName == "EntryCode" && e.Value == entityCode))
                {
                    existingAssociation.Add(newElement);
                    _epiElementContainer.AddAssociationKey(associationKey);
                }
            }
            else
            {
                var associationElement = _catalogElementFactory.CreateCatalogAssociationElement(structureEntity);
                _epiElementContainer.AddAssociation(associationElement, associationKey);
            }
        }
Пример #3
0
        private bool BelongsInChannel(StructureEntity arg)
        {
            bool isRelation        = _mappingHelper.IsRelation(arg.LinkTypeIdFromParent);
            bool isChannelNodeLink = _mappingHelper.IsChannelNodeLink(arg.LinkTypeIdFromParent);

            return(isRelation || isChannelNodeLink);
        }
        public Entity GetParentChannelNode(StructureEntity structureEntity)
        {
            List <StructureEntity> channelNodesInPath = _entityService.GetChannelNodeStructureEntitiesInPath(structureEntity.Path);
            StructureEntity        entity             = channelNodesInPath.LastOrDefault();

            return(entity != null?_entityService.GetEntity(entity.EntityId, LoadLevel.DataOnly) : null);
        }
        public bool ItemHasParentInChannel(StructureEntity itemStructureEntity)
        {
            Entity parentProduct = _entityService.GetParentProduct(itemStructureEntity);
            List <StructureEntity> parentEntityStructureEntities = RemoteManager.ChannelService.GetAllStructureEntitiesForEntityInChannel(_config.ChannelId, parentProduct.Id);

            return(parentEntityStructureEntities != null && parentEntityStructureEntities.Any());
        }
Пример #6
0
        public int GetParentChannelNode(StructureEntity structureEntity, Configuration config)
        {
            int           entityId = 0;
            List <string> entities = structureEntity.Path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries).ToList();

            entities.RemoveAt(entities.Count - 1);
            entities.RemoveAt(0);
            if (entities.Count == 0)
            {
                return(entityId);
            }

            for (int index = entities.Count - 1; index > -1; index--)
            {
                int tempEntityId = int.Parse(entities[index]);

                StructureEntity foundStructureEntity = config.ChannelStructureEntities.Find(i => i.EntityId.Equals(tempEntityId));

                if (foundStructureEntity != null && foundStructureEntity.Type == "ChannelNode")
                {
                    entityId = tempEntityId;
                    break;
                }
            }

            return(entityId);
        }
        public ConnectorEvent ChannelEntityAdded(Entity channel, int entityId)
        {
            ConnectorEvent connectorEvent =
                ConnectorEventHelper.InitiateEvent(_config, ConnectorEventType.ChannelEntityAdded, $"Received entity added for entity {entityId} in channel {channel.DisplayName}", 0);

            var structureEntities = new List <StructureEntity>();
            List <StructureEntity> addedStructureEntities = _entityService.GetStructureEntitiesForEntityInChannel(_config.ChannelId, entityId);

            foreach (StructureEntity addedEntity in addedStructureEntities)
            {
                StructureEntity parentEntity = _entityService.GetParentStructureEntity(_config.ChannelId, addedEntity.ParentId, addedEntity.EntityId, addedStructureEntities);
                structureEntities.Add(parentEntity);
            }

            structureEntities.AddRange(addedStructureEntities);

            string targetEntityPath           = _entityService.GetTargetEntityPath(entityId, addedStructureEntities);
            List <StructureEntity> childLinks = _entityService.GetChildrenEntitiesInChannel(entityId, targetEntityPath);

            foreach (StructureEntity linkStructureEntity in childLinks)
            {
                List <StructureEntity> childLinkedEntities = _entityService.GetChildrenEntitiesInChannel(linkStructureEntity.EntityId, linkStructureEntity.Path);
                structureEntities.AddRange(childLinkedEntities);
            }

            structureEntities.AddRange(childLinks);

            PublishEntities(channel, connectorEvent, structureEntities);

            string channelName = _mappingHelper.GetNameForEntity(channel, 100);

            _epiApi.ImportUpdateCompleted(channelName, ImportUpdateCompletedEventType.EntityAdded, true);
            return(connectorEvent);
        }
        private void AddNodeEntryRelationElement(LinkType linkType, StructureEntity structureEntity, string skuCode)
        {
            IntegrationLogger.Write(LogLevel.Debug, $"For SKU {skuCode}: Found relation between {linkType.SourceEntityTypeId} and {linkType.TargetEntityTypeId} called {linkType.Id}");

            var parentNode = _channelHelper.GetParentChannelNode(structureEntity);

            if (parentNode == null)
            {
                return;
            }

            var parentCode   = _catalogCodeGenerator.GetEpiserverCode(parentNode);
            var relationName = "NodeEntryRelation_" + _catalogCodeGenerator.GetRelationName(skuCode, parentCode);

            if (_epiElementContainer.HasRelation(relationName))
            {
                return;
            }

            var relationElement = _catalogElementFactory.CreateNodeEntryRelation(parentCode, skuCode, structureEntity.SortOrder);

            _epiElementContainer.AddRelation(relationElement, relationName);

            IntegrationLogger.Write(LogLevel.Debug, $"Added NodeEntryRelation for EntryCode {skuCode}. Relation name: {relationName}.");
        }
 public XElement CreateAssociationElement(StructureEntity structureEntity)
 {
     return(new XElement(
                "Association",
                new XElement("EntryCode", _catalogCodeGenerator.GetEpiserverCode(structureEntity.EntityId)),
                new XElement("SortOrder", structureEntity.SortOrder),
                new XElement("Type", structureEntity.LinkTypeIdFromParent)));
 }
Пример #10
0
        private void AddItemToSkusAssociations(LinkType linkType,
                                               StructureEntity structureEntity,
                                               string skuId)
        {
            string associationName = _epiMappingHelper.GetAssociationName(structureEntity);

            Entity source = _entityService.GetEntity(structureEntity.ParentId, LoadLevel.DataOnly);

            List <string> skuCodes = _catalogElementFactory.SkuItemIds(source);

            for (var i = 0; i < skuCodes.Count; i++)
            {
                skuCodes[i] = _catalogCodeGenerator.GetPrefixedCode(skuCodes[i]);
            }

            foreach (string skuCode in skuCodes)
            {
                string associationKey = _catalogCodeGenerator.GetAssociationKey(skuCode, structureEntity.ParentId.ToString(), associationName);
                if (_epiElementContainer.HasAssociation(associationKey))
                {
                    continue;
                }

                XElement existingCatalogAssociationElement = _epiElementContainer.Associations.FirstOrDefault(
                    x => x.Element("Name")?.Value == associationName &&
                    x.Element("EntryCode")?.Value == skuCode);
                ;

                var associationElement = new XElement("Association",
                                                      new XElement("EntryCode", skuId),
                                                      new XElement("SortOrder", structureEntity.SortOrder),
                                                      new XElement("Type", linkType.Id));

                if (existingCatalogAssociationElement != null)
                {
                    if (existingCatalogAssociationElement.Descendants().Any(e => e.Name.LocalName == "EntryCode" && e.Value == skuId))
                    {
                        continue;
                    }

                    existingCatalogAssociationElement.Add(associationElement);
                    _epiElementContainer.AddAssociationKey(associationKey);
                }
                else
                {
                    var catalogAssociation = new XElement("CatalogAssociation",
                                                          new XElement("Name", associationName),
                                                          new XElement("Description", linkType.Id),
                                                          new XElement("SortOrder", structureEntity.SortOrder),
                                                          new XElement("EntryCode", skuCode),
                                                          associationElement);

                    _epiElementContainer.AddAssociation(catalogAssociation, associationKey);
                }
            }
        }
Пример #11
0
        public string GetAssociationName(StructureEntity structureEntity, Entity linkEntity, Configuration config)
        {
            if (structureEntity.LinkEntityId != null)
            {
                // Use the Link name + the display name to create a unique ASSOCIATION NAME in EPi Commerce
                return(linkEntity.EntityType.Id + '_'
                       + _businessHelper.GetDisplayNameFromEntity(linkEntity, config, -1).Replace(' ', '_'));
            }

            return(structureEntity.LinkTypeIdFromParent);
        }
        public XElement CreateCatalogAssociationElement(StructureEntity structureEntity, Dictionary <int, Entity> channelEntities = null)
        {
            string name = _mappingHelper.GetAssociationName(structureEntity);

            return(new XElement(
                       "CatalogAssociation",
                       new XElement("Name", name),
                       new XElement("Description", structureEntity.LinkTypeIdFromParent),
                       new XElement("SortOrder", structureEntity.SortOrder),
                       new XElement("EntryCode", _catalogCodeGenerator.GetEpiserverCode(structureEntity.ParentId)),
                       CreateAssociationElement(structureEntity)));
        }
Пример #13
0
        public string GetTargetEntityPath(int targetEntityId, List <StructureEntity> channelEntities, int?parentId = null)
        {
            StructureEntity targetStructureEntity = parentId == null
                ? channelEntities.Find(i => i.EntityId.Equals(targetEntityId))
                : channelEntities.Find(i => i.EntityId.Equals(targetEntityId) && i.ParentId.Equals(parentId));

            string path = String.Empty;

            if (targetStructureEntity != null)
            {
                path = targetStructureEntity.Path;
            }

            return(path);
        }
Пример #14
0
        public StructureEntity GetParentStructureEntity(int channelId, int sourceEntityId, int targetEntityId, List <StructureEntity> channelEntities)
        {
            StructureEntity        targetStructureEntity = channelEntities.Find(i => i.EntityId.Equals(targetEntityId) && i.ParentId.Equals(sourceEntityId));
            List <StructureEntity> structureEntities     = RemoteManager.ChannelService.GetAllStructureEntitiesForEntityInChannel(channelId, sourceEntityId);

            if (targetStructureEntity == null || !structureEntities.Any())
            {
                return(null);
            }

            int endIndex = targetStructureEntity.Path.LastIndexOf("/", StringComparison.InvariantCulture);

            string parentPath = targetStructureEntity.Path.Substring(0, endIndex);

            return(structureEntities.Find(i => i.Path.Equals(parentPath) && i.EntityId.Equals(sourceEntityId)));
        }
        private void AddChannelNodeRelation(LinkType linkType, StructureEntity structureEntity, Entity entity)
        {
            string addedRelationName = _catalogCodeGenerator.GetRelationName(entity.Id, structureEntity.ParentId);

            if (_epiElementContainer.HasRelation(addedRelationName))
            {
                return;
            }

            XElement relationElement = _catalogElementFactory.CreateNodeEntryRelation(structureEntity.ParentId, structureEntity.EntityId, structureEntity.SortOrder);

            _epiElementContainer.AddRelation(relationElement, addedRelationName);

            IntegrationLogger.Write(LogLevel.Debug,
                                    $"Added Relation for Source {structureEntity.ParentId} and Target {structureEntity.EntityId} for LinkTypeId {linkType.Id}");
        }
        private void AddAssociationElements(LinkType linkType,
                                            StructureEntity structureEntity,
                                            string itemCode)
        {
            if (!IsAssociationLinkType(linkType))
            {
                return;
            }

            if (!_config.UseThreeLevelsInCommerce && _config.ItemsToSkus && structureEntity.IsItem())
            {
                AddItemToSkusAssociations(linkType, structureEntity, itemCode);
            }
            else
            {
                AddNormalAssociations(structureEntity);
            }
        }
Пример #17
0
        private void AddRelations(LinkType linkType,
                                  StructureEntity structureEntity,
                                  Entity entity)
        {
            var skus = new List <string> {
                _catalogCodeGenerator.GetEpiserverCode(entity.Id)
            };

            int parentId = structureEntity.EntityId;

            if (structureEntity.IsItem() && _config.ItemsToSkus)
            {
                skus = _catalogElementFactory.SkuItemIds(entity);
                for (var i = 0; i < skus.Count; i++)
                {
                    skus[i] = _catalogCodeGenerator.GetPrefixedCode(skus[i]);
                }

                if (_config.UseThreeLevelsInCommerce)
                {
                    skus.Add(_catalogCodeGenerator.GetEpiserverCode(parentId));
                }
            }

            foreach (string skuId in skus)
            {
                if (_epiMappingHelper.IsRelation(linkType))
                {
                    AddNodeEntryRelationElement(linkType, structureEntity, skuId);
                    AddEntryRelationElement(structureEntity, skuId, linkType);
                }
                else
                {
                    if (_config.ForceIncludeLinkedContent)
                    {
                        AddMissingParentRelation(structureEntity, skuId);
                    }

                    IntegrationLogger.Write(LogLevel.Debug, "AddAssociationElements");
                    AddAssociationElements(linkType, structureEntity, skuId);
                }
            }
        }
Пример #18
0
        public async Task <ConnectorEvent> ChannelLinkUpdatedAsync(Entity channel, int sourceEntityId, int targetEntityId, string linkTypeId, int?linkEntityId)
        {
            List <StructureEntity> targetEntityStructure = _entityService.GetEntityInChannelWithParent(_config.ChannelId, targetEntityId, sourceEntityId);

            StructureEntity parentStructureEntity = _entityService.GetParentStructureEntity(_config.ChannelId, sourceEntityId, targetEntityId, targetEntityStructure);

            string channelName = _mappingHelper.GetNameForEntity(channel, 100);

            if (parentStructureEntity == null)
            {
                ConnectorEvent deleteEvent = ConnectorEventHelper.InitiateEvent(_config, ConnectorEventType.ChannelLinkDeleted,
                                                                                $"Received link deleted for sourceEntityId {sourceEntityId} and targetEntityId {targetEntityId} in channel {channel.DisplayName.Data}", 0);
                Entity removalTarget = _entityService.GetEntity(targetEntityId, LoadLevel.DataAndLinks);
                Entity removalSource = _entityService.GetEntity(sourceEntityId, LoadLevel.DataAndLinks);
                await DeleteLinkAsync(removalSource, removalTarget, linkTypeId, true);

                await _epiApi.DeleteCompletedAsync(channelName, DeleteCompletedEventType.LinkDeleted);

                return(deleteEvent);
            }

            ConnectorEvent connectorEvent = ConnectorEventHelper.InitiateEvent(_config, ConnectorEventType.ChannelLinkAdded,
                                                                               $"Received link update for sourceEntityId {sourceEntityId} and targetEntityId {targetEntityId} in channel {channel.DisplayName}.", 0);

            ConnectorEventHelper.UpdateEvent(connectorEvent, "Fetching channel entities...", 1);

            var structureEntities = new List <StructureEntity>
            {
                parentStructureEntity
            };

            List <StructureEntity> entities = _entityService.GetChildrenEntitiesInChannel(parentStructureEntity.EntityId, parentStructureEntity.Path);

            structureEntities.AddRange(entities);

            ConnectorEventHelper.UpdateEvent(connectorEvent, "Done fetching channel entities", 10);

            await PublishEntitiesAsync(channel, connectorEvent, structureEntities);

            await _epiApi.ImportUpdateCompletedAsync(channelName, ImportUpdateCompletedEventType.LinkUpdated, true);

            return(connectorEvent);
        }
        /// <summary>
        /// Items included only as upsell/accessories etc might not have their parent products/bundles in the channel.
        /// Add them if you're force including linked content.
        /// </summary>
        private void AddMissingParentRelation(StructureEntity structureEntity, string skuId)
        {
            var parentProduct = _entityService.GetParentProduct(structureEntity);

            if (parentProduct == null)
            {
                return;
            }

            var parentCode = _catalogCodeGenerator.GetEpiserverCode(parentProduct);
            var hasParent  = _epiElementContainer.Entries.Any(x => x.Element("Code")?.Value == parentCode);

            if (!hasParent)
            {
                IntegrationLogger.Write(LogLevel.Debug, $"Could not find parent for {skuId}, adding it to the list. Parent is {parentCode}.");
                var missingParent = _catalogElementFactory.InRiverEntityToEpiEntry(parentProduct);
                _epiElementContainer.Entries.Add(missingParent);
            }

            AddEntryRelationElement(structureEntity, skuId, new LinkType());
        }
Пример #20
0
        internal int GetParentChannelNode(StructureEntity structureEntity, int channelId)
        {
            int parentNodeId = 0;

            List <string> parentIds = structureEntity.Path.Split('/').ToList();

            parentIds.Reverse();
            parentIds.RemoveAt(0);

            for (int i = 0; i < parentIds.Count - 1; i++)
            {
                int entityId = int.Parse(parentIds[i]);
                int parentId = int.Parse(parentIds[i + 1]);

                var structureEntities = _context.ExtensionManager.ChannelService.GetAllStructureEntitiesForEntityWithParentInChannel(
                    channelId,
                    entityId,
                    parentId);

                foreach (var se in structureEntities)
                {
                    if (se.Type == "ChannelNode")
                    {
                        parentNodeId = se.EntityId;
                        break;
                    }
                }

                if (parentNodeId != 0)
                {
                    break;
                }
            }

            return(parentNodeId);
        }
Пример #21
0
        public Entity GetParentProduct(StructureEntity itemStructureEntity)
        {
            int entityId = itemStructureEntity.EntityId;

            if (_cachedParentEntities.ContainsKey(entityId))
            {
                return(_cachedParentEntities[entityId]);
            }

            List <Link> inboundLinks = RemoteManager.DataService.GetInboundLinksForEntity(entityId);
            Link        relationLink = inboundLinks.OrderBy(x => x.Index)
                                       .FirstOrDefault(x => _mappingHelper.IsRelation(x.LinkType));

            if (relationLink == null)
            {
                return(null);
            }

            Entity parent = GetEntity(relationLink.Source.Id, LoadLevel.DataOnly);

            _cachedParentEntities.Add(entityId, parent);

            return(parent);
        }
Пример #22
0
        private Dictionary <String, String> LoadMixedTypes(String baseFolder, IList <FrameworkEntity> entities)
        {
            this.Log(Level.Info, "Loading mixed types...");
            Dictionary <String, String> table = new Dictionary <String, String> ();

            foreach (var e in entities)
            {
                String sourcePath = e.GetPath(baseFolder, DocumentType.Model);
                if (sourcePath == null || !File.Exists(sourcePath))
                {
                    continue;
                }

                this.Log(Level.Verbose, String.Format("Scanning '{0}' for mixed types...", e.name));

                switch (e.type)
                {
                case FrameworkEntityType.T:
                {
                    TypedEntity entity = BaseEntity.LoadFrom <TypedEntity> (sourcePath);
                    this.AddMixedType(table, entity.Name, entity.MixedType);
                    foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                    {
                        this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType);
                    }
                }
                break;

                case FrameworkEntityType.C:
                {
                    ClassEntity entity = BaseEntity.LoadFrom <ClassEntity> (sourcePath);
                    this.AddMixedType(table, entity.Name, entity.MixedType);
                    foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                    {
                        this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType);
                    }
                }
                break;

                case FrameworkEntityType.P:
                {
                    ProtocolEntity entity = BaseEntity.LoadFrom <ProtocolEntity> (sourcePath);
                    this.AddMixedType(table, entity.Name, entity.MixedType);
                    foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                    {
                        this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType);
                    }
                }
                break;

                case FrameworkEntityType.S:
                {
                    StructureEntity entity = BaseEntity.LoadFrom <StructureEntity> (sourcePath);
                    this.AddMixedType(table, entity.Name, entity.MixedType);
                }
                break;

                case FrameworkEntityType.E:
                {
                    EnumerationEntity entity = BaseEntity.LoadFrom <EnumerationEntity> (sourcePath);
                    this.AddMixedType(table, entity.Name, entity.MixedType);
                }
                break;

                default:
                    throw new NotSupportedException("Entity type not support: " + e.type);
                }
            }
            this.Log(Level.Info, "Loaded {0} mixed types", table.Count);

            return(table);
        }
Пример #23
0
        /// <summary>
        /// Executes the task.
        /// </summary>
        protected override void ExecuteTask()
        {
            String baseFolder = this.CreateBaseDir();
            DocSet docSet     = this.CreateDocSet();
            IEnumerable <Framework> frameworks = this.CreateFrameworks(docSet);
            IList <FrameworkEntity> entities   = frameworks.SelectMany(f => f.GetEntities()).ToList();

            String mixedTypesFile = this.MixedTypesFile.ToString();
            Dictionary <String, String> mixedTypesTable = new Dictionary <String, String> ();

            this.LoadMixedTypes(mixedTypesFile, mixedTypesTable);

            foreach (var e in entities)
            {
                String sourcePath = e.GetPath(baseFolder, DocumentType.Model);
                if (sourcePath == null || !File.Exists(sourcePath))
                {
                    continue;
                }

                if (sourcePath.IsOlderThan(mixedTypesFile))
                {
                    continue;
                }

                this.Log(Level.Verbose, String.Format("Scanning '{0}' for mixed types...", e.name));

                switch (e.type)
                {
                case FrameworkEntityType.T:
                {
                    TypedEntity entity = BaseEntity.LoadFrom <TypedEntity> (sourcePath);
                    if (entity.Generate)
                    {
                        foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                        {
                            if (!enumerationEntity.Generate)
                            {
                                continue;
                            }
                            this.AddMixedType(mixedTypesTable, enumerationEntity);
                        }
                    }
                }
                break;

                case FrameworkEntityType.C:
                {
                    ClassEntity entity = BaseEntity.LoadFrom <ClassEntity> (sourcePath);
                    if (entity.Generate)
                    {
                        foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                        {
                            if (!enumerationEntity.Generate)
                            {
                                continue;
                            }
                            this.AddMixedType(mixedTypesTable, enumerationEntity);
                        }
                    }
                }
                break;

                case FrameworkEntityType.P:
                {
                    ProtocolEntity entity = BaseEntity.LoadFrom <ProtocolEntity> (sourcePath);
                    if (entity.Generate)
                    {
                        foreach (EnumerationEntity enumerationEntity in entity.Enumerations)
                        {
                            if (!enumerationEntity.Generate)
                            {
                                continue;
                            }
                            this.AddMixedType(mixedTypesTable, enumerationEntity);
                        }
                    }
                }
                break;

                case FrameworkEntityType.S:
                {
                    StructureEntity entity = BaseEntity.LoadFrom <StructureEntity> (sourcePath);
                    if (entity.Generate)
                    {
                        this.AddMixedType(mixedTypesTable, entity);
                    }
                }
                break;

                case FrameworkEntityType.E:
                {
                    EnumerationEntity entity = BaseEntity.LoadFrom <EnumerationEntity> (sourcePath);
                    if (entity.Generate)
                    {
                        this.AddMixedType(mixedTypesTable, entity);
                    }
                }
                break;

                default:
                    throw new NotSupportedException("Entity type not support: " + e.type);
                }
            }

            this.SaveMixedTypes(mixedTypesFile, mixedTypesTable);
        }
 internal static bool IsItem(this StructureEntity structureEntity)
 {
     return(structureEntity.Type == "Item");
 }
 /// <summary>
 /// Creates the unique name as required for by Episerver
 /// </summary>
 /// <param name="structureEntity"></param>
 /// <returns></returns>
 public string GetAssociationName(StructureEntity structureEntity)
 {
     return(structureEntity.LinkTypeIdFromParent);
 }
Пример #26
0
        /// <summary>
        /// Tells you whether or not a structure entity belongs in the channel, based on it's links.
        /// True for any entity that has a direct relation with either a product/bundle/package, or a channel node. False for
        /// anything that's ONLY included in the channel as upsell/accessories and the like (typically item-item-links or product-product-links).
        /// </summary>
        /// <param name="structureEntity">The StructureEntity to query.</param>
        /// <param name="allStructureEntities">Everything in the channel.</param>
        private bool FilterLinkedContentNotBelongingToChannelNode(StructureEntity structureEntity, List <StructureEntity> allStructureEntities)
        {
            IEnumerable <StructureEntity> sameEntityStructureEntities = allStructureEntities.Where(x => x.EntityId == structureEntity.EntityId);

            return(sameEntityStructureEntities.Any(BelongsInChannel));
        }
 internal static bool IsChannelNode(this StructureEntity structureEntity)
 {
     return(structureEntity.Type == "ChannelNode");
 }
 private bool ShouldCreateSkus(StructureEntity structureEntity)
 {
     return(structureEntity.IsItem() && _config.ItemsToSkus);
 }
Пример #29
0
        private void FillElements(List <StructureEntity> structureEntitiesBatch, Configuration config, List <string> addedEntities, List <string> addedNodes, List <string> addedRelations, Dictionary <string, List <XElement> > epiElements)
        {
            int logCounter          = 0;
            var channelPrefixHelper = new ChannelPrefixHelper(_context);


            Dictionary <string, LinkType> linkTypes = new Dictionary <string, LinkType>();

            foreach (LinkType linkType in config.LinkTypes)
            {
                if (!linkTypes.ContainsKey(linkType.Id))
                {
                    linkTypes.Add(linkType.Id, linkType);
                }
            }

            foreach (StructureEntity structureEntity in structureEntitiesBatch)
            {
                try
                {
                    if (structureEntity.EntityId == config.ChannelId)
                    {
                        continue;
                    }

                    logCounter++;

                    if (logCounter == 1000)
                    {
                        logCounter = 0;
                        _context.Log(LogLevel.Debug, "Generating catalog xml.");
                    }

                    int id = structureEntity.EntityId;

                    if (structureEntity.LinkEntityId.HasValue)
                    {
                        // Add the link entity

                        Entity linkEntity = null;

                        if (config.ChannelEntities.ContainsKey(structureEntity.LinkEntityId.Value))
                        {
                            linkEntity = config.ChannelEntities[structureEntity.LinkEntityId.Value];
                        }

                        if (linkEntity == null)
                        {
                            _context.Log(
                                LogLevel.Warning,
                                string.Format(
                                    "Link Entity with id {0} does not exist in system or ChannelStructure table is not in sync.",
                                    (int)structureEntity.LinkEntityId));
                            continue;
                        }

                        XElement entryElement = _epiElement.InRiverEntityToEpiEntry(linkEntity, config);

                        XElement codeElement = entryElement.Element("Code");
                        if (codeElement != null && !addedEntities.Contains(codeElement.Value))
                        {
                            epiElements["Entries"].Add(entryElement);
                            addedEntities.Add(codeElement.Value);

                            _context.Log(LogLevel.Debug, string.Format("Added Entity {0} to Entries", linkEntity.DisplayName));
                        }

                        if (!addedRelations.Contains(channelPrefixHelper.GetEPiCodeWithChannelPrefix(linkEntity.Id, config) + "_" + channelPrefixHelper.GetEPiCodeWithChannelPrefix("_inRiverAssociations", config)))
                        {
                            epiElements["Relations"].Add(
                                _epiElement.CreateNodeEntryRelationElement(
                                    "_inRiverAssociations",
                                    linkEntity.Id.ToString(CultureInfo.InvariantCulture),
                                    0,
                                    config));
                            addedRelations.Add(
                                channelPrefixHelper.GetEPiCodeWithChannelPrefix(linkEntity.Id, config) + "_"
                                + channelPrefixHelper.GetEPiCodeWithChannelPrefix("_inRiverAssociations", config));


                            _context.Log(LogLevel.Debug, string.Format("Added Relation for EntryCode {0}", channelPrefixHelper.GetEPiCodeWithChannelPrefix(linkEntity.Id, config)));
                        }
                    }

                    if (structureEntity.Type == "Resource")
                    {
                        continue;
                    }

                    Entity entity;

                    if (config.ChannelEntities.ContainsKey(id))
                    {
                        entity = config.ChannelEntities[id];
                    }
                    else
                    {
                        entity = _context.ExtensionManager.DataService.GetEntity(id, LoadLevel.DataOnly);

                        config.ChannelEntities.Add(id, entity);
                    }

                    if (entity == null)
                    {
                        //missmatch with entity data and ChannelStructure.

                        config.ChannelEntities.Remove(id);
                        continue;
                    }

                    if (structureEntity.Type == "ChannelNode")
                    {
                        string parentId = structureEntity.ParentId.ToString(CultureInfo.InvariantCulture);

                        if (config.ChannelId.Equals(structureEntity.ParentId))
                        {
                            _epiApi.CheckAndMoveNodeIfNeeded(id.ToString(CultureInfo.InvariantCulture), config);
                        }

                        _context.Log(LogLevel.Debug, string.Format("Trying to add channelNode {0} to Nodes", id));

                        XElement nodeElement = epiElements["Nodes"].Find(e =>
                        {
                            XElement xElement = e.Element("Code");
                            return(xElement != null && xElement.Value.Equals(channelPrefixHelper.GetEPiCodeWithChannelPrefix(entity.Id, config)));
                        });

                        int linkIndex = structureEntity.SortOrder;

                        if (nodeElement == null)
                        {
                            epiElements["Nodes"].Add(_epiElement.CreateNodeElement(entity, parentId, linkIndex, config));
                            addedNodes.Add(channelPrefixHelper.GetEPiCodeWithChannelPrefix(entity.Id, config));

                            _context.Log(LogLevel.Debug, string.Format("Added channelNode {0} to Nodes", id));
                        }
                        else
                        {
                            XElement parentNode = nodeElement.Element("ParentNode");
                            if (parentNode != null && (parentNode.Value != config.ChannelId.ToString(CultureInfo.InvariantCulture) && parentId == config.ChannelId.ToString(CultureInfo.InvariantCulture)))
                            {
                                string oldParent = parentNode.Value;
                                parentNode.Value = config.ChannelId.ToString(CultureInfo.InvariantCulture);
                                parentId         = oldParent;

                                XElement sortOrderElement = nodeElement.Element("SortOrder");
                                if (sortOrderElement != null)
                                {
                                    string oldSortOrder = sortOrderElement.Value;
                                    sortOrderElement.Value = linkIndex.ToString(CultureInfo.InvariantCulture);
                                    linkIndex = int.Parse(oldSortOrder);
                                }
                            }

                            if (!addedRelations.Contains(channelPrefixHelper.GetEPiCodeWithChannelPrefix(
                                                             id.ToString(CultureInfo.InvariantCulture),
                                                             config) + "_" + channelPrefixHelper.GetEPiCodeWithChannelPrefix(parentId, config)))
                            {
                                // add relation
                                epiElements["Relations"].Add(
                                    _epiElement.CreateNodeRelationElement(
                                        parentId,
                                        id.ToString(CultureInfo.InvariantCulture),
                                        linkIndex,
                                        config));

                                addedRelations.Add(
                                    channelPrefixHelper.GetEPiCodeWithChannelPrefix(
                                        id.ToString(CultureInfo.InvariantCulture),
                                        config) + "_" + channelPrefixHelper.GetEPiCodeWithChannelPrefix(parentId, config));

                                _context.Log(LogLevel.Debug, string.Format("Adding relation to channelNode {0}", id));
                            }
                        }

                        continue;
                    }

                    if (structureEntity.Type == "Item" && config.ItemsToSkus)
                    {
                        List <XElement> skus = _epiElement.GenerateSkuItemElemetsFromItem(entity, config);
                        foreach (XElement sku in skus)
                        {
                            XElement codeElement = sku.Element("Code");
                            if (codeElement != null && !addedEntities.Contains(codeElement.Value))
                            {
                                epiElements["Entries"].Add(sku);
                                addedEntities.Add(codeElement.Value);

                                _context.Log(LogLevel.Debug, string.Format("Added Item/SKU {0} to Entries", sku.Name.LocalName));
                            }
                        }
                    }

                    if ((structureEntity.Type == "Item" && config.ItemsToSkus && config.UseThreeLevelsInCommerce) ||
                        !(structureEntity.Type == "Item" && config.ItemsToSkus))
                    {
                        XElement element = _epiElement.InRiverEntityToEpiEntry(entity, config);

                        StructureEntity specificationStructureEntity =
                            config.ChannelStructureEntities.FirstOrDefault(
                                s => s.ParentId.Equals(id) && s.Type.Equals("Specification"));

                        if (specificationStructureEntity != null)
                        {
                            XElement metaField = new XElement(
                                "MetaField",
                                new XElement("Name", "SpecificationField"),
                                new XElement("Type", "LongHtmlString"));
                            foreach (KeyValuePair <CultureInfo, CultureInfo> culturePair in config.LanguageMapping)
                            {
                                string htmlData =
                                    _context.ExtensionManager.DataService.GetSpecificationAsHtml(
                                        specificationStructureEntity.EntityId,
                                        entity.Id,
                                        culturePair.Value);
                                metaField.Add(
                                    new XElement(
                                        "Data",
                                        new XAttribute("language", culturePair.Key.Name.ToLower()),
                                        new XAttribute("value", htmlData)));
                            }

                            XElement metaFieldsElement = element.Descendants().FirstOrDefault(f => f.Name == "MetaFields");
                            metaFieldsElement?.Add(metaField);
                        }

                        XElement codeElement = element.Element("Code");
                        if (codeElement != null && !addedEntities.Contains(codeElement.Value))
                        {
                            epiElements["Entries"].Add(element);
                            addedEntities.Add(codeElement.Value);

                            _context.Log(LogLevel.Debug, string.Format("Added Entity {0} to Entries", id));
                        }
                    }

                    List <StructureEntity> existingStructureEntities =
                        config.ChannelStructureEntities.FindAll(i => i.EntityId.Equals(id));

                    List <StructureEntity> filteredStructureEntities = new List <StructureEntity>();

                    foreach (StructureEntity se in existingStructureEntities)
                    {
                        if (!filteredStructureEntities.Exists(i => i.EntityId == se.EntityId && i.ParentId == se.ParentId))
                        {
                            filteredStructureEntities.Add(se);
                        }
                        else
                        {
                            if (se.LinkEntityId.HasValue)
                            {
                                if (!filteredStructureEntities.Exists(
                                        i =>
                                        i.EntityId == se.EntityId && i.ParentId == se.ParentId &&
                                        (i.LinkEntityId != null && i.LinkEntityId == se.LinkEntityId)))
                                {
                                    filteredStructureEntities.Add(se);
                                }
                            }
                        }
                    }

                    foreach (StructureEntity existingStructureEntity in filteredStructureEntities)
                    {
                        //Parent.
                        LinkType linkType = null;

                        if (linkTypes.ContainsKey(existingStructureEntity.LinkTypeIdFromParent))
                        {
                            linkType = linkTypes[existingStructureEntity.LinkTypeIdFromParent];
                        }

                        if (linkType == null)
                        {
                            continue;
                        }

                        if (linkType.SourceEntityTypeId == "ChannelNode")
                        {
                            if (!addedRelations.Contains(channelPrefixHelper.GetEPiCodeWithChannelPrefix(id.ToString(CultureInfo.InvariantCulture), config) + "_" + channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.ParentId.ToString(CultureInfo.InvariantCulture), config)))
                            {
                                epiElements["Relations"].Add(_epiElement.CreateNodeEntryRelationElement(existingStructureEntity.ParentId.ToString(), existingStructureEntity.EntityId.ToString(), existingStructureEntity.SortOrder, config));

                                addedRelations.Add(channelPrefixHelper.GetEPiCodeWithChannelPrefix(id, config) + "_" + channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.ParentId, config));

                                _context.Log(LogLevel.Debug, string.Format("Added Relation for Source {0} and Target {1} for LinkTypeId {2}", existingStructureEntity.ParentId, existingStructureEntity.EntityId, linkType.Id));
                            }

                            continue;
                        }

                        List <string> skus = new List <string> {
                            id.ToString(CultureInfo.InvariantCulture)
                        };
                        string parent = null;

                        if (structureEntity.Type.Equals("Item") && config.ItemsToSkus)
                        {
                            skus = _epiElement.SkuItemIds(entity, config);
                            for (int i = 0; i < skus.Count; i++)
                            {
                                skus[i] = channelPrefixHelper.GetEPiCodeWithChannelPrefix(skus[i], config);
                            }

                            if (config.UseThreeLevelsInCommerce)
                            {
                                parent = structureEntity.EntityId.ToString(CultureInfo.InvariantCulture);
                                skus.Add(parent);
                            }
                        }

                        Entity linkEntity = null;

                        if (existingStructureEntity.LinkEntityId != null)
                        {
                            if (config.ChannelEntities.ContainsKey(existingStructureEntity.LinkEntityId.Value))
                            {
                                linkEntity = config.ChannelEntities[existingStructureEntity.LinkEntityId.Value];
                            }
                            else
                            {
                                linkEntity = _context.ExtensionManager.DataService.GetEntity(
                                    existingStructureEntity.LinkEntityId.Value,
                                    LoadLevel.DataOnly);

                                config.ChannelEntities.Add(linkEntity.Id, linkEntity);
                            }
                        }

                        foreach (string skuId in skus)
                        {
                            string channelPrefixAndSkuId = channelPrefixHelper.GetEPiCodeWithChannelPrefix(skuId, config);

                            // prod -> item link, bundle, package or dynamic package => Relation
                            if (_epiMappingHelper.IsRelation(linkType.SourceEntityTypeId, linkType.TargetEntityTypeId, linkType.Index, config))
                            {
                                int parentNodeId = _channelHelper.GetParentChannelNode(structureEntity, config);
                                if (parentNodeId == 0)
                                {
                                    continue;
                                }

                                string channelPrefixAndParentNodeId = channelPrefixHelper.GetEPiCodeWithChannelPrefix(parentNodeId, config);

                                if (!addedRelations.Contains(channelPrefixAndSkuId + "_" + channelPrefixAndParentNodeId))
                                {
                                    epiElements["Relations"].Add(
                                        _epiElement.CreateNodeEntryRelationElement(
                                            parentNodeId.ToString(CultureInfo.InvariantCulture),
                                            skuId,
                                            existingStructureEntity.SortOrder,
                                            config));
                                    addedRelations.Add(channelPrefixAndSkuId + "_" + channelPrefixAndParentNodeId);

                                    _context.Log(
                                        LogLevel.Debug,
                                        string.Format("Added Relation for EntryCode {0}", channelPrefixAndSkuId));
                                }

                                string channelPrefixAndParentStructureEntityId =
                                    channelPrefixHelper.GetEPiCodeWithChannelPrefix(
                                        existingStructureEntity.ParentId.ToString(CultureInfo.InvariantCulture),
                                        config);

                                if (parent != null && skuId != parent)
                                {
                                    string channelPrefixAndParent = channelPrefixHelper.GetEPiCodeWithChannelPrefix(parent, config);

                                    if (!addedRelations.Contains(channelPrefixAndSkuId + "_" + channelPrefixAndParent))
                                    {
                                        epiElements["Relations"].Add(_epiElement.CreateEntryRelationElement(parent, linkType.SourceEntityTypeId, skuId, existingStructureEntity.SortOrder, config));
                                        addedRelations.Add(channelPrefixAndSkuId + "_" + channelPrefixAndParent);

                                        _context.Log(
                                            LogLevel.Debug,
                                            string.Format("Added Relation for ChildEntryCode {0}", channelPrefixAndSkuId));
                                    }
                                }
                                else if (!addedRelations.Contains(string.Format("{0}_{1}", channelPrefixAndSkuId, channelPrefixAndParentStructureEntityId)))
                                {
                                    epiElements["Relations"].Add(_epiElement.CreateEntryRelationElement(existingStructureEntity.ParentId.ToString(CultureInfo.InvariantCulture), linkType.SourceEntityTypeId, skuId, existingStructureEntity.SortOrder, config));
                                    addedRelations.Add(string.Format("{0}_{1}", channelPrefixAndSkuId, channelPrefixAndParentStructureEntityId));

                                    _context.Log(
                                        LogLevel.Debug,
                                        string.Format("Added Relation for ChildEntryCode {0}", channelPrefixAndSkuId));
                                }
                            }
                            else
                            {
                                if (!addedRelations.Contains(string.Format("{0}_{1}", channelPrefixAndSkuId, channelPrefixHelper.GetEPiCodeWithChannelPrefix("_inRiverAssociations", config))))
                                {
                                    epiElements["Relations"].Add(_epiElement.CreateNodeEntryRelationElement("_inRiverAssociations", skuId, existingStructureEntity.SortOrder, config));
                                    addedRelations.Add(string.Format("{0}_{1}", channelPrefixAndSkuId, channelPrefixHelper.GetEPiCodeWithChannelPrefix("_inRiverAssociations", config)));

                                    _context.Log(LogLevel.Debug, string.Format("Added Relation for EntryCode {0}", channelPrefixAndSkuId));
                                }

                                if (!config.UseThreeLevelsInCommerce && config.ItemsToSkus && structureEntity.Type == "Item")
                                {
                                    string channelPrefixAndLinkEntityId = channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.LinkEntityId, config);
                                    string associationName = _epiMappingHelper.GetAssociationName(existingStructureEntity, linkEntity, config);

                                    Entity source;

                                    if (config.ChannelEntities.ContainsKey(existingStructureEntity.ParentId))
                                    {
                                        source = config.ChannelEntities[existingStructureEntity.ParentId];
                                    }
                                    else
                                    {
                                        source = _context.ExtensionManager.DataService.GetEntity(
                                            existingStructureEntity.ParentId,
                                            LoadLevel.DataOnly);
                                        config.ChannelEntities.Add(source.Id, source);
                                    }

                                    List <string> sourceSkuIds = _epiElement.SkuItemIds(source, config);
                                    for (int i = 0; i < sourceSkuIds.Count; i++)
                                    {
                                        sourceSkuIds[i] = channelPrefixHelper.GetEPiCodeWithChannelPrefix(
                                            sourceSkuIds[i],
                                            config);
                                    }

                                    foreach (string sourceSkuId in sourceSkuIds)
                                    {
                                        bool exists;
                                        if (existingStructureEntity.LinkEntityId != null)
                                        {
                                            exists = epiElements["Associations"].Any(
                                                e =>
                                            {
                                                XElement entryCode   = e.Element("EntryCode");
                                                XElement description = e.Element("Description");
                                                return(description != null && entryCode != null && entryCode.Value.Equals(sourceSkuId) && e.Elements("Association").Any(
                                                           e2 =>
                                                {
                                                    XElement associatedEntryCode =
                                                        e2.Element("EntryCode");
                                                    return associatedEntryCode != null &&
                                                    associatedEntryCode.Value
                                                    .Equals(sourceSkuId);
                                                }) && description.Value.Equals(channelPrefixAndLinkEntityId));
                                            });
                                        }
                                        else
                                        {
                                            exists = epiElements["Associations"].Any(
                                                e =>
                                            {
                                                XElement entryCode = e.Element("EntryCode");
                                                return(entryCode != null && entryCode.Value.Equals(sourceSkuId) && e.Elements("Association").Any(
                                                           e2 =>
                                                {
                                                    XElement associatedEntryCode = e2.Element("EntryCode");
                                                    return associatedEntryCode != null && associatedEntryCode.Value.Equals(sourceSkuId);
                                                }) && e.Elements("Association").Any(
                                                           e3 =>
                                                {
                                                    XElement typeElement = e3.Element("Type");
                                                    return typeElement != null && typeElement.Value.Equals(linkType.Id);
                                                }));
                                            });
                                        }

                                        if (!exists)
                                        {
                                            XElement existingAssociation;

                                            if (existingStructureEntity.LinkEntityId != null)
                                            {
                                                existingAssociation = epiElements["Associations"].FirstOrDefault(
                                                    a =>
                                                {
                                                    XElement nameElement        = a.Element("Name");
                                                    XElement entryCodeElement   = a.Element("EntryCode");
                                                    XElement descriptionElement = a.Element("Description");
                                                    return(descriptionElement != null && entryCodeElement != null && nameElement != null && nameElement.Value.Equals(
                                                               associationName) && entryCodeElement.Value.Equals(sourceSkuId) && descriptionElement.Value.Equals(channelPrefixAndLinkEntityId));
                                                });
                                            }
                                            else
                                            {
                                                existingAssociation = epiElements["Associations"].FirstOrDefault(
                                                    a =>
                                                {
                                                    XElement nameElement      = a.Element("Name");
                                                    XElement entryCodeElement = a.Element("EntryCode");
                                                    return(entryCodeElement != null && nameElement != null && nameElement.Value.Equals(
                                                               associationName) && entryCodeElement.Value.Equals(sourceSkuId));
                                                });
                                            }

                                            XElement associationElement = new XElement(
                                                "Association",
                                                new XElement("EntryCode", skuId),
                                                new XElement("SortOrder", existingStructureEntity.SortOrder),
                                                new XElement("Type", linkType.Id));

                                            if (existingAssociation != null)
                                            {
                                                if (!existingAssociation.Descendants().Any(e => e.Name.LocalName == "EntryCode" && e.Value == skuId))
                                                {
                                                    existingAssociation.Add(associationElement);
                                                }
                                            }
                                            else
                                            {
                                                string description = existingStructureEntity.LinkEntityId == null
                                                                         ? linkType.Id
                                                                         : channelPrefixAndLinkEntityId;
                                                description = description ?? string.Empty;

                                                XElement catalogAssociation = new XElement(
                                                    "CatalogAssociation",
                                                    new XElement("Name", associationName),
                                                    new XElement("Description", description),
                                                    new XElement("SortOrder", existingStructureEntity.SortOrder),
                                                    new XElement("EntryCode", sourceSkuId),
                                                    associationElement);

                                                epiElements["Associations"].Add(catalogAssociation);
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    string channelPrefixAndEntityId       = channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.EntityId.ToString(CultureInfo.InvariantCulture), config);
                                    string channelPrefixAndParentEntityId = channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.ParentId.ToString(CultureInfo.InvariantCulture), config);

                                    string channelPrefixAndLinkEntityId = string.Empty;

                                    if (existingStructureEntity.LinkEntityId != null)
                                    {
                                        channelPrefixAndLinkEntityId = channelPrefixHelper.GetEPiCodeWithChannelPrefix(existingStructureEntity.LinkEntityId, config);
                                    }

                                    string associationName = _epiMappingHelper.GetAssociationName(existingStructureEntity, linkEntity, config);

                                    bool exists;
                                    if (existingStructureEntity.LinkEntityId != null)
                                    {
                                        exists = epiElements["Associations"].Any(
                                            e =>
                                        {
                                            XElement entryCodeElement   = e.Element("EntryCode");
                                            XElement descriptionElement = e.Element("Description");
                                            return(descriptionElement != null && entryCodeElement != null && entryCodeElement.Value.Equals(channelPrefixAndParentEntityId) && e.Elements("Association").Any(
                                                       e2 =>
                                            {
                                                XElement associatedEntryCode = e2.Element("EntryCode");
                                                return associatedEntryCode != null && associatedEntryCode.Value.Equals(channelPrefixAndEntityId);
                                            }) && descriptionElement.Value.Equals(channelPrefixAndLinkEntityId));
                                        });
                                    }
                                    else
                                    {
                                        exists = epiElements["Associations"].Any(
                                            e =>
                                        {
                                            XElement entryCodeElement = e.Element("EntryCode");
                                            return(entryCodeElement != null && entryCodeElement.Value.Equals(channelPrefixAndParentEntityId) && e.Elements("Association").Any(
                                                       e2 =>
                                            {
                                                XElement associatedEntryCode = e2.Element("EntryCode");
                                                return associatedEntryCode != null && associatedEntryCode.Value.Equals(channelPrefixAndEntityId);
                                            }) && e.Elements("Association").Any(
                                                       e3 =>
                                            {
                                                XElement typeElement = e3.Element("Type");
                                                return typeElement != null && typeElement.Value.Equals(linkType.Id);
                                            }));
                                        });
                                    }

                                    if (!exists)
                                    {
                                        XElement existingAssociation;

                                        if (existingStructureEntity.LinkEntityId != null)
                                        {
                                            existingAssociation = epiElements["Associations"].FirstOrDefault(
                                                a =>
                                            {
                                                XElement nameElement        = a.Element("Name");
                                                XElement entryCodeElement   = a.Element("EntryCode");
                                                XElement descriptionElement = a.Element("Description");
                                                return(descriptionElement != null && entryCodeElement != null && nameElement != null && nameElement.Value.Equals(associationName) && entryCodeElement.Value.Equals(
                                                           channelPrefixAndParentEntityId) && descriptionElement.Value.Equals(channelPrefixAndLinkEntityId));
                                            });
                                        }
                                        else
                                        {
                                            existingAssociation = epiElements["Associations"].FirstOrDefault(
                                                a =>
                                            {
                                                XElement nameElement      = a.Element("Name");
                                                XElement entryCodeElement = a.Element("EntryCode");
                                                return(entryCodeElement != null && nameElement != null && nameElement.Value.Equals(associationName) && entryCodeElement.Value.Equals(channelPrefixAndParentEntityId));
                                            });
                                        }

                                        if (existingAssociation != null)
                                        {
                                            XElement newElement = _epiElement.CreateAssociationElement(existingStructureEntity, config);

                                            if (!existingAssociation.Descendants().Any(
                                                    e =>
                                                    e.Name.LocalName == "EntryCode" &&
                                                    e.Value == channelPrefixAndEntityId))
                                            {
                                                existingAssociation.Add(newElement);
                                            }
                                        }
                                        else
                                        {
                                            epiElements["Associations"].Add(
                                                _epiElement.CreateCatalogAssociationElement(
                                                    existingStructureEntity,
                                                    linkEntity,
                                                    config));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _context.Log(LogLevel.Error, ex.Message, ex);
                }
            }
        }