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); } }
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()); }
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))); }
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); } } }
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))); }
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); }
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); } }
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); } } }
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()); }
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); }
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); }
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); }
/// <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); }
/// <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); }
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); } } }