コード例 #1
0
        /// <summary>
        /// Handles the SaveClick event of the mdAddCampaignRequests control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void mdAddCampaignRequests_SaveClick(object sender, EventArgs e)
        {
            // note if there is only one CampaignConnectionItem, ddlCampaignConnectionItemsMultiple will not be visible, but it is still the selected one, because there is only one
            var selectedCampaignConnectionItemGuid = ddlCampaignConnectionItemsMultiple.SelectedValue.AsGuidOrNull();

            if (!selectedCampaignConnectionItemGuid.HasValue)
            {
                // shouldn't happen
                return;
            }

            var campaignConnectionItems        = Rock.Web.SystemSettings.GetValue(CampaignConnectionKey.CAMPAIGN_CONNECTION_CONFIGURATION).FromJsonOrNull <List <CampaignItem> >() ?? new List <CampaignItem>();
            var selectedCampaignConnectionItem = campaignConnectionItems.Where(a => a.Guid == selectedCampaignConnectionItemGuid.Value).FirstOrDefault();

            if (selectedCampaignConnectionItem == null)
            {
                // shouldn't happen
                return;
            }

            int numberOfRequests, numberOfRequestsRemaining;

            numberOfRequests = nbNumberOfRequests.Text.AsInteger();
            CampaignConnectionHelper.AddConnectionRequestsForPerson(selectedCampaignConnectionItem, this.CurrentPerson, numberOfRequests, out numberOfRequestsRemaining);

            if (numberOfRequestsRemaining == numberOfRequests)
            {
                nbAddConnectionRequestsMessage.Text = "Additional Requests are not available as this time.";
                nbAddConnectionRequestsMessage.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                nbAddConnectionRequestsMessage.Visible             = true;
            }

            mdAddCampaignRequests.Hide();
            NavigateToCurrentPageReference();
        }
コード例 #2
0
ファイル: CampaignManager.cs プロジェクト: marcoramzy/Rock
        /// <summary>
        /// Processes the campaign configuration entity set.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="campaignItem">The campaign item.</param>
        private void ProcessCampaignConfigurationEntitySet(IJobExecutionContext context, CampaignItem campaignItem)
        {
            context.UpdateLastStatusMessage($"Processing entity set for {campaignItem.Name}.");

            campaignItem.EntitySetId = CampaignConnectionHelper.GetEntitySet(campaignItem);
            CampaignConnectionHelper.AddOrUpdateCampaignConfiguration(campaignItem.Guid, campaignItem);
        }
コード例 #3
0
        /// <summary>
        /// Handles the DeleteClick event of the gCampaigns control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void gCampaigns_DeleteClick(object sender, RowEventArgs e)
        {
            var campaignConnectionItem = CampaignConnectionHelper.GetCampaignConfiguration(e.RowKeyValue.ToString().AsGuid());

            if (campaignConnectionItem != null && campaignConnectionItem.EntitySetId != default(int))
            {
                var rockContext      = new RockContext();
                var entitySetService = new EntitySetService(rockContext);
                var entitySet        = entitySetService.Get(campaignConnectionItem.EntitySetId);

                string errorMessage;
                if (!entitySetService.CanDelete(entitySet, out errorMessage))
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                    return;
                }

                var entitySetItemQry = new EntitySetItemService(rockContext)
                                       .Queryable().AsNoTracking()
                                       .Where(i => i.EntitySetId == entitySet.Id);
                rockContext.BulkDelete(entitySetItemQry);
                entitySetService.Delete(entitySet);
                rockContext.SaveChanges();

                CampaignConnectionHelper.RemoveCampaignConfiguration(e.RowKeyValue.ToString().AsGuid());

                BindGrid();
            }
        }
コード例 #4
0
        /// <summary>
        /// Handles the Click event of the btnAddCampaignRequests control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnAddCampaignRequests_Click(object sender, EventArgs e)
        {
            var campaignConnectionItems = Rock.Web.SystemSettings.GetValue(CampaignConnectionKey.CAMPAIGN_CONNECTION_CONFIGURATION).FromJsonOrNull <List <CampaignItem> >() ?? new List <CampaignItem>();

            campaignConnectionItems = campaignConnectionItems.Where(c => c.IsActive).OrderBy(a => a.Name).ToList();
            var rockContext = new RockContext();

            // limit to campaigns that the current person is a connector in
            campaignConnectionItems = campaignConnectionItems.Where(a => CampaignConnectionHelper.GetConnectorCampusIds(a, CurrentPerson).Any()).ToList();

            ddlCampaignConnectionItemsMultiple.Items.Clear();

            var campaignConnectionItemsPendingCount = new Dictionary <CampaignItem, int>();

            foreach (var campaignConnectionItem in campaignConnectionItems)
            {
                int pendingCount = CampaignConnectionHelper.GetPendingConnectionCount(campaignConnectionItem, CurrentPerson);
                campaignConnectionItemsPendingCount.AddOrIgnore(campaignConnectionItem, pendingCount);
                var listItem = new ListItem();
                listItem.Text  = string.Format("{0} ({1} pending connections)", campaignConnectionItem.Name, pendingCount);
                listItem.Value = campaignConnectionItem.Guid.ToString();
                ddlCampaignConnectionItemsMultiple.Items.Add(listItem);
            }

            nbAddConnectionRequestsMessage.Visible = false;
            nbNumberOfRequests.Visible             = true;

            if (campaignConnectionItems.Count() == 0)
            {
                nbAddConnectionRequestsMessage.Text = "There are no campaigns available for you to request connections for.";
                nbAddConnectionRequestsMessage.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Warning;
                nbAddConnectionRequestsMessage.Visible             = true;
                ddlCampaignConnectionItemsMultiple.Visible         = false;
                lCampaignConnectionItemSingle.Visible = false;
                nbNumberOfRequests.Visible            = false;
            }
            else if (campaignConnectionItems.Count() == 1)
            {
                var campaignConnectionItem = campaignConnectionItems[0];
                lCampaignConnectionItemSingle.Visible = true;
                int pendingCount = campaignConnectionItemsPendingCount.GetValueOrNull(campaignConnectionItem) ?? 0;
                lCampaignConnectionItemSingle.Text = string.Format("{0} ({1} pending connections)", campaignConnectionItem.Name, pendingCount);

                ddlCampaignConnectionItemsMultiple.Visible = false;
            }
            else
            {
                lCampaignConnectionItemSingle.Visible      = false;
                ddlCampaignConnectionItemsMultiple.Visible = true;
            }

            if (campaignConnectionItems.Count > 0)
            {
                var firstCampaignConnectionItem = campaignConnectionItems.First();
                SetDefaultNumberOfRequests(firstCampaignConnectionItem.Guid, campaignConnectionItemsPendingCount.GetValueOrNull(firstCampaignConnectionItem) ?? 0);
            }

            mdAddCampaignRequests.Show();
        }
コード例 #5
0
        /// <summary>
        /// Sets the default number of requests.
        /// </summary>
        /// <param name="selectedCampaignConnectionItemGuid">The selected campaign connection item unique identifier.</param>
        private void SetDefaultNumberOfRequests(Guid?selectedCampaignConnectionItemGuid)
        {
            if (!selectedCampaignConnectionItemGuid.HasValue)
            {
                // shouldn't happen
                return;
            }

            var campaignConnectionItems        = Rock.Web.SystemSettings.GetValue(CampaignConnectionKey.CAMPAIGN_CONNECTION_CONFIGURATION).FromJsonOrNull <List <CampaignItem> >() ?? new List <CampaignItem>();
            var selectedCampaignConnectionItem = campaignConnectionItems.Where(a => a.Guid == selectedCampaignConnectionItemGuid.Value).FirstOrDefault();

            var rockContext        = new RockContext();
            var opportunityService = new ConnectionOpportunityService(rockContext);
            IQueryable <ConnectionOpportunityConnectorGroup> opportunityConnecterGroupQuery = opportunityService.Queryable()
                                                                                              .Where(a => a.Guid == selectedCampaignConnectionItem.OpportunityGuid)
                                                                                              .SelectMany(a => a.ConnectionOpportunityConnectorGroups);

            int?defaultDailyLimitAssigned = null;

            // Check to see if the group member has any CampaignDailyLimit values defined.
            var currentPersonConnectorGroupMember = opportunityConnecterGroupQuery
                                                    .Select(s => s.ConnectorGroup).SelectMany(g => g.Members)
                                                    .WhereAttributeValue(rockContext, av => (av.Attribute.Key == "CampaignDailyLimit") && av.ValueAsNumeric > 0)
                                                    .FirstOrDefault(m => m.PersonId == this.CurrentPersonId.Value);

            if (currentPersonConnectorGroupMember != null)
            {
                currentPersonConnectorGroupMember.LoadAttributes();
                defaultDailyLimitAssigned = currentPersonConnectorGroupMember.GetAttributeValue("CampaignDailyLimit").AsIntegerOrNull();
            }

            if (defaultDailyLimitAssigned == null && selectedCampaignConnectionItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded)
            {
                defaultDailyLimitAssigned = selectedCampaignConnectionItem.DailyLimitAssigned;
            }

            var entitySetItemService = new EntitySetItemService(rockContext);
            int pendingCount         = CampaignConnectionHelper.GetPendingConnectionCount(selectedCampaignConnectionItem, CurrentPerson);

            if (pendingCount == 0)
            {
                nbAddConnectionRequestsMessage.Text = "There are no pending requests remaining.";
                nbAddConnectionRequestsMessage.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                nbAddConnectionRequestsMessage.Visible             = true;
            }
            else if (pendingCount < defaultDailyLimitAssigned)
            {
                nbAddConnectionRequestsMessage.Text = string.Format("There are only {0} pending requests remaining.", pendingCount);
                nbAddConnectionRequestsMessage.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                nbAddConnectionRequestsMessage.Visible             = true;
                defaultDailyLimitAssigned = pendingCount;
            }
            else
            {
                nbAddConnectionRequestsMessage.Visible = false;
            }

            nbNumberOfRequests.Text = defaultDailyLimitAssigned.ToString();
        }
コード例 #6
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            var campaignConnectionGuid = hfCampaignConnectionGuid.Value.AsGuid();

            CampaignItem campaignConnection = null;

            if (campaignConnectionGuid == Guid.Empty)
            {
                campaignConnection = new CampaignItem()
                {
                    Guid = Guid.NewGuid()
                };
            }
            else
            {
                campaignConnection = CampaignConnectionHelper.GetCampaignConfiguration(campaignConnectionGuid);
            }

            campaignConnection.Name                        = tbName.Text;
            campaignConnection.IsActive                    = cbIsActive.Checked;
            campaignConnection.ConnectionTypeGuid          = ddlConnectionType.SelectedValue.AsGuid();
            campaignConnection.RequestCommentsLavaTemplate = ceCommentLavaTemplate.Text;
            campaignConnection.OpportunityGuid             = ddlConnectionOpportunity.SelectedValue.AsGuid();
            var dataViewGuid = new DataViewService(new RockContext()).GetGuid(dvRequestor.SelectedValue.AsInteger());

            if (dataViewGuid.HasValue)
            {
                campaignConnection.DataViewGuid = dataViewGuid.Value;
            }
            campaignConnection.FamilyLimits = rblFamilyLimits.SelectedValueAsEnum <FamilyLimits>(FamilyLimits.Everyone);
            campaignConnection.CreateConnectionRequestOption = rblCreateConnectionRequests.SelectedValueAsEnum <CreateConnectionRequestOptions>(CreateConnectionRequestOptions.AsNeeded);
            if (gpOptOutGroup.GroupId.HasValue)
            {
                campaignConnection.OptOutGroupGuid = new GroupService(new RockContext()).GetGuid(gpOptOutGroup.GroupId.Value);
            }
            campaignConnection.DailyLimitAssigned      = nbDailyLimit.Text.AsIntegerOrNull();
            campaignConnection.DaysBetweenConnection   = nbNumberOfDays.Text.AsInteger();
            campaignConnection.PreferPreviousConnector = cbPreferPreviousConnector.Checked;

            // Save what we have so far, and it will be saved again once the EntitySetId is updated when the thread completes.
            CampaignConnectionHelper.AddOrUpdateCampaignConfiguration(campaignConnection.Guid, campaignConnection);

            // Only update the EntitySet if the campaign is active
            if (campaignConnection.IsActive)
            {
                // Run this thread in the background since it takes several seconds to calculate.
                Task.Run(() => {
                    campaignConnection.EntitySetId = CampaignConnectionHelper.GetEntitySet(campaignConnection);
                    CampaignConnectionHelper.AddOrUpdateCampaignConfiguration(campaignConnection.Guid, campaignConnection);
                });
            }

            NavigateToParentPage();
        }
コード例 #7
0
        /// <summary>
        /// Handles the SelectedIndexChanged event of the ddlCampaignConnectionItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void ddlCampaignConnectionItem_SelectedIndexChanged(object sender, EventArgs e)
        {
            var selectedCampaignConnectionItemGuid = ddlCampaignConnectionItemsMultiple.SelectedValue.AsGuidOrNull();

            if (!selectedCampaignConnectionItemGuid.HasValue)
            {
                // shouldn't happen
                return;
            }

            var campaignConnectionItem = CampaignConnectionHelper.GetCampaignConfiguration(selectedCampaignConnectionItemGuid.Value);
            int pendingCount           = CampaignConnectionHelper.GetPendingConnectionCount(campaignConnectionItem, CurrentPerson);

            SetDefaultNumberOfRequests(selectedCampaignConnectionItemGuid.Value, pendingCount);
        }
コード例 #8
0
ファイル: CampaignManager.cs プロジェクト: marcoramzy/Rock
        /// <summary>
        /// Creates the connection requests.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="campaignItem">The campaign item.</param>
        /// <returns></returns>
        private int CreateConnectionRequests(IJobExecutionContext context, CampaignItem campaignItem)
        {
            context.UpdateLastStatusMessage($"Processing create connection requests for {campaignItem.Name}");

            // Skip creating connection requests if set to "AsNeeded" and DailyLimitAssigned is 0 or null
            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                (campaignItem.DailyLimitAssigned <= 0 || campaignItem.DailyLimitAssigned == null))
            {
                return(0);
            }

            int recordsProcessed = 0;

            var rockContext = new RockContext();
            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var personAliasService           = new PersonAliasService(rockContext);
            var entitySetItemService         = new EntitySetItemService(rockContext);

            var connectionOpportunity = connectionOpportunityService.Get(campaignItem.OpportunityGuid);

            if (connectionOpportunity == null)
            {
                return(0);
            }

            // get cutoff for the last connection datetime.
            var lastConnectionDateTime = RockDateTime.Now.AddDays(-campaignItem.DaysBetweenConnection);

            // if DaysBetweenConnection is 0 then check for connection request for any time period.
            if (campaignItem.DaysBetweenConnection == default(int))
            {
                lastConnectionDateTime = DateTime.MinValue;
            }

            var entitySetItemsQry = entitySetItemService
                                    .Queryable()
                                    .Where(a => a.EntitySetId == campaignItem.EntitySetId)
                                    .OrderBy(a => a.Order);

            bool autoAssignment     = false;
            var  eligibleConnectors = new List <ConnectionConnector>();

            if (campaignItem.DailyLimitAssigned.HasValue &&
                campaignItem.DailyLimitAssigned != default(int))
            {
                autoAssignment     = true;
                eligibleConnectors = GetEligibleConnectorWithLimit(connectionOpportunity.Id, rockContext, campaignItem.DailyLimitAssigned.Value);
            }

            var connectionStatusId = GetConnectionStatus(connectionOpportunity);

            if (!connectionStatusId.HasValue)
            {
                return(0);
            }

            var entitySetItemList = entitySetItemsQry.ToList();

            foreach (var entitySetItem in entitySetItemList)
            {
                var entityItemPersonAlias = personAliasService.GetPrimaryAlias(entitySetItem.EntityId);

                int?connectorPersonId = null;
                if (autoAssignment)
                {
                    connectorPersonId = GetConnector(campaignItem, connectionOpportunity, eligibleConnectors, entityItemPersonAlias, rockContext);

                    if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded && !connectorPersonId.HasValue)
                    {
                        continue;
                    }
                }

                // double check that they haven't already been added
                var personAlreadyHasConnectionRequest = CampaignConnectionHelper.PersonAlreadyHasConnectionRequest(connectionOpportunity.Id, rockContext, lastConnectionDateTime, entitySetItem.EntityId);

                if (personAlreadyHasConnectionRequest)
                {
                    continue;
                }

                int?connectorPersonAliasId = null;
                if (connectorPersonId.HasValue)
                {
                    foreach (var connectionConnector in eligibleConnectors.Where(a => a.PersonId == connectorPersonId.Value))
                    {
                        connectorPersonAliasId       = connectionConnector.PersonAliasId;
                        connectionConnector.Current += 1;
                    }
                }

                CreateConnectionRequest(entityItemPersonAlias, campaignItem.RequestCommentsLavaTemplate, connectionOpportunity.Id, connectionStatusId, connectorPersonAliasId, rockContext);

                recordsProcessed += 1;
            }

            return(recordsProcessed);
        }
コード例 #9
0
ファイル: CampaignManager.cs プロジェクト: waldo2590/Rock
        /// <summary>
        /// Creates the connection requests.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="campaignItem">The campaign item.</param>
        /// <returns></returns>
        private int CreateConnectionRequests(IJobExecutionContext context, CampaignItem campaignItem)
        {
            context.UpdateLastStatusMessage($"Processing create connection requests for {campaignItem.Name}");

            // Skip creating connection requests if set to "AsNeeded" and DailyLimitAssigned is 0 or null
            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                (campaignItem.DailyLimitAssigned <= 0 || campaignItem.DailyLimitAssigned == null))
            {
                return(0);
            }

            int recordsProcessed = 0;

            var rockContext = new RockContext();
            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var personAliasService           = new PersonAliasService(rockContext);
            var connectionRequestService     = new ConnectionRequestService(rockContext);

            var connectionOpportunity = connectionOpportunityService.Get(campaignItem.OpportunityGuid);

            if (connectionOpportunity == null)
            {
                return(0);
            }

            // get cutoff for the last connection datetime.
            var lastConnectionDateTime = RockDateTime.Now.AddDays(-campaignItem.DaysBetweenConnection);

            // if DaysBetweenConnection is 0 then check for connection request for any time period.
            if (campaignItem.DaysBetweenConnection == default(int))
            {
                lastConnectionDateTime = DateTime.MinValue;
            }

            var entitySetItemService = new EntitySetItemService(rockContext);

            var entitySetItemsQry = entitySetItemService
                                    .Queryable()
                                    .Where(a => a.EntitySetId == campaignItem.EntitySetId)
                                    .OrderBy(a => a.Order);

            bool autoAssignment     = false;
            var  eligibleConnectors = new List <ConnectionConnector>();

            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                campaignItem.DailyLimitAssigned.HasValue &&
                campaignItem.DailyLimitAssigned != default(int))
            {
                autoAssignment     = true;
                eligibleConnectors = GetEligibleConnectorWithLimit(connectionOpportunity.Id, rockContext, campaignItem.DailyLimitAssigned.Value);
            }

            int?connectionStatusId = connectionOpportunity.ConnectionType.ConnectionStatuses
                                     .Where(s => s.IsDefault)
                                     .Select(s => ( int? )s.Id)
                                     .FirstOrDefault();

            // If opportunity doesn't have a default status, something is wrong
            if (connectionStatusId == null)
            {
                ExceptionLogService.LogException(new Exception($"Unable to determine default connection status for {connectionOpportunity.Name} while processing campaigns", null));
                return(0);
            }

            var dayofWeek         = RockDateTime.Now.DayOfWeek;
            var entitySetItemList = entitySetItemsQry.ToList();

            foreach (var entitySetItem in entitySetItemList)
            {
                var personAlias            = personAliasService.GetPrimaryAlias(entitySetItem.EntityId);
                var defaultCampus          = personAlias.Person.GetCampus();
                int?connectorPersonAliasId = null;
                if (autoAssignment)
                {
                    int?connectorPersonId = null;
                    if (campaignItem.PreferPreviousConnector)
                    {
                        var personIds = eligibleConnectors
                                        .Where(a => a.Limit - a.Current > 0 &&
                                               (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) &&
                                               (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value)))
                                        .Select(a => a.PersonId)
                                        .ToList();

                        if (personIds.Any())
                        {
                            var person = connectionRequestService
                                         .Queryable()
                                         .Where(a => a.ConnectionOpportunityId == connectionOpportunity.Id &&
                                                a.PersonAlias.PersonId == personAlias.PersonId &&
                                                a.ConnectionState == ConnectionState.Connected &&
                                                a.ConnectorPersonAliasId.HasValue &&
                                                personIds.Contains(a.ConnectorPersonAlias.PersonId))
                                         .Select(a => a.ConnectorPersonAlias.Person)
                                         .FirstOrDefault();

                            if (person != null)
                            {
                                connectorPersonId = person.Id;
                            }
                        }
                    }

                    if (!connectorPersonId.HasValue)
                    {
                        var eligibleConnector = eligibleConnectors
                                                .Where(a => a.Limit - a.Current > 0 &&
                                                       (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) &&
                                                       (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value)))
                                                .OrderBy(a => a.Current)     // order from least assigned to most assigned
                                                .ThenBy(x => Guid.NewGuid()) // and then randomize
                                                .FirstOrDefault();

                        if (eligibleConnector != null)
                        {
                            connectorPersonId = eligibleConnector.PersonId;
                        }
                    }

                    if (!connectorPersonId.HasValue)
                    {
                        continue;
                    }

                    foreach (var connectionConnector in eligibleConnectors.Where(a => a.PersonId == connectorPersonId.Value))
                    {
                        connectorPersonAliasId       = connectionConnector.PersonAliasId;
                        connectionConnector.Current += 1;
                    }
                }

                using (var insertRockContext = new RockContext())
                {
                    try
                    {
                        /*
                         *  3/30/2020 - NA
                         *
                         *  When setting the connection request's Requester, we have to use the PrimaryAlias
                         *  to set the connectionRequest.PersonAlias property because the ConnectionRequestChangeTransaction
                         *  https://github.com/SparkabilityGroup/Rock/blob/a556a9285b7fdfe5594441286242f4feaa5847f2/Rock/Transactions/ConnectionRequestChangeTransaction.cs#L123
                         *  (which handles triggered workflows) expects it.  Also, it needs to be tracked by
                         *  the current rockContext...
                         *
                         *  In other words, this will not work correctly:
                         *  PersonAliasId = personAlias.Id,
                         *
                         *  Reason: This plug-in cannot change Rock core assembly code.
                         */

                        var personPrimaryAlias = new PersonAliasService(insertRockContext).GetPrimaryAlias(entitySetItem.EntityId);
                        var connectionRequestActivityService = new ConnectionRequestActivityService(insertRockContext);
                        var insertConnectionRequestService   = new ConnectionRequestService(insertRockContext);

                        // double check that they haven't already been added
                        var personAlreadyHasConnectionRequest = CampaignConnectionHelper.PersonAlreadyHasConnectionRequest(connectionOpportunity.Id, rockContext, lastConnectionDateTime, entitySetItem.EntityId);

                        if (personAlreadyHasConnectionRequest)
                        {
                            continue;
                        }

                        var connectionRequest = new ConnectionRequest()
                        {
                            ConnectionOpportunityId = connectionOpportunity.Id,
                            PersonAlias             = personPrimaryAlias,
                            ConnectionState         = ConnectionState.Active,
                            ConnectorPersonAliasId  = connectorPersonAliasId,
                            CampusId           = defaultCampus?.Id,
                            ConnectionStatusId = connectionStatusId.Value,
                        };

                        if (campaignItem.RequestCommentsLavaTemplate.IsNotNullOrWhiteSpace())
                        {
                            var mergeFields = new Dictionary <string, object>();
                            mergeFields.Add("Person", personAlias.Person);
                            mergeFields.Add("Family", personAlias.Person.GetFamily());
                            connectionRequest.Comments = campaignItem.RequestCommentsLavaTemplate.ResolveMergeFields(mergeFields);
                        }

                        insertConnectionRequestService.Add(connectionRequest);

                        if (connectorPersonAliasId.HasValue)
                        {
                            var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid();
                            int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid);
                            if (assignedActivityId.HasValue)
                            {
                                var connectionRequestActivity = new ConnectionRequestActivity();
                                connectionRequestActivity.ConnectionRequest        = connectionRequest;
                                connectionRequestActivity.ConnectionOpportunityId  = connectionRequest.ConnectionOpportunityId;
                                connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value;
                                connectionRequestActivity.ConnectorPersonAliasId   = connectorPersonAliasId;
                                connectionRequestActivityService.Add(connectionRequestActivity);
                            }
                        }

                        insertRockContext.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        // Log exception and keep on trucking.
                        var exception = new Exception($"Exception occurred trying to create connection request:{personAlias.Id}.", ex);
                        createConnectionRequestExceptions.Add(exception);
                        ExceptionLogService.LogException(exception, null);
                    }
                }

                recordsProcessed += 1;
            }

            return(recordsProcessed);
        }