コード例 #1
0
        public List <XElement> GetParentXElements(Entity parentEntity, Configuration configuration)
        {
            List <XElement> elements = new List <XElement>();
            List <string>   parents  = new List <string>();

            if (parentEntity == null)
            {
                return(elements);
            }

            if (parentEntity.EntityType.Id == "Item" && configuration.ItemsToSkus)
            {
                parents = _epiElement.SkuItemIds(parentEntity, configuration);
            }
            else
            {
                parents.Add(parentEntity.Id.ToString(CultureInfo.InvariantCulture));
            }
            var channelPrefixHelper = new ChannelPrefixHelper(_context);

            foreach (var parent in parents)
            {
                XElement parentElement = new XElement("parent", channelPrefixHelper.GetEPiCodeWithChannelPrefix(parent, configuration));
                elements.Add(parentElement);
            }

            return(elements);
        }
コード例 #2
0
        private void DeleteEntityThatStillExistInChannel(Entity channelEntity, Entity targetEntity, Entity parentEnt, string linkTypeId, List <StructureEntity> existingEntities, string channelIdentifier, string folderDateTime, string resourceZipFile)
        {
            var channelHelper = new ChannelHelper(_context);

            Dictionary <string, Dictionary <string, bool> > entitiesToUpdate = new Dictionary <string, Dictionary <string, bool> >();

            var channelNodes = _context.ExtensionManager.ChannelService.GetAllChannelStructureEntitiesForType(channelEntity.Id, "ChannelNode").ToList();

            if (!channelNodes.Any() && parentEnt.EntityType.Id == "Channel")
            {
                channelNodes.Add(_context.ExtensionManager.ChannelService.GetAllStructureEntitiesForEntityInChannel(channelEntity.Id, parentEnt.Id).First());
            }

            List <string> linkEntityIds = new List <string>();

            if (channelHelper.LinkTypeHasLinkEntity(linkTypeId))
            {
                DeleteUtilConfig.ChannelStructureEntities = channelHelper.GetAllEntitiesInChannel(
                    channelEntity.Id,
                    DeleteUtilConfig.ExportEnabledEntityTypes);

                List <StructureEntity> newEntityNodes = channelHelper.FindEntitiesElementInStructure(DeleteUtilConfig.ChannelStructureEntities, parentEnt.Id, targetEntity.Id, linkTypeId);

                List <string> pars = new List <string>();
                if (parentEnt.EntityType.Id == "Item" && DeleteUtilConfig.ItemsToSkus)
                {
                    pars = _epiElement.SkuItemIds(parentEnt, DeleteUtilConfig);

                    if (DeleteUtilConfig.UseThreeLevelsInCommerce)
                    {
                        pars.Add(parentEnt.Id.ToString(CultureInfo.InvariantCulture));
                    }
                }
                else
                {
                    pars.Add(parentEnt.Id.ToString(CultureInfo.InvariantCulture));
                }

                List <string> targets = new List <string>();
                if (targetEntity.EntityType.Id == "Item" && DeleteUtilConfig.ItemsToSkus)
                {
                    targets = _epiElement.SkuItemIds(targetEntity, DeleteUtilConfig);

                    if (DeleteUtilConfig.UseThreeLevelsInCommerce)
                    {
                        targets.Add(targetEntity.Id.ToString(CultureInfo.InvariantCulture));
                    }
                }
                else
                {
                    targets.Add(targetEntity.Id.ToString(CultureInfo.InvariantCulture));
                }

                linkEntityIds = _epiApi.GetLinkEntityAssociationsForEntity(linkTypeId, channelEntity.Id, channelEntity, DeleteUtilConfig, pars, targets);

                linkEntityIds.RemoveAll(i => newEntityNodes.Any(n => i == _channelPrefixHelper.GetEPiCodeWithChannelPrefix(n.ParentId, DeleteUtilConfig)));
            }

            // Add the removed entity element together with all the underlying entity elements
            List <XElement> elementList = new List <XElement>();

            foreach (StructureEntity existingEntity in existingEntities)
            {
                XElement copyOfElement = new XElement(existingEntity.Type + "_" + existingEntity.EntityId);
                if (elementList.All(p => p.Name.LocalName != copyOfElement.Name.LocalName))
                {
                    elementList.Add(copyOfElement);
                }

                if (DeleteUtilConfig.ChannelEntities.ContainsKey(existingEntity.EntityId))
                {
                    foreach (Link outboundLinks in DeleteUtilConfig.ChannelEntities[existingEntity.EntityId].OutboundLinks)
                    {
                        XElement copyOfDescendant = new XElement(outboundLinks.Target.EntityType.Id + "_" + outboundLinks.Target.Id);
                        if (elementList.All(p => p.Name.LocalName != copyOfDescendant.Name.LocalName))
                        {
                            elementList.Add(copyOfDescendant);
                        }
                    }
                }
            }

            List <XElement> updatedElements = elementList;

            foreach (XElement element in updatedElements)
            {
                string elementEntityType = element.Name.LocalName.Split('_')[0];
                string elementEntityId   = element.Name.LocalName.Split('_')[1];

                Dictionary <string, bool> shouldExsistInChannelNodes = channelHelper.ShouldEntityExistInChannelNodes(int.Parse(elementEntityId), channelNodes, channelEntity.Id);

                if (elementEntityType == "Link")
                {
                    continue;
                }

                if (elementEntityType == "Item" && DeleteUtilConfig.ItemsToSkus)
                {
                    Entity deletedEntity = null;

                    try
                    {
                        deletedEntity = _context.ExtensionManager.DataService.GetEntity(
                            int.Parse(elementEntityId),
                            LoadLevel.DataOnly);
                    }
                    catch (Exception ex)
                    {
                        _context.Log(LogLevel.Warning, "Error when getting entity:" + ex);
                    }

                    if (deletedEntity != null)
                    {
                        List <XElement> skus = _epiElement.GenerateSkuItemElemetsFromItem(deletedEntity, DeleteUtilConfig);
                        foreach (XElement sku in skus)
                        {
                            XElement skuCode = sku.Element("Code");
                            if (skuCode != null && !entitiesToUpdate.ContainsKey(skuCode.Value))
                            {
                                entitiesToUpdate.Add(skuCode.Value, shouldExsistInChannelNodes);
                            }
                        }
                    }

                    if (!DeleteUtilConfig.UseThreeLevelsInCommerce)
                    {
                        continue;
                    }
                }

                if (!entitiesToUpdate.ContainsKey(elementEntityId))
                {
                    entitiesToUpdate.Add(elementEntityId, shouldExsistInChannelNodes);
                }
            }

            List <string> parents = new List <string> {
                parentEnt.Id.ToString(CultureInfo.InvariantCulture)
            };

            if (parentEnt.EntityType.Id == "Item")
            {
                if (DeleteUtilConfig.ItemsToSkus)
                {
                    parents = _epiElement.SkuItemIds(parentEnt, DeleteUtilConfig);

                    if (DeleteUtilConfig.UseThreeLevelsInCommerce)
                    {
                        parents.Add(parentEnt.Id.ToString(CultureInfo.InvariantCulture));
                    }
                }
            }

            XDocument updateXml = new XDocument(new XElement("xml", new XAttribute("action", "updated")));

            if (updateXml.Root != null)
            {
                List <XElement> parentElements = channelHelper.GetParentXElements(parentEnt, DeleteUtilConfig);
                foreach (var parentElement in parentElements)
                {
                    updateXml.Root.Add(parentElement);
                }
            }

            foreach (KeyValuePair <string, Dictionary <string, bool> > entityIdToUpdate in entitiesToUpdate)
            {
                foreach (string parentId in parents)
                {
                    _epiApi.UpdateEntryRelations(entityIdToUpdate.Key, channelEntity.Id, channelEntity, DeleteUtilConfig, parentId, entityIdToUpdate.Value, linkTypeId, linkEntityIds);
                }

                updateXml.Root?.Add(new XElement("entry", _channelPrefixHelper.GetEPiCodeWithChannelPrefix(entityIdToUpdate.Key, DeleteUtilConfig)));
            }


            if (!DocumentFileHelper.ZipDocumentAndUploadToAzure(XmlDocumentType.Catalog, updateXml, DeleteUtilConfig, folderDateTime))
            {
                _context.Log(LogLevel.Information, "Failed to zip and upload the catalog file to azure from delete utility DeleteEntityThatStillExistInChannel() method");
            }

            _context.Log(LogLevel.Debug, "catalog saved");
        }
コード例 #3
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);
                }
            }
        }