Example #1
0
        public void EpiCodeFieldUpdatedAddAssociationAndRelationsToDocument(XDocument doc, Entity updatedEntity, Configuration config, int channelId)
        {
            List <Link> links = new List <Link>();
            var         channelPrefixHelper = new ChannelPrefixHelper(_context);
            var         epiMappingHelper    = new EpiMappingHelper(_context);


            if (updatedEntity.EntityType.IsLinkEntityType)
            {
                links = _context.ExtensionManager.DataService.GetLinksForLinkEntity(updatedEntity.Id);
            }
            else
            {
                links = _context.ExtensionManager.DataService.GetLinksForEntity(updatedEntity.Id);
            }

            List <XElement> associationsElements = new List <XElement>();

            Dictionary <string, XElement> relationsElements = new Dictionary <string, XElement>();

            foreach (Link link in links)
            {
                var structureEntityList = _context.ExtensionManager.ChannelService.GetAllStructureEntitiesForEntityWithParentInChannel
                                              (channelId, link.Target.Id, link.Source.Id);

                if (!epiMappingHelper.IsRelation(
                        link.LinkType.SourceEntityTypeId,
                        link.LinkType.TargetEntityTypeId,
                        link.LinkType.Index,
                        config))
                {
                    foreach (StructureEntity structureEntity in structureEntityList)
                    {
                        if (!structureEntity.LinkEntityId.HasValue)
                        {
                            associationsElements.Add(_epiElement.CreateCatalogAssociationElement(
                                                         structureEntity,
                                                         null,
                                                         config));
                        }
                        else
                        {
                            associationsElements.Add(_epiElement.CreateCatalogAssociationElement(
                                                         structureEntity,
                                                         link.LinkEntity,
                                                         config));
                        }
                    }
                }
                else
                {
                    foreach (StructureEntity structureEntity in structureEntityList)
                    {
                        int parentNodeId = GetParentChannelNode(structureEntity, channelId);

                        if (parentNodeId == 0)
                        {
                            continue;
                        }

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

                        if (!relationsElements.ContainsKey(channelPrefixAndSkuId + "_" + channelPrefixAndParentNodeId))
                        {
                            relationsElements.Add(channelPrefixAndSkuId + "_" + channelPrefixAndParentNodeId,
                                                  _epiElement.CreateNodeEntryRelationElement(
                                                      parentNodeId.ToString(CultureInfo.InvariantCulture),
                                                      structureEntity.EntityId.ToString(),
                                                      structureEntity.SortOrder,
                                                      config));
                        }

                        string channelPrefixAndParent = channelPrefixHelper.GetEPiCodeWithChannelPrefix(structureEntity.ParentId, config);

                        if (!relationsElements.ContainsKey(channelPrefixAndSkuId + "_" + channelPrefixAndParent))
                        {
                            relationsElements.Add(channelPrefixAndSkuId + "_" + channelPrefixAndParent,
                                                  _epiElement.CreateEntryRelationElement(
                                                      structureEntity.ParentId.ToString(CultureInfo.InvariantCulture),
                                                      link.LinkType.SourceEntityTypeId,
                                                      structureEntity.EntityId.ToString(),
                                                      structureEntity.SortOrder, config));
                        }
                    }
                }
            }

            if (relationsElements.Any())
            {
                doc.Descendants("Relations").ElementAt(0).Add(new XAttribute("totalCount", relationsElements.Count), relationsElements.Values);
            }

            if (associationsElements.Any())
            {
                doc.Descendants("Associations").ElementAt(0).Add(new XAttribute("totalCount", associationsElements.Count), associationsElements);
            }
        }
Example #2
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);
                }
            }
        }