/// <summary>
        /// Should the achievement type process attempts if the given source entity has been modified in some way.
        /// </summary>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <param name="sourceEntity">The source entity.</param>
        /// <returns></returns>
        public override bool ShouldProcess(AchievementTypeCache achievementTypeCache, IEntity sourceEntity)
        {
            var interaction = sourceEntity as Interaction;

            if (interaction == null)
            {
                return(false);
            }

            var channel = GetInteractionChannelCache(achievementTypeCache);

            if (channel == null)
            {
                return(true);
            }

            var component = GetInteractionComponentCache(achievementTypeCache);

            if (component == null)
            {
                component = InteractionComponentCache.Get(interaction.InteractionComponentId);
                return(component.InteractionChannelId == channel.Id);
            }

            return(interaction.InteractionComponentId == component.Id);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the models from the delimited values.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="interactionChannel">The interactionChannel</param>
        /// <param name="interactionComponent">The interactionComponent</param>
        private void GetModelsFromAttributeValue(string value, out InteractionChannelCache interactionChannel, out InteractionComponentCache interactionComponent)
        {
            interactionChannel   = null;
            interactionComponent = null;

            ParseDelimitedGuids(value, out var interactionChannelGuid, out var interactionComponentGuid);

            if (interactionChannelGuid.HasValue || interactionComponentGuid.HasValue)
            {
                if (interactionChannelGuid.HasValue)
                {
                    interactionChannel = InteractionChannelCache.Get(interactionChannelGuid.Value);
                }

                if (interactionComponentGuid.HasValue)
                {
                    interactionComponent = InteractionComponentCache.Get(interactionComponentGuid.Value);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Reads new values entered by the user for the field ( as Guid )
        /// </summary>
        /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <returns></returns>
        public override string GetEditValue(Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            var interactionChannelInteractionComponentPicker = control as InteractionChannelInteractionComponentPicker;

            if (interactionChannelInteractionComponentPicker != null)
            {
                var  rockContext              = new RockContext();
                Guid?interactionChannelGuid   = null;
                Guid?interactionComponentGuid = null;

                if (interactionChannelInteractionComponentPicker.InteractionChannelId.HasValue)
                {
                    var channel = InteractionChannelCache.Get(interactionChannelInteractionComponentPicker.InteractionChannelId.Value);

                    if (channel != null)
                    {
                        interactionChannelGuid = channel.Guid;
                    }
                }

                if (interactionChannelInteractionComponentPicker.InteractionComponentId.HasValue)
                {
                    var component = InteractionComponentCache.Get(interactionChannelInteractionComponentPicker.InteractionComponentId.Value);

                    if (component != null)
                    {
                        interactionComponentGuid = component.Guid;
                    }
                }

                if (interactionChannelGuid.HasValue || interactionComponentGuid.HasValue)
                {
                    return(string.Format("{0}|{1}", interactionChannelGuid, interactionComponentGuid));
                }
            }

            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// BulkInserts Interaction Records
        /// </summary>
        /// <remarks>
        /// If any PersonAliasId references a PersonAliasId record that doesn't exist, the field value will be set to null.
        /// Also, if the InteractionComponent Id (or Guid) is specified, but references a Interaction Component record that doesn't exist
        /// the Interaction will not be recorded.
        /// </remarks>
        /// <param name="interactionsImport">The interactions import.</param>
        internal static void BulkInteractionImport(InteractionsImport interactionsImport)
        {
            if (interactionsImport == null)
            {
                throw new Exception("InteractionsImport must be assigned a value.");
            }

            var interactionImportList = interactionsImport.Interactions;

            if (interactionImportList == null || !interactionImportList.Any())
            {
                // if there aren't any return
                return;
            }

            /* 2020-05-14 MDP
             * Make sure that all the PersonAliasIds in the import exist in the database.
             * For performance reasons, look them up all at one and keep a list of valid ones.
             *
             * If there are any PersonAliasIds that aren't valid,
             * we decided that just set the PersonAliasId to null (we want ignore bad data).
             */

            HashSet <int> validPersonAliasIds = interactionsImport.GetValidPersonAliasIds();

            List <Interaction> interactionsToInsert = new List <Interaction>();

            foreach (InteractionImport interactionImport in interactionImportList)
            {
                if (interactionImport.Interaction == null)
                {
                    throw new ArgumentNullException("InteractionImport.Interaction can not be null");
                }

                // Determine which Channel this should be set to
                if (interactionImport.InteractionChannelId.HasValue)
                {
                    // make sure it is a valid Id
                    interactionImport.InteractionChannelId = InteractionChannelCache.Get(interactionImport.InteractionChannelId.Value)?.Id;
                }

                // Determine which Channel Type Medium this should be set to
                if (interactionImport.InteractionChannelChannelTypeMediumValueId.HasValue)
                {
                    // make sure it is a valid Id
                    interactionImport.InteractionChannelChannelTypeMediumValueId = DefinedValueCache.Get(interactionImport.InteractionChannelChannelTypeMediumValueId.Value)?.Id;
                }

                if (!interactionImport.InteractionChannelChannelTypeMediumValueId.HasValue)
                {
                    if (interactionImport.InteractionChannelChannelTypeMediumValueGuid.HasValue)
                    {
                        interactionImport.InteractionChannelChannelTypeMediumValueId = DefinedValueCache.GetId(interactionImport.InteractionChannelChannelTypeMediumValueGuid.Value);
                    }
                }

                if (!interactionImport.InteractionChannelId.HasValue)
                {
                    if (interactionImport.InteractionChannelGuid.HasValue)
                    {
                        interactionImport.InteractionChannelId = InteractionChannelCache.GetId(interactionImport.InteractionChannelGuid.Value);
                    }

                    // if InteractionChannelId is still null, lookup (or create) an InteractionChannel from InteractionChannelForeignKey (if it is specified)
                    if (interactionImport.InteractionChannelId == null && interactionImport.InteractionChannelForeignKey.IsNotNullOrWhiteSpace())
                    {
                        interactionImport.InteractionChannelId = InteractionChannelCache.GetCreateChannelIdByForeignKey(interactionImport.InteractionChannelForeignKey, interactionImport.InteractionChannelName, interactionImport.InteractionChannelChannelTypeMediumValueId);
                    }
                    else
                    {
                        /* 2020-05-14 MDP
                         *  Discussed this and decided that if we tried InteractionChannelId and InteractionChannelGuid, and InteractionChannelForeignKey was not specified,
                         *  we'll just skip over this record
                         */
                        continue;
                    }
                }

                // Determine which Component this should be set to
                if (interactionImport.InteractionComponentId.HasValue)
                {
                    // make sure it is a valid Id
                    interactionImport.InteractionComponentId = InteractionComponentCache.Get(interactionImport.InteractionComponentId.Value)?.Id;
                }

                if (!interactionImport.InteractionComponentId.HasValue)
                {
                    if (interactionImport.InteractionComponentGuid.HasValue)
                    {
                        interactionImport.InteractionComponentId = InteractionComponentCache.GetId(interactionImport.InteractionComponentGuid.Value);
                    }

                    // if InteractionComponentId is still null, lookup (or create) an InteractionComponent from the ForeignKey and ChannelId
                    if (interactionImport.InteractionComponentForeignKey.IsNotNullOrWhiteSpace())
                    {
                        interactionImport.InteractionComponentId = InteractionComponentCache.GetComponentIdByForeignKeyAndChannelId(
                            interactionImport.InteractionComponentForeignKey,
                            interactionImport.InteractionChannelId.Value,
                            interactionImport.InteractionComponentName);
                    }
                    else
                    {
                        /* 2020-05-14 MDP
                         *  Discussed this and decided that and if we tried InteractionComponentId and InteractionComponentGuid, and InteractionComponentForeignKey was not specified,
                         *  we'll just skip over this record
                         */
                        continue;
                    }
                }
            }

            foreach (InteractionImport interactionImport in interactionImportList.Where(a => a.InteractionComponentId.HasValue))
            {
                Interaction interaction = new Interaction
                {
                    InteractionComponentId = interactionImport.InteractionComponentId.Value
                };

                interaction.InteractionDateTime = interactionImport.Interaction.InteractionDateTime;

                // if operation is over 25, truncate it
                interaction.Operation = interactionImport.Interaction.Operation.Truncate(25);

                interaction.InteractionComponentId = interactionImport.InteractionComponentId.Value;
                interaction.EntityId = interactionImport.Interaction.EntityId;
                if (interactionImport.Interaction.RelatedEntityTypeId.HasValue)
                {
                    /* 2020-05-14 MDP
                     * We want to ignore bad data, so first see if the RelatedEntityTypeId exists by looking it up in a cache.
                     * If it doesn't exist, it'll set RelatedEntityTypeId to null (so that we don't get a database constraint error)
                     */

                    interaction.RelatedEntityTypeId = EntityTypeCache.Get(interactionImport.Interaction.RelatedEntityTypeId.Value)?.Id;
                }

                interaction.RelatedEntityId = interactionImport.Interaction.RelatedEntityId;

                if (interactionImport.Interaction.PersonAliasId.HasValue)
                {
                    /* 2020-05-14 MDP
                     * We want to ignore bad data, so see if the specified PersonAliasId exists in the validPersonAliasIds that we lookup up
                     * If it doesn't exist, we'll leave interaction.PersonAliasId null (so that we don't get a database constraint error)
                     */

                    if (validPersonAliasIds.Contains(interactionImport.Interaction.PersonAliasId.Value))
                    {
                        interaction.PersonAliasId = interactionImport.Interaction.PersonAliasId.Value;
                    }
                }

                // BulkImport doesn't include Session information TODO???
                interaction.InteractionSessionId = null;

                // if the summary is over 500 chars, truncate with addEllipsis=true
                interaction.InteractionSummary = interactionImport.Interaction.InteractionSummary.Truncate(500, true);

                interaction.InteractionData  = interactionImport.Interaction.InteractionData;
                interaction.PersonalDeviceId = interactionImport.Interaction.PersonalDeviceId;

                interaction.InteractionEndDateTime = interactionImport.Interaction.InteractionEndDateTime;

                // Campaign related fields, we'll truncate those if they are too long
                interaction.Source      = interactionImport.Interaction.Source.Truncate(25);
                interaction.Medium      = interactionImport.Interaction.Medium.Truncate(25);
                interaction.Campaign    = interactionImport.Interaction.Campaign.Truncate(50);
                interaction.Content     = interactionImport.Interaction.Content.Truncate(50);
                interaction.Term        = interactionImport.Interaction.Term.Truncate(50);
                interaction.ForeignId   = interactionImport.Interaction.ForeignId;
                interaction.ForeignKey  = interactionImport.Interaction.ForeignKey;
                interaction.ForeignGuid = interactionImport.Interaction.ForeignGuid;

                interaction.ChannelCustom1         = interactionImport.Interaction.ChannelCustom1.Truncate(500, true);
                interaction.ChannelCustom2         = interactionImport.Interaction.ChannelCustom2.Truncate(2000, true);
                interaction.ChannelCustomIndexed1  = interactionImport.Interaction.ChannelCustomIndexed1.Truncate(500, true);
                interaction.InteractionLength      = interactionImport.Interaction.InteractionLength;
                interaction.InteractionTimeToServe = interactionImport.Interaction.InteractionTimeToServe;

                interactionsToInsert.Add(interaction);
            }

            using (var rockContext = new RockContext())
            {
                rockContext.BulkInsert(interactionsToInsert);
            }

            // This logic is normally handled in the Interaction.PostSave method, but since the BulkInsert bypasses those
            // model hooks, streaks need to be updated here. Also, it is not necessary for this logic to complete before this
            // transaction can continue processing and exit, so update the streak using a task.

            // Only launch this task if there are StreakTypes configured that have interactions. Otherwise several
            // database calls are made only to find out there are no streak types defined.
            if (StreakTypeCache.All().Any(s => s.IsInteractionRelated))
            {
                // Ids do not exit for the interactions in the collection since they were bulk imported.
                // Read their ids from their guids and append the id.
                var insertedGuids = interactionsToInsert.Select(i => i.Guid).ToList();

                var interactionIds = new InteractionService(new RockContext()).Queryable()
                                     .Where(i => insertedGuids.Contains(i.Guid))
                                     .Select(i => new { i.Id, i.Guid })
                                     .ToList();

                foreach (var interactionId in interactionIds)
                {
                    var interaction = interactionsToInsert.Where(i => i.Guid == interactionId.Guid).FirstOrDefault();
                    if (interaction != null)
                    {
                        interaction.Id = interactionId.Id;
                    }
                }

                // Launch task
                interactionsToInsert.ForEach(i => Task.Run(() => StreakTypeService.HandleInteractionRecord(i.Id)));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Gets the component.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="channel">The channel.</param>
        /// <param name="entityId">The entity identifier.</param>
        /// <param name="identifier">The identifier.</param>
        /// <returns></returns>
        private InteractionComponentCache GetComponent(RockContext rockContext, InteractionChannelCache channel, int?entityId, string identifier)
        {
            if (channel != null)
            {
                if (entityId.HasValue)
                {
                    // Find by the Entity Id
                    int?interactionComponentId = new InteractionComponentService(rockContext)
                                                 .Queryable()
                                                 .AsNoTracking()
                                                 .Where(c => c.EntityId.HasValue && c.InteractionChannelId == channel.Id && c.EntityId.Value == entityId.Value)
                                                 .Select(c => c.Id)
                                                 .Cast <int?>()
                                                 .FirstOrDefault();

                    if (interactionComponentId != null)
                    {
                        return(InteractionComponentCache.Get(interactionComponentId.Value));
                    }
                }

                if (identifier.IsNotNullOrWhiteSpace())
                {
                    // Find by Id
                    int?id = identifier.AsIntegerOrNull();
                    if (id.HasValue)
                    {
                        var component = InteractionComponentCache.Get(id.Value);
                        if (component != null && component.InteractionChannelId == channel.Id)
                        {
                            return(component);
                        }
                    }

                    // Find by Guid
                    Guid?guid = identifier.AsGuidOrNull();
                    if (guid.HasValue)
                    {
                        var component = InteractionComponentCache.Get(guid.Value);
                        if (component != null && component.InteractionChannelId == channel.Id)
                        {
                            return(component);
                        }
                    }

                    if (!id.HasValue && !guid.HasValue)
                    {
                        // Find by Name
                        int?interactionComponentId = new InteractionComponentService(rockContext)
                                                     .Queryable()
                                                     .AsNoTracking()
                                                     .Where(c => c.InteractionChannelId == channel.Id)
                                                     .Where(c => c.Name.Equals(identifier, StringComparison.OrdinalIgnoreCase))
                                                     .Select(c => c.Id)
                                                     .Cast <int?>()
                                                     .FirstOrDefault();

                        if (interactionComponentId != null)
                        {
                            return(InteractionComponentCache.Get(interactionComponentId.Value));
                        }

                        // If still no match, and we have a name, create a new channel
                        using (var newRockContext = new RockContext())
                        {
                            var interactionComponent = new InteractionComponent();
                            interactionComponent.Name = identifier;
                            interactionComponent.InteractionChannelId = channel.Id;
                            new InteractionComponentService(newRockContext).Add(interactionComponent);
                            newRockContext.SaveChanges();

                            return(InteractionComponentCache.Get(interactionComponent.Id));
                        }
                    }
                }
            }

            return(null);
        }
Esempio n. 6
0
 /// <summary>
 /// Gets the cache object associated with this Entity
 /// </summary>
 /// <returns></returns>
 public IEntityCache GetCacheObject()
 {
     return(InteractionComponentCache.Get(this.Id));
 }
        /// <summary>
        /// Gets the interaction component cache.
        /// </summary>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <returns></returns>
        private InteractionComponentCache GetInteractionComponentCache(AchievementTypeCache achievementTypeCache)
        {
            var guid = GetInteractionComponentGuid(achievementTypeCache);

            return(guid.HasValue ? InteractionComponentCache.Get(guid.Value) : null);
        }