Ejemplo n.º 1
0
        /// <summary>
        /// Loads the drop down items.
        /// </summary>
        /// <param name="picker">The picker.</param>
        /// <param name="includeEmptyOption">if set to <c>true</c> [include empty option].</param>
        internal static void LoadDropDownItems(IInteractionComponentPicker picker, bool includeEmptyOption)
        {
            var selectedItems = picker.Items.Cast <ListItem>()
                                .Where(i => i.Selected)
                                .Select(i => i.Value)
                                .AsIntegerList();

            picker.Items.Clear();

            if (!picker.InteractionChannelId.HasValue)
            {
                return;
            }

            if (includeEmptyOption)
            {
                // add Empty option first
                picker.Items.Add(new ListItem());
            }

            var rockContext = new RockContext();
            var interactionComponentService = new InteractionComponentService(rockContext);
            var components = interactionComponentService.Queryable().AsNoTracking()
                             .Where(ic => ic.InteractionChannelId == picker.InteractionChannelId.Value)
                             .OrderBy(ic => ic.Name)
                             .ToList();

            foreach (var component in components)
            {
                var li = new ListItem(component.Name, component.Id.ToString());
                li.Selected = selectedItems.Contains(component.Id);
                picker.Items.Add(li);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the selection.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="controls">The controls.</param>
        /// <returns></returns>
        public override string GetSelection(Type entityType, Control[] controls)
        {
            var ddlInteractionChannel   = (controls[0] as RockDropDownList);
            var ddlInteractionComponent = (controls[1] as RockDropDownList);
            var tbOperation             = (controls[2] as RockTextBox);
            var slidingDateRangePicker  = (controls[3] as SlidingDateRangePicker);


            int  interactionChannelId   = ddlInteractionChannel.SelectedValueAsId() ?? 0;
            var  rockContext            = new RockContext();
            var  interactionChannel     = new InteractionChannelService(rockContext).Get(interactionChannelId);
            Guid?interactionChannelGuid = null;

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

            int  interactionComponentId   = ddlInteractionComponent.SelectedValueAsId() ?? 0;
            var  interactionComponent     = new InteractionComponentService(rockContext).Get(interactionComponentId);
            Guid?interactionComponentGuid = null;

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

            // convert pipe to comma delimited
            var delimitedValues = slidingDateRangePicker.DelimitedValues.Replace("|", ",");

            return($"{interactionChannelGuid.ToString()}|{interactionComponentGuid}|{tbOperation.Text}|{delimitedValues}");
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the component identifier by channel identifier and component entity identifier, and creates it if it doesn't exist.
        /// </summary>
        /// <param name="interactionChannelId">The interaction channel identifier.</param>
        /// <param name="componentEntityId">The component entity identifier.</param>
        /// <param name="componentName">Name of the component. This value will only be used if a new record is created.</param>
        /// <returns></returns>
        public static int GetComponentIdByChannelIdAndEntityId(int interactionChannelId, int?componentEntityId, string componentName)
        {
            var lookupKey = $"{interactionChannelId}|{componentEntityId}";

            if (_interactionComponentLookupComponentIdByEntityId.TryGetValue(lookupKey, out int componentId))
            {
                return(componentId);
            }

            using (var rockContext = new RockContext())
            {
                int?interactionComponentId = null;
                var interactionComponent   = new InteractionComponentService(rockContext).GetComponentByChannelIdAndEntityId(interactionChannelId, componentEntityId, componentName);

                // If a new component was added above we need to save the change
                rockContext.SaveChanges();

                if (interactionComponent != null)
                {
                    interactionComponentId = Get(interactionComponent).Id;
                    _interactionComponentLookupComponentIdByEntityId.AddOrUpdate(lookupKey, interactionComponent.Id, (k, v) => interactionComponent.Id);
                }

                return(interactionComponentId.Value);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the interaction component ids.
        /// </summary>
        /// <returns></returns>
        private List <int> GetInteractionComponentIds()
        {
            if (_interactionComponentIds == null)
            {
                var pageCache = GetPageCache();

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

                var rockContext = new RockContext();
                var interactionComponentService = new InteractionComponentService(rockContext);
                var channelMediumTypeValueId    = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE).Id;

                _interactionComponentIds = interactionComponentService.Queryable()
                                           .AsNoTracking()
                                           .Where(ic => ic.InteractionChannel.ChannelTypeMediumValueId == channelMediumTypeValueId)
                                           .Where(ic => ic.EntityId == pageCache.Id)
                                           .Select(ic => ic.Id)
                                           .ToList();
            }

            return(_interactionComponentIds);
        }
        /// <summary>
        /// Gets the selection.
        /// </summary>
        /// <param name="controls">The controls.</param>
        /// <returns></returns>
        public override string GetSelection(System.Web.UI.Control[] controls)
        {
            var ddlInteractionChannel   = (controls[0] as RockDropDownList);
            var ddlInteractionComponent = (controls[1] as RockDropDownList);
            var tbOperation             = (controls[2] as RockTextBox);
            var rblSelectionMode        = (controls[3] as RockRadioButtonList);

            int  interactionChannelId   = ddlInteractionChannel.SelectedValueAsId() ?? 0;
            var  rockContext            = new RockContext();
            var  interactionChannel     = new InteractionChannelService(rockContext).Get(interactionChannelId);
            Guid?interactionChannelGuid = null;

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

            int  interactionComponentId   = ddlInteractionComponent.SelectedValueAsId() ?? 0;
            var  interactionComponent     = new InteractionComponentService(rockContext).Get(interactionComponentId);
            Guid?interactionComponentGuid = null;

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

            return($"{interactionChannelGuid.ToString()}|{interactionComponentGuid}|{tbOperation.Text}|{rblSelectionMode.SelectedValue}");
        }
Ejemplo n.º 6
0
        private static int LoadByGuid2(Guid guid, RockContext rockContext)
        {
            var interactionComponentService = new InteractionComponentService(rockContext);

            return(interactionComponentService
                   .Queryable().AsNoTracking()
                   .Where(c => c.Guid.Equals(guid))
                   .Select(c => c.Id)
                   .FirstOrDefault());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Generates the receipt.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        protected InteractionComponent GenerateReceipt(RockContext rockContext)
        {
            var interactionService = new InteractionService(rockContext);
            var receipt            = new InteractionComponent();

            new InteractionComponentService(rockContext).Add(receipt);

            receipt.ChannelId        = InteractionChannelCache.Get(com.shepherdchurch.CubeDown.SystemGuid.InteractionChannel.CUBE_DOWN_RECEIPTS.AsGuid()).Id;
            receipt.Name             = "Temporary Receipt";
            receipt.ComponentSummary = string.Format("Total {0:c}", Cart.Total);

            if (Customer != null)
            {
                receipt.EntityId = Customer.PrimaryAliasId;
            }

            foreach (var item in Cart.Items)
            {
                var interaction = new Interaction
                {
                    EntityId            = null,
                    Operation           = "Buy",
                    InteractionDateTime = RockDateTime.Now,
                    InteractionData     = item.ToJson()
                };

                if (item.Quantity == 1)
                {
                    interaction.InteractionSummary = item.Name;
                }
                else
                {
                    interaction.InteractionSummary = string.Format("{0} (qty {1})", item.Name, item.Quantity);
                }

                interactionService.Add(interaction);
            }

            rockContext.SaveChanges();

            receipt = new InteractionComponentService(rockContext).Get(receipt.Id);

            var receiptCode = ReceiptHelper.EncodeReceiptCode(receipt);

            Cart.ReceiptCode = receiptCode;

            receipt.Name          = string.Format("Receipt #{0}", receiptCode);
            receipt.ComponentData = Cart.ToJson();

            rockContext.SaveChanges();


            return(receipt);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Shows the list.
        /// </summary>
        public void ShowList(int componentId)
        {
            int pageSize = GetAttributeValue("PageSize").AsInteger();

            int skipCount = pageNumber * pageSize;

            using (var rockContext = new RockContext())
            {
                var component = new InteractionComponentService(rockContext).Get(componentId);
                if (component != null && (UserCanEdit || component.IsAuthorized(Authorization.VIEW, CurrentPerson)))
                {
                    var interactions = new InteractionService(rockContext)
                                       .Queryable().AsNoTracking()
                                       .Where(a =>
                                              a.InteractionComponentId == componentId)
                                       .OrderByDescending(a => a.InteractionDateTime)
                                       .Skip(skipCount)
                                       .Take(pageSize + 1);

                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                    mergeFields.AddOrIgnore("Person", CurrentPerson);
                    mergeFields.Add("InteractionDetailPage", LinkedPageRoute("InteractionDetailPage"));
                    mergeFields.Add("InteractionChannel", component.Channel);
                    mergeFields.Add("InteractionComponent", component);
                    mergeFields.Add("Interactions", interactions.ToList().Take(pageSize));

                    // set next button
                    if (interactions.Count() > pageSize)
                    {
                        Dictionary <string, string> queryStringNext = new Dictionary <string, string>();
                        queryStringNext.Add("ComponentId", componentId.ToString());
                        queryStringNext.Add("Page", (pageNumber + 1).ToString());

                        var pageReferenceNext = new Rock.Web.PageReference(CurrentPageReference.PageId, CurrentPageReference.RouteId, queryStringNext);
                        mergeFields.Add("NextPageNavigateUrl", pageReferenceNext.BuildUrl());
                    }

                    // set prev button
                    if (pageNumber != 0)
                    {
                        Dictionary <string, string> queryStringPrev = new Dictionary <string, string>();
                        queryStringPrev.Add("ComponentId", componentId.ToString());
                        queryStringPrev.Add("Page", (pageNumber - 1).ToString());

                        var pageReferencePrev = new Rock.Web.PageReference(CurrentPageReference.PageId, CurrentPageReference.RouteId, queryStringPrev);
                        mergeFields.Add("PreviousPageNavigateUrl", pageReferencePrev.BuildUrl());
                    }

                    lContent.Text = component.Channel.InteractionListTemplate.IsNotNullOrWhitespace() ?
                                    component.Channel.InteractionListTemplate.ResolveMergeFields(mergeFields) :
                                    GetAttributeValue("DefaultTemplate").ResolveMergeFields(mergeFields);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Returns breadcrumbs specific to the block that should be added to navigation
        /// based on the current page reference.  This function is called during the page's
        /// oninit to load any initial breadcrumbs.
        /// </summary>
        /// <param name="pageReference">The <see cref="T:Rock.Web.PageReference" />.</param>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.List`1" /> of block related <see cref="T:Rock.Web.UI.BreadCrumb">BreadCrumbs</see>.
        /// </returns>
        public override List <BreadCrumb> GetBreadCrumbs(PageReference pageReference)
        {
            _rockContext      = new RockContext();
            _componentService = new InteractionComponentService(_rockContext);
            _component        = _componentService.Get(PageParameter("ComponentId").AsInteger());

            var breadCrumbs = new List <BreadCrumb>();

            breadCrumbs.Add(new BreadCrumb(_component != null ? _component.Name : "Component", pageReference));
            return(breadCrumbs);
        }
Ejemplo n.º 10
0
        private static InteractionComponentCache LoadById2(int id, RockContext rockContext)
        {
            var interactionComponentService = new InteractionComponentService(rockContext);
            var interactionComponentModel   = interactionComponentService.Get(id);

            if (interactionComponentModel != null)
            {
                return(new InteractionComponentCache(interactionComponentModel));
            }

            return(null);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Shows the list.
        /// </summary>
        public void ShowList()
        {
            int pageSize = GetAttributeValue("PageSize").AsInteger();

            int skipCount = pageNumber * pageSize;

            using (var rockContext = new RockContext())
            {
                var interactionChannel = new InteractionChannelService(rockContext).Get(_channelId.Value);
                if (interactionChannel != null)
                {
                    var interactionComponentQry = new InteractionComponentService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(a =>
                                                         a.ChannelId == _channelId.Value)
                                                  .OrderByDescending(a => a.ModifiedDateTime)
                                                  .Skip(skipCount)
                                                  .Take(pageSize + 1);

                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                    mergeFields.Add("ComponentDetailPage", LinkedPageRoute("ComponentDetailPage"));
                    mergeFields.Add("InteractionDetailPage", LinkedPageRoute("InteractionDetailPage"));
                    mergeFields.Add("InteractionChannel", interactionChannel);
                    mergeFields.Add("InteractionComponents", interactionComponentQry.ToList().Take(pageSize));

                    // set next button
                    if (interactionComponentQry.Count() > pageSize)
                    {
                        Dictionary <string, string> queryStringNext = new Dictionary <string, string>();
                        queryStringNext.Add("ChannelId", _channelId.ToString());
                        queryStringNext.Add("Page", (pageNumber + 1).ToString());

                        var pageReferenceNext = new Rock.Web.PageReference(CurrentPageReference.PageId, CurrentPageReference.RouteId, queryStringNext);
                        mergeFields.Add("NextPageNavigateUrl", pageReferenceNext.BuildUrl());
                    }

                    // set prev button
                    if (pageNumber != 0)
                    {
                        Dictionary <string, string> queryStringPrev = new Dictionary <string, string>();
                        queryStringPrev.Add("ChannelId", _channelId.ToString());
                        queryStringPrev.Add("Page", (pageNumber - 1).ToString());

                        var pageReferencePrev = new Rock.Web.PageReference(CurrentPageReference.PageId, CurrentPageReference.RouteId, queryStringPrev);
                        mergeFields.Add("PreviousPageNavigateUrl", pageReferencePrev.BuildUrl());
                    }

                    lContent.Text = interactionChannel.ComponentListTemplate.IsNotNullOrWhitespace() ?
                                    interactionChannel.ComponentListTemplate.ResolveMergeFields(mergeFields) :
                                    GetAttributeValue("DefaultTemplate").ResolveMergeFields(mergeFields);
                }
            }
        }
        /// <summary>
        /// Executes this instance.
        /// </summary>
        /// <param name="message"></param>
        public override void Execute(Message message)
        {
            var pageCache = PageCache.Get(message.PageGuid);

            if (pageCache == null)
            {
                return;
            }

            var rockContext = new RockContext();
            var interactionComponentService = new InteractionComponentService(rockContext);
            var componentQuery = interactionComponentService.QueryByPage(pageCache);

            rockContext.BulkUpdate(componentQuery, ic => new InteractionComponent {
                Name = pageCache.InternalName
            });
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Formats the selection.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override string FormatSelection(Type entityType, string selection)
        {
            string result = "Interactions";

            string[] selectionValues = selection.Split('|');
            if (selectionValues.Length >= 2)
            {
                var rockContext        = new RockContext();
                var interactionChannel = new InteractionChannelService(rockContext).Get(selectionValues[0].AsGuid());

                if (interactionChannel != null)
                {
                    result = string.Format("In Interaction Channel: {0}", interactionChannel.Name);

                    var interactionComponentGuid = selectionValues[1].AsGuidOrNull();
                    if (interactionComponentGuid.HasValue)
                    {
                        var interactionComponent = new InteractionComponentService(rockContext).Get(interactionComponentGuid.Value);
                        if (interactionComponent != null)
                        {
                            result += string.Format(", in Interaction Component: {0}", interactionComponent.Name);
                        }
                    }

                    var operation = selectionValues[2];
                    if (!string.IsNullOrEmpty(operation))
                    {
                        result += string.Format(", with operation: {0}", operation);
                    }

                    if (!string.IsNullOrEmpty(selectionValues[3]))
                    {
                        SlidingDateRangePicker fakeSlidingDateRangePicker = new SlidingDateRangePicker();
                        var formattedDelimitedValues = SlidingDateRangePicker.FormatDelimitedValues(selectionValues[3].Replace(',', '|'));
                        if (!string.IsNullOrEmpty(formattedDelimitedValues))
                        {
                            result += string.Format(", date range: {0}", formattedDelimitedValues);
                        }
                    }
                }
            }

            return(result);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Writes the opened interaction.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="recipient">The recipient.</param>
        private void WriteInteraction(RockContext rockContext, CommunicationRecipient recipient)
        {
            var interactionService = new InteractionService(rockContext);

            InteractionComponent interactionComponent = new InteractionComponentService(rockContext)
                                                        .GetComponentByEntityId(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid(),
                                                                                recipient.Communication.Id, recipient.Communication.Subject);

            rockContext.SaveChanges();

            var clientType = "None";
            var clientOs   = string.Empty;
            var ipAddress  = RequestContext.ClientInformation.IpAddress;
            var site       = MobileHelper.GetCurrentApplicationSite(false, rockContext);
            var siteName   = site?.Name ?? "Unknown";
            var now        = RockDateTime.Now;

            //
            // Determine if this is a phone or tablet.
            //
            var deviceData = RequestContext.GetHeader("X-Rock-DeviceData")
                             .FirstOrDefault()
                             ?.FromJsonOrNull <DeviceData>();

            if (deviceData != null)
            {
                clientType = deviceData.DeviceType == Common.Mobile.Enums.DeviceType.Phone ? "Mobile" : "Tablet";
                clientOs   = deviceData.DevicePlatform.ToString();
            }

            recipient.Status         = CommunicationRecipientStatus.Opened;
            recipient.OpenedDateTime = now;
            recipient.OpenedClient   = $"{clientOs} {siteName} ({clientType})";

            interactionService.AddInteraction(interactionComponent.Id, recipient.Id, "Opened", "", recipient.PersonAliasId, now, siteName, clientOs, clientType, string.Empty, ipAddress, null);

            rockContext.SaveChanges();
        }
        /// <summary>
        /// Sets the selection.
        /// </summary>
        /// <param name="controls">The controls.</param>
        /// <param name="selection">The selection.</param>
        public override void SetSelection(System.Web.UI.Control[] controls, string selection)
        {
            string[] selectionValues = selection.Split('|');
            if (selectionValues.Length >= 1)
            {
                Guid interactionChannelGuid = selectionValues[0].AsGuid();
                var  rockContext            = new RockContext();
                var  interactionChannel     = new InteractionChannelService(rockContext).Get(interactionChannelGuid);
                var  ddlInteractionChannel  = (controls[0] as RockDropDownList);
                ddlInteractionChannel.SetValue(interactionChannel != null ? interactionChannel.Id : ( int? )null);

                ddlInteractionChannel_SelectedIndexChanged(ddlInteractionChannel, new EventArgs());

                if (selectionValues.Length >= 2)
                {
                    var interactionComponentGuid = selectionValues[1].AsGuidOrNull();
                    if (interactionComponentGuid.HasValue)
                    {
                        RockDropDownList ddlInteractionComponent = (controls[1] as RockDropDownList);
                        var interactionComponent = new InteractionComponentService(rockContext).Get(interactionComponentGuid.Value);
                        ddlInteractionComponent.SetValue(interactionComponent != null ? interactionComponent.Id : ( int? )null);
                    }
                }

                RockTextBox tbOperation = controls[2] as RockTextBox;
                if (selectionValues.Length >= 3)
                {
                    tbOperation.Text = selectionValues[2];
                }

                RockRadioButtonList rblSelectionMode = controls[3] as RockRadioButtonList;
                if (selectionValues.Length >= 4)
                {
                    rblSelectionMode.SetValue(selectionValues[3]);
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sets the selection.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="controls">The controls.</param>
        /// <param name="selection">The selection.</param>
        public override void SetSelection(Type entityType, Control[] controls, string selection)
        {
            string[] selectionValues = selection.Split('|');
            if (selectionValues.Length >= 1)
            {
                Guid interactionChannelGuid = selectionValues[0].AsGuid();
                var  rockContext            = new RockContext();
                var  interactionChannel     = new InteractionChannelService(rockContext).Get(interactionChannelGuid);
                var  ddlInteractionChannel  = (controls[0] as RockDropDownList);
                ddlInteractionChannel.SetValue(interactionChannel != null ? interactionChannel.Id : ( int? )null);

                ddlInteractionChannel_SelectedIndexChanged(ddlInteractionChannel, new EventArgs());

                if (selectionValues.Length >= 2)
                {
                    var interactionComponentGuid = selectionValues[1].AsGuidOrNull();
                    if (interactionComponentGuid.HasValue)
                    {
                        RockDropDownList ddlInteractionComponent = (controls[1] as RockDropDownList);
                        var interactionComponent = new InteractionComponentService(rockContext).Get(interactionComponentGuid.Value);
                        ddlInteractionComponent.SetValue(interactionComponent != null ? interactionComponent.Id : ( int? )null);
                    }
                }

                RockTextBox tbOperation = controls[2] as RockTextBox;
                if (selectionValues.Length >= 3)
                {
                    tbOperation.Text = selectionValues[2];
                }

                SlidingDateRangePicker slidingDateRangePicker = controls[3] as SlidingDateRangePicker;
                if (selectionValues.Length >= 4)
                {
                    slidingDateRangePicker.DelimitedValues = selectionValues[3].Replace(',', '|');
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Gets the component identifier by foreign key and ChannelId, and creates it if it doesn't exist.
        /// If foreignKey is blank, this will throw a <seealso cref="ArgumentNullException" />
        /// If creating a new InteractionComponent with this, componentName must be specified
        /// </summary>
        /// <param name="foreignKey">The foreign key.</param>
        /// <param name="interactionChannelId">The interaction channel identifier.</param>
        /// <param name="componentName">Name of the component.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">ForeignKey must be specified when using GetComponentIdByForeignKey</exception>
        public static int GetComponentIdByForeignKeyAndChannelId(string foreignKey, int interactionChannelId, string componentName)
        {
            if (foreignKey.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException("ForeignKey must be specified when using GetComponentIdByForeignKey");
            }

            var lookupKey = $"{foreignKey}|interactionChannelId:{interactionChannelId}";

            if (_interactionComponentIdLookupFromForeignKey.TryGetValue(lookupKey, out int channelId))
            {
                return(channelId);
            }

            using (var rockContext = new RockContext())
            {
                var interactionComponentService = new InteractionComponentService(rockContext);
                var interactionComponent        = interactionComponentService.Queryable()
                                                  .Where(a => a.ForeignKey == foreignKey && a.InteractionChannelId == interactionChannelId).FirstOrDefault();

                if (interactionComponent == null)
                {
                    interactionComponent                      = new InteractionComponent();
                    interactionComponent.Name                 = componentName;
                    interactionComponent.ForeignKey           = foreignKey;
                    interactionComponent.InteractionChannelId = interactionChannelId;
                    interactionComponentService.Add(interactionComponent);
                    rockContext.SaveChanges();
                }

                var interactionComponentId = Get(interactionComponent).Id;
                _interactionComponentIdLookupFromForeignKey.AddOrUpdate(lookupKey, interactionComponentId, (k, v) => interactionComponentId);

                return(interactionComponentId);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Populates the group roles.
        /// </summary>
        /// <param name="interactionChannelId">The interaction channel identifier.</param>
        /// <param name="ddlInteractionComponent">The Interaction Component.</param>
        private void PopulateInteractionComponent(int?interactionChannelId, RockDropDownList ddlInteractionComponent)
        {
            if (interactionChannelId.HasValue)
            {
                var interactionComponentService = new InteractionComponentService(new RockContext());
                var interactionComponents       = interactionComponentService.Queryable()
                                                  .Where(a => a.ChannelId == (interactionChannelId ?? 0))
                                                  .OrderBy(a => a.Name).
                                                  Select(a => new
                {
                    a.Id,
                    a.Name
                }).ToList();

                ddlInteractionComponent.Items.Clear();
                ddlInteractionComponent.Items.Add(new ListItem());
                ddlInteractionComponent.Items.AddRange(interactionComponents.Select(a => new ListItem(a.Name, a.Id.ToString())).ToArray());
                ddlInteractionComponent.Visible = interactionComponents.Count > 0;
            }
            else
            {
                ddlInteractionComponent.Visible = false;
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Execute method to write transaction to the database.
        /// </summary>
        public void Execute()
        {
            using ( var rockContext = new RockContext() )
            {

                var userAgent = (this.UserAgent ?? string.Empty).Trim();
                if ( userAgent.Length > 450 )
                {
                    userAgent = userAgent.Substring( 0, 450 ); // trim super long useragents to fit in pageViewUserAgent.UserAgent
                }

                // get user agent info
                var clientType = PageViewUserAgent.GetClientType( userAgent );

                // don't log visits from crawlers
                if ( clientType != "Crawler" )
                {
                    InteractionChannelService interactionChannelService = new InteractionChannelService( rockContext );
                    InteractionComponentService interactionComponentService = new InteractionComponentService( rockContext );
                    InteractionDeviceTypeService interactionDeviceTypeService = new InteractionDeviceTypeService( rockContext );
                    InteractionSessionService interactionSessionService = new InteractionSessionService( rockContext );
                    InteractionService interactionService = new InteractionService( rockContext );

                    ClientInfo client = uaParser.Parse( userAgent );
                    var clientOs = client.OS.ToString();
                    var clientBrowser = client.UserAgent.ToString();

                    // lookup the interactionDeviceType, and create it if it doesn't exist
                    var interactionDeviceType = interactionDeviceTypeService.Queryable().Where( a => a.Application == clientBrowser
                                                && a.OperatingSystem == clientOs && a.ClientType == clientType ).FirstOrDefault();

                    if ( interactionDeviceType == null )
                    {
                        interactionDeviceType = new InteractionDeviceType();
                        interactionDeviceType.DeviceTypeData = userAgent;
                        interactionDeviceType.ClientType = clientType;
                        interactionDeviceType.OperatingSystem = clientOs;
                        interactionDeviceType.Application = clientBrowser;
                        interactionDeviceType.Name = string.Format( "{0} - {1}", clientOs, clientBrowser );
                        interactionDeviceTypeService.Add( interactionDeviceType );
                        rockContext.SaveChanges();
                    }

                    // lookup interactionSession, and create it if it doesn't exist
                    Guid sessionId = this.SessionId.AsGuid();
                    int? interactionSessionId = interactionSessionService.Queryable()
                                                    .Where(
                                                        a => a.DeviceTypeId == interactionDeviceType.Id
                                                        && a.Guid == sessionId )
                                                    .Select( a => (int?)a.Id )
                                                    .FirstOrDefault();

                    if ( !interactionSessionId.HasValue )
                    {
                        var interactionSession = new InteractionSession();
                        interactionSession.DeviceTypeId = interactionDeviceType.Id;
                        interactionSession.IpAddress = this.IPAddress;
                        interactionSession.Guid = sessionId;
                        interactionSessionService.Add( interactionSession );
                        rockContext.SaveChanges();
                        interactionSessionId = interactionSession.Id;
                    }

                    int componentEntityTypeId = EntityTypeCache.Read<Rock.Model.Page>().Id;
                    string siteName = SiteCache.Read( SiteId ?? 1 ).Name;

                    // lookup the interaction channel, and create it if it doesn't exist
                    int channelMediumTypeValueId = DefinedValueCache.Read( SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid() ).Id;

                    // check that the site exists as a channel
                    var interactionChannel = interactionChannelService.Queryable()
                                                        .Where( a =>
                                                            a.ChannelTypeMediumValueId == channelMediumTypeValueId
                                                            && a.ChannelEntityId == this.SiteId )
                                                        .FirstOrDefault();
                    if ( interactionChannel == null )
                    {
                        interactionChannel = new InteractionChannel();
                        interactionChannel.Name = siteName;
                        interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                        interactionChannel.ChannelEntityId = this.SiteId;
                        interactionChannel.ComponentEntityTypeId = componentEntityTypeId;
                        interactionChannelService.Add( interactionChannel );
                        rockContext.SaveChanges();
                    }

                    // check that the page exists as a component
                    var interactionComponent = interactionComponentService.Queryable()
                                                        .Where( a =>
                                                            a.EntityId == PageId
                                                            && a.ChannelId == interactionChannel.Id )
                                                        .FirstOrDefault();
                    if ( interactionComponent == null )
                    {
                        interactionComponent = new InteractionComponent();
                        interactionComponent.Name = PageTitle;
                        interactionComponent.EntityId = PageId;
                        interactionComponent.ChannelId = interactionChannel.Id;
                        interactionComponentService.Add( interactionComponent );
                        rockContext.SaveChanges();
                    }

                    // add the interaction
                    Interaction interaction = new Interaction();
                    interactionService.Add( interaction );

                    // obfuscate rock magic token
                    Regex rgx = new Regex( @"rckipid=([^&]*)" );
                    string cleanUrl = rgx.Replace( this.Url, "rckipid=XXXXXXXXXXXXXXXXXXXXXXXXXXXX" );

                    interaction.InteractionData = cleanUrl;
                    interaction.Operation = "View";
                    interaction.PersonAliasId = this.PersonAliasId;
                    interaction.InteractionDateTime = this.DateViewed;
                    interaction.InteractionSessionId = interactionSessionId;
                    interaction.InteractionComponentId = interactionComponent.Id;
                    rockContext.SaveChanges();
                }
            }
        }
Ejemplo n.º 20
0
        public IHttpActionResult PostInteractions([FromBody] List <MobileInteractionSession> sessions, Guid?personalDeviceGuid = null)
        {
            var person    = GetPerson();
            var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress;

            using (var rockContext = new Data.RockContext())
            {
                var interactionChannelService   = new InteractionChannelService(rockContext);
                var interactionComponentService = new InteractionComponentService(rockContext);
                var interactionSessionService   = new InteractionSessionService(rockContext);
                var interactionService          = new InteractionService(rockContext);
                var userLoginService            = new UserLoginService(rockContext);
                var channelMediumTypeValue      = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE);
                var pageEntityTypeId            = EntityTypeCache.Get(typeof(Model.Page)).Id;

                //
                // Check to see if we have a site and the API key is valid.
                //
                if (MobileHelper.GetCurrentApplicationSite() == null)
                {
                    return(StatusCode(System.Net.HttpStatusCode.Forbidden));
                }

                //
                // Get the personal device identifier if they provided it's unique identifier.
                //
                int?personalDeviceId = null;
                if (personalDeviceGuid.HasValue)
                {
                    personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value);
                }

                rockContext.WrapTransaction(() =>
                {
                    foreach (var mobileSession in sessions)
                    {
                        var interactionGuids         = mobileSession.Interactions.Select(i => i.Guid).ToList();
                        var existingInteractionGuids = interactionService.Queryable()
                                                       .Where(i => interactionGuids.Contains(i.Guid))
                                                       .Select(i => i.Guid)
                                                       .ToList();

                        //
                        // Loop through all interactions that don't already exist and add each one.
                        //
                        foreach (var mobileInteraction in mobileSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid)))
                        {
                            int?interactionComponentId = null;

                            //
                            // Lookup the interaction channel, and create it if it doesn't exist
                            //
                            if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue)
                            {
                                var site = SiteCache.Get(mobileInteraction.AppId.Value);
                                var page = PageCache.Get(mobileInteraction.PageGuid.Value);

                                if (site == null || page == null)
                                {
                                    continue;
                                }

                                //
                                // Try to find an existing interaction channel.
                                //
                                var interactionChannelId = interactionChannelService.Queryable()
                                                           .Where(a =>
                                                                  a.ChannelTypeMediumValueId == channelMediumTypeValue.Id &&
                                                                  a.ChannelEntityId == site.Id)
                                                           .Select(a => ( int? )a.Id)
                                                           .FirstOrDefault();

                                //
                                // If not found, create one.
                                //
                                if (!interactionChannelId.HasValue)
                                {
                                    var interactionChannel = new InteractionChannel
                                    {
                                        Name = site.Name,
                                        ChannelTypeMediumValueId = channelMediumTypeValue.Id,
                                        ChannelEntityId          = site.Id,
                                        ComponentEntityTypeId    = pageEntityTypeId
                                    };

                                    interactionChannelService.Add(interactionChannel);
                                    rockContext.SaveChanges();

                                    interactionChannelId = interactionChannel.Id;
                                }

                                //
                                // Get an existing or create a new component.
                                //
                                var interactionComponent = interactionComponentService.GetComponentByChannelIdAndEntityId(interactionChannelId.Value, page.Id, page.InternalName);
                                rockContext.SaveChanges();

                                interactionComponentId = interactionComponent.Id;
                            }
                            else if (mobileInteraction.ChannelId.HasValue)
                            {
                                var interactionChannelId = mobileInteraction.ChannelId;

                                if (mobileInteraction.ComponentId.HasValue)
                                {
                                    interactionComponentId = mobileInteraction.ComponentId.Value;
                                }
                                else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace())
                                {
                                    //
                                    // Get an existing or create a new component.
                                    //
                                    var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName);
                                    rockContext.SaveChanges();

                                    interactionComponentId = interactionComponent.Id;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                continue;
                            }

                            //
                            // Add the interaction
                            //
                            if (interactionComponentId.HasValue)
                            {
                                var interaction = interactionService.CreateInteraction(interactionComponentId.Value,
                                                                                       mobileInteraction.EntityId,
                                                                                       mobileInteraction.Operation,
                                                                                       mobileInteraction.Summary,
                                                                                       mobileInteraction.Data,
                                                                                       person?.PrimaryAliasId,
                                                                                       mobileInteraction.DateTime,
                                                                                       mobileSession.Application,
                                                                                       mobileSession.OperatingSystem,
                                                                                       mobileSession.ClientType,
                                                                                       null,
                                                                                       ipAddress,
                                                                                       mobileSession.Guid);

                                interaction.Guid             = mobileInteraction.Guid;
                                interaction.PersonalDeviceId = personalDeviceId;
                                interactionService.Add(interaction);
                                rockContext.SaveChanges();
                            }
                        }
                    }
                });
            }

            return(Ok());
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Execute method to write transaction to the database.
        /// </summary>
        public void Execute()
        {
            if (PageShortLinkId.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var userAgent = (this.UserAgent ?? string.Empty).Trim();
                    if (userAgent.Length > 450)
                    {
                        userAgent = userAgent.Substring(0, 450);   // trim super long useragents to fit in pageViewUserAgent.UserAgent
                    }

                    // get user agent info
                    var clientType = InteractionDeviceType.GetClientType(userAgent);

                    // don't log visits from crawlers
                    if (clientType != "Crawler")
                    {
                        // lookup the interaction channel, and create it if it doesn't exist
                        int channelMediumTypeValueId = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_URLSHORTENER.AsGuid()).Id;
                        InteractionChannelService interactionChannelService = new InteractionChannelService(rockContext);
                        var interactionChannel = interactionChannelService.Queryable()
                                                 .Where(a => a.ChannelTypeMediumValueId == channelMediumTypeValueId)
                                                 .FirstOrDefault();
                        if (interactionChannel == null)
                        {
                            interactionChannel      = new InteractionChannel();
                            interactionChannel.Name = "Short Links";
                            interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                            interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Get <Rock.Model.PageShortLink>().Id;;
                            interactionChannel.Guid = SystemGuid.InteractionChannel.SHORT_LINKS.AsGuid();
                            interactionChannelService.Add(interactionChannel);
                            rockContext.SaveChanges();
                        }

                        // check that the page exists as a component
                        var interactionComponent = new InteractionComponentService(rockContext).GetComponentByEntityId(interactionChannel.Id, PageShortLinkId.Value, Token);
                        if (Url.IsNotNullOrWhiteSpace())
                        {
                            if (interactionComponent.ComponentSummary != Url)
                            {
                                interactionComponent.ComponentSummary = Url;
                            }

                            var urlDataJson = new { Url = Url }.ToJson();
                            if (interactionComponent.ComponentData != urlDataJson)
                            {
                                interactionComponent.ComponentData = urlDataJson;
                            }
                        }

                        rockContext.SaveChanges();

                        // Add the interaction
                        if (interactionComponent != null)
                        {
                            int?personAliasId = null;
                            if (UserName.IsNotNullOrWhiteSpace())
                            {
                                var currentUser = new UserLoginService(rockContext).GetByUserName(UserName);
                                personAliasId = currentUser?.Person?.PrimaryAlias?.Id;
                            }

                            ClientInfo client        = uaParser.Parse(userAgent);
                            var        clientOs      = client.OS.ToString();
                            var        clientBrowser = client.UserAgent.ToString();

                            new InteractionService(rockContext).AddInteraction(interactionComponent.Id, null, "View", Url, personAliasId, DateViewed,
                                                                               clientBrowser, clientOs, clientType, userAgent, IPAddress, this.SessionId?.AsGuidOrNull());
                            rockContext.SaveChanges();
                        }
                    }
                }
            }
        }
Ejemplo n.º 22
0
    /// <summary>
    /// Processes for recipient.
    /// </summary>
    /// <param name="eventType">Type of the event.</param>
    /// <param name="communicationRecipientGuid">The communication recipient unique identifier.</param>
    /// <param name="rockContext">The rock context.</param>
    private void ProcessForReceipent(string eventType, Guid?communicationRecipientGuid, Rock.Data.RockContext rockContext)
    {
        if (!communicationRecipientGuid.HasValue)
        {
            return;
        }

        var communicationRecipient = new CommunicationRecipientService(rockContext).Get(communicationRecipientGuid.Value);

        if (communicationRecipient != null && communicationRecipient.Communication != null)
        {
            int      secs = request.Form["timestamp"].AsInteger();
            DateTime ts   = RockDateTime.ConvertLocalDateTimeToRockDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(secs).ToLocalTime());

            var communicationGuid = Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid();

            InteractionComponent interactionComponent = new InteractionComponentService(rockContext)
                                                        .GetComponentByEntityId(communicationGuid, communicationRecipient.CommunicationId, communicationRecipient.Communication.Subject);

            rockContext.SaveChanges();

            var interactionService = new InteractionService(rockContext);

            switch (eventType)
            {
            case "delivered":
                communicationRecipient.Status     = CommunicationRecipientStatus.Delivered;
                communicationRecipient.StatusNote = string.Format("Confirmed delivered by Mailgun at {0}", ts.ToString());
                break;

            case "opened":
                communicationRecipient.Status         = CommunicationRecipientStatus.Opened;
                communicationRecipient.OpenedDateTime = ts;
                communicationRecipient.OpenedClient   = string.Format(
                    "{0} {1} ({2})",
                    request.Form["client-os"] ?? "unknown",
                    request.Form["client-name"] ?? "unknown",
                    request.Form["device-type"] ?? "unknown");

                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Opened",
                        string.Empty,
                        communicationRecipient.PersonAliasId,
                        ts,
                        request.Form["client-name"],
                        request.Form["client-os"],
                        request.Form["client-type"],
                        request.Form["device-type"],
                        request.Form["ip"],
                        null);
                }

                break;

            case "clicked":
                if (interactionComponent != null)
                {
                    interactionService.AddInteraction(
                        interactionComponent.Id,
                        communicationRecipient.Id,
                        "Click",
                        request.Form["url"],
                        communicationRecipient.PersonAliasId,
                        ts,
                        request.Form["client-name"],
                        request.Form["client-os"],
                        request.Form["client-type"],
                        request.Form["device-type"],
                        request.Form["ip"],
                        null);
                }

                break;

            case "complained":
                break;

            case "unsubscribed":
                break;

            case "dropped":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = request.Form["description"];
                break;

            case "bounced":
                communicationRecipient.Status     = CommunicationRecipientStatus.Failed;
                communicationRecipient.StatusNote = request.Form["notification"];

                Rock.Communication.Email.ProcessBounce(
                    request.Form["recipient"],
                    Rock.Communication.BounceType.HardBounce,
                    request.Form["notification"],
                    ts);

                break;
            }

            rockContext.SaveChanges();
        }
    }
Ejemplo n.º 23
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);
        }
        public void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap     = context.JobDetail.JobDataMap;
            var        rockContext = new RockContext();

            InteractionChannelService   channelService     = new InteractionChannelService(rockContext);
            InteractionComponentService componentService   = new InteractionComponentService(rockContext);
            InteractionService          interactionService = new InteractionService(rockContext);
            ScheduleService             scheduleService    = new ScheduleService(rockContext);
            LocationService             locationService    = new LocationService(rockContext);
            AttendanceService           attendanceService  = new AttendanceService(rockContext);
            GroupService groupService = new GroupService(rockContext);

            // Load the channel
            InteractionChannelCache channel = InteractionChannelCache.Read(dataMap.GetString("InteractionChannel").AsGuid());

            // Setup
            int    campusLocationTypeId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_CAMPUS).Id;
            var    groupType            = GroupTypeCache.Read(dataMap.GetString("GroupType").AsGuid());
            var    groups    = groupService.GetByGroupTypeId(groupType.Id);
            string operation = !string.IsNullOrWhiteSpace(dataMap.GetString("Operation")) ? dataMap.GetString("Operation") : null;

            // Fetch the job so we can get the last run date/time
            int jobId      = Convert.ToInt16(context.JobDetail.Description);
            var jobService = new ServiceJobService(rockContext);
            var job        = jobService.Get(jobId);

            DateTime lastRun = job?.LastSuccessfulRunDateTime ?? DateTime.MinValue;

            var componentCampusMapping = dataMap.GetString("ComponentCampusMapping").AsDictionaryOrNull();

            foreach (var componentName in componentCampusMapping.Keys)
            {
                var         component = componentService.Queryable().Where(cs => cs.Name.ToLower() == componentName.ToLower() && cs.ChannelId == channel.Id).FirstOrDefault();
                CampusCache campus    = CampusCache.All().Where(c => c.Name == componentCampusMapping[componentName]).FirstOrDefault();

                if (campus != null && component != null)
                {
                    Group group = groups.Where(g => g.IsActive == true && g.CampusId == campus.Id).FirstOrDefault();
                    if (group?.GroupLocations != null)
                    {
                        foreach (var gl in group?.GroupLocations)
                        {
                            Location location = gl.Location;
                            foreach (Schedule schedule in gl.Schedules)
                            {
                                var occurrences = schedule.GetOccurrences(DateTime.MinValue, DateTime.Now);
                                foreach (var occurrence in occurrences)
                                {
                                    DateTime startDate = occurrence.Period.StartTime.Value;
                                    DateTime endDate   = occurrence.Period.EndTime.Value;

                                    var peopleAttended = interactionService.Queryable().Where(
                                        i => i.InteractionComponentId == component.Id &&
                                        i.InteractionDateTime <= endDate &&
                                        i.InteractionEndDateTime >= startDate &&
                                        i.PersonAliasId != null &&
                                        (i.CreatedDateTime > lastRun || i.PersonalDevice.ModifiedDateTime > lastRun || i.PersonalDevice.CreatedDateTime > lastRun) &&
                                        (operation == null || i.Operation == operation)
                                        ).Select(i => i.PersonAliasId).Distinct();
                                    int newAttendance = 0;
                                    foreach (int personAliasId in peopleAttended)
                                    {
                                        // Make sure we don't already have an attendance Record
                                        if (!attendanceService.Queryable().Any(a => DbFunctions.TruncateTime(a.StartDateTime) == occurrence.Period.StartTime.Value.Date && a.ScheduleId == schedule.Id && a.PersonAliasId == personAliasId && a.GroupId == group.Id && a.LocationId == location.Id && a.DidAttend == true))
                                        {
                                            Attendance attendance = new Attendance()
                                            {
                                                PersonAliasId = personAliasId,
                                                CampusId      = campus.Id,
                                                GroupId       = group.Id,
                                                LocationId    = location.Id,
                                                ScheduleId    = schedule.Id,
                                                StartDateTime = occurrence.Period.StartTime.Value,
                                                EndDateTime   = occurrence.Period?.EndTime?.Value,
                                                DidAttend     = true
                                            };
                                            attendanceService.Add(attendance);
                                            newAttendance++;
                                        }
                                    }
                                    if (newAttendance > 0)
                                    {
                                        rockContext.SaveChanges();
                                        context.Result += string.Format("{0} people attended {1} on {2} (Component {3}).\n", newAttendance, campus.Name, occurrence.Period.StartTime.Value.ToString("MM/dd/yyyy h:mm tt"), component.Name);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Execute method to write transaction to the database.
        /// </summary>
        public void Execute()
        {
            if (!PageId.HasValue)
            {
                return;
            }

            var userAgent = (this.UserAgent ?? string.Empty).Trim();

            if (userAgent.Length > 450)
            {
                userAgent = userAgent.Substring(0, 450);   // trim super long useragents to fit in pageViewUserAgent.UserAgent
            }

            // get user agent info
            var clientType = InteractionDeviceType.GetClientType(userAgent);

            // don't log visits from crawlers
            if (clientType == "Crawler")
            {
                return;
            }

            using (var rockContext = new RockContext())
            {
                // lookup the interaction channel, and create it if it doesn't exist
                int channelMediumTypeValueId  = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid()).Id;
                var interactionChannelService = new InteractionChannelService(rockContext);
                var interactionChannelId      = interactionChannelService.Queryable()
                                                .Where(a =>
                                                       a.ChannelTypeMediumValueId == channelMediumTypeValueId &&
                                                       a.ChannelEntityId == this.SiteId)
                                                .Select(a => ( int? )a.Id)
                                                .FirstOrDefault();
                if (interactionChannelId == null)
                {
                    var interactionChannel = new InteractionChannel();
                    interactionChannel.Name = SiteCache.Get(SiteId ?? 1).Name;
                    interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                    interactionChannel.ChannelEntityId          = this.SiteId;
                    interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Get <Rock.Model.Page>().Id;
                    interactionChannelService.Add(interactionChannel);
                    rockContext.SaveChanges();
                    interactionChannelId = interactionChannel.Id;
                }

                // check that the page exists as a component
                var interactionComponent = new InteractionComponentService(rockContext).GetComponentByEntityId(interactionChannelId.Value, PageId.Value, PageTitle);
                if (interactionComponent.Id == 0)
                {
                    rockContext.SaveChanges();
                }

                // Add the interaction
                if (interactionComponent != null)
                {
                    var title = string.Empty;
                    if (BrowserTitle.IsNotNullOrWhiteSpace())
                    {
                        title = BrowserTitle;
                    }
                    else
                    {
                        title = PageTitle;
                    }

                    // remove site name from browser title
                    if (title.Contains("|"))
                    {
                        title = title.Substring(0, title.LastIndexOf('|')).Trim();
                    }

                    var interactionService = new InteractionService(rockContext);
                    var interaction        = interactionService.CreateInteraction(interactionComponent.Id, this.UserAgent, this.Url, this.IPAddress, this.SessionId.AsGuidOrNull());

                    interaction.EntityId            = null;
                    interaction.Operation           = "View";
                    interaction.InteractionSummary  = title;
                    interaction.InteractionData     = Url;
                    interaction.PersonAliasId       = PersonAliasId;
                    interaction.InteractionDateTime = DateViewed;
                    interactionService.Add(interaction);

                    rockContext.SaveChanges();
                }
            }
        }
Ejemplo n.º 26
0
        public HttpResponseMessage Post(List <MACPresence> presenceList)
        {
            using (var rockContext = new RockContext())
            {
                var interactionChannel = new InteractionChannelService(rockContext).Get(Rock.SystemGuid.InteractionChannel.WIFI_PRESENCE.AsGuid());
                if (interactionChannel != null)
                {
                    var interactionComponentIds = new Dictionary <string, int>();

                    var personalDeviceService       = new PersonalDeviceService(rockContext);
                    var interactionService          = new InteractionService(rockContext);
                    var interactionComponentService = new InteractionComponentService(rockContext);

                    // Can't set to local time here as it won't compute DST correctly later.
                    var epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

                    foreach (var macPresence in presenceList.Where(l => l.Mac != null && l.Mac != ""))
                    {
                        var device = personalDeviceService.GetByMACAddress(macPresence.Mac);
                        if (device == null)
                        {
                            device            = new PersonalDevice();
                            device.MACAddress = macPresence.Mac;
                            personalDeviceService.Add(device);

                            rockContext.SaveChanges();
                        }

                        if (macPresence.Presence != null && macPresence.Presence.Any())
                        {
                            foreach (var presence in macPresence.Presence)
                            {
                                // Calc data needed for new and existing data
                                DateTime interactionStart = epochTime.AddSeconds(presence.Arrive).ToLocalTime();
                                DateTime interactionEnd   = epochTime.AddSeconds(presence.Depart).ToLocalTime();
                                TimeSpan ts       = interactionEnd.Subtract(interactionStart);
                                string   duration = (ts.TotalMinutes >= 60 ? $"{ts:%h} hours and " : "") + $"{ts:%m} minutes";

                                Interaction interaction = interactionService.Queryable().Where(i => i.ForeignKey != null && i.ForeignKey == presence.SessionId).FirstOrDefault();
                                if (interaction == null)
                                {
                                    if (!interactionComponentIds.ContainsKey(presence.Space))
                                    {
                                        var component = interactionComponentService
                                                        .Queryable().AsNoTracking()
                                                        .Where(c =>
                                                               c.InteractionChannelId == interactionChannel.Id &&
                                                               c.Name == presence.Space)
                                                        .FirstOrDefault();
                                        if (component == null)
                                        {
                                            component = new InteractionComponent();
                                            interactionComponentService.Add(component);
                                            component.InteractionChannelId = interactionChannel.Id;
                                            component.Name = presence.Space;
                                            rockContext.SaveChanges();
                                        }

                                        interactionComponentIds.Add(presence.Space, component.Id);
                                    }

                                    interaction = new Interaction();
                                    interaction.InteractionDateTime    = interactionStart;
                                    interaction.InteractionEndDateTime = interactionEnd;
                                    interaction.Operation              = "Present";
                                    interaction.InteractionSummary     = $"Arrived at {presence.Space} on {interactionStart.ToShortDateTimeString()}. Stayed for {duration}.";
                                    interaction.InteractionComponentId = interactionComponentIds[presence.Space];
                                    interaction.InteractionData        = presence.ToJson();
                                    interaction.PersonalDeviceId       = device.Id;
                                    interaction.PersonAliasId          = device.PersonAliasId;
                                    interaction.ForeignKey             = presence.SessionId;

                                    interactionService.Add(interaction);
                                }
                                else
                                {
                                    // Update the existing interaction
                                    interaction.InteractionEndDateTime = interactionEnd;
                                    interaction.InteractionSummary     = $"Arrived at {presence.Space} on {interactionStart.ToShortDateTimeString()}. Stayed for {duration}.";
                                    interaction.InteractionData        = presence.ToJson();
                                }

                                rockContext.SaveChanges();
                            }
                        }
                    }

                    var response = ControllerContext.Request.CreateResponse(HttpStatusCode.Created);
                    return(response);
                }
                else
                {
                    var response = ControllerContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "A WiFi Presense Interaction Channel Was Not Found!");
                    throw new HttpResponseException(response);
                }
            }
        }
Ejemplo n.º 27
0
        public void Execute()
        {
            if (PageId.HasValue || !string.IsNullOrWhiteSpace(ComponentName))
            {
                using (var rockContext = new RockContext())
                {
                    int channelMediumTypeValueId  = DefinedValueCache.Get(AvalancheUtilities.AppMediumValue.AsGuid()).Id;
                    var interactionChannelService = new InteractionChannelService(rockContext);
                    var interactionService        = new InteractionService(rockContext);
                    var interactionChannel        = interactionChannelService.Queryable()
                                                    .Where(a =>
                                                           a.ChannelTypeMediumValueId == channelMediumTypeValueId &&
                                                           a.ChannelEntityId == this.SiteId)
                                                    .FirstOrDefault();
                    if (interactionChannel == null)
                    {
                        interactionChannel      = new InteractionChannel();
                        interactionChannel.Name = SiteCache.Get(SiteId ?? 1).Name;
                        interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                        interactionChannel.ChannelEntityId          = this.SiteId;
                        interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Get <Rock.Model.Page>().Id;
                        interactionChannelService.Add(interactionChannel);
                        rockContext.SaveChanges();
                    }

                    InteractionComponent interactionComponent = null;
                    var interactionComponentService           = new InteractionComponentService(rockContext);

                    if (PageId.HasValue)
                    {
                        interactionComponent = interactionComponentService.GetComponentByEntityId(interactionChannel.Id, PageId.Value, PageTitle);
                    }
                    else
                    {
                        interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannel.Id, ComponentName);
                    }
                    rockContext.SaveChanges();

                    // Add the interaction
                    if (interactionComponent != null)
                    {
                        var deviceId = Regex.Match(UserAgent, "(?<=-).+(?=\\))").Value.Trim();
                        if (deviceId.Length > 20)
                        {
                            deviceId = deviceId.Substring(0, 20);
                        }
                        var deviceApplication = Regex.Match(UserAgent, "^[\\S]{0,}").Value.Trim() + " " + deviceId;
                        var clientOs          = Regex.Match(UserAgent, "(?<=;).+(?=-)").Value.Trim();
                        var clientType        = Regex.Match(UserAgent, "(?<=\\().+(?=;)").Value.Trim();

                        var deviceType = interactionService.GetInteractionDeviceType(deviceApplication, clientOs, clientType, UserAgent);
                        var interactionSessionService = new InteractionSessionService(rockContext);
                        var interactionSession        = interactionSessionService.Queryable().Where(s => s.IpAddress == IPAddress && s.DeviceTypeId == deviceType.Id).FirstOrDefault();

                        if (interactionSession == null)
                        {
                            interactionSession = new InteractionSession()
                            {
                                DeviceTypeId = deviceType.Id,
                                IpAddress    = TrimString(IPAddress, 25)
                            };
                            interactionSessionService.Add(interactionSession);
                            rockContext.SaveChanges();
                        }

                        Operation          = TrimString(Operation, 25);
                        InteractionSummary = TrimString(InteractionSummary, 500);
                        clientType         = TrimString(clientType, 25);
                        deviceApplication  = TrimString(deviceApplication, 100);
                        clientOs           = TrimString(clientOs, 100);

                        var interaction = new InteractionService(rockContext).AddInteraction(interactionComponent.Id, null, Operation, InteractionData, PersonAliasId, DateViewed,
                                                                                             deviceApplication, clientOs, clientType, UserAgent, IPAddress, interactionSession.Guid);

                        interaction.InteractionSummary = InteractionSummary;

                        PersonalDevice personalDevice = AvalancheUtilities.GetPersonalDevice(deviceId, PersonAliasId, rockContext);
                        if (personalDevice != null)
                        {
                            interaction.PersonalDeviceId = personalDevice.Id;
                        }

                        rockContext.SaveChanges();
                    }
                }
            }
        }
        /// <summary>
        /// Unsubscribes the person from any lists that were selected.
        /// </summary>
        /// <returns>true if they were actually unsubscribed from something or false otherwise.</returns>
        private bool UnsubscribeFromLists()
        {
            if (_person == null)
            {
                return(false);
            }

            if (!cblUnsubscribeFromLists.SelectedValuesAsInt.Any())
            {
                nbUnsubscribeSuccessMessage.NotificationBoxType = NotificationBoxType.Warning;
                nbUnsubscribeSuccessMessage.Text    = "Please select the lists that you want to unsubscribe from.";
                nbUnsubscribeSuccessMessage.Visible = true;
                return(false);
            }

            List <Group> unsubscribedGroups = new List <Group>();
            var          rockContext        = new RockContext();

            foreach (var communicationListId in cblUnsubscribeFromLists.SelectedValuesAsInt)
            {
                // normally there would be at most 1 group member record for the person, but just in case, mark them all inactive
                var groupMemberRecordsForPerson = new GroupMemberService(rockContext).Queryable().Include(a => a.Group).Where(a => a.GroupId == communicationListId && a.PersonId == _person.Id);
                foreach (var groupMember in groupMemberRecordsForPerson.ToList())
                {
                    groupMember.GroupMemberStatus = GroupMemberStatus.Inactive;
                    if (groupMember.Note.IsNullOrWhiteSpace())
                    {
                        groupMember.Note = "Unsubscribed";
                    }

                    unsubscribedGroups.Add(groupMember.Group);

                    rockContext.SaveChanges();
                }

                // if they selected the CommunicationList associated with the CommunicationId from the Url, log an 'Unsubscribe' Interaction
                if (_communication != null && _communication.ListGroupId.HasValue && communicationListId == _communication.ListGroupId)
                {
                    var communicationRecipient = _communication.GetRecipientsQry(rockContext).Where(a => a.PersonAlias.PersonId == _person.Id).FirstOrDefault();
                    if (communicationRecipient != null)
                    {
                        var interactionService = new InteractionService(rockContext);

                        InteractionComponent interactionComponent = new InteractionComponentService(rockContext)
                                                                    .GetComponentByEntityId(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid(), _communication.Id, _communication.Subject);

                        rockContext.SaveChanges();

                        var ipAddress = GetClientIpAddress();
                        var userAgent = Request.UserAgent ?? "";

                        UAParser.ClientInfo client = UAParser.Parser.GetDefault().Parse(userAgent);
                        var clientOs      = client.OS.ToString();
                        var clientBrowser = client.UA.ToString();
                        var clientType    = InteractionDeviceType.GetClientType(userAgent);

                        interactionService.AddInteraction(interactionComponent.Id, communicationRecipient.Id, "Unsubscribe", "", communicationRecipient.PersonAliasId, RockDateTime.Now, clientBrowser, clientOs, clientType, userAgent, ipAddress, null);

                        rockContext.SaveChanges();
                    }
                }
            }

            var mergeFields     = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
            int?communicationId = PageParameter(PageParameterKey.CommunicationId).AsIntegerOrNull();

            if (_communication != null)
            {
                mergeFields.Add("Communication", _communication);
            }

            mergeFields.Add("UnsubscribedGroups", unsubscribedGroups);

            nbUnsubscribeSuccessMessage.NotificationBoxType = NotificationBoxType.Success;
            nbUnsubscribeSuccessMessage.Text    = GetAttributeValue(AttributeKey.UnsubscribeSuccessText).ResolveMergeFields(mergeFields);
            nbUnsubscribeSuccessMessage.Visible = true;
            return(true);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler" /> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
        public void ProcessRequest(HttpContext context)
        {
            Guid?communicationGuid = context.Request.QueryString["c"].AsGuidOrNull();

            if (communicationGuid.HasValue)
            {
                var rockContext   = new RockContext();
                var communication = new CommunicationService(rockContext).Get(communicationGuid.Value);

                if (communication != null)
                {
                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);
                    mergeFields.Add("Communication", communication);

                    Person person = null;

                    string encodedKey = context.Request.QueryString["p"];
                    if (!string.IsNullOrWhiteSpace(encodedKey))
                    {
                        // first try and see if we can use the new GetByPersonActionIdentifier() otherwise
                        // fall-back to the old GetByImpersonationToken method.
                        var personService = new PersonService(rockContext);
                        person = personService.GetByPersonActionIdentifier(encodedKey, "Unsubscribe");
                        if (person == null)
                        {
                            // TODO: Support for trying via impersonation token should be removed once we get to Rock v11
                            person = personService.GetByImpersonationToken(encodedKey, true, null);
                        }
                    }

                    if (person == null)
                    {
                        var principal = context.User;
                        if (principal != null && principal.Identity != null)
                        {
                            var userLoginService = new Rock.Model.UserLoginService(new RockContext());
                            var userLogin        = userLoginService.GetByUserName(principal.Identity.Name);

                            if (userLogin != null)
                            {
                                var currentPerson = userLogin.Person;
                                // if a person wasn't specified in the URL, then only show it if the current person has EDIT auth to the communication
                                if (communication.IsAuthorized(Authorization.EDIT, currentPerson))
                                {
                                    person = currentPerson;
                                }
                            }
                        }
                    }

                    if (person != null)
                    {
                        mergeFields.Add("Person", person);

                        var recipient = new CommunicationRecipientService(rockContext).Queryable()
                                        .Where(r =>
                                               r.CommunicationId == communication.Id &&
                                               r.PersonAlias != null &&
                                               r.PersonAlias.PersonId == person.Id)
                                        .FirstOrDefault();

                        if (recipient != null)
                        {
                            // Add any additional merge fields created through a report
                            foreach (var mergeField in recipient.AdditionalMergeValues)
                            {
                                if (!mergeFields.ContainsKey(mergeField.Key))
                                {
                                    mergeFields.Add(mergeField.Key, mergeField.Value);
                                }
                            }
                        }

                        context.Response.ContentType = "text/html";
                        context.Response.Write(GetHtmlPreview(communication, mergeFields));

                        if (recipient != null)
                        {
                            // write an 'opened' interaction
                            var interactionService = new InteractionService(rockContext);

                            InteractionComponent interactionComponent = new InteractionComponentService(rockContext)
                                                                        .GetComponentByEntityId(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid(),
                                                                                                communication.Id, communication.Subject);
                            rockContext.SaveChanges();

                            var ipAddress = Rock.Web.UI.RockPage.GetClientIpAddress();

                            var userAgent = context.Request.UserAgent ?? "";

                            UAParser.ClientInfo client = UAParser.Parser.GetDefault().Parse(userAgent);
                            var clientOs      = client.OS.ToString();
                            var clientBrowser = client.UA.ToString();
                            var clientType    = InteractionDeviceType.GetClientType(userAgent);

                            interactionService.AddInteraction(interactionComponent.Id, recipient.Id, "Opened", "", recipient.PersonAliasId, RockDateTime.Now, clientBrowser, clientOs, clientType, userAgent, ipAddress, null);

                            rockContext.SaveChanges();
                        }

                        return;
                    }
                }
            }

            context.Response.ContentType = "text/plain";
            context.Response.Write("Sorry, the communication you requested does not exist, or you are not authorized to view it.");
            return;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Execute method to write transaction to the database.
        /// </summary>
        public void Execute()
        {
            if (PageId.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var userAgent = (this.UserAgent ?? string.Empty).Trim();
                    if (userAgent.Length > 450)
                    {
                        userAgent = userAgent.Substring(0, 450);   // trim super long useragents to fit in pageViewUserAgent.UserAgent
                    }

                    // get user agent info
                    var clientType = InteractionDeviceType.GetClientType(userAgent);

                    // don't log visits from crawlers
                    if (clientType != "Crawler")
                    {
                        // lookup the interaction channel, and create it if it doesn't exist
                        int channelMediumTypeValueId  = DefinedValueCache.Read(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid()).Id;
                        var interactionChannelService = new InteractionChannelService(rockContext);
                        var interactionChannel        = interactionChannelService.Queryable()
                                                        .Where(a =>
                                                               a.ChannelTypeMediumValueId == channelMediumTypeValueId &&
                                                               a.ChannelEntityId == this.SiteId)
                                                        .FirstOrDefault();
                        if (interactionChannel == null)
                        {
                            interactionChannel      = new InteractionChannel();
                            interactionChannel.Name = SiteCache.Read(SiteId ?? 1).Name;
                            interactionChannel.ChannelTypeMediumValueId = channelMediumTypeValueId;
                            interactionChannel.ChannelEntityId          = this.SiteId;
                            interactionChannel.ComponentEntityTypeId    = EntityTypeCache.Read <Rock.Model.Page>().Id;
                            interactionChannelService.Add(interactionChannel);
                            rockContext.SaveChanges();
                        }

                        // check that the page exists as a component
                        var interactionComponent = new InteractionComponentService(rockContext).GetComponentByEntityId(interactionChannel.Id, PageId.Value, PageTitle);
                        rockContext.SaveChanges();

                        // Add the interaction
                        if (interactionComponent != null)
                        {
                            ClientInfo client        = uaParser.Parse(userAgent);
                            var        clientOs      = client.OS.ToString();
                            var        clientBrowser = client.UserAgent.ToString();

                            var interaction = new InteractionService(rockContext).AddInteraction(interactionComponent.Id, null, "View", Url, PersonAliasId, DateViewed,
                                                                                                 clientBrowser, clientOs, clientType, userAgent, IPAddress, this.SessionId?.AsGuidOrNull());

                            if (Url.IsNotNullOrWhitespace() && Url.IndexOf("utm_", StringComparison.OrdinalIgnoreCase) >= 0)
                            {
                                var urlParams = HttpUtility.ParseQueryString(Url);
                                interaction.Source   = urlParams.Get("utm_source").Truncate(25);
                                interaction.Medium   = urlParams.Get("utm_medium").Truncate(25);
                                interaction.Campaign = urlParams.Get("utm_campaign").Truncate(50);
                                interaction.Content  = urlParams.Get("utm_content").Truncate(50);
                            }

                            rockContext.SaveChanges();
                        }
                    }
                }
            }
        }
        public void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap     = context.JobDetail.JobDataMap;
            var        rockContext = new RockContext();

            InteractionChannelService   channelService              = new InteractionChannelService(rockContext);
            InteractionComponentService componentService            = new InteractionComponentService(rockContext);
            InteractionService          interactionService          = new InteractionService(rockContext);
            ScheduleService             scheduleService             = new ScheduleService(rockContext);
            LocationService             locationService             = new LocationService(rockContext);
            AttendanceService           attendanceService           = new AttendanceService(rockContext);
            AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            GroupService groupService = new GroupService(rockContext);

            // Load the channel
            InteractionChannelCache channel = InteractionChannelCache.Get(dataMap.GetString("InteractionChannel").AsGuid());

            // Setup
            int    campusLocationTypeId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_CAMPUS).Id;
            var    groupType            = GroupTypeCache.Get(dataMap.GetString("GroupType").AsGuid());
            var    groupLocations       = groupService.GetByGroupTypeId(groupType.Id).Where(g => g.IsActive == true).SelectMany(g => g.GroupLocations).ToList();
            string operation            = !string.IsNullOrWhiteSpace(dataMap.GetString("Operation")) ? dataMap.GetString("Operation") : null;

            // Fetch the job so we can get the last run date/time
            int jobId      = Convert.ToInt16(context.JobDetail.Description);
            var jobService = new ServiceJobService(rockContext);
            var job        = jobService.Get(jobId);

            DateTime  lastRun = job?.LastSuccessfulRunDateTime ?? DateTime.MinValue;
            var       componentCampusMapping = dataMap.GetString("ComponentCampusMapping").AsDictionaryOrNull();
            DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||");

            // Flip the component campus mapping around and translate to ids
            Dictionary <int, List <int> > campusComponentIds = new Dictionary <int, List <int> >();

            foreach (CampusCache campus in CampusCache.All())
            {
                var componentNames = componentCampusMapping.Where(ccm => ccm.Value == campus.Name).Select(c => c.Key.ToLower());
                campusComponentIds[campus.Id] = componentService.Queryable().Where(cs => componentNames.Contains(cs.Name.ToLower()) && cs.ChannelId == channel.Id).Select(c => c.Id).ToList();
            }

            foreach (GroupLocation gl in groupLocations)
            {
                if (gl.Group.CampusId.HasValue)
                {
                    Location   location     = gl.Location;
                    List <int> componentIds = campusComponentIds[gl.Group.CampusId.Value];

                    foreach (Schedule schedule in gl.Schedules)
                    {
                        var occurrences = schedule.GetOccurrences(dateRange.Start.Value, dateRange.End.Value);
                        foreach (var occurrence in occurrences)
                        {
                            DateTime startDate = occurrence.Period.StartTime.Value;
                            DateTime endDate   = occurrence.Period.EndTime.Value;

                            var peopleAttended = interactionService.Queryable().Where(
                                i => componentIds.Contains(i.InteractionComponentId) &&
                                i.InteractionDateTime <= endDate &&
                                i.InteractionEndDateTime >= startDate &&
                                i.PersonAliasId != null &&
                                (i.CreatedDateTime > lastRun || i.PersonalDevice.ModifiedDateTime > lastRun || i.PersonalDevice.CreatedDateTime > lastRun) &&
                                (operation == null || i.Operation == operation)
                                ).Select(i => i.PersonAliasId).Distinct();
                            int newAttendance = 0;

                            var occurrenceModel = attendanceOccurrenceService.Get(occurrence.Period.StartTime.Value.Date, gl.GroupId, location.Id, schedule.Id);

                            // Make sure we don't already have an attendance Record
                            var existingAttendees = attendanceOccurrenceService.Queryable().Where(ao => DbFunctions.TruncateTime(ao.OccurrenceDate) == occurrence.Period.StartTime.Value.Date && ao.ScheduleId == schedule.Id && ao.GroupId == gl.GroupId && ao.LocationId == location.Id).SelectMany(a => a.Attendees).Where(a => a.DidAttend == true).Select(a => a.PersonAliasId);
                            foreach (int personAliasId in peopleAttended.Except(existingAttendees))
                            {
                                // Check to see if an occurrence exists already
                                if (occurrenceModel == null)
                                {
                                    var attendance = attendanceService.AddOrUpdate(personAliasId, occurrence.Period.StartTime.Value, gl.GroupId, location.Id, schedule.Id, gl.Group.CampusId);

                                    attendance.EndDateTime = occurrence.Period?.EndTime?.Value;
                                    attendance.DidAttend   = true;
                                    attendance.CampusId    = gl.Group.CampusId;
                                    occurrenceModel        = attendance.Occurrence;
                                }
                                else
                                {
                                    Attendance attendance = new Attendance();
                                    attendance.PersonAliasId = personAliasId;
                                    attendance.OccurrenceId  = occurrenceModel.Id;
                                    attendance.StartDateTime = occurrence.Period.StartTime.Value;
                                    attendance.EndDateTime   = occurrence.Period?.EndTime?.Value;
                                    attendance.DidAttend     = true;
                                    attendance.CampusId      = gl.Group.CampusId;
                                    attendanceService.Add(attendance);
                                }

                                newAttendance++;
                            }
                            if (newAttendance > 0)
                            {
                                rockContext.SaveChanges();
                                context.Result += string.Format("{0} people attended {1} on {2}.\n", newAttendance, gl.Group.Campus.Name, occurrence.Period.StartTime.Value.ToString("MM/dd/yyyy h:mm tt"));
                            }
                        }
                    }
                }
            }
        }