Exemple #1
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 page reference.</param>
        /// <returns></returns>
        public override List<BreadCrumb> GetBreadCrumbs( PageReference pageReference )
        {
            var rockContext = new RockContext();
            var breadCrumbs = new List<BreadCrumb>();

            ConnectionRequest connectionRequest = null;

            int? requestId = PageParameter( "ConnectionRequestId" ).AsIntegerOrNull();
            if ( requestId.HasValue && requestId.Value > 0 )
            {
                connectionRequest = new ConnectionRequestService( rockContext ).Get( requestId.Value );
            }

            if ( connectionRequest != null )
            {
                breadCrumbs.Add( new BreadCrumb( connectionRequest.PersonAlias.Person.FullName, pageReference ) );
            }
            else
            {
                var connectionOpportunity = new ConnectionOpportunityService( rockContext ).Get( PageParameter( "ConnectionOpportunityId" ).AsInteger() );
                if ( connectionOpportunity != null )
                {
                    breadCrumbs.Add( new BreadCrumb( String.Format( "New {0} Connection Request", connectionOpportunity.Name ), pageReference ) );
                }
                else
                {
                    breadCrumbs.Add( new BreadCrumb( "New Connection Request", pageReference ) );
                }
            }

            return breadCrumbs;
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages )
        {
            errorMessages = new List<string>();

            // Get the connection request
            ConnectionRequest request = null;
            Guid connectionRequestGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionRequestAttribute" ).AsGuid() ).AsGuid();
            request = new ConnectionRequestService( rockContext ).Get( connectionRequestGuid );
            if ( request == null )
            {
                errorMessages.Add( "Invalid Connection Request Attribute or Value!" );
                return false;
            }

            // Get connection state
            ConnectionState? connectionState = null;
            Guid? connectionStateAttributeGuid = GetAttributeValue( action, "ConnectionStateAttribute" ).AsGuidOrNull();
            if ( connectionStateAttributeGuid.HasValue )
            {
                connectionState = action.GetWorklowAttributeValue( connectionStateAttributeGuid.Value ).ConvertToEnumOrNull<ConnectionState>();
            }
            if ( connectionState == null )
            {
                connectionState = GetAttributeValue( action, "ConnectionState" ).ConvertToEnumOrNull<ConnectionState>();
            }
            if ( connectionState == null )
            {
                errorMessages.Add( "Invalid Connection State Attribute or Value!" );
                return false;
            }
            request.ConnectionState = connectionState.Value;

            // Get follow up date
            if ( connectionState.Value == ConnectionState.FutureFollowUp )
            {
                DateTime? followupDate = null;
                Guid? FollowUpDateAttributeGuid = GetAttributeValue( action, "FollowUpDateAttribute" ).AsGuidOrNull();
                if ( FollowUpDateAttributeGuid.HasValue )
                {
                    followupDate = action.GetWorklowAttributeValue( FollowUpDateAttributeGuid.Value ).AsDateTime();
                }
                if ( followupDate == null )
                {
                    followupDate = GetAttributeValue( action, "FollowUpDate" ).AsDateTime();
                }
                if ( followupDate == null )
                {
                    errorMessages.Add( "Invalid Follow Up DateAttribute or Value!" );
                    return false;
                }
                request.FollowupDate = followupDate.Value;
            }

            rockContext.SaveChanges();

            return true;
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var groupAttendanceFilterSelection = selection.FromJsonOrNull <GroupAttendanceFilterSelection>();

            if (groupAttendanceFilterSelection.GroupGuids == null || groupAttendanceFilterSelection.GroupGuids.Count == 0)
            {
                // no groups selected, so return nothing
                return(Expression.Constant(false));
            }

            var rockContext   = serviceInstance.Context as RockContext;
            var attendanceQry = new AttendanceService(rockContext).Queryable().Where(a => a.DidAttend.HasValue && a.DidAttend.Value);

            var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(groupAttendanceFilterSelection.SlidingDateRangeDelimitedValues);

            if (dateRange.Start.HasValue)
            {
                var startDate = dateRange.Start.Value;
                attendanceQry = attendanceQry.Where(a => a.Occurrence.OccurrenceDate >= startDate);
            }

            if (dateRange.End.HasValue)
            {
                var endDate = dateRange.End.Value;
                attendanceQry = attendanceQry.Where(a => a.Occurrence.OccurrenceDate < endDate);
            }

            var groupIds = GetGroupIds(groupAttendanceFilterSelection.GroupGuids, groupAttendanceFilterSelection.IncludeChildGroups);

            if (groupIds.Count == 1)
            {
                // if there is exactly one groupId we can avoid a 'Contains' (Contains has a small performance impact)
                int groupId = groupIds[0];
                attendanceQry = attendanceQry.Where(a => a.Occurrence.GroupId.HasValue && a.Occurrence.GroupId.Value == groupId);
            }
            else if (groupIds.Count > 1)
            {
                attendanceQry = attendanceQry.Where(a => a.Occurrence.GroupId.HasValue && groupIds.Contains(a.Occurrence.GroupId.Value));
            }

            if (groupAttendanceFilterSelection.ScheduleIds.Any())
            {
                attendanceQry = attendanceQry.Where(a => a.Occurrence.ScheduleId.HasValue && groupAttendanceFilterSelection.ScheduleIds.Contains(a.Occurrence.ScheduleId.Value));
            }

            var qry = new ConnectionRequestService(rockContext)
                      .Queryable();

            qry = qry.Where(p => attendanceQry.Where(xx => p.AssignedGroupId.HasValue && xx.PersonAlias.PersonId == p.PersonAlias.PersonId && xx.Occurrence.GroupId == p.AssignedGroupId).Count() == groupAttendanceFilterSelection.AttendedCount);

            var compareEqualExpression = FilterExpressionExtractor.Extract <Rock.Model.ConnectionRequest>(qry, parameterExpression, "p") as BinaryExpression;
            var result = FilterExpressionExtractor.AlterComparisonType(groupAttendanceFilterSelection.IntegerCompare, compareEqualExpression, null);

            return(result);
        }
        private void BindData()
        {
            string contents = GetAttributeValue(AttributeKey.Contents);

            string appRoot   = ResolveRockUrl("~/");
            string themeRoot = ResolveRockUrl("~~/");

            contents = contents.Replace("~~/", themeRoot).Replace("~/", appRoot);

            var includedConnectionTypeGuids = GetAttributeValue(AttributeKey.IncludedConnectionTypes).SplitDelimitedValues().AsGuidList();
            var excludedConnectionTypeGuids = GetAttributeValue(AttributeKey.ExcludedConnectionTypes).SplitDelimitedValues().AsGuidList();

            DateTime midnightToday = RockDateTime.Today.AddDays(1);

            var rockContext        = new RockContext();
            var connectionRequests = new ConnectionRequestService(rockContext).Queryable()
                                     .Where(a => a.ConnectorPersonAlias != null && a.ConnectorPersonAlias.PersonId == CurrentPersonId)
                                     .Where(r => r.ConnectionState == ConnectionState.Active ||
                                            (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday));

            if (includedConnectionTypeGuids.Any())
            {
                connectionRequests = connectionRequests.Where(a => includedConnectionTypeGuids.Contains(a.ConnectionOpportunity.ConnectionType.Guid));
            }

            if (excludedConnectionTypeGuids.Any())
            {
                connectionRequests = connectionRequests.Where(a => !excludedConnectionTypeGuids.Contains(a.ConnectionOpportunity.ConnectionType.Guid));
            }

            connectionRequests = connectionRequests.OrderBy(r => r.PersonAlias.Person.LastName).ThenBy(r => r.PersonAlias.Person.NickName);

            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new Rock.Lava.CommonMergeFieldsOptions {
                GetLegacyGlobalMergeFields = false
            });

            mergeFields.Add("ConnectionRequests", connectionRequests.ToList());

            var lastActivityNotes = connectionRequests.Select(r => new
            {
                ConnectionRequestId = r.Id,
                LastActivity        = r.ConnectionRequestActivities.OrderByDescending(
                    a => a.CreatedDateTime).FirstOrDefault()
            }).ToDictionary(k => k.ConnectionRequestId, v => v.LastActivity);

            mergeFields.Add("LastActivityLookup", lastActivityNotes);

            Dictionary <string, object> linkedPages = new Dictionary <string, object>();

            linkedPages.Add("DetailPage", LinkedPageRoute(AttributeKey.DetailPage));
            mergeFields.Add("LinkedPages", linkedPages);

            lContents.Text = contents.ResolveMergeFields(mergeFields);
        }
Exemple #5
0
        public IConnectionRequestService ConnectionRequestRejectsMock()
        {
            var requestSender = new Mock <IHttpRequestSender>();
            var httpResponse  = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);

            requestSender.Setup(s => s.PostAsync(It.IsAny <string>(), It.IsAny <HttpContent>()))
            .ReturnsAsync(httpResponse);

            var service = new ConnectionRequestService(requestSender.Object);

            return(service);
        }
Exemple #6
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            // Get the connection request
            ConnectionRequest request     = null;
            Guid connectionRequestGuid    = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid();
            var  connectionRequestService = new ConnectionRequestService(rockContext);

            request = connectionRequestService.Get(connectionRequestGuid);
            if (request == null)
            {
                errorMessages.Add("Invalid Connection Request Attribute or Value!");
                return(false);
            }

            // Get the opportunity
            ConnectionOpportunity opportunity = null;
            Guid opportunityTypeGuid          = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionOpportunityAttribute").AsGuid()).AsGuid();

            opportunity = new ConnectionOpportunityService(rockContext).Get(opportunityTypeGuid);
            if (opportunity == null)
            {
                errorMessages.Add("Invalid Connection Opportunity Attribute or Value!");
                return(false);
            }

            // Get the transfer note
            string note = GetAttributeValue(action, "TransferNote", true);

            if (request != null && opportunity != null)
            {
                request.ConnectionOpportunityId = opportunity.Id;

                var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid();
                var transferredActivityId = new ConnectionActivityTypeService(rockContext)
                                            .Queryable()
                                            .Where(t => t.Guid == guid)
                                            .Select(t => t.Id)
                                            .FirstOrDefault();

                ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity();
                connectionRequestActivity.ConnectionRequestId      = request.Id;
                connectionRequestActivity.ConnectionOpportunityId  = opportunity.Id;
                connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId;
                connectionRequestActivity.Note = note;
                new ConnectionRequestActivityService(rockContext).Add(connectionRequestActivity);

                rockContext.SaveChanges();
            }

            return(true);
        }
        /// <summary>
        /// Sets the value (as id)
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="value">The value.</param>
        public override void SetEditValue(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues, string value)
        {
            var picker = control as ConnectionRequestPicker;

            if (picker != null)
            {
                Guid guid = value.AsGuid();

                // get the item (or null) and set it
                var connectionRequest = new ConnectionRequestService(new RockContext()).Get(guid);
                picker.SetValue(connectionRequest);
            }
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages )
        {
            errorMessages = new List<string>();

            // Get the connection request
            ConnectionRequest request = null;
            Guid connectionRequestGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionRequestAttribute" ).AsGuid() ).AsGuid();
            var connectionRequestService = new ConnectionRequestService( rockContext );
            request = connectionRequestService.Get( connectionRequestGuid );
            if ( request == null )
            {
                errorMessages.Add( "Invalid Connection Request Attribute or Value!" );
                return false;
            }

            // Get the opportunity
            ConnectionOpportunity opportunity = null;
            Guid opportunityTypeGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionOpportunityAttribute" ).AsGuid() ).AsGuid();
            opportunity = new ConnectionOpportunityService( rockContext ).Get( opportunityTypeGuid );
            if ( opportunity == null )
            {
                errorMessages.Add( "Invalid Connection Opportunity Attribute or Value!" );
                return false;
            }

            // Get the tranfer note
            string note = GetAttributeValue( action, "TransferNote", true );

            if ( request != null && opportunity != null )
            {
                request.ConnectionOpportunityId = opportunity.Id;

                var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid();
                var transferredActivityId = new ConnectionActivityTypeService( rockContext )
                    .Queryable()
                    .Where( t => t.Guid == guid )
                    .Select( t => t.Id )
                    .FirstOrDefault();

                ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity();
                connectionRequestActivity.ConnectionRequestId = request.Id;
                connectionRequestActivity.ConnectionOpportunityId = opportunity.Id;
                connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId;
                connectionRequestActivity.Note = note;
                new ConnectionRequestActivityService( rockContext ).Add( connectionRequestActivity );

                rockContext.SaveChanges();
            }

            return true;
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            // Get the connection request
            ConnectionRequest request  = null;
            Guid connectionRequestGuid = action.GetWorkflowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid();

            request = new ConnectionRequestService(rockContext).Get(connectionRequestGuid);
            if (request == null)
            {
                errorMessages.Add("Invalid Connection Request Attribute or Value!");
                return(false);
            }

            // Get connection status
            ConnectionStatus status = null;
            Guid?            connectionStatusGuid          = null;
            Guid?            connectionStatusAttributeGuid = GetAttributeValue(action, "ConnectionStatusAttribute").AsGuidOrNull();

            if (connectionStatusAttributeGuid.HasValue)
            {
                connectionStatusGuid = action.GetWorkflowAttributeValue(connectionStatusAttributeGuid.Value).AsGuidOrNull();
                if (connectionStatusGuid.HasValue)
                {
                    status = request.ConnectionOpportunity.ConnectionType.ConnectionStatuses
                             .Where(s => s.Guid.Equals(connectionStatusGuid.Value))
                             .FirstOrDefault();
                }
            }
            if (status == null)
            {
                connectionStatusGuid = GetAttributeValue(action, "ConnectionStatus").AsGuidOrNull();
                if (connectionStatusGuid.HasValue)
                {
                    status = request.ConnectionOpportunity.ConnectionType.ConnectionStatuses
                             .Where(s => s.Guid.Equals(connectionStatusGuid.Value))
                             .FirstOrDefault();
                }
            }
            if (status == null)
            {
                errorMessages.Add("Invalid Connection Status Attribute or Value!");
                return(false);
            }

            request.ConnectionStatusId = status.Id;
            rockContext.SaveChanges();

            return(true);
        }
        /// <summary>
        /// Creates the connection request.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="person">The person.</param>
        private void CreateConnectionRequest(RockContext rockContext, Person person)
        {
            if (person != null && _connectionOpportunity != null)
            {
                int defaultStatusId = _connectionOpportunity.ConnectionType.ConnectionStatuses
                                      .Where(s => s.IsDefault)
                                      .Select(s => s.Id)
                                      .FirstOrDefault();

                ConnectionRequestService connectionRequestService = new ConnectionRequestService(rockContext);
                ConnectionRequest        connectionRequest        = new ConnectionRequest();
                connectionRequest.PersonAliasId           = person.PrimaryAliasId.Value;
                connectionRequest.ConnectionOpportunityId = _connectionOpportunity.Id;
                connectionRequest.ConnectionState         = ConnectionState.Active;
                connectionRequest.ConnectionStatusId      = defaultStatusId;
                connectionRequest.CampusId = cpCampus.SelectedCampusId;

                StringBuilder sb = new StringBuilder();

                sb.AppendFormat("#### General\n");
                //sb.AppendFormat( "**Entry Point**: {0}  \n", rblSource.SelectedValue );
                sb.AppendFormat("**Guest Type**: {0}  \n", rblGuestType.SelectedValue);

                if (cblDecisions.SelectedValues.Count > 0)
                {
                    sb.AppendFormat("#### Decisions\n");
                    sb.AppendFormat("- {0}", cblDecisions.SelectedValues.AsDelimited("\n- "));
                    sb.AppendFormat("\n");
                }

                if (cblInterests.SelectedValues.Count > 0)
                {
                    sb.AppendFormat("#### Interests\n");
                    sb.AppendFormat("- {0}", cblInterests.SelectedValues.AsDelimited("\n- "));
                    sb.AppendFormat("\n");
                }

                if (!string.IsNullOrWhiteSpace(tbComments.Text))
                {
                    sb.AppendFormat("#### Additional Comments\n");
                    sb.AppendFormat("{0}", tbComments.Text);
                }

                connectionRequest.Comments = sb.ToString();

                connectionRequestService.Add(connectionRequest);
                rockContext.SaveChanges();
            }
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages )
        {
            errorMessages = new List<string>();

            // Get the connection request
            ConnectionRequest request = null;
            Guid connectionRequestGuid = action.GetWorklowAttributeValue( GetAttributeValue( action, "ConnectionRequestAttribute" ).AsGuid() ).AsGuid();
            request = new ConnectionRequestService( rockContext ).Get( connectionRequestGuid );
            if ( request == null )
            {
                errorMessages.Add( "Invalid Connection Request Attribute or Value!" );
                return false;
            }

            // Get connection status
            ConnectionStatus status = null;
            Guid? connectionStatusGuid = null;
            Guid? connectionStatusAttributeGuid = GetAttributeValue( action, "ConnectionStatusAttribute" ).AsGuidOrNull();
            if ( connectionStatusAttributeGuid.HasValue )
            {
                connectionStatusGuid = action.GetWorklowAttributeValue( connectionStatusAttributeGuid.Value ).AsGuidOrNull();
                if ( connectionStatusGuid.HasValue )
                {
                    status = request.ConnectionOpportunity.ConnectionType.ConnectionStatuses
                        .Where( s => s.Guid.Equals( connectionStatusGuid.Value ) )
                        .FirstOrDefault();
                }
            }
            if ( status == null )
            {
                connectionStatusGuid = GetAttributeValue( action, "ConnectionStatus" ).AsGuidOrNull();
                if ( connectionStatusGuid.HasValue )
                {
                    status = request.ConnectionOpportunity.ConnectionType.ConnectionStatuses
                        .Where( s => s.Guid.Equals( connectionStatusGuid.Value ) )
                        .FirstOrDefault();
                }
            }
            if ( status == null )
            {
                errorMessages.Add( "Invalid Connection Status Attribute or Value!" );
                return false;
            }

            request.ConnectionStatusId = status.Id;
            rockContext.SaveChanges();

            return true;
        }
Exemple #12
0
        /// <summary>
        /// Sets the value (as id)
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="value">The value.</param>
        public override void SetEditValue(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues, string value)
        {
            var picker = control as ConnectionRequestPicker;

            if (picker != null)
            {
                ConnectionRequest connectionRequest = null;

                Guid?guid = value.AsGuidOrNull();
                if (guid.HasValue)
                {
                    connectionRequest = new ConnectionRequestService(new RockContext()).Get(guid.Value);
                }

                picker.SetValue(connectionRequest);
            }
        }
Exemple #13
0
        /// <summary>
        /// Sets the values on select.
        /// </summary>
        protected override void SetValuesOnSelect()
        {
            var connectionRequestIds = new List <int>();

            foreach (var itemId in ItemIds)
            {
                int?connectionRequestId = ItemId.AsIntegerOrNull();
                if (connectionRequestId.HasValue)
                {
                    connectionRequestIds.Add(connectionRequestId.Value);
                }
            }

            var connectionRequests = new ConnectionRequestService(new RockContext()).Queryable().Where(g => connectionRequestIds.Contains(g.Id));

            this.SetValues(connectionRequests);
        }
Exemple #14
0
        /// <summary>
        /// Gets both the opportunity request counts (TotalCount and AssignedToYouCount) for the
        /// given opportunities. The Person the service was initialized with is used to calculate
        /// <see cref="ConnectionRequestCountsViewModel.AssignedToYouCount"/>.
        /// </summary>
        /// <remarks>This method does not check security, it is assumed you have already done so.</remarks>
        /// <param name="connectionOpportunityIds">The connection opportunity identifiers.</param>
        /// <returns>A dictionary of connection request count objects.</returns>
        public Dictionary <int, ConnectionRequestCountsViewModel> GetOpportunityRequestCounts(IEnumerable <int> connectionOpportunityIds)
        {
            var connectionRequestService = new ConnectionRequestService(RockContext);

            // Create all counts as initially empty, this method must always return
            // a value for each opportunity id.
            var requestCounts = connectionOpportunityIds.ToDictionary(id => id, _ => new ConnectionRequestCountsViewModel());

            // Find all the connection requests assigned to the person.
            var activeConnectionRequestQry = connectionRequestService.Queryable()
                                             .Where(r => connectionOpportunityIds.Contains(r.ConnectionOpportunityId) &&
                                                    r.ConnectionState == ConnectionState.Active);

            // Group them by the connection opportunity and get the counts for
            // each opportunity.
            if (Person != null)
            {
                // If we have a Person (Person.Id) count their requests into the AssignedToYouCount along with the TotalCount.
                activeConnectionRequestQry
                .GroupBy(r => r.ConnectionOpportunityId)
                .Select(g => new
                {
                    Id         = g.Key,
                    Count      = g.Count(r => r.ConnectorPersonAliasId.HasValue && r.ConnectorPersonAlias.PersonId == Person.Id),
                    TotalCount = g.Count()
                })
                .ToList()
                .ForEach(o => { requestCounts[o.Id].AssignedToYouCount = o.Count; requestCounts[o.Id].TotalCount = o.TotalCount; });
            }
            else
            {
                // Otherwise, we can only count the total into the TotalCount.
                activeConnectionRequestQry
                .GroupBy(r => r.ConnectionOpportunityId)
                .Select(g => new
                {
                    Id         = g.Key,
                    TotalCount = g.Count()
                })
                .ToList()
                .ForEach(o => requestCounts[o.Id].TotalCount = o.TotalCount);
            }

            return(requestCounts);
        }
Exemple #15
0
        /// <summary>
        /// Gets any (active or past due FutureFollowUp) connection requests that don't have a connector
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="selectedCampaignItem">The selected campaign item.</param>
        /// <param name="connectorPerson">The connector person.</param>
        /// <returns></returns>
        public static IQueryable <ConnectionRequest> GetConnectionRequestsWithoutConnectorQuery(RockContext rockContext, CampaignItem selectedCampaignItem, Person connectorPerson)
        {
            var connectionRequestService = new ConnectionRequestService(rockContext);
            var currentDate = RockDateTime.Today;

            var connectorCampusIds = GetConnectorCampusIds(selectedCampaignItem, connectorPerson);

            // first, get any (active or past due FutureFollowUp) connection requests that don't have a connector
            var connectionRequestsWithoutConnectorQuery = connectionRequestService.Queryable()
                                                          .Where(a => a.ConnectionOpportunity.Guid == selectedCampaignItem.OpportunityGuid &&
                                                                 a.ConnectorPersonAliasId == null &&
                                                                 (a.ConnectionState == ConnectionState.Active || (a.ConnectionState == ConnectionState.FutureFollowUp && a.FollowupDate < currentDate)))

                                                          // only include pending connection requests that have a null campus, or the campus matches the connector's campus
                                                          .Where(a => (a.CampusId == null) || connectorCampusIds.Any(connectorCampusId => connectorCampusId == null || a.CampusId.Value == connectorCampusId));

            return(connectionRequestsWithoutConnectorQuery);
        }
        /// <summary>
        /// Returns the field's current value(s)
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">Information about the value</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param>
        /// <returns></returns>
        public override string FormatValue( Control parentControl, string value, Dictionary<string, ConfigurationValue> configurationValues, bool condensed )
        {
            string formattedValue = value;

            Guid? guid = value.AsGuidOrNull();
            if ( guid.HasValue )
            {
                var connectionRequest = new ConnectionRequestService( new RockContext() ).Get( guid.Value );
                if (connectionRequest != null &&
                    connectionRequest.PersonAlias != null &&
                    connectionRequest.PersonAlias.Person != null )
                {
                    formattedValue = connectionRequest.PersonAlias.Person.FullName;
                }
            }

            return base.FormatValue( parentControl, formattedValue, configurationValues, condensed );
        }
Exemple #17
0
        /// <summary>
        /// Gets the eligible connector with limit considering how many non-closed requests the connector may already have.
        /// </summary>
        /// <param name="connectionOpportunityId">The connection opportunity identifier.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="globalLimit">The global limit.</param>
        /// <returns></returns>
        private List <ConnectionConnector> GetEligibleConnectorWithLimit(int connectionOpportunityId, RockContext rockContext, int globalLimit)
        {
            var eligibleConnectors = new List <ConnectionConnector>();
            var qryConnectionOpportunityConnectorGroups = new ConnectionOpportunityConnectorGroupService(rockContext).Queryable()
                                                          .Where(a => a.ConnectionOpportunityId == connectionOpportunityId &&
                                                                 a.ConnectorGroup.IsActive &&
                                                                 !a.ConnectorGroup.IsArchived);

            // Get all connection requests that are active for the given opportunity that have a connector
            var activeConnectionRequestsWithConnector = new ConnectionRequestService(rockContext)
                                                        .Queryable()
                                                        .Where(a => a.ConnectionOpportunityId == connectionOpportunityId &&
                                                               a.ConnectorPersonAlias != null &&
                                                               a.ConnectionState == ConnectionState.Active);

            foreach (var opportunityConnectionGroup in qryConnectionOpportunityConnectorGroups)
            {
                var members = opportunityConnectionGroup.ConnectorGroup.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Active).ToList();
                members.LoadAttributes();
                foreach (var member in members)
                {
                    ConnectionConnector connectionConnector = new ConnectionConnector()
                    {
                        PersonAliasId = member.Person.PrimaryAliasId,
                        PersonId      = member.PersonId,
                        CampusId      = opportunityConnectionGroup.CampusId,
                    };
                    eligibleConnectors.Add(connectionConnector);

                    var campaignDailyLimit = member.GetAttributeValue("CampaignDailyLimit").AsIntegerOrNull();
                    connectionConnector.Limit   = campaignDailyLimit.HasValue ? campaignDailyLimit.Value : globalLimit;
                    connectionConnector.Current = activeConnectionRequestsWithConnector.Where(a => a.ConnectorPersonAlias.PersonId == member.PersonId).Count();

                    var campaignScheduleDays = member.GetAttributeValue("CampaignScheduleDays");
                    connectionConnector.DaysOfWeek = new List <DayOfWeek>();
                    if (!string.IsNullOrWhiteSpace(campaignScheduleDays))
                    {
                        connectionConnector.DaysOfWeek = campaignScheduleDays.Split(',').Select(a => ( DayOfWeek )a.AsInteger()).ToList();
                    }
                }
            }

            return(eligibleConnectors);
        }
        /// <summary>
        /// Returns the field's current value(s)
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">Information about the value</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param>
        /// <returns></returns>
        public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed)
        {
            string formattedValue = value;

            Guid?guid = value.AsGuidOrNull();

            if (guid.HasValue)
            {
                var connectionRequest = new ConnectionRequestService(new RockContext()).Get(guid.Value);
                if (connectionRequest != null &&
                    connectionRequest.PersonAlias != null &&
                    connectionRequest.PersonAlias.Person != null)
                {
                    formattedValue = connectionRequest.PersonAlias.Person.FullName;
                }
            }

            return(base.FormatValue(parentControl, formattedValue, configurationValues, condensed));
        }
Exemple #19
0
        private void LaunchWorkflow(RockContext rockContext, ConnectionWorkflow connectionWorkflow, string name, Message message)
        {
            var workflowType = WorkflowTypeCache.Get(connectionWorkflow.WorkflowTypeId.Value);

            if (workflowType != null && (workflowType.IsActive ?? true))
            {
                ConnectionRequest connectionRequest = null;
                if (message.ConnectionRequestGuid.HasValue)
                {
                    connectionRequest = new ConnectionRequestService(rockContext).Get(message.ConnectionRequestGuid.Value);

                    if (connectionRequest == null)
                    {
                        // If the ConnectionRequest doesn't exist anymore, exit
                        return;
                    }

                    var workflow = Rock.Model.Workflow.Activate(workflowType, name);

                    if (workflow == null)
                    {
                        // if no workflow was created, exit
                        return;
                    }

                    workflow.InitiatorPersonAliasId = message.InitiatorPersonAliasId;

                    List <string> workflowErrors;
                    new WorkflowService(rockContext).Process(workflow, connectionRequest, out workflowErrors);
                    if (workflow.Id != 0)
                    {
                        ConnectionRequestWorkflow connectionRequestWorkflow = new ConnectionRequestWorkflow();
                        connectionRequestWorkflow.ConnectionRequestId  = connectionRequest.Id;
                        connectionRequestWorkflow.WorkflowId           = workflow.Id;
                        connectionRequestWorkflow.ConnectionWorkflowId = connectionWorkflow.Id;
                        connectionRequestWorkflow.TriggerType          = connectionWorkflow.TriggerType;
                        connectionRequestWorkflow.TriggerQualifier     = connectionWorkflow.QualifierValue;
                        new ConnectionRequestWorkflowService(rockContext).Add(connectionRequestWorkflow);
                        rockContext.SaveChanges();
                    }
                }
            }
        }
        public void ConnectionRequestDateKeySavesCorrectly()
        {
            var rockContext = new RockContext();
            var connectionRequestService = new ConnectionRequestService(rockContext);

            var connectionRequest = BuildConnectionRequest(rockContext, Convert.ToDateTime("3/15/2010"));

            connectionRequestService.Add(connectionRequest);
            rockContext.SaveChanges();

            var connectionRequestId = connectionRequest.Id;

            // We're bypassing the model because the model doesn't user the ConnectionRequestDateKey from the database,
            // but it still needs to be correct for inner joins to work correctly.
            var result = rockContext.Database.
                         SqlQuery <int>($"SELECT CreatedDateKey FROM ConnectionRequest WHERE Id = {connectionRequestId}").First();

            Assert.AreEqual(20100315, result);
        }
        /// <summary>
        /// Reads new values entered by the user for the field (as id)
        /// </summary>
        /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <returns></returns>
        public override string GetEditValue(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            ConnectionRequestPicker picker = control as ConnectionRequestPicker;

            if (picker != null)
            {
                int?id = picker.ItemId.AsIntegerOrNull();
                if (id.HasValue)
                {
                    var connectionRequest = new ConnectionRequestService(new RockContext()).Get(id.Value);

                    if (connectionRequest != null)
                    {
                        return(connectionRequest.Guid.ToString());
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Get's all of the (get connected/ follow up) *requests* for a given person
        /// </summary>
        /// <param name="currentPerson">The leader</param>
        /// <returns></returns>
        public static IQueryable <ConnectionRequest> GetPeopleInLineFollowUpRequests(Person currentPerson)
        {
            if (currentPerson == null)
            {
                return(new List <ConnectionRequest>().AsQueryable());
            }

            var rockContext = new RockContext();

            var connectionRequestService  = new ConnectionRequestService(rockContext);
            int getConnectedOpportunityId =
                new ConnectionOpportunityService(rockContext).Get(
                    SystemGuid.ConnectionOpportunity.GET_CONNECTED.AsGuid()).Id;
            var connectionRequests = connectionRequestService
                                     .Queryable()
                                     .Where(c => c.ConnectionOpportunityId == getConnectedOpportunityId && c.ConnectorPersonAliasId == currentPerson.PrimaryAliasId && c.ConnectionState == ConnectionState.Active);


            return(connectionRequests);
        }
Exemple #23
0
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();
            var mergeFields = GetMergeFields(action);

            // Get the connection request
            ConnectionRequest request = null;
            var connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid();

            request = new ConnectionRequestService(rockContext).Get(connectionRequestGuid);
            if (request == null)
            {
                errorMessages.Add("Invalid Connection Request Attribute or Value!");
                return(false);
            }

            // Get the connector
            PersonAlias personAlias         = null;
            Guid?       personAttributeGuid = GetAttributeValue(action, "PersonAttribute").AsGuidOrNull();

            if (personAttributeGuid.HasValue)
            {
                Guid?personAliasGuid = action.GetWorklowAttributeValue(personAttributeGuid.Value).AsGuidOrNull();
                if (personAliasGuid.HasValue)
                {
                    personAlias = new PersonAliasService(rockContext).Get(personAliasGuid.Value);
                    if (personAlias == null)
                    {
                        errorMessages.Add("Invalid Person");
                        return(false);
                    }
                }
            }

            request.ConnectorPersonAlias = personAlias;
            rockContext.SaveChanges();

            return(true);
        }
Exemple #24
0
        private int GetNotificationCount()
        {
            var lastChecked = GetUserPreference("LastViewedDashboard").AsDateTime();

            if (!lastChecked.HasValue)
            {
                lastChecked = RockDateTime.Now.AddMonths(-3);
            }
            RockContext rockContext = new RockContext();

            //Any workflow assigned to the person where we have active forms.
            var workflowCount = new WorkflowActionService(rockContext).GetActiveForms(CurrentPerson).Where(a => a.CreatedDateTime > lastChecked.Value).DistinctBy(a => a.Activity.WorkflowId).Count();

            //Connections - If a new connecion was made, a connection was just transfered, or a future followup just came up
            DateTime midnightToday      = RockDateTime.Today.AddDays(1);
            var      connectionRequests = new ConnectionRequestService(rockContext).Queryable()
                                          .Where(r => r.ConnectorPersonAlias != null && r.ConnectorPersonAlias.PersonId == CurrentPersonId)
                                          .Where(r => (r.ConnectionState == ConnectionState.Active && (r.CreatedDateTime > lastChecked.Value || r.ConnectionRequestActivities.Where(a => a.CreatedDateTime > lastChecked.Value && a.ConnectionActivityType.Name == "Transferred").Any())) ||
                                                 (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday) && r.FollowupDate.Value > lastChecked.Value)
                                          .Count();

            return(workflowCount + connectionRequests);
        }
Exemple #25
0
        /// <summary>
        /// Gets the opportunity request counts for the given opportunities. The
        /// Person the service was initialized with is used to calculate
        /// <see cref="ConnectionRequestCountsViewModel.AssignedToYouCount"/>.
        /// </summary>
        /// <remarks>This method does not check security, it is assumed you have already done so.</remarks>
        /// <param name="connectionOpportunityIds">The connection opportunity identifiers.</param>
        /// <returns>A dictionary of connection request count objects.</returns>
        public Dictionary <int, ConnectionRequestCountsViewModel> GetOpportunityRequestCounts(IEnumerable <int> connectionOpportunityIds)
        {
            var connectionRequestService = new ConnectionRequestService(RockContext);

            // Create all counts as initially empty, this method must always return
            // a value for each opportunity id.
            var requestCounts = connectionOpportunityIds.ToDictionary(id => id, _ => new ConnectionRequestCountsViewModel());

            // Fast out, if there is no logged in person then just return a
            // bunch of zeros for now. Later if we add other counts we might
            // need more complex logic.
            if (Person == null)
            {
                return(requestCounts);
            }

            // Find all the connection requests assigned to the person.
            var assignedToYouRequestQry = connectionRequestService.Queryable()
                                          .Where(r => connectionOpportunityIds.Contains(r.ConnectionOpportunityId) &&
                                                 r.ConnectionState == ConnectionState.Active &&
                                                 r.ConnectorPersonAliasId.HasValue &&
                                                 r.ConnectorPersonAlias.PersonId == Person.Id);

            // Group them by the connection opportunity and get the counts for
            // each opportunity.
            assignedToYouRequestQry
            .GroupBy(r => r.ConnectionOpportunityId)
            .Select(g => new
            {
                Id    = g.Key,
                Count = g.Count()
            })
            .ToList()
            .ForEach(o => requestCounts[o.Id].AssignedToYouCount = o.Count);

            return(requestCounts);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            SelectionConfig selectionConfig = SelectionConfig.Parse(selection);

            if (!selectionConfig.PlacementGroupTypeGuid.HasValue)
            {
                return(null);
            }

            var groupType   = new GroupTypeService(new RockContext()).Get(selectionConfig.PlacementGroupTypeGuid.Value);
            int?groupTypeId = null;

            if (groupType != null)
            {
                groupTypeId = groupType.Id;
            }

            var qry = new ConnectionRequestService(( RockContext )serviceInstance.Context).Queryable()
                      .Where(p => p.AssignedGroupId.HasValue && p.AssignedGroup.GroupTypeId == groupTypeId);

            Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.ConnectionRequest>(qry, parameterExpression, "p");

            return(extractedFilterExpression);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            SelectionConfig selectionConfig = SelectionConfig.Parse(selection);

            if (!selectionConfig.ConnectionOpportunityGuid.HasValue)
            {
                return(null);
            }

            var connectionOpportunity   = new ConnectionOpportunityService(new RockContext()).Get(selectionConfig.ConnectionOpportunityGuid.Value);
            int?connectionOpportunityId = null;

            if (connectionOpportunity != null)
            {
                connectionOpportunityId = connectionOpportunity.Id;
            }

            var qry = new ConnectionRequestService(( RockContext )serviceInstance.Context).Queryable()
                      .Where(p => p.ConnectionOpportunityId == connectionOpportunityId);

            Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.ConnectionRequest>(qry, parameterExpression, "p");

            return(extractedFilterExpression);
        }
 /// <summary>
 /// Handles the GridRebind event of the gConnectionRequestActivities control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
 private void gConnectionRequestActivities_GridRebind( object sender, EventArgs e )
 {
     using ( var rockContext = new RockContext() )
     {
         var connectionRequestService = new ConnectionRequestService( rockContext );
         var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
         if ( connectionRequest != null )
         {
             BindConnectionRequestActivitiesGrid( connectionRequest, rockContext );
         }
     }
 }
        /// <summary>
        /// Updates the Connection Requests to us the new To person
        /// </summary>
        protected void UpdateConnectionRequests()
        {
            //Get the selected people
            FromPersonId = ppFrom.PersonId;
            ToPersonId = ppTo.PersonId;

            // Create Needed Services
            ConnectionRequestService connectionRequestService = new ConnectionRequestService(rockContext);

            //Get Connection Requests from From person
            var assigned = connectionRequestService.Queryable().Where(a => a.ConnectorPersonAliasId == FromPersonId);

            //Set each Connection Request in From person to To person
            foreach (var x in assigned)
            {
                x.ConnectorPersonAliasId = ToPersonId;
                x.ModifiedDateTime = DateTime.Now;
                x.ModifiedByPersonAliasId = CurrentPersonAliasId;
            }

            //Save changes
            rockContext.SaveChanges();

            //Update UI
            nbSuccess.Visible = true;
        }
        /// <summary>
        /// Handles the Click event of the lbConnect 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 lbConnect_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var groupMemberService = new GroupMemberService( rockContext );
                var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext );
                var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );

                if ( connectionRequest != null &&
                    connectionRequest.PersonAlias != null &&
                    connectionRequest.ConnectionOpportunity != null )
                {
                    bool okToConnect = true;

                    GroupMember groupMember = null;

                    // Only do group member placement if the request has an assigned placement group, role, and status
                    if ( connectionRequest.AssignedGroupId.HasValue &&
                        connectionRequest.AssignedGroupMemberRoleId.HasValue &&
                        connectionRequest.AssignedGroupMemberStatus.HasValue )
                    {
                        var group = new GroupService( rockContext ).Get( connectionRequest.AssignedGroupId.Value );
                        if ( group != null )
                        {
                            // Only attempt the add if person does not already exist in group with same role
                            groupMember = groupMemberService.GetByGroupIdAndPersonIdAndGroupRoleId( connectionRequest.AssignedGroupId.Value,
                                connectionRequest.PersonAlias.PersonId, connectionRequest.AssignedGroupMemberRoleId.Value );
                            if ( groupMember == null )
                            {
                                groupMember = new GroupMember();
                                groupMember.PersonId = connectionRequest.PersonAlias.PersonId;
                                groupMember.GroupId = connectionRequest.AssignedGroupId.Value;
                                groupMember.GroupRoleId = connectionRequest.AssignedGroupMemberRoleId.Value;
                                groupMember.GroupMemberStatus = connectionRequest.AssignedGroupMemberStatus.Value;

                                foreach ( ListItem item in cblManualRequirements.Items )
                                {
                                    if ( !item.Selected && group.MustMeetRequirementsToAddMember.HasValue && group.MustMeetRequirementsToAddMember.Value )
                                    {
                                        okToConnect = false;
                                        nbRequirementsErrors.Text = "Group Requirements have not been met. Please verify all of the requirements.";
                                        nbRequirementsErrors.Visible = true;
                                        break;
                                    }
                                    else
                                    {
                                        groupMember.GroupMemberRequirements.Add( new GroupMemberRequirement
                                        {
                                            GroupRequirementId = item.Value.AsInteger(),
                                            RequirementMetDateTime = RockDateTime.Now,
                                            LastRequirementCheckDateTime = RockDateTime.Now
                                        } );
                                    }
                                }

                                if ( okToConnect )
                                {
                                    groupMemberService.Add( groupMember );
                                    if ( !string.IsNullOrWhiteSpace( connectionRequest.AssignedGroupMemberAttributeValues ) )
                                    {
                                        var savedValues = JsonConvert.DeserializeObject<Dictionary<string, string>>( connectionRequest.AssignedGroupMemberAttributeValues );
                                        if ( savedValues != null )
                                        {
                                            groupMember.LoadAttributes();
                                            foreach ( var item in savedValues )
                                            {
                                                groupMember.SetAttributeValue( item.Key, item.Value );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if ( okToConnect )
                    {
                        // ... but always record the connection activity and change the state to connected.
                        var guid = Rock.SystemGuid.ConnectionActivityType.CONNECTED.AsGuid();
                        var connectedActivityId = connectionActivityTypeService.Queryable()
                            .Where( t => t.Guid == guid )
                            .Select( t => t.Id )
                            .FirstOrDefault();
                        if ( connectedActivityId > 0 )
                        {
                            var connectionRequestActivity = new ConnectionRequestActivity();
                            connectionRequestActivity.ConnectionRequestId = connectionRequest.Id;
                            connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId;
                            connectionRequestActivity.ConnectionActivityTypeId = connectedActivityId;
                            connectionRequestActivity.ConnectorPersonAliasId = CurrentPersonAliasId;
                            connectionRequestActivityService.Add( connectionRequestActivity );
                        }

                        connectionRequest.ConnectionState = ConnectionState.Connected;

                        rockContext.SaveChanges();
                        if ( groupMember != null && !string.IsNullOrWhiteSpace( connectionRequest.AssignedGroupMemberAttributeValues ) )
                        {
                            groupMember.SaveAttributeValues( rockContext );
                        }

                        ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId );
                    }
                }
            }
        }
        /// <summary>
        /// Handles the SaveClick event of the dlgSearch 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 dlgSearch_SaveClick( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null &&
                    connectionRequest.ConnectionOpportunity != null &&
                    connectionRequest.ConnectionOpportunity.ConnectionType != null )
                {
                    var qrySearch = connectionRequest.ConnectionOpportunity.ConnectionType.ConnectionOpportunities.ToList();

                    if ( !string.IsNullOrWhiteSpace( tbSearchName.Text ) )
                    {
                        var searchTerms = tbSearchName.Text.ToLower().SplitDelimitedValues( true );
                        qrySearch = qrySearch.Where( o => searchTerms.Any( t => t.Contains( o.Name.ToLower() ) || o.Name.ToLower().Contains( t ) ) ).ToList();
                    }

                    var searchCampuses = cblCampus.SelectedValuesAsInt;
                    if ( searchCampuses.Count > 0 )
                    {
                        qrySearch = qrySearch.Where( o => o.ConnectionOpportunityCampuses.Any( c => searchCampuses.Contains( c.CampusId ) ) ).ToList();
                    }

                    // Filter query by any configured attribute filters
                    if ( SearchAttributes != null && SearchAttributes.Any() )
                    {
                        var attributeValueService = new AttributeValueService( rockContext );
                        var parameterExpression = attributeValueService.ParameterExpression;

                        foreach ( var attribute in SearchAttributes )
                        {
                            var filterControl = phAttributeFilters.FindControl( "filter_" + attribute.Id.ToString() );
                            if ( filterControl != null )
                            {
                                var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues, Rock.Reporting.FilterMode.SimpleFilter );
                                var expression = attribute.FieldType.Field.AttributeFilterExpression( attribute.QualifierValues, filterValues, parameterExpression );
                                if ( expression != null )
                                {
                                    var attributeValues = attributeValueService
                                        .Queryable()
                                        .Where( v => v.Attribute.Id == attribute.Id );

                                    attributeValues = attributeValues.Where( parameterExpression, expression, null );

                                    qrySearch = qrySearch.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) ).ToList();
                                }
                            }
                        }
                    }
                    rptSearchResult.DataSource = qrySearch;
                    rptSearchResult.DataBind();
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the btnTransferSave 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 btnTransferSave_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext );
                var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );

                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null )
                {
                    int? newOpportunityId = ddlTransferOpportunity.SelectedValueAsId();
                    int? newStatusId = ddlTransferStatus.SelectedValueAsId();

                    var guid = Rock.SystemGuid.ConnectionActivityType.TRANSFERRED.AsGuid();
                    var transferredActivityId = connectionActivityTypeService.Queryable()
                        .Where( t => t.Guid == guid )
                        .Select( t => t.Id )
                        .FirstOrDefault();

                    if ( newOpportunityId.HasValue && newStatusId.HasValue && transferredActivityId > 0 )
                    {
                        ConnectionRequestActivity connectionRequestActivity = new ConnectionRequestActivity();
                        connectionRequestActivity.ConnectionRequestId = connectionRequest.Id;
                        connectionRequestActivity.ConnectionOpportunityId = newOpportunityId.Value;
                        connectionRequestActivity.ConnectionActivityTypeId = transferredActivityId;
                        connectionRequestActivity.Note = tbTransferNote.Text;
                        connectionRequestActivityService.Add( connectionRequestActivity );

                        connectionRequest.ConnectionOpportunityId = newOpportunityId.Value;
                        connectionRequest.ConnectionStatusId = newStatusId.Value;
                        connectionRequest.AssignedGroupId = null;
                        connectionRequest.AssignedGroupMemberRoleId = null;
                        connectionRequest.AssignedGroupMemberStatus = null;

                        if ( cbClearConnector.Checked )
                        {
                            connectionRequest.ConnectorPersonAliasId = null;
                        }

                        rockContext.SaveChanges();

                        pnlReadDetails.Visible = true;
                        wpConnectionRequestActivities.Visible = true;
                        wpConnectionRequestWorkflow.Visible = true;
                        pnlTransferDetails.Visible = false;

                        ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId );
                    }
                }
            }
        }
        /// <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 )
        {
            if ( ! ppRequestor.PersonAliasId.HasValue )
            {
                ShowErrorMessage( "Incomplete", "You must select a person to save a request." );
                return;
            }

            if ( Page.IsValid )
            {
                using ( var rockContext = new RockContext() )
                {
                    ConnectionRequestService connectionRequestService = new ConnectionRequestService( rockContext );
                    ConnectionRequest connectionRequest = null;

                    int connectionRequestId = hfConnectionRequestId.ValueAsInt();

                    // if adding a new connection request
                    if ( connectionRequestId.Equals( 0 ) )
                    {
                        connectionRequest = new ConnectionRequest();
                        connectionRequest.ConnectionOpportunityId = hfConnectionOpportunityId.ValueAsInt();
                        if ( ddlCampus.SelectedValueAsId().HasValue )
                        {
                            SetUserPreference( CAMPUS_SETTING, ddlCampus.SelectedValueAsId().Value.ToString() );
                        }
                    }
                    else
                    {
                        // load existing connection request
                        connectionRequest = connectionRequestService.Get( connectionRequestId );
                    }

                    var personAliasService = new PersonAliasService( rockContext );

                    int? oldConnectorPersonAliasId = connectionRequest.ConnectorPersonAliasId;
                    int? newConnectorPersonId = ddlConnectorEdit.SelectedValueAsId();
                    int? newConnectorPersonAliasId = newConnectorPersonId.HasValue ? personAliasService.GetPrimaryAliasId( newConnectorPersonId.Value ) : (int?)null;

                    connectionRequest.ConnectorPersonAliasId = newConnectorPersonAliasId;
                    connectionRequest.PersonAlias = personAliasService.Get( ppRequestor.PersonAliasId.Value );
                    connectionRequest.ConnectionState = rblState.SelectedValueAsEnum<ConnectionState>();
                    connectionRequest.ConnectionStatusId = rblStatus.SelectedValueAsId().Value;

                    if ( ddlCampus.SelectedValueAsId().HasValue )
                    {
                        connectionRequest.CampusId = ddlCampus.SelectedValueAsId().Value;
                    }

                    connectionRequest.AssignedGroupId = ddlPlacementGroup.SelectedValueAsId();
                    connectionRequest.AssignedGroupMemberRoleId = ddlPlacementGroupRole.SelectedValueAsInt();
                    connectionRequest.AssignedGroupMemberStatus = ddlPlacementGroupStatus.SelectedValueAsEnumOrNull<GroupMemberStatus>();
                    connectionRequest.AssignedGroupMemberAttributeValues = GetGroupMemberAttributeValues();

                    connectionRequest.Comments = tbComments.Text.ScrubHtmlAndConvertCrLfToBr();
                    connectionRequest.FollowupDate = dpFollowUp.SelectedDate;

                    if ( !Page.IsValid )
                    {
                        return;
                    }

                    // if the connectionRequest IsValue is false, and the UI controls didn't report any errors, it is probably
                    // because the custom rules of ConnectionRequest didn't pass.
                    // So, make sure a message is displayed in the validation summary.
                    cvConnectionRequest.IsValid = connectionRequest.IsValid;

                    if ( !cvConnectionRequest.IsValid )
                    {
                        cvConnectionRequest.ErrorMessage = connectionRequest.ValidationResults.Select( a => a.ErrorMessage ).ToList().AsDelimited( "<br />" );
                        return;
                    }

                    if ( connectionRequest.Id.Equals( 0 ) )
                    {
                        connectionRequestService.Add( connectionRequest );
                    }

                    rockContext.SaveChanges();

                    if ( newConnectorPersonAliasId.HasValue && !newConnectorPersonAliasId.Equals( oldConnectorPersonAliasId ) )
                    {
                        var guid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid();
                        var assignedActivityId = new ConnectionActivityTypeService( rockContext ).Queryable()
                            .Where( t => t.Guid == guid )
                            .Select( t => t.Id )
                            .FirstOrDefault();
                        if ( assignedActivityId > 0 )
                        {
                            var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );
                            var connectionRequestActivity = new ConnectionRequestActivity();
                            connectionRequestActivity.ConnectionRequestId = connectionRequest.Id;
                            connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId;
                            connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId;
                            connectionRequestActivity.ConnectorPersonAliasId = newConnectorPersonAliasId;
                            connectionRequestActivityService.Add( connectionRequestActivity );
                            rockContext.SaveChanges();
                        }
                    }

                    var qryParams = new Dictionary<string, string>();
                    qryParams["ConnectionRequestId"] = connectionRequest.Id.ToString();
                    qryParams["ConnectionOpportunityId"] = connectionRequest.ConnectionOpportunityId.ToString();

                    NavigateToPage( RockPage.Guid, qryParams );
                }
            }
        }
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="connectionRequestId">The connection request identifier.</param>
        /// <param name="connectionOpportunityId">The connectionOpportunity id.</param>
        public void ShowDetail( int connectionRequestId, int? connectionOpportunityId )
        {
            bool editAllowed = UserCanEdit;

            // autoexpand the person picker if this is an add
            this.Page.ClientScript.RegisterStartupScript(
                this.GetType(),
                "StartupScript", @"Sys.Application.add_load(function () {

                // if the person picker is empty then open it for quick entry
                var personPicker = $('.js-authorizedperson');
                var currentPerson = personPicker.find('.picker-selectedperson').html();
                if (currentPerson != null && currentPerson.length == 0) {
                    $(personPicker).find('a.picker-label').trigger('click');
                }

            });", true );

            using ( var rockContext = new RockContext() )
            {
                var connectionOpportunityService = new ConnectionOpportunityService( rockContext );
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionStatusService = new ConnectionStatusService( rockContext );

                ConnectionOpportunity connectionOpportunity = null;
                ConnectionRequest connectionRequest = null;

                if ( connectionRequestId > 0 )
                {
                    connectionRequest = new ConnectionRequestService( rockContext ).Get( connectionRequestId );
                }

                if ( connectionRequest == null )
                {
                    connectionOpportunity = connectionOpportunityService.Get( connectionOpportunityId.Value );
                    if ( connectionOpportunity != null )
                    {
                        var connectionStatus = connectionStatusService
                            .Queryable()
                            .Where( s =>
                                s.ConnectionTypeId == connectionOpportunity.ConnectionTypeId &&
                                s.IsDefault )
                            .FirstOrDefault();

                        if ( connectionStatus != null )
                        {
                            connectionRequest = new ConnectionRequest();
                            connectionRequest.ConnectionOpportunity = connectionOpportunity;
                            connectionRequest.ConnectionOpportunityId = connectionOpportunity.Id;
                            connectionRequest.ConnectionState = ConnectionState.Active;
                            connectionRequest.ConnectionStatus = connectionStatus;
                            connectionRequest.ConnectionStatusId = connectionStatus.Id;

                            int? campusId = GetUserPreference( CAMPUS_SETTING ).AsIntegerOrNull();
                            if ( campusId.HasValue )
                            {
                                connectionRequest.CampusId = campusId.Value;
                            }
                        }
                    }
                }
                else
                {
                    connectionOpportunity = connectionRequest.ConnectionOpportunity;
                }

                if ( connectionOpportunity != null && connectionRequest != null )
                {
                    hfConnectionOpportunityId.Value = connectionRequest.ConnectionOpportunityId.ToString();
                    hfConnectionRequestId.Value = connectionRequest.Id.ToString();
                    lConnectionOpportunityIconHtml.Text = string.Format( "<i class='{0}' ></i>", connectionOpportunity.IconCssClass );

                    pnlReadDetails.Visible = true;

                    if ( connectionRequest.PersonAlias != null && connectionRequest.PersonAlias.Person != null )
                    {
                        lTitle.Text = connectionRequest.PersonAlias.Person.FullName.FormatAsHtmlTitle();
                    }
                    else
                    {
                        lTitle.Text = String.Format( "New {0} Connection Request", connectionOpportunity.Name );
                    }

                    // Only users that have Edit rights to block, or edit rights to the opportunity
                    if ( !editAllowed )
                    {
                        editAllowed = connectionRequest.IsAuthorized( Authorization.EDIT, CurrentPerson );
                    }

                    // Grants edit access to those in the opportunity's connector groups
                    if ( !editAllowed && CurrentPersonId.HasValue )
                    {
                        // Grant edit access to any of those in a non campus-specific connector group
                        editAllowed = connectionOpportunity.ConnectionOpportunityConnectorGroups
                            .Any( g =>
                                !g.CampusId.HasValue &&
                                g.ConnectorGroup != null &&
                                g.ConnectorGroup.Members.Any( m => m.PersonId == CurrentPersonId ) );

                        if ( !editAllowed )
                        {
                            //If this is a new request, grant edit access to any connector group. Otherwise, match the request's campus to the corresponding campus-specific connector group
                            foreach ( var groupCampus in connectionOpportunity
                                .ConnectionOpportunityConnectorGroups
                                .Where( g =>
                                    ( connectionRequest.Id == 0 || ( connectionRequest.CampusId.HasValue && g.CampusId == connectionRequest.CampusId.Value ) ) &&
                                    g.ConnectorGroup != null &&
                                    g.ConnectorGroup.Members.Any( m => m.PersonId == CurrentPersonId ) ) )
                            {
                                editAllowed = true;
                                break;
                            }
                        }
                    }

                    lbConnect.Visible = editAllowed;
                    lbEdit.Visible = editAllowed;
                    lbTransfer.Visible = editAllowed;
                    gConnectionRequestActivities.IsDeleteEnabled = editAllowed;
                    gConnectionRequestActivities.Actions.ShowAdd = editAllowed;

                    if ( !editAllowed )
                    {
                        // User is not authorized
                        nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( ConnectionRequest.FriendlyTypeName );
                        ShowReadonlyDetails( connectionRequest );
                    }
                    else
                    {
                        nbEditModeMessage.Text = string.Empty;
                        if ( connectionRequest.Id > 0 )
                        {
                            ShowReadonlyDetails( connectionRequest );
                        }
                        else
                        {
                            ShowEditDetails( connectionRequest, rockContext );
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the btnEdit 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 btnConnect_Click(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var opportunityService       = new ConnectionOpportunityService(rockContext);
                var connectionRequestService = new ConnectionRequestService(rockContext);
                var personService            = new PersonService(rockContext);

                Person person = null;

                string firstName         = tbFirstName.Text.Trim();
                string lastName          = tbLastName.Text.Trim();
                string email             = tbEmail.Text.Trim();
                string mobilePhoneNumber = pnMobile.Text.Trim();
                int?   campusId          = cpCampus.SelectedCampusId;

                // if a person guid was passed in from the query string use that
                if (RockPage.PageParameter("PersonGuid") != null && !string.IsNullOrWhiteSpace(RockPage.PageParameter("PersonGuid")))
                {
                    Guid?personGuid = RockPage.PageParameter("PersonGuid").AsGuidOrNull();

                    if (personGuid.HasValue)
                    {
                        person = personService.Get(personGuid.Value);
                    }
                }
                else if (CurrentPerson != null &&
                         CurrentPerson.LastName.Equals(lastName, StringComparison.OrdinalIgnoreCase) &&
                         (CurrentPerson.NickName.Equals(firstName, StringComparison.OrdinalIgnoreCase) || CurrentPerson.FirstName.Equals(firstName, StringComparison.OrdinalIgnoreCase)) &&
                         CurrentPerson.Email.Equals(email, StringComparison.OrdinalIgnoreCase))
                {
                    // If the name and email entered are the same as current person (wasn't changed), use the current person
                    person = personService.Get(CurrentPerson.Id);
                }
                else
                {
                    // Try to find matching person
                    var personQuery = new PersonService.PersonMatchQuery(firstName, lastName, email, mobilePhoneNumber);
                    person = personService.FindPerson(personQuery, true);
                }

                // If person was not found, create a new one
                if (person == null)
                {
                    // If a match was not found, create a new person
                    var dvcConnectionStatus = DefinedValueCache.Get(GetAttributeValue("ConnectionStatus").AsGuid());
                    var dvcRecordStatus     = DefinedValueCache.Get(GetAttributeValue("RecordStatus").AsGuid());

                    person                   = new Person();
                    person.FirstName         = firstName;
                    person.LastName          = lastName;
                    person.IsEmailActive     = true;
                    person.Email             = email;
                    person.EmailPreference   = EmailPreference.EmailAllowed;
                    person.RecordTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                    if (dvcConnectionStatus != null)
                    {
                        person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                    }
                    if (dvcRecordStatus != null)
                    {
                        person.RecordStatusValueId = dvcRecordStatus.Id;
                    }

                    PersonService.SaveNewPerson(person, rockContext, campusId, false);
                    person = personService.Get(person.Id);
                }

                // If there is a valid person with a primary alias, continue
                if (person != null && person.PrimaryAliasId.HasValue)
                {
                    if (pnHome.Visible)
                    {
                        SavePhone(pnHome, person, _homePhone.Guid);
                    }

                    if (pnMobile.Visible)
                    {
                        SavePhone(pnMobile, person, _cellPhone.Guid);
                    }

                    //
                    // Now that we have a person, we can create the Connection Request
                    // Walk each of the controls found and determine if we need to
                    // take any action for the value of that control.
                    //
                    var checkboxes = new List <Control>();
                    var types      = new Type[] { typeof(CheckBox), typeof(RadioButton) };
                    KFSFindControlsRecursive(phConnections, types, ref checkboxes);

                    foreach (CheckBox box in checkboxes)
                    {
                        if (box.Checked)
                        {
                            int opportunityId = box.ID.AsInteger();
                            var opportunity   = opportunityService
                                                .Queryable()
                                                .Where(o => o.Id == opportunityId)
                                                .FirstOrDefault();

                            int defaultStatusId = opportunity.ConnectionType.ConnectionStatuses
                                                  .Where(s => s.IsDefault)
                                                  .Select(s => s.Id)
                                                  .FirstOrDefault();

                            // If opportunity is valid and has a default status
                            if (opportunity != null && defaultStatusId > 0)
                            {
                                var personCampus = person.GetCampus();
                                if (personCampus != null)
                                {
                                    campusId = personCampus.Id;
                                }

                                var connectionRequest = new ConnectionRequest();
                                connectionRequest.PersonAliasId           = person.PrimaryAliasId.Value;
                                connectionRequest.Comments                = tbComments.Text.Trim();
                                connectionRequest.ConnectionOpportunityId = opportunity.Id;
                                connectionRequest.ConnectionState         = ConnectionState.Active;
                                connectionRequest.ConnectionStatusId      = defaultStatusId;
                                connectionRequest.CampusId                = campusId;
                                connectionRequest.ConnectorPersonAliasId  = opportunity.GetDefaultConnectorPersonAliasId(campusId);
                                if (campusId.HasValue &&
                                    opportunity != null &&
                                    opportunity.ConnectionOpportunityCampuses != null)
                                {
                                    var campus = opportunity.ConnectionOpportunityCampuses
                                                 .Where(c => c.CampusId == campusId.Value)
                                                 .FirstOrDefault();
                                    if (campus != null)
                                    {
                                        connectionRequest.ConnectorPersonAliasId = campus.DefaultConnectorPersonAliasId;
                                    }
                                }

                                if (!connectionRequest.IsValid)
                                {
                                    // Controls will show warnings
                                    return;
                                }

                                connectionRequestService.Add(connectionRequest);

                                rockContext.SaveChanges();

                                var mergeFields = new Dictionary <string, object>();
                                mergeFields.Add("CurrentPerson", CurrentPerson);
                                mergeFields.Add("Person", person);

                                lResponseMessage.Text    = GetAttributeValue("LavaTemplate").ResolveMergeFields(mergeFields);
                                lResponseMessage.Visible = true;

                                pnlSignup.Visible = false;
                            }
                        }
                    }
                }
            }
        }
Exemple #36
0
        /// <summary>
        /// Deletes the family's addresses, phone numbers, photos, viewed records, and people.
        /// TODO: delete attendance codes for attendance data that's about to be deleted when
        /// we delete the person record.
        /// </summary>
        /// <param name="families">The families.</param>
        /// <param name="rockContext">The rock context.</param>
        private void DeleteExistingFamilyData( XElement families, RockContext rockContext )
        {
            PersonService personService = new PersonService( rockContext );
            PhoneNumberService phoneNumberService = new PhoneNumberService( rockContext );
            PersonViewedService personViewedService = new PersonViewedService( rockContext );
            PageViewService pageViewService = new PageViewService( rockContext );
            BinaryFileService binaryFileService = new BinaryFileService( rockContext );
            PersonAliasService personAliasService = new PersonAliasService( rockContext );
            PersonDuplicateService personDuplicateService = new PersonDuplicateService( rockContext );
            NoteService noteService = new NoteService( rockContext );
            AuthService authService = new AuthService( rockContext );
            CommunicationService communicationService = new CommunicationService( rockContext );
            CommunicationRecipientService communicationRecipientService = new CommunicationRecipientService( rockContext );
            FinancialBatchService financialBatchService = new FinancialBatchService( rockContext );
            FinancialTransactionService financialTransactionService = new FinancialTransactionService( rockContext );
            PersonPreviousNameService personPreviousNameService = new PersonPreviousNameService( rockContext );
            ConnectionRequestService connectionRequestService = new ConnectionRequestService( rockContext );
            ConnectionRequestActivityService connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );

            // delete the batch data
            List<int> imageIds = new List<int>();
            foreach ( var batch in financialBatchService.Queryable().Where( b => b.Name.StartsWith( "SampleData" ) ) )
            {
                imageIds.AddRange( batch.Transactions.SelectMany( t => t.Images ).Select( i => i.BinaryFileId ).ToList() );
                financialTransactionService.DeleteRange( batch.Transactions );
                financialBatchService.Delete( batch );
            }

            // delete all transaction images
            foreach ( var image in binaryFileService.GetByIds( imageIds ) )
            {
                binaryFileService.Delete( image );
            }

            foreach ( var elemFamily in families.Elements( "family" ) )
            {
                Guid guid = elemFamily.Attribute( "guid" ).Value.Trim().AsGuid();

                GroupService groupService = new GroupService( rockContext );
                Group family = groupService.Get( guid );
                if ( family != null )
                {
                    var groupMemberService = new GroupMemberService( rockContext );
                    var members = groupMemberService.GetByGroupId( family.Id, true );

                    // delete the people records
                    string errorMessage;
                    List<int> photoIds = members.Select( m => m.Person ).Where( p => p.PhotoId != null ).Select( a => (int)a.PhotoId ).ToList();

                    foreach ( var person in members.Select( m => m.Person ) )
                    {
                        person.GivingGroup = null;
                        person.GivingGroupId = null;
                        person.PhotoId = null;

                        // delete phone numbers
                        foreach ( var phone in phoneNumberService.GetByPersonId( person.Id ) )
                        {
                            if ( phone != null )
                            {
                                phoneNumberService.Delete( phone );
                            }
                        }

                        // delete communication recipient
                        foreach ( var recipient in communicationRecipientService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id ) )
                        {
                            communicationRecipientService.Delete( recipient );
                        }

                        // delete communication
                        foreach ( var communication in communicationService.Queryable().Where( c => c.SenderPersonAliasId == person.PrimaryAlias.Id ) )
                        {
                            communicationService.Delete( communication );
                        }

                        // delete person viewed records
                        foreach ( var view in personViewedService.GetByTargetPersonId( person.Id ) )
                        {
                            personViewedService.Delete( view );
                        }

                        // delete page viewed records
                        foreach ( var view in pageViewService.GetByPersonId( person.Id ) )
                        {
                            pageViewService.Delete( view );
                        }

                        // delete notes created by them or on their record.
                        foreach ( var note in noteService.Queryable().Where ( n => n.CreatedByPersonAlias.PersonId == person.Id
                            || (n.NoteType.EntityTypeId == _personEntityTypeId && n.EntityId == person.Id ) ) )
                        {
                            noteService.Delete( note );
                        }

                        // delete previous names on their records
                        foreach ( var previousName in personPreviousNameService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id ) )
                        {
                            personPreviousNameService.Delete( previousName );
                        }

                        // delete any GroupMember records they have
                        foreach ( var groupMember in groupMemberService.Queryable().Where( gm => gm.PersonId == person.Id ) )
                        {
                            groupMemberService.Delete( groupMember );
                        }

                        //// delete any Authorization data
                        //foreach ( var auth in authService.Queryable().Where( a => a.PersonId == person.Id ) )
                        //{
                        //    authService.Delete( auth );
                        //}

                        // delete their aliases
                        foreach ( var alias in personAliasService.Queryable().Where( a => a.PersonId == person.Id ) )
                        {
                            foreach ( var duplicate in personDuplicateService.Queryable().Where( d => d.DuplicatePersonAliasId == alias.Id ) )
                            {
                                personDuplicateService.Delete( duplicate );
                            }

                            personAliasService.Delete( alias );
                        }

                        // delete any connection requests tied to them
                        foreach ( var request in connectionRequestService.Queryable().Where( r => r.PersonAlias.PersonId == person.Id || r.ConnectorPersonAlias.PersonId == person.Id ) )
                        {
                            connectionRequestActivityService.DeleteRange( request.ConnectionRequestActivities );
                            connectionRequestService.Delete( request );
                        }

                        // Save these changes so the CanDelete passes the check...
                        //rockContext.ChangeTracker.DetectChanges();
                        rockContext.SaveChanges( disablePrePostProcessing: true );

                        if ( personService.CanDelete( person, out errorMessage ) )
                        {
                            personService.Delete( person );
                            //rockContext.ChangeTracker.DetectChanges();
                            //rockContext.SaveChanges( disablePrePostProcessing: true );
                        }
                        else
                        {
                            throw new Exception( string.Format( "Trying to delete {0}, but: {1}", person.FullName, errorMessage ) );
                        }
                    }

                    //rockContext.ChangeTracker.DetectChanges();
                    rockContext.SaveChanges( disablePrePostProcessing: true );

                    // delete all member photos
                    foreach ( var photo in binaryFileService.GetByIds( photoIds ) )
                    {
                        binaryFileService.Delete( photo );
                    }

                    DeleteGroupAndMemberData( family, rockContext );
                }
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            OpportunitySummary opportunitySummary = null;

            if (SelectedOpportunityId.HasValue)
            {
                opportunitySummary = SummaryState.SelectMany(t => t.Opportunities.Where(o => o.Id == SelectedOpportunityId.Value)).FirstOrDefault();
            }

            if (opportunitySummary != null)
            {
                using (var rockContext = new RockContext())
                {
                    // Get queryable of all requests that belong to the selected opportunity, and user is authorized to view (based on security or connector group)
                    var requests = new ConnectionRequestService(rockContext)
                                   .Queryable().AsNoTracking()
                                   .Where(r =>
                                          r.ConnectionOpportunityId == SelectedOpportunityId.Value &&
                                          (
                                              !opportunitySummary.CampusSpecificConnector ||
                                              (r.CampusId.HasValue && opportunitySummary.ConnectorCampusIds.Contains(r.CampusId.Value))
                                          ));

                    // Filter by Requester
                    if (ppRequester.PersonId.HasValue)
                    {
                        requests = requests
                                   .Where(r =>
                                          r.PersonAlias != null &&
                                          r.PersonAlias.PersonId == ppRequester.PersonId.Value);
                    }

                    // Filter by Connector
                    if (tglMyOpportunities.Checked)
                    {
                        requests = requests
                                   .Where(r =>
                                          r.ConnectorPersonAlias != null &&
                                          r.ConnectorPersonAlias.PersonId == CurrentPersonId);
                    }
                    else if (ppConnector.PersonId.HasValue)
                    {
                        requests = requests
                                   .Where(r =>
                                          r.ConnectorPersonAlias != null &&
                                          r.ConnectorPersonAlias.PersonId == ppConnector.PersonId.Value);
                    }

                    // Filter by State

                    if (tglMyOpportunities.Checked)
                    {
                        requests = requests
                                   .Where(r => r.ConnectionState == ConnectionState.Active ||
                                          (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday));
                    }
                    else
                    {
                        var  states         = new List <ConnectionState>();
                        bool futureFollowup = false;
                        foreach (string stateValue in cblState.SelectedValues)
                        {
                            futureFollowup = futureFollowup || stateValue.AsInteger() == -2;
                            var state = stateValue.ConvertToEnumOrNull <ConnectionState>();
                            if (state.HasValue)
                            {
                                states.Add(state.Value);
                            }
                        }
                        if (futureFollowup || states.Any())
                        {
                            requests = requests
                                       .Where(r =>
                                              (futureFollowup && r.ConnectionState == ConnectionState.FutureFollowUp &&
                                               r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday) ||
                                              states.Contains(r.ConnectionState));
                        }
                    }

                    // Filter by Status
                    List <int> statusIds = cblStatus.SelectedValuesAsInt;
                    if (statusIds.Any())
                    {
                        requests = requests
                                   .Where(r => statusIds.Contains(r.ConnectionStatusId));
                    }

                    // Filter by Campus
                    List <int> campusIds = cblCampus.SelectedValuesAsInt;
                    if (campusIds.Count > 0)
                    {
                        requests = requests
                                   .Where(r =>
                                          r.Campus != null &&
                                          campusIds.Contains(r.CampusId.Value));
                    }

                    // Filter by Last Activity Note
                    List <int> lastActivityIds = cblLastActivity.SelectedValuesAsInt;
                    if (lastActivityIds.Any())
                    {
                        requests = requests
                                   .Where(r => lastActivityIds.Contains(
                                              r.ConnectionRequestActivities.OrderByDescending(a => a.CreatedDateTime).Select(a => a.ConnectionActivityTypeId).FirstOrDefault()));
                    }


                    SortProperty sortProperty = gRequests.SortProperty;
                    if (sortProperty != null)
                    {
                        requests = requests.Sort(sortProperty);
                    }
                    else
                    {
                        requests = requests
                                   .OrderBy(r => r.PersonAlias.Person.LastName)
                                   .ThenBy(r => r.PersonAlias.Person.NickName);
                    }

                    gRequests.DataSource = requests.ToList()
                                           .Select(r => new
                    {
                        r.Id,
                        r.Guid,
                        PersonId         = r.PersonAlias.PersonId,
                        Name             = r.PersonAlias.Person.FullNameReversed,
                        Campus           = r.Campus,
                        Group            = r.AssignedGroup != null ? r.AssignedGroup.Name : "",
                        Connector        = r.ConnectorPersonAlias != null ? r.ConnectorPersonAlias.Person.FullName : "",
                        LastActivity     = FormatActivity(r.ConnectionRequestActivities.OrderByDescending(a => a.CreatedDateTime).FirstOrDefault()),
                        LastActivityNote = gRequests.Columns[6].Visible ? r.ConnectionRequestActivities.OrderByDescending(
                            a => a.CreatedDateTime).Select(a => a.Note).FirstOrDefault() : "",
                        Status          = r.ConnectionStatus.Name,
                        StatusLabel     = r.ConnectionStatus.IsCritical ? "warning" : "info",
                        ConnectionState = r.ConnectionState,
                        StateLabel      = FormatStateLabel(r.ConnectionState, r.FollowupDate)
                    })
                                           .ToList();
                    gRequests.DataBind();

                    lOpportunityIcon.Text   = string.Format("<i class='{0}'></i>", opportunitySummary.IconCssClass);
                    lConnectionRequest.Text = String.Format("{0} Connection Requests", opportunitySummary.Name);
                }
            }
            else
            {
                pnlGrid.Visible = false;
            }
        }
        /// <summary>
        /// Gets the summary data.
        /// </summary>
        private void GetSummaryData()
        {
            SummaryState = new List <ConnectionTypeSummary>();

            var rockContext   = new RockContext();
            var opportunities = new ConnectionOpportunityService(rockContext)
                                .Queryable().AsNoTracking();

            var typeFilter = GetAttributeValue("ConnectionTypes").SplitDelimitedValues().AsGuidList();

            if (typeFilter.Any())
            {
                opportunities = opportunities.Where(o => typeFilter.Contains(o.ConnectionType.Guid));
            }

            // Loop through opportunities
            foreach (var opportunity in opportunities)
            {
                // Check to see if person can view the opportunity because of admin rights to this block or admin rights to
                // the opportunity
                bool canView = UserCanAdministrate || opportunity.IsAuthorized(Authorization.ADMINISTRATE, CurrentPerson);
                bool campusSpecificConnector = false;
                var  campusIds = new List <int>();

                if (CurrentPersonId.HasValue)
                {
                    // Check to see if person belongs to any connector group that is not campus specific
                    if (!canView)
                    {
                        canView = opportunity
                                  .ConnectionOpportunityConnectorGroups
                                  .Any(g =>
                                       !g.CampusId.HasValue &&
                                       g.ConnectorGroup != null &&
                                       g.ConnectorGroup.Members.Any(m => m.PersonId == CurrentPersonId.Value));
                    }

                    // If user is not yet authorized to view the opportunity, check to see if they are a member of one of the
                    // campus-specific connector groups for the opportunity, and note the campus
                    if (!canView)
                    {
                        foreach (var groupCampus in opportunity
                                 .ConnectionOpportunityConnectorGroups
                                 .Where(g =>
                                        g.CampusId.HasValue &&
                                        g.ConnectorGroup != null &&
                                        g.ConnectorGroup.Members.Any(m => m.PersonId == CurrentPersonId.Value)))
                        {
                            campusSpecificConnector = true;
                            canView = true;
                            campusIds.Add(groupCampus.CampusId.Value);
                        }
                    }
                }

                // Is user is authorized to view this opportunity type...
                if (canView)
                {
                    // Check if the opportunity's type has been added to summary yet, and if not, add it
                    var connectionTypeSummary = SummaryState.Where(c => c.Id == opportunity.ConnectionTypeId).FirstOrDefault();
                    if (connectionTypeSummary == null)
                    {
                        connectionTypeSummary = new ConnectionTypeSummary
                        {
                            Id            = opportunity.ConnectionTypeId,
                            Name          = opportunity.ConnectionType.Name,
                            Opportunities = new List <OpportunitySummary>()
                        };
                        SummaryState.Add(connectionTypeSummary);
                    }

                    // Count number of idle requests (no activity in past X days)

                    var connectionRequestsQry = new ConnectionRequestService(rockContext).Queryable().Where(a => a.ConnectionOpportunityId == opportunity.Id);
                    var currentDateTime       = RockDateTime.Now;
                    int idleCount             = connectionRequestsQry
                                                .Where(cr =>
                                                       (
                                                           cr.ConnectionState == ConnectionState.Active ||
                                                           (cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < _midnightToday)
                                                       ) &&
                                                       (
                                                           (cr.ConnectionRequestActivities.Any() && cr.ConnectionRequestActivities.Max(ra => ra.CreatedDateTime) < SqlFunctions.DateAdd("day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime))) ||
                                                       (!cr.ConnectionRequestActivities.Any() && cr.CreatedDateTime < SqlFunctions.DateAdd("day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime))
                                                       )
                                                .Count();

                    // Count the number requests that have a status that is considered critical.
                    int criticalCount = connectionRequestsQry
                                        .Where(r =>
                                               r.ConnectionStatus.IsCritical &&
                                               (
                                                   r.ConnectionState == ConnectionState.Active ||
                                                   (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday)
                                               )
                                               )
                                        .Count();

                    // Add the opportunity
                    var opportunitySummary = new OpportunitySummary
                    {
                        Id            = opportunity.Id,
                        Name          = opportunity.Name,
                        IconCssClass  = opportunity.IconCssClass,
                        IdleCount     = idleCount,
                        CriticalCount = criticalCount
                    };

                    // If the user is limited requests with specific campus(es) set the list, otherwise leave it to be null
                    opportunitySummary.CampusSpecificConnector = campusSpecificConnector;
                    opportunitySummary.ConnectorCampusIds      = campusIds.Distinct().ToList();

                    connectionTypeSummary.Opportunities.Add(opportunitySummary);
                }
            }

            // Get a list of all the authorized opportunity ids
            var allOpportunities = SummaryState.SelectMany(s => s.Opportunities).Select(o => o.Id).Distinct().ToList();

            // Get all the active and past-due future followup request ids, and include the campus id and personid of connector
            var midnightToday  = RockDateTime.Today.AddDays(1);
            var activeRequests = new ConnectionRequestService(rockContext)
                                 .Queryable().AsNoTracking()
                                 .Where(r =>
                                        allOpportunities.Contains(r.ConnectionOpportunityId) &&
                                        (r.ConnectionState == ConnectionState.Active ||
                                         (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday)))
                                 .Select(r => new
            {
                r.ConnectionOpportunityId,
                r.CampusId,
                ConnectorPersonId = r.ConnectorPersonAlias != null ? r.ConnectorPersonAlias.PersonId : -1
            })
                                 .ToList();

            // Based on the active requests, set additional properties for each opportunity
            foreach (var opportunity in SummaryState.SelectMany(s => s.Opportunities))
            {
                // Get the active requests for this opportunity that user is authorized to view (based on campus connector)
                var opportunityRequests = activeRequests
                                          .Where(r =>
                                                 r.ConnectionOpportunityId == opportunity.Id &&
                                                 (
                                                     !opportunity.CampusSpecificConnector ||
                                                     (r.CampusId.HasValue && opportunity.ConnectorCampusIds.Contains(r.CampusId.Value))
                                                 ))
                                          .ToList();

                // The count of active requests assigned to the current person
                opportunity.AssignedToYou = opportunityRequests.Count(r => r.ConnectorPersonId == CurrentPersonId);

                // The count of active requests that are unassigned
                opportunity.UnassignedCount = opportunityRequests.Count(r => r.ConnectorPersonId == -1);

                // Flag indicating if current user is connector for any of the active types
                opportunity.HasActiveRequestsForConnector = opportunityRequests.Any(r => r.ConnectorPersonId == CurrentPersonId);
            }

            //Set the Idle tooltip
            var           connectionTypes = opportunities.Where(o => allOpportunities.Contains(o.Id)).Select(o => o.ConnectionType).Distinct().ToList();
            StringBuilder sb = new StringBuilder();

            if (connectionTypes.Select(t => t.DaysUntilRequestIdle).Distinct().Count() == 1)
            {
                sb.Append(String.Format("Idle (no activity in {0} days)", connectionTypes.Select(t => t.DaysUntilRequestIdle).Distinct().First()));
            }
            else
            {
                sb.Append("Idle (no activity in several days)<br/><ul class='list-unstyled'>");
                foreach (var connectionType in connectionTypes)
                {
                    sb.Append(String.Format("<li>{0}: {1} days</li>", connectionType.Name, connectionType.DaysUntilRequestIdle));
                }
                sb.Append("</ul>");
            }

            var statusTemplate    = this.GetAttributeValue("StatusTemplate");
            var statusMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage);

            statusMergeFields.Add("ConnectionOpportunities", allOpportunities);
            statusMergeFields.Add("ConnectionTypes", connectionTypes);
            statusMergeFields.Add("IdleTooltip", sb.ToString());
            lStatusBarContent.Text = statusTemplate.ResolveMergeFields(statusMergeFields);
            BindSummaryData();
        }
Exemple #39
0
        /// <summary>
        /// Adds the connections requests to the system from the given XML element.
        /// </summary>
        /// <example>
        ///   &lt;connections&gt;
        ///       &lt;connection type="Involvement" opportunity="Children's" comment="I would love to help teach kids about Jesus." date="2015-10-11T00:00:00" personGuid="1dfff821-e97c-4324-9883-cf59b5c5bdd6" /&gt;
        ///   &lt;/connections&gt;
        /// </example>
        /// <param name="elemConnections">The elem connections.</param>
        /// <param name="rockContext">The rock context.</param>
        private void AddConnections( XElement elemConnections, RockContext rockContext )
        {
            if ( elemConnections == null )
            {
                return;
            }

            ConnectionRequestService crService = new ConnectionRequestService( rockContext );
            ConnectionOpportunityService coService = new ConnectionOpportunityService( rockContext );
            ConnectionTypeService typeService = new ConnectionTypeService( rockContext );
            ConnectionStatusService connectionStatusService = new ConnectionStatusService( rockContext );
            ConnectionStatus noContact = connectionStatusService.Get( "901e1a6a-0e91-4f42-880f-47c061c24e0c".AsGuid() );

            // Find the type and it's corresponding opportunity and then add a connection request for the given person.
            foreach ( var element in elemConnections.Elements( "connection" ) )
            {
                string connectionTypeName = element.Attribute( "type" ).Value.Trim();
                string opportunityName = element.Attribute( "opportunity" ).Value.Trim();
                string comment = element.Attribute( "comment" ).Value.Trim();
                DateTime date = DateTime.Parse( element.Attribute( "date" ).Value.Trim(), new CultureInfo( "en-US" ) );
                Guid personGuid = element.Attribute( "personGuid" ).Value.Trim().AsGuid();

                var connectionOpportunity = coService.Queryable( "ConnectionType" ).AsNoTracking().Where( co => co.ConnectionType.Name == connectionTypeName && co.Name == opportunityName ).FirstOrDefault();

                // make sure we found a matching connection opportunity
                if ( connectionOpportunity != null )
                {
                    ConnectionRequest connectionRequest = new ConnectionRequest()
                    {
                        ConnectionOpportunityId = connectionOpportunity.Id,
                        PersonAliasId = _peopleAliasDictionary[personGuid],
                        Comments = comment,
                        ConnectionStatus = noContact,
                        ConnectionState = global::ConnectionState.Active,
                        CreatedDateTime = date
                    };

                    crService.Add( connectionRequest );
                }
            }
        }
        /// <summary>
        /// Handles the SelectedIndexChanged event of the ddlCampus 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 ddlCampus_SelectedIndexChanged( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest == null )
                {
                    connectionRequest = new ConnectionRequest();
                    connectionRequest.ConnectionOpportunity = new ConnectionOpportunityService( rockContext ).Get( hfConnectionOpportunityId.ValueAsInt() );
                }

                RebindConnectors( connectionRequest, ddlCampus.SelectedValueAsInt(), rockContext );
            }
        }
        /// <summary>
        /// Shows the activity dialog.
        /// </summary>
        /// <param name="activityGuid">The activity unique identifier.</param>
        private void ShowActivityDialog( Guid activityGuid )
        {
            ddlActivity.Items.Clear();
            ddlActivity.Items.Add( new ListItem( string.Empty, string.Empty ) );

            var connectors = new Dictionary<int, Person>();
            ConnectionRequestActivity activity = null;

            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null &&
                    connectionRequest.ConnectionOpportunity != null &&
                    connectionRequest.ConnectionOpportunity.ConnectionType != null )
                {
                    foreach ( var activityType in connectionRequest.ConnectionOpportunity.ConnectionType.ConnectionActivityTypes.OrderBy( a => a.Name ) )
                    {
                        if ( activityType.IsAuthorized( Authorization.VIEW, CurrentPerson ) )
                        {
                            ddlActivity.Items.Add( new ListItem( activityType.Name, activityType.Id.ToString() ) );
                        }
                    }

                    connectionRequest.ConnectionOpportunity.ConnectionOpportunityConnectorGroups
                        .Where( g =>
                            !g.CampusId.HasValue ||
                            !connectionRequest.CampusId.HasValue ||
                            g.CampusId.Value == connectionRequest.CampusId.Value )
                        .SelectMany( g => g.ConnectorGroup.Members )
                        .Select( m => m.Person )
                        .ToList()
                        .ForEach( p => connectors.AddOrIgnore( p.Id, p ) );
                }

                if ( activityGuid != Guid.Empty )
                {
                    activity = new ConnectionRequestActivityService( rockContext ).Get( activityGuid );
                    if ( activity != null && activity.ConnectorPersonAlias != null && activity.ConnectorPersonAlias.Person != null )
                    {
                        connectors.AddOrIgnore( activity.ConnectorPersonAlias.Person.Id, activity.ConnectorPersonAlias.Person );
                    }
                }
            }

            if ( CurrentPerson != null )
            {
                connectors.AddOrIgnore( CurrentPerson.Id, CurrentPerson );
            }

            ddlActivity.SetValue( activity != null ? activity.ConnectionActivityTypeId : 0 );

            ddlActivityConnector.Items.Clear();
            connectors
                .ToList()
                .OrderBy( p => p.Value.LastName )
                .ThenBy( p => p.Value.NickName )
                .ToList()
                .ForEach( c =>
                    ddlActivityConnector.Items.Add( new ListItem( c.Value.FullName, c.Key.ToString() ) ) );

            ddlActivityConnector.SetValue(
                activity != null && activity.ConnectorPersonAlias != null ?
                activity.ConnectorPersonAlias.PersonId : CurrentPersonId ?? 0 );

            tbNote.Text = activity != null ? activity.Note : string.Empty;

            hfAddConnectionRequestActivityGuid.Value = activityGuid.ToString();
            if ( activityGuid == Guid.Empty )
            {
                dlgConnectionRequestActivities.Title = "Add Activity";
                dlgConnectionRequestActivities.SaveButtonText = "Add";
            }
            else
            {
                dlgConnectionRequestActivities.Title = "Edit Activity";
                dlgConnectionRequestActivities.SaveButtonText = "Save";
            }

            ShowDialog( "ConnectionRequestActivities", true );
        }
        /// <summary>
        /// Gets the summary data.
        /// </summary>
        private void GetSummaryData()
        {
            SummaryState = new List<ConnectionTypeSummary>();

            var rockContext = new RockContext();
            var opportunities = new ConnectionOpportunityService( rockContext )
                .Queryable().AsNoTracking();

            var typeFilter = GetAttributeValue( "ConnectionTypes" ).SplitDelimitedValues().AsGuidList();
            if ( typeFilter.Any() )
            {
                opportunities = opportunities.Where( o => typeFilter.Contains( o.ConnectionType.Guid ) );
            }

            // Loop through opportunities
            foreach ( var opportunity in opportunities )
            {
                // Check to see if person can view the opportunity because of admin rights to this block or admin rights to
                // the opportunity
                bool canView = UserCanAdministrate || opportunity.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson );
                bool campusSpecificConnector = false;
                var campusIds = new List<int>();

                if ( CurrentPersonId.HasValue )
                {
                    // Check to see if person belongs to any connector group that is not campus specific
                    if ( !canView )
                    {
                        canView = opportunity
                            .ConnectionOpportunityConnectorGroups
                            .Any( g =>
                                !g.CampusId.HasValue &&
                                g.ConnectorGroup != null &&
                                g.ConnectorGroup.Members.Any( m => m.PersonId == CurrentPersonId.Value ) );
                    }

                    // If user is not yet authorized to view the opportunity, check to see if they are a member of one of the
                    // campus-specific connector groups for the opportunity, and note the campus
                    if ( !canView )
                    {
                        foreach ( var groupCampus in opportunity
                            .ConnectionOpportunityConnectorGroups
                            .Where( g =>
                                g.CampusId.HasValue &&
                                g.ConnectorGroup != null &&
                                g.ConnectorGroup.Members.Any( m => m.PersonId == CurrentPersonId.Value ) ) )
                        {
                            campusSpecificConnector = true;
                            canView = true;
                            campusIds.Add( groupCampus.CampusId.Value );
                        }
                    }
                }

                // Is user is authorized to view this opportunity type...
                if ( canView )
                {
                    // Check if the opportunity's type has been added to summary yet, and if not, add it
                    var connectionTypeSummary = SummaryState.Where( c => c.Id == opportunity.ConnectionTypeId ).FirstOrDefault();
                    if ( connectionTypeSummary == null )
                    {
                        connectionTypeSummary = new ConnectionTypeSummary
                        {
                            Id = opportunity.ConnectionTypeId,
                            Name = opportunity.ConnectionType.Name,
                            Opportunities = new List<OpportunitySummary>()
                        };
                        SummaryState.Add( connectionTypeSummary );
                    }

                    // Count number of idle requests (no activity in past X days)

                    var connectionRequestsQry = new ConnectionRequestService( rockContext ).Queryable().Where( a => a.ConnectionOpportunityId == opportunity.Id );
                    var currentDateTime = RockDateTime.Now;
                    int activeRequestCount = connectionRequestsQry
                        .Where( cr =>
                                cr.ConnectionState == ConnectionState.Active
                                || ( cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < _midnightToday )
                        )
                        .Count();

                    // only show if the oppportunity is active and there are active requests
                    if ( opportunity.IsActive || ( !opportunity.IsActive && activeRequestCount > 0 ) )
                    {
                        // idle count is:
                        //  (the request is active OR future follow-up who's time has come)
                        //  AND
                        //  (where the activity is more than DaysUntilRequestIdle days old OR no activity but created more than DaysUntilRequestIdle days ago)
                        int idleCount = connectionRequestsQry
                                        .Where( cr =>
                                            (
                                                cr.ConnectionState == ConnectionState.Active
                                                || ( cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < _midnightToday )
                                            )
                                            &&
                                            (
                                                ( cr.ConnectionRequestActivities.Any() && cr.ConnectionRequestActivities.Max( ra => ra.CreatedDateTime ) < SqlFunctions.DateAdd( "day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime ) )
                                                || ( !cr.ConnectionRequestActivities.Any() && cr.CreatedDateTime < SqlFunctions.DateAdd( "day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime ) )
                                            )
                                        )
                                        .Count();

                        // Count the number requests that have a status that is considered critical.
                        int criticalCount = connectionRequestsQry
                                                .Where( r =>
                                                    r.ConnectionStatus.IsCritical
                                                    && (
                                                            r.ConnectionState == ConnectionState.Active
                                                            || ( r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday )
                                                       )
                                                )
                                                .Count();

                        // Add the opportunity
                        var opportunitySummary = new OpportunitySummary
                        {
                            Id = opportunity.Id,
                            Name = opportunity.Name,
                            IsActive = opportunity.IsActive,
                            IconCssClass = opportunity.IconCssClass,
                            IdleCount = idleCount,
                            CriticalCount = criticalCount
                        };

                        // If the user is limited requests with specific campus(es) set the list, otherwise leave it to be null
                        opportunitySummary.CampusSpecificConnector = campusSpecificConnector;
                        opportunitySummary.ConnectorCampusIds = campusIds.Distinct().ToList();

                        connectionTypeSummary.Opportunities.Add( opportunitySummary );
                    }
                }
            }

            // Get a list of all the authorized opportunity ids
            var allOpportunities = SummaryState.SelectMany( s => s.Opportunities ).Select( o => o.Id ).Distinct().ToList();

            // Get all the active and past-due future followup request ids, and include the campus id and personid of connector
            var midnightToday = RockDateTime.Today.AddDays(1);
            var activeRequests = new ConnectionRequestService( rockContext )
                .Queryable().AsNoTracking()
                .Where( r =>
                    allOpportunities.Contains( r.ConnectionOpportunityId ) &&
                    ( r.ConnectionState == ConnectionState.Active ||
                        ( r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday ) ) )
                .Select( r => new
                {
                    r.ConnectionOpportunityId,
                    r.CampusId,
                    ConnectorPersonId = r.ConnectorPersonAlias != null ? r.ConnectorPersonAlias.PersonId : -1
                } )
                .ToList();

            // Based on the active requests, set additional properties for each opportunity
            foreach ( var opportunity in SummaryState.SelectMany( s => s.Opportunities ) )
            {
                // Get the active requests for this opportunity that user is authorized to view (based on campus connector)
                var opportunityRequests = activeRequests
                    .Where( r =>
                        r.ConnectionOpportunityId == opportunity.Id &&
                        (
                            !opportunity.CampusSpecificConnector ||
                            ( r.CampusId.HasValue && opportunity.ConnectorCampusIds.Contains( r.CampusId.Value ) )
                        ) )
                    .ToList();

                // The count of active requests assigned to the current person
                opportunity.AssignedToYou = opportunityRequests.Count( r => r.ConnectorPersonId == CurrentPersonId );

                // The count of active requests that are unassigned
                opportunity.UnassignedCount = opportunityRequests.Count( r => r.ConnectorPersonId == -1 );

                // Flag indicating if current user is connector for any of the active types
                opportunity.HasActiveRequestsForConnector = opportunityRequests.Any( r => r.ConnectorPersonId == CurrentPersonId );
            }

            //Set the Idle tooltip
            var connectionTypes = opportunities.Where( o => allOpportunities.Contains( o.Id ) ).Select( o => o.ConnectionType ).Distinct().ToList();
            StringBuilder sb = new StringBuilder();
            if ( connectionTypes.Select( t => t.DaysUntilRequestIdle ).Distinct().Count() == 1 )
            {
                sb.Append( String.Format( "Idle (no activity in {0} days)", connectionTypes.Select( t => t.DaysUntilRequestIdle ).Distinct().First() ) );
            }
            else
            {
                sb.Append( "Idle (no activity in several days)<br/><ul class='list-unstyled'>" );
                foreach ( var connectionType in connectionTypes )
                {
                    sb.Append( String.Format( "<li>{0}: {1} days</li>", connectionType.Name, connectionType.DaysUntilRequestIdle ) );
                }
                sb.Append( "</ul>" );
            }

            var statusTemplate = this.GetAttributeValue( "StatusTemplate" );
            var statusMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage);
            statusMergeFields.Add( "ConnectionOpportunities", allOpportunities );
            statusMergeFields.Add( "ConnectionTypes", connectionTypes );
            statusMergeFields.Add( "IdleTooltip", sb.ToString() );
            lStatusBarContent.Text = statusTemplate.ResolveMergeFields( statusMergeFields );
            BindSummaryData();
        }
        /// <summary>
        /// Shows the connectionOpportunity requirements statuses.
        /// </summary>
        private void ShowConnectionOpportunityRequirementsStatuses()
        {
            using ( var rockContext = new RockContext() )
            {
                int connectionRequestId = hfConnectionRequestId.Value.AsInteger();
                var connectionOpportunityId = hfConnectionOpportunityId.Value.AsInteger();

                IEnumerable<GroupRequirementStatus> requirementsResults = new List<PersonGroupRequirementStatus>();
                bool passedAllRequirements = true;

                var connectionRequest = new ConnectionRequestService( rockContext ).Get( connectionRequestId );
                if ( connectionRequest != null && connectionRequest.PersonAlias != null )
                {
                    var group = new GroupService( rockContext ).Get( connectionRequest.AssignedGroupId.Value );
                    if ( group != null )
                    {
                        requirementsResults = group.PersonMeetsGroupRequirements(
                            connectionRequest.PersonAlias.PersonId,
                            connectionRequest.AssignedGroupMemberRoleId );

                        if ( requirementsResults != null )
                        {
                            // Ignore notapplicable requirements
                            requirementsResults = requirementsResults.Where( r => r.MeetsGroupRequirement != MeetsGroupRequirement.NotApplicable ).ToList();
                        }

                        // Clear results
                        cblManualRequirements.Items.Clear();
                        lRequirementsLabels.Text = string.Empty;

                        rcwRequirements.Visible = requirementsResults.Any();

                        foreach ( var requirementResult in requirementsResults )
                        {
                            if ( requirementResult.GroupRequirement.GroupRequirementType.RequirementCheckType == RequirementCheckType.Manual )
                            {
                                var checkboxItem = new ListItem( requirementResult.GroupRequirement.GroupRequirementType.CheckboxLabel, requirementResult.GroupRequirement.Id.ToString() );
                                if ( string.IsNullOrEmpty( requirementResult.GroupRequirement.GroupRequirementType.CheckboxLabel ) )
                                {
                                    checkboxItem.Text = requirementResult.GroupRequirement.GroupRequirementType.Name;
                                }
                                checkboxItem.Selected = requirementResult.MeetsGroupRequirement == MeetsGroupRequirement.Meets;
                                cblManualRequirements.Items.Add( checkboxItem );
                            }
                            else
                            {
                                string labelText;
                                string labelType;
                                string labelTooltip;
                                if ( requirementResult.MeetsGroupRequirement == MeetsGroupRequirement.Meets )
                                {
                                    labelText = requirementResult.GroupRequirement.GroupRequirementType.PositiveLabel;
                                    labelType = "success";
                                }
                                else if ( requirementResult.MeetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning )
                                {
                                    labelText = requirementResult.GroupRequirement.GroupRequirementType.WarningLabel;
                                    labelType = "warning";
                                }
                                else
                                {
                                    passedAllRequirements = false;
                                    labelText = requirementResult.GroupRequirement.GroupRequirementType.NegativeLabel;
                                    labelType = "danger";
                                }

                                if ( string.IsNullOrEmpty( labelText ) )
                                {
                                    labelText = requirementResult.GroupRequirement.GroupRequirementType.Name;
                                }

                                if ( requirementResult.MeetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning )
                                {
                                    labelTooltip = requirementResult.RequirementWarningDateTime.HasValue
                                        ? "Last Checked: " + requirementResult.RequirementWarningDateTime.Value.ToString( "g" )
                                        : "Not calculated yet";
                                }
                                else
                                {
                                    labelTooltip = requirementResult.LastRequirementCheckDateTime.HasValue
                                        ? "Last Checked: " + requirementResult.LastRequirementCheckDateTime.Value.ToString( "g" )
                                        : "Not calculated yet";
                                }

                                lRequirementsLabels.Text += string.Format(
                                    @"<span class='label label-{1}' title='{2}'>{0}</span>
                        ",
                                    labelText,
                                    labelType,
                                    labelTooltip );
                            }
                        }

                        var requirementsWithErrors = requirementsResults.Where( a => a.MeetsGroupRequirement == MeetsGroupRequirement.Error ).ToList();
                        if ( requirementsWithErrors.Any() )
                        {
                            nbRequirementsErrors.Text = string.Format(
                                "An error occurred in one or more of the requirement calculations: <br /> {0}",
                                requirementsWithErrors.AsDelimited( "<br />" ) );
                            nbRequirementsErrors.Visible = true;
                        }

                        if ( passedAllRequirements || ( group.MustMeetRequirementsToAddMember.HasValue && !group.MustMeetRequirementsToAddMember.Value ) )
                        {
                            if ( passedAllRequirements )
                            {
                                lbConnect.RemoveCssClass( "js-confirm-connect" );
                            }
                            else
                            {
                                lbConnect.AddCssClass( "js-confirm-connect" );
                            }

                            lbConnect.Enabled = true;
                        }
                        else
                        {
                            lbConnect.Enabled = false;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            OpportunitySummary opportunitySummary = null;

            if ( SelectedOpportunityId.HasValue )
            {
                opportunitySummary = SummaryState.SelectMany( t => t.Opportunities.Where( o => o.Id == SelectedOpportunityId.Value ) ).FirstOrDefault();
            }

            if ( opportunitySummary != null )
            {
                using ( var rockContext = new RockContext() )
                {

                    // Get queryable of all requests that belong to the selected opportunity, and user is authorized to view (based on security or connector group)
                    var requests = new ConnectionRequestService( rockContext )
                        .Queryable().AsNoTracking()
                        .Where( r =>
                            r.ConnectionOpportunityId == SelectedOpportunityId.Value &&
                            (
                                !opportunitySummary.CampusSpecificConnector ||
                                ( r.CampusId.HasValue && opportunitySummary.ConnectorCampusIds.Contains( r.CampusId.Value ) )
                            ) );

                    // Filter by Requester
                    if ( ppRequester.PersonId.HasValue )
                    {
                        requests = requests
                            .Where( r =>
                                r.PersonAlias != null &&
                                r.PersonAlias.PersonId == ppRequester.PersonId.Value );
                    }

                    // Filter by Connector
                    if ( tglMyOpportunities.Checked )
                    {
                        requests = requests
                            .Where( r =>
                                r.ConnectorPersonAlias != null &&
                                r.ConnectorPersonAlias.PersonId == CurrentPersonId );
                    }
                    else if ( ppConnector.PersonId.HasValue )
                    {
                        requests = requests
                            .Where( r =>
                                r.ConnectorPersonAlias != null &&
                                r.ConnectorPersonAlias.PersonId == ppConnector.PersonId.Value );
                    }

                    // Filter by State

                    if ( tglMyOpportunities.Checked )
                    {
                        requests = requests
                            .Where( r => r.ConnectionState == ConnectionState.Active ||
                                    ( r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday ) );
                    }
                    else
                    {
                        var states = new List<ConnectionState>();
                        bool futureFollowup = false;
                        foreach ( string stateValue in cblState.SelectedValues )
                        {
                            futureFollowup = futureFollowup || stateValue.AsInteger() == -2;
                            var state = stateValue.ConvertToEnumOrNull<ConnectionState>();
                            if ( state.HasValue )
                            {
                                states.Add( state.Value );
                            }
                        }
                        if ( futureFollowup || states.Any() )
                        {
                            requests = requests
                                .Where( r =>
                                    ( futureFollowup && r.ConnectionState == ConnectionState.FutureFollowUp &&
                                        r.FollowupDate.HasValue && r.FollowupDate.Value < _midnightToday ) ||
                                    states.Contains( r.ConnectionState ) );
                        }
                    }

                    // Filter by Status
                    List<int> statusIds = cblStatus.SelectedValuesAsInt;
                    if ( statusIds.Any() )
                    {
                        requests = requests
                            .Where( r => statusIds.Contains( r.ConnectionStatusId ) );
                    }

                    // Filter by Campus
                    List<int> campusIds = cblCampus.SelectedValuesAsInt;
                    if ( campusIds.Count > 0 )
                    {
                        requests = requests
                            .Where( r =>
                                r.Campus != null &&
                                campusIds.Contains( r.CampusId.Value ) );
                    }

                    // Filter by Last Activity Note
                    List<int> lastActivityIds = cblLastActivity.SelectedValuesAsInt;
                    if ( lastActivityIds.Any() )
                    {
                        requests = requests
                            .Where( r => lastActivityIds.Contains(
                                r.ConnectionRequestActivities.OrderByDescending( a => a.CreatedDateTime ).Select( a => a.ConnectionActivityTypeId ).FirstOrDefault() ) );
                    }

                    SortProperty sortProperty = gRequests.SortProperty;
                    if ( sortProperty != null )
                    {
                        requests = requests.Sort( sortProperty );
                    }
                    else
                    {
                        requests = requests
                            .OrderBy( r => r.PersonAlias.Person.LastName )
                            .ThenBy( r => r.PersonAlias.Person.NickName );
                    }

                    var requestList = requests.ToList();
                    var roleIds = requestList.Where( r => r.AssignedGroupMemberRoleId.HasValue).Select( r => r.AssignedGroupMemberRoleId.Value ).ToList();

                    var roles = new GroupTypeRoleService( rockContext )
                        .Queryable().AsNoTracking()
                        .Where( r => roleIds.Contains( r.Id ) )
                        .ToDictionary( k => k.Id, v => v.Name );

                    gRequests.DataSource = requests.ToList()
                    .Select( r => new
                    {
                        r.Id,
                        r.Guid,
                        PersonId = r.PersonAlias.PersonId,
                        Name = r.PersonAlias.Person.FullNameReversed,
                        Campus = r.Campus,
                        Group = r.AssignedGroup != null ? r.AssignedGroup.Name : "",
                        GroupStatus = r.AssignedGroupMemberStatus != null ? r.AssignedGroupMemberStatus.ConvertToString() : "",
                        GroupRole = r.AssignedGroupMemberRoleId.HasValue ? roles[r.AssignedGroupMemberRoleId.Value] : "",
                        Connector = r.ConnectorPersonAlias != null ? r.ConnectorPersonAlias.Person.FullName : "",
                        LastActivity = FormatActivity( r.ConnectionRequestActivities.OrderByDescending( a => a.CreatedDateTime ).FirstOrDefault() ),
                        LastActivityNote = gRequests.Columns[6].Visible ? r.ConnectionRequestActivities.OrderByDescending(
                            a => a.CreatedDateTime ).Select( a => a.Note ).FirstOrDefault() : "",
                        Status = r.ConnectionStatus.Name,
                        StatusLabel = r.ConnectionStatus.IsCritical ? "warning" : "info",
                        ConnectionState = r.ConnectionState,
                        StateLabel = FormatStateLabel( r.ConnectionState, r.FollowupDate )
                    } )
                   .ToList();
                    gRequests.DataBind();

                    lOpportunityIcon.Text = string.Format( "<i class='{0}'></i>", opportunitySummary.IconCssClass );
                    lConnectionRequest.Text = String.Format( "{0} Connection Requests", opportunitySummary.Name );
                }
            }
            else
            {
                pnlGrid.Visible = false;
            }
        }
        /// <summary>
        /// Handles the Click event of the btnAddConnectionRequestActivity 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 btnAddConnectionRequestActivity_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );
                var personAliasService = new PersonAliasService( rockContext );

                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null )
                {
                    int? activityTypeId = ddlActivity.SelectedValueAsId();
                    int? personAliasId = personAliasService.GetPrimaryAliasId( ddlActivityConnector.SelectedValueAsId() ?? 0 );
                    if ( activityTypeId.HasValue && personAliasId.HasValue )
                    {

                        ConnectionRequestActivity connectionRequestActivity = null;
                        Guid? guid = hfAddConnectionRequestActivityGuid.Value.AsGuidOrNull();
                        if ( guid.HasValue )
                        {
                            connectionRequestActivity = connectionRequestActivityService.Get( guid.Value );
                        }
                        if ( connectionRequestActivity == null )
                        {
                            connectionRequestActivity = new ConnectionRequestActivity();
                            connectionRequestActivity.ConnectionRequestId = connectionRequest.Id;
                            connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId;
                            connectionRequestActivityService.Add( connectionRequestActivity );
                        }

                        connectionRequestActivity.ConnectionActivityTypeId = activityTypeId.Value;
                        connectionRequestActivity.ConnectorPersonAliasId = personAliasId.Value;
                        connectionRequestActivity.Note = tbNote.Text;

                        rockContext.SaveChanges();

                        BindConnectionRequestActivitiesGrid( connectionRequest, rockContext );
                        HideDialog();
                    }
                }
            }
        }
        /// <summary>
        /// Handles the SelectPerson event of the ppRequestor control checking for possible duplicate records.
        /// </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 ppRequestor_SelectPerson( object sender, EventArgs e )
        {
            if ( ppRequestor.PersonId.HasValue )
            {
                using ( var rockContext = new RockContext() )
                {
                    ConnectionRequestService connectionRequestService = new ConnectionRequestService( rockContext );

                    int connectionOpportunityId = hfConnectionOpportunityId.ValueAsInt();

                    // Check if this person already has a connection request for this opportunity.
                    var connectionRequest = connectionRequestService.Queryable()
                        .Where( r => r.PersonAliasId == ppRequestor.PersonAliasId.Value && r.ConnectionOpportunityId == connectionOpportunityId &&
                            ( r.ConnectionState == ConnectionState.Active || r.ConnectionState == ConnectionState.FutureFollowUp ) )
                        .FirstOrDefault();

                    if ( connectionRequest != null )
                    {
                        nbWarningMessage.Visible = true;
                        nbWarningMessage.Title = "Possible Duplicate: ";
                        nbWarningMessage.Text = string.Format( "There is already an active (or future follow up) request in the '{0}' opportunity for {1}. Are you sure you want to save this request?"
                            , connectionRequest.ConnectionOpportunity.PublicName, ppRequestor.PersonName.TrimEnd() );
                    }
                    else
                    {
                        nbWarningMessage.Visible = false;
                    }
                }
            }

            CheckGroupRequirement();
        }
        /// <summary>
        /// Handles the Click event of the btnSearch 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 btnSearch_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null &&
                    connectionRequest.ConnectionOpportunity != null &&
                    connectionRequest.ConnectionOpportunity.ConnectionType != null )
                {
                    cblCampus.DataSource = CampusCache.All();
                    cblCampus.DataBind();

                    if ( connectionRequest.CampusId.HasValue )
                    {
                        cblCampus.SetValues( new List<string> { connectionRequest.CampusId.Value.ToString() } );
                    }

                    BindAttributes();
                    AddDynamicControls();

                    rptSearchResult.DataSource = connectionRequest.ConnectionOpportunity.ConnectionType.ConnectionOpportunities.ToList();
                    rptSearchResult.DataBind();
                    ShowDialog( "Search", true );
                }
            }
        }
 /// <summary>
 /// Handles the ItemCommand event of the rptRequestWorkflows control.
 /// </summary>
 /// <param name="source">The source of the event.</param>
 /// <param name="e">The <see cref="RepeaterCommandEventArgs"/> instance containing the event data.</param>
 protected void rptRequestWorkflows_ItemCommand( object source, RepeaterCommandEventArgs e )
 {
     if ( e.CommandName == "LaunchWorkflow" )
     {
         using ( var rockContext = new RockContext() )
         {
             var connectionRequest = new ConnectionRequestService( rockContext ).Get( hfConnectionRequestId.ValueAsInt() );
             var connectionWorkflow = new ConnectionWorkflowService( rockContext ).Get( e.CommandArgument.ToString().AsInteger() );
             if ( connectionRequest != null && connectionWorkflow != null )
             {
                 LaunchWorkflow( rockContext, connectionRequest, connectionWorkflow );
             }
         }
     }
 }
        protected void ddlPlacementGroup_SelectedIndexChanged( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest == null )
                {
                    connectionRequest = new ConnectionRequest();
                    var connectionOpportunity = new ConnectionOpportunityService( rockContext ).Get( hfConnectionOpportunityId.ValueAsInt() );
                    if ( connectionOpportunity != null )
                    {
                        connectionRequest.ConnectionOpportunity = connectionOpportunity;
                        connectionRequest.ConnectionOpportunityId = connectionOpportunity.Id;
                    }
                }

                RebindGroupRole( connectionRequest, rockContext );

            }
        }
        /// <summary>
        /// Binds the attributes.
        /// </summary>
        private void BindAttributes()
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null &&
                    connectionRequest.ConnectionOpportunity != null )
                {
                    // Parse the attribute filters
                    SearchAttributes = new List<AttributeCache>();

                    int entityTypeId = new ConnectionOpportunity().TypeId;
                    foreach ( var attributeModel in new AttributeService( rockContext ).Queryable()
                        .Where( a =>
                            a.EntityTypeId == entityTypeId &&
                            a.EntityTypeQualifierColumn.Equals( "ConnectionTypeId", StringComparison.OrdinalIgnoreCase ) &&
                            a.EntityTypeQualifierValue.Equals( connectionRequest.ConnectionOpportunity.ConnectionTypeId.ToString() ) &&
                            a.AllowSearch )
                        .OrderBy( a => a.Order )
                        .ThenBy( a => a.Name ) )
                    {
                        SearchAttributes.Add( AttributeCache.Read( attributeModel ) );
                    }
                }
            }
        }
        /// <summary>
        /// Handles the Delete event of the gConnectionRequestActivities 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 gConnectionRequestActivities_Delete( object sender, RowEventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                // only allow deleting if current user created the activity, and not a system activity
                var activityGuid = e.RowKeyValue.ToString().AsGuid();
                var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );
                var activity = connectionRequestActivityService.Get( activityGuid );
                if ( activity != null &&
                    ( activity.CreatedByPersonAliasId.Equals( CurrentPersonAliasId ) || activity.ConnectorPersonAliasId.Equals( CurrentPersonAliasId ) ) &&
                    activity.ConnectionActivityType.ConnectionTypeId.HasValue )
                {
                    connectionRequestActivityService.Delete( activity );
                    rockContext.SaveChanges();
                }

                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                BindConnectionRequestActivitiesGrid( connectionRequest, rockContext );
            }
        }
        /// <summary>
        /// Binds the connection request workflows grid.
        /// </summary>
        private void BindConnectionRequestWorkflowsGrid()
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null )
                {
                    var instantiatedWorkflows = connectionRequest.ConnectionRequestWorkflows
                        .Where( c =>
                            c.Workflow != null &&
                            c.Workflow.WorkflowType != null )
                        .ToList();

                    gConnectionRequestWorkflows.DataSource = instantiatedWorkflows
                        .Select( c => new
                            {
                                c.Id,
                                c.Guid,
                                WorkflowType = c.Workflow.WorkflowType.Name,
                                Trigger = c.TriggerType.ConvertToString(),
                                CurrentActivity = c.Workflow.ActiveActivityNames,
                                Date = c.Workflow.ActivatedDateTime.Value.ToShortDateString(),
                                OrderByDate = c.Workflow.ActivatedDateTime.Value,
                                Status = c.Workflow.Status == "Completed" ? "<span class='label label-success'>Complete</span>" : "<span class='label label-info'>Running</span>"
                            } )
                        .OrderByDescending( c => c.OrderByDate )
                        .ToList();
                    gConnectionRequestWorkflows.DataBind();

                    if ( !instantiatedWorkflows.Any() )
                    {
                        wpConnectionRequestWorkflow.Visible = false;
                    }
                    else
                    {
                        wpConnectionRequestWorkflow.Title = String.Format( "Workflows <span class='badge badge-info'>{0}</span>", instantiatedWorkflows.Count.ToString() );
                    }
                }
            }
        }
Exemple #53
0
        /// <summary>
        /// creates or updates the entity set on the basis of campaign connection configuration, and returns the Id of the entitySetId
        /// </summary>
        /// <param name="campaignConfiguration">The campaign configuration.</param>
        /// <returns></returns>
        public static int GetEntitySet(CampaignItem campaignConfiguration)
        {
            var rockContext = new RockContext();

            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var connectionRequestService     = new ConnectionRequestService(rockContext);
            var entitySetService             = new Rock.Model.EntitySetService(rockContext);

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

            // list of person on the basis of Dataview result and optout group.
            var filteredPersonIds = GetFilteredPersonIds(campaignConfiguration, rockContext);

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

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

            // list of person that has active connection request OR has connection closed in the past number of days between connection.
            var excludedPersonIds = connectionRequestService
                                    .Queryable()
                                    .Where(a =>
                                           a.ConnectionOpportunityId == connectionOpportunity.Id && (
                                               a.ConnectionState == ConnectionState.Active ||
                                               a.ConnectionState == ConnectionState.FutureFollowUp ||
                                               ((a.ConnectionState == ConnectionState.Connected || a.ConnectionState == ConnectionState.Inactive) && a.ModifiedDateTime > lastConnectionDateTime)))
                                    .Select(a => a.PersonAlias.PersonId)
                                    .ToList();

            // filtered list of person removing all the personIds found in excludedPersonIds List
            filteredPersonIds = filteredPersonIds.Where(a => !excludedPersonIds.Contains(a)).ToList();

            // get the ordered list of personIds based on the oldest previous connection request and connection opportunity

            /* 2020-05-06 MDP
             * If there are many filteredPersonIds, we'll get a SQL Exception, so let's get *all* the Connected connection Requests first,
             * and then use C# to filter.
             */

            var orderedLastCompletedRequestForPerson = connectionRequestService
                                                       .Queryable()
                                                       .Where(a => a.ConnectionOpportunityId == connectionOpportunity.Id &&
                                                              a.ConnectionState == ConnectionState.Connected)
                                                       .GroupBy(a => a.PersonAlias.PersonId)
                                                       .Select(a => new
            {
                PersonId = a.Key,
                LastConnectionDateTime = a.OrderByDescending(b => b.ModifiedDateTime).Select(b => b.ModifiedDateTime).FirstOrDefault()
            })
                                                       .OrderBy(a => a.LastConnectionDateTime)
                                                       .Select(a => a.PersonId).ToList();

            // Use C# to filter persons so we can avoid a SQL Exception
            orderedLastCompletedRequestForPerson = orderedLastCompletedRequestForPerson.Where(a => filteredPersonIds.Contains(a)).ToList();

            var random = new Random();

            //// get the final ordered list of personIds based on the oldest previous connection request and
            //// connection opportunity otherwise order randomly for the person who don't have any previous connection request.
            var orderedPersonIds = filteredPersonIds
                                   .OrderBy(a =>
            {
                var index = orderedLastCompletedRequestForPerson.IndexOf(a);
                if (index == -1)
                {
                    return(random.Next(orderedLastCompletedRequestForPerson.Count, int.MaxValue));
                }
                else
                {
                    return(index);
                }
            }).ToList();

            EntitySet entitySet = null;

            if (campaignConfiguration.EntitySetId != default(int))
            {
                entitySet = entitySetService.Get(campaignConfiguration.EntitySetId);
            }

            List <Rock.Model.EntitySetItem> entitySetItems = new List <Rock.Model.EntitySetItem>();
            var personEntityTypeId = EntityTypeCache.Get <Rock.Model.Person>().Id;

            if (entitySet == null || entitySet.EntityTypeId != personEntityTypeId)
            {
                entitySet = new Rock.Model.EntitySet();
                entitySet.EntityTypeId   = personEntityTypeId;
                entitySet.ExpireDateTime = null;
                entitySetService.Add(entitySet);
            }
            else
            {
                var entitySetItemQry = new EntitySetItemService(rockContext)
                                       .Queryable().AsNoTracking()
                                       .Where(i => i.EntitySetId == entitySet.Id);
                rockContext.BulkDelete(entitySetItemQry);
            }

            // Update the EntitySet name
            entitySet.Name = campaignConfiguration.Name;

            var orderIndex = 0;

            foreach (var personId in orderedPersonIds)
            {
                try
                {
                    var item = new Rock.Model.EntitySetItem();
                    item.Order    = orderIndex++;
                    item.EntityId = personId;
                    entitySetItems.Add(item);
                }
                catch
                {
                    // ignore
                }
            }

            rockContext.SaveChanges();
            entitySetItems.ForEach(a =>
            {
                a.EntitySetId = entitySet.Id;
            });

            rockContext.BulkInsert(entitySetItems);

            return(entitySet.Id);
        }
        /// <summary>
        /// Handles the Click event of the lbConnect 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 lbConnect_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var groupMemberService = new GroupMemberService( rockContext );
                var connectionActivityTypeService = new ConnectionActivityTypeService( rockContext );
                var connectionRequestActivityService = new ConnectionRequestActivityService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );

                if ( connectionRequest != null &&
                    connectionRequest.PersonAlias != null &&
                    connectionRequest.ConnectionOpportunity != null )
                {

                    // Only do group member placement if the request has an assigned placement group
                    if ( connectionRequest.ConnectionOpportunity.GroupMemberRoleId.HasValue &&
                        connectionRequest.AssignedGroupId.HasValue )
                    {
                        // Only attempt the add if person does not already exist in group with same role
                        var groupMember = groupMemberService.GetByGroupIdAndPersonIdAndGroupRoleId( connectionRequest.AssignedGroupId.Value,
                            connectionRequest.PersonAlias.PersonId, connectionRequest.ConnectionOpportunity.GroupMemberRoleId.Value );
                        if ( groupMember == null )
                        {
                            groupMember = new GroupMember();
                            groupMember.PersonId = connectionRequest.PersonAlias.PersonId;
                            groupMember.GroupRoleId = connectionRequest.ConnectionOpportunity.GroupMemberRoleId.Value;
                            groupMember.GroupMemberStatus = connectionRequest.ConnectionOpportunity.GroupMemberStatus;
                            groupMember.GroupId = connectionRequest.AssignedGroupId.Value;
                            groupMemberService.Add( groupMember );
                        }
                    }

                    // ... but always record the connection activity and change the state to connected.
                    var guid = Rock.SystemGuid.ConnectionActivityType.CONNECTED.AsGuid();
                    var connectedActivityId = connectionActivityTypeService.Queryable()
                        .Where( t => t.Guid == guid )
                        .Select( t => t.Id )
                        .FirstOrDefault();
                    if ( connectedActivityId > 0 )
                    {
                        var connectionRequestActivity = new ConnectionRequestActivity();
                        connectionRequestActivity.ConnectionRequestId = connectionRequest.Id;
                        connectionRequestActivity.ConnectionOpportunityId = connectionRequest.ConnectionOpportunityId;
                        connectionRequestActivity.ConnectionActivityTypeId = connectedActivityId;
                        connectionRequestActivity.ConnectorPersonAliasId = CurrentPersonAliasId;
                        connectionRequestActivityService.Add( connectionRequestActivity );
                    }

                    connectionRequest.ConnectionState = ConnectionState.Connected;

                    rockContext.SaveChanges();
                    ShowDetail( connectionRequest.Id, connectionRequest.ConnectionOpportunityId );
                }
            }
        }
Exemple #55
0
        /// <summary>
        /// Assigns the connection requests from the SelectedCampaign's entity set.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="selectedCampaignItem">The selected campaign item.</param>
        /// <param name="numberOfRequestsRemaining">The number of requests remaining.</param>
        /// <param name="connectorPerson">The connector person.</param>
        private static void AssignConnectionRequestsFromEntitySet(RockContext rockContext, CampaignItem selectedCampaignItem, ref int numberOfRequestsRemaining, Person connectorPerson)
        {
            var opportunityService            = new ConnectionOpportunityService(rockContext);
            ConnectionOpportunity opportunity = opportunityService.Get(selectedCampaignItem.OpportunityGuid);

            if (opportunity == null || !opportunity.IsActive)
            {
                return;
            }

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

            // If opportunity doesn't have a default status, something is wrong
            if (defaultStatusId == null)
            {
                return;
            }

            var connectorCampusIds = GetConnectorCampusIds(selectedCampaignItem, connectorPerson);

            var connectionRequestService         = new ConnectionRequestService(rockContext);
            var connectionRequestActivityService = new ConnectionRequestActivityService(rockContext);

            // get previous connections for the connector that have the same campus of the connector, or if the person's campus or connector person's campus is null
            var previousConnectedPersonIdsForCurrentPerson = connectionRequestService.Queryable()
                                                             .Where(a => a.ConnectionOpportunityId == opportunity.Id)
                                                             .Where(a => a.ConnectorPersonAlias.PersonId == connectorPerson.Id)
                                                             .Where(a => (a.CampusId == null) || connectorCampusIds.Any(connectorCampusId => connectorCampusId == null || a.CampusId.Value == connectorCampusId))
                                                             .Select(a => a.PersonAlias.PersonId).Distinct().ToList();

            var entitySetId          = CampaignConnectionHelper.GetEntitySet(selectedCampaignItem);
            var entitySetItemService = new EntitySetItemService(rockContext);
            var entitySetItemList    = entitySetItemService.Queryable().Where(a => a.EntitySetId == entitySetId).OrderBy(a => a.Order).Select(a => new
            {
                PersonId        = a.EntityId,
                EntityItemOrder = a.Order
            }).ToList();

            if (selectedCampaignItem.PreferPreviousConnector)
            {
                // sort them by any where the current person was assigned to this person before
                entitySetItemList = entitySetItemList
                                    .OrderBy(a => previousConnectedPersonIdsForCurrentPerson.Any(x => x == a.PersonId))
                                    .ThenBy(a => a.EntityItemOrder).ToList();
            }
            else
            {
                entitySetItemList = entitySetItemList.OrderBy(a => a.EntityItemOrder).ToList();
            }

            var personService = new PersonService(rockContext);

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

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

            foreach (var entitySetItem in entitySetItemList)
            {
                var entitySetPerson = personService.Get(entitySetItem.PersonId);
                if (entitySetPerson == null)
                {
                    continue;
                }

                var entitySetPersonPrimaryCampusId = entitySetPerson.PrimaryCampusId;

                bool validCampus = IsValidCampus(connectorCampusIds, entitySetPersonPrimaryCampusId);
                if (!validCampus)
                {
                    continue;
                }

                // double check that they haven't already been added
                bool personAlreadyHasConnectionRequest = PersonAlreadyHasConnectionRequest(opportunity.Id, rockContext, lastConnectionDateTime, entitySetPerson.Id);

                if (personAlreadyHasConnectionRequest)
                {
                    continue;
                }

                var connectionRequest = new ConnectionRequest();
                connectionRequest.ConnectionOpportunityId = opportunity.Id;

                /*
                 *  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... hence the change from GetAsNoTracking() to just Get() above:
                 *  var entitySetPerson = personService.Get( entitySetItem.PersonId );
                 *
                 *  In other words, this will not work correctly:
                 *  connectionRequest.PersonAliasId = entitySetPerson.PrimaryAliasId.Value;
                 *
                 *  Reason: This plug-in cannot change Rock core assembly code.
                 */

                connectionRequest.PersonAlias            = entitySetPerson.PrimaryAlias;
                connectionRequest.ConnectionState        = ConnectionState.Active;
                connectionRequest.ConnectorPersonAliasId = connectorPerson.PrimaryAliasId;
                connectionRequest.CampusId           = entitySetPersonPrimaryCampusId;
                connectionRequest.ConnectionStatusId = defaultStatusId.Value;

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

                connectionRequestService.Add(connectionRequest);

                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   = connectorPerson.PrimaryAliasId;
                    connectionRequestActivityService.Add(connectionRequestActivity);
                }

                numberOfRequestsRemaining--;
                if (numberOfRequestsRemaining <= 0)
                {
                    break;
                }
            }
        }
Exemple #56
0
        /// <summary>
        /// Handles the Click event of the btnEdit 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 btnConnect_Click(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var opportunityService       = new ConnectionOpportunityService(rockContext);
                var connectionRequestService = new ConnectionRequestService(rockContext);
                var personService            = new PersonService(rockContext);

                // Get the opportunity and default status
                int opportunityId = PageParameter("OpportunityId").AsInteger();
                var opportunity   = opportunityService
                                    .Queryable()
                                    .Where(o => o.Id == opportunityId)
                                    .FirstOrDefault();

                int defaultStatusId = opportunity.ConnectionType.ConnectionStatuses
                                      .Where(s => s.IsDefault)
                                      .Select(s => s.Id)
                                      .FirstOrDefault();

                // If opportunity is valid and has a default status
                if (opportunity != null && defaultStatusId > 0)
                {
                    Person person = null;

                    string   firstName = tbFirstName.Text.Trim();
                    string   lastName  = tbLastName.Text.Trim();
                    DateTime?birthdate = bpBirthdate.SelectedDate;
                    string   email     = tbEmail.Text.Trim();
                    int?     campusId  = cpCampus.SelectedCampusId;

                    // if a person guid was passed in from the query string use that
                    if (RockPage.PageParameter("PersonGuid") != null && !string.IsNullOrWhiteSpace(RockPage.PageParameter("PersonGuid")))
                    {
                        Guid?personGuid = RockPage.PageParameter("PersonGuid").AsGuidOrNull();

                        if (personGuid.HasValue)
                        {
                            person = personService.Get(personGuid.Value);
                        }
                    }
                    else if (CurrentPerson != null &&
                             CurrentPerson.LastName.Equals(lastName, StringComparison.OrdinalIgnoreCase) &&
                             (CurrentPerson.NickName.Equals(firstName, StringComparison.OrdinalIgnoreCase) || CurrentPerson.FirstName.Equals(firstName, StringComparison.OrdinalIgnoreCase)) &&
                             CurrentPerson.Email.Equals(email, StringComparison.OrdinalIgnoreCase))
                    {
                        // If the name and email entered are the same as current person (wasn't changed), use the current person
                        person = personService.Get(CurrentPerson.Id);
                    }

                    else
                    {
                        List <Person> personMatches = new List <Person>();
                        if (Assembly.GetExecutingAssembly().GetReferencedAssemblies()
                            .FirstOrDefault(c => c.FullName == "org.secc.PersonMatch") != null)
                        {
                            var assembly = Assembly.Load("org.secc.PersonMatch");
                            if (assembly != null)
                            {
                                Type type = assembly.GetExportedTypes().Where(et => et.FullName == "org.secc.PersonMatch.Extension").FirstOrDefault();
                                if (type != null)
                                {
                                    var matchMethod = type.GetMethod("GetByMatch");
                                    personMatches = ((IEnumerable <Person>)matchMethod.Invoke(null, new object[] { personService, firstName, lastName, birthdate, email, null, null, null })).ToList();
                                }
                            }
                        }
                        else
                        {
                            personMatches = personService.GetByMatch(firstName, lastName, email).ToList();
                            if (bpBirthdate.Visible)
                            {
                                personMatches = personMatches.Where(p => p.BirthDate == birthdate).ToList();
                            }
                        }

                        if (personMatches.Count() == 1 &&
                            personMatches.First().Email != null &&
                            email.ToLower().Trim() == personMatches.First().Email.ToLower().Trim())
                        {
                            // If one person with same name and email address exists, use that person
                            person = personMatches.First();
                        }
                    }

                    // If person was not found, create a new one
                    if (person == null)
                    {
                        // If a match was not found, create a new person
                        var dvcConnectionStatus = DefinedValueCache.Read(GetAttributeValue("ConnectionStatus").AsGuid());
                        var dvcRecordStatus     = DefinedValueCache.Read(GetAttributeValue("RecordStatus").AsGuid());

                        person               = new Person();
                        person.FirstName     = firstName;
                        person.LastName      = lastName;
                        person.IsEmailActive = true;
                        person.SetBirthDate(birthdate);
                        person.Email             = email;
                        person.EmailPreference   = EmailPreference.EmailAllowed;
                        person.RecordTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                        if (dvcConnectionStatus != null)
                        {
                            person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                        }
                        if (dvcRecordStatus != null)
                        {
                            person.RecordStatusValueId = dvcRecordStatus.Id;
                        }

                        PersonService.SaveNewPerson(person, rockContext, campusId, false);
                        person = personService.Get(person.Id);
                    }

                    // If there is a valid person with a primary alias, continue
                    if (person != null && person.PrimaryAliasId.HasValue)
                    {
                        var changes = new List <string>();

                        if (pnHome.Visible)
                        {
                            SavePhone(pnHome, person, _homePhone.Guid, changes);
                        }

                        if (pnMobile.Visible)
                        {
                            SavePhone(pnMobile, person, _cellPhone.Guid, changes);
                        }

                        // Save the DOB
                        if (bpBirthdate.Visible && bpBirthdate.SelectedDate.HasValue && bpBirthdate.SelectedDate != person.BirthDate)
                        {
                            person.BirthDay   = bpBirthdate.SelectedDate.Value.Day;
                            person.BirthMonth = bpBirthdate.SelectedDate.Value.Month;
                            person.BirthYear  = bpBirthdate.SelectedDate.Value.Year;
                        }

                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(Person),
                                Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                person.Id,
                                changes);
                        }

                        // Now that we have a person, we can create the connection requests
                        int RepeaterIndex = 0;
                        foreach (ConnectionRoleRequest roleRequest in RoleRequests)
                        {
                            var connectionRequest = new ConnectionRequest();
                            connectionRequest.PersonAliasId           = person.PrimaryAliasId.Value;
                            connectionRequest.Comments                = tbComments.Text.Trim();
                            connectionRequest.ConnectionOpportunityId = opportunity.Id;
                            connectionRequest.ConnectionState         = ConnectionState.Active;
                            connectionRequest.ConnectionStatusId      = defaultStatusId;
                            connectionRequest.CampusId                = campusId;
                            connectionRequest.ConnectorPersonAliasId  = opportunity.GetDefaultConnectorPersonAliasId(campusId);
                            if (campusId.HasValue &&
                                opportunity != null &&
                                opportunity.ConnectionOpportunityCampuses != null)
                            {
                                var campus = opportunity.ConnectionOpportunityCampuses
                                             .Where(c => c.CampusId == campusId.Value)
                                             .FirstOrDefault();
                                if (campus != null)
                                {
                                    connectionRequest.ConnectorPersonAliasId = campus.DefaultConnectorPersonAliasId;
                                }
                            }

                            var hdnGroupId         = (( HiddenField )(rptGroupRoleAttributes.Items[RepeaterIndex].FindControl("hdnGroupId")));
                            var hdnGroupRoleTypeId = (( HiddenField )(rptGroupRoleAttributes.Items[RepeaterIndex].FindControl("hdnGroupRoleTypeId")));


                            if (hdnGroupId.Value.AsInteger() > 0 && hdnGroupRoleTypeId.Value.AsInteger() > 0)
                            {
                                connectionRequest.AssignedGroupId           = hdnGroupId.Value.AsInteger();
                                connectionRequest.AssignedGroupMemberRoleId = hdnGroupRoleTypeId.Value.AsInteger();
                                var groupConfig = opportunity.ConnectionOpportunityGroupConfigs.Where(gc => gc.GroupMemberRoleId == hdnGroupRoleTypeId.Value.AsInteger()).FirstOrDefault();
                                connectionRequest.AssignedGroupMemberStatus = groupConfig.GroupMemberStatus;
                            }

                            var connectionAttributes = GetGroupMemberAttributes(rockContext, RepeaterIndex);

                            if (connectionAttributes != null && connectionAttributes.Keys.Any())
                            {
                                var connectionDictionary = new Dictionary <string, string>();
                                foreach (var kvp in connectionAttributes)
                                {
                                    connectionDictionary.Add(kvp.Key, kvp.Value.Value);
                                }

                                connectionRequest.AssignedGroupMemberAttributeValues = connectionDictionary.ToJson();
                            }

                            if (!connectionRequest.IsValid)
                            {
                                // Controls will show warnings
                                return;
                            }

                            connectionRequestService.Add(connectionRequest);

                            RepeaterIndex++;
                        }

                        rockContext.SaveChanges();

                        var mergeFields = new Dictionary <string, object>();
                        mergeFields.Add("Opportunity", new ConnectionOpportunityService(rockContext).Get(PageParameter("OpportunityId").AsInteger()));
                        mergeFields.Add("CurrentPerson", CurrentPerson);
                        mergeFields.Add("Person", person);

                        lResponseMessage.Text    = GetAttributeValue("LavaTemplate").ResolveMergeFields(mergeFields);
                        lResponseMessage.Visible = true;

                        pnlSignup.Visible = false;
                    }
                }
            }
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();
            var mergeFields = GetMergeFields(action);

            // Get the connection request
            ConnectionRequest request  = null;
            Guid connectionRequestGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionRequestAttribute").AsGuid()).AsGuid();

            request = new ConnectionRequestService(rockContext).Get(connectionRequestGuid);
            if (request == null)
            {
                errorMessages.Add("Invalid Connection Request Attribute or Value!");
                return(false);
            }

            // Get the activity type
            ConnectionActivityType activityType = null;
            Guid activityTypeGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "ConnectionActivityTypeAttribute").AsGuid()).AsGuid();

            activityType = new ConnectionActivityTypeService(rockContext).Get(activityTypeGuid);
            if (activityType == null)
            {
                errorMessages.Add("Invalid Connection Activity Type Attribute or Value!");
                return(false);
            }

            // Get the note
            string noteValue = GetAttributeValue(action, "Note", true);
            string note      = string.Empty;
            Guid?  noteGuid  = noteValue.AsGuidOrNull();

            if (noteGuid.HasValue)
            {
                var attribute = AttributeCache.Read(noteGuid.Value, rockContext);
                if (attribute != null)
                {
                    note = action.GetWorklowAttributeValue(noteGuid.Value);
                }
            }
            else
            {
                note = noteValue;
            }

            // Get the connector
            int? personAliasId       = null;
            Guid?personAttributeGuid = GetAttributeValue(action, "PersonAttribute").AsGuidOrNull();

            if (personAttributeGuid.HasValue)
            {
                Guid?personAliasGuid = action.GetWorklowAttributeValue(personAttributeGuid.Value).AsGuidOrNull();
                if (personAliasGuid.HasValue)
                {
                    var personAlias = new PersonAliasService(rockContext).Get(personAliasGuid.Value);
                    if (personAlias != null)
                    {
                        personAliasId = personAlias.Id;
                    }
                }
            }

            // Add the activity
            var activity = new ConnectionRequestActivity();

            activity.ConnectionRequestId      = request.Id;
            activity.ConnectionActivityTypeId = activityType.Id;
            activity.ConnectionOpportunityId  = request.ConnectionOpportunityId;
            activity.ConnectorPersonAliasId   = personAliasId;
            activity.Note = note.ResolveMergeFields(mergeFields);
            new ConnectionRequestActivityService(rockContext).Add(activity);
            rockContext.SaveChanges();

            return(true);
        }
        /// <summary>
        /// Handles the Click event of the lbTransfer 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 lbTransfer_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionRequestService = new ConnectionRequestService( rockContext );
                var connectionRequest = connectionRequestService.Get( hfConnectionRequestId.ValueAsInt() );
                if ( connectionRequest != null &&
                    connectionRequest.ConnectionOpportunity != null &&
                    connectionRequest.ConnectionOpportunity.ConnectionType != null )
                {
                    pnlReadDetails.Visible = false;
                    wpConnectionRequestActivities.Visible = false;
                    wpConnectionRequestWorkflow.Visible = false;
                    pnlTransferDetails.Visible = true;

                    ddlTransferStatus.Items.Clear();
                    foreach ( var status in connectionRequest.ConnectionOpportunity.ConnectionType.ConnectionStatuses )
                    {
                        ddlTransferStatus.Items.Add( new ListItem( status.Name, status.Id.ToString() ) );
                    }
                    ddlTransferStatus.SetValue( connectionRequest.ConnectionStatusId.ToString() );

                    ddlTransferOpportunity.Items.Clear();
                    foreach ( var opportunity in connectionRequest.ConnectionOpportunity.ConnectionType.ConnectionOpportunities
                        .Where( o => o.Id != connectionRequest.ConnectionOpportunityId ).OrderBy( o => o.Name ) )
                    {
                        ddlTransferOpportunity.Items.Add( new ListItem( opportunity.Name, opportunity.Id.ToString().ToUpper() ) );
                    }
                }
            }
        }
        /// <summary>
        /// Gets the summary data.
        /// </summary>
        private void GetSummaryData()
        {
            var midnightToday = RockDateTime.Today.AddDays(1);

            SummaryState = new List <ConnectionTypeSummary>();

            var rockContext = new RockContext();
            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var followingService             = new FollowingService(rockContext);
            var opportunityEntityTypeId      = EntityTypeCache.Get <ConnectionOpportunity>().Id;

            var followedOpportunityIds = followingService.Queryable()
                                         .AsNoTracking()
                                         .Where(f =>
                                                f.PersonAliasId == CurrentPersonAliasId &&
                                                f.EntityTypeId == opportunityEntityTypeId &&
                                                string.IsNullOrEmpty(f.PurposeKey))
                                         .Select(f => f.EntityId)
                                         .ToList();

            var opportunityQuery = connectionOpportunityService.Queryable()
                                   .AsNoTracking()
                                   .Where(co =>
                                          co.IsActive &&
                                          co.ConnectionType.IsActive);

            var typeFilter = GetAttributeValue(AttributeKey.ConnectionTypes).SplitDelimitedValues().AsGuidList();

            if (typeFilter.Any())
            {
                opportunityQuery = opportunityQuery.Where(o => typeFilter.Contains(o.ConnectionType.Guid));
            }

            var selfAssignedOpportunities          = new List <int>();
            var isSelfAssignedOpportunitiesQueried = false;
            var opportunities = opportunityQuery.ToList();

            // Loop through opportunities
            foreach (var opportunity in opportunities)
            {
                // Check to see if person can edit the opportunity because of edit rights to this block or edit rights to
                // the opportunity
                bool canEdit = UserCanEdit || opportunity.IsAuthorized(Authorization.EDIT, CurrentPerson);
                bool campusSpecificConnector = false;
                var  campusIds = new List <int>();

                if (CurrentPersonId.HasValue)
                {
                    // Check to see if person belongs to any connector group that is not campus specific
                    if (!canEdit)
                    {
                        canEdit = opportunity
                                  .ConnectionOpportunityConnectorGroups
                                  .Any(g =>
                                       !g.CampusId.HasValue &&
                                       g.ConnectorGroup != null &&
                                       g.ConnectorGroup.Members.Any(m => m.PersonId == CurrentPersonId.Value));
                    }

                    // If user is not yet authorized to edit the opportunity, check to see if they are a member of one of the
                    // campus-specific connector groups for the opportunity, and note the campus
                    if (!canEdit)
                    {
                        foreach (var groupCampus in opportunity
                                 .ConnectionOpportunityConnectorGroups
                                 .Where(g =>
                                        g.CampusId.HasValue &&
                                        g.ConnectorGroup != null &&
                                        g.ConnectorGroup.Members.Any(m => m.PersonId == CurrentPersonId.Value)))
                        {
                            campusSpecificConnector = true;
                            canEdit = true;
                            campusIds.Add(groupCampus.CampusId.Value);
                        }
                    }
                }

                if (opportunity.ConnectionType.EnableRequestSecurity && !isSelfAssignedOpportunitiesQueried)
                {
                    isSelfAssignedOpportunitiesQueried = true;
                    selfAssignedOpportunities          = new ConnectionRequestService(rockContext)
                                                         .Queryable()
                                                         .Where(a => a.ConnectorPersonAlias.PersonId == CurrentPersonId.Value)
                                                         .Select(a => a.ConnectionOpportunityId)
                                                         .Distinct()
                                                         .ToList();
                }

                var canView = opportunity.IsAuthorized(Authorization.VIEW, CurrentPerson) ||
                              (opportunity.ConnectionType.EnableRequestSecurity && selfAssignedOpportunities.Contains(opportunity.Id));

                // Is user is authorized to view this opportunity type...
                if (canView)
                {
                    // Check if the opportunity's type has been added to summary yet, and if not, add it
                    var connectionTypeSummary = SummaryState.Where(c => c.Id == opportunity.ConnectionTypeId).FirstOrDefault();
                    if (connectionTypeSummary == null)
                    {
                        connectionTypeSummary = new ConnectionTypeSummary
                        {
                            Id   = opportunity.ConnectionTypeId,
                            Name = opportunity.ConnectionType.Name,
                            EnableRequestSecurity              = opportunity.ConnectionType.EnableRequestSecurity,
                            ConnectionRequestDetailPageId      = opportunity.ConnectionType.ConnectionRequestDetailPageId,
                            ConnectionRequestDetailPageRouteId = opportunity.ConnectionType.ConnectionRequestDetailPageRouteId,
                            Opportunities = new List <OpportunitySummary>(),
                            IconMarkup    = opportunity.ConnectionType.IconCssClass.IsNullOrWhiteSpace() ?
                                            string.Empty :
                                            $@"<i class=""{opportunity.ConnectionType.IconCssClass}""></i>",
                            Order = opportunity.ConnectionType.Order
                        };
                        SummaryState.Add(connectionTypeSummary);
                    }

                    // get list of idle requests (no activity in past X days)

                    var connectionRequestsQry = new ConnectionRequestService(rockContext).Queryable().Where(a => a.ConnectionOpportunityId == opportunity.Id);
                    if (cpCampusFilter.SelectedCampusId.HasValue)
                    {
                        connectionRequestsQry = connectionRequestsQry.Where(a => a.CampusId.HasValue && a.CampusId == cpCampusFilter.SelectedCampusId);
                    }

                    var currentDateTime    = RockDateTime.Now;
                    int activeRequestCount = connectionRequestsQry
                                             .Where(cr =>
                                                    cr.ConnectionState == ConnectionState.Active ||
                                                    (cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < midnightToday)
                                                    )
                                             .Count();

                    // only show if the opportunity is active and there are active requests
                    if (opportunity.IsActive || (!opportunity.IsActive && activeRequestCount > 0))
                    {
                        // idle count is:
                        //  (the request is active OR future follow-up who's time has come)
                        //  AND
                        //  (where the activity is more than DaysUntilRequestIdle days old OR no activity but created more than DaysUntilRequestIdle days ago)
                        List <int> idleConnectionRequests = connectionRequestsQry
                                                            .Where(cr =>
                                                                   (
                                                                       cr.ConnectionState == ConnectionState.Active ||
                                                                       (cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < midnightToday)
                                                                   )
                                                                   &&
                                                                   (
                                                                       (cr.ConnectionRequestActivities.Any() && cr.ConnectionRequestActivities.Max(ra => ra.CreatedDateTime) < SqlFunctions.DateAdd("day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime)) ||
                                                                       (!cr.ConnectionRequestActivities.Any() && cr.CreatedDateTime < SqlFunctions.DateAdd("day", -cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle, currentDateTime))
                                                                   )
                                                                   )
                                                            .Select(a => a.Id).ToList();

                        // get list of requests that have a status that is considered critical.
                        List <int> criticalConnectionRequests = connectionRequestsQry
                                                                .Where(r =>
                                                                       r.ConnectionStatus.IsCritical &&
                                                                       (
                                                                           r.ConnectionState == ConnectionState.Active ||
                                                                           (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday)
                                                                       )
                                                                       )
                                                                .Select(a => a.Id).ToList();

                        // Add the opportunity
                        var opportunitySummary = new OpportunitySummary
                        {
                            Id                         = opportunity.Id,
                            Order                      = opportunity.Order,
                            Name                       = opportunity.Name,
                            IsActive                   = opportunity.IsActive,
                            IconCssClass               = opportunity.IconCssClass,
                            IdleConnectionRequests     = idleConnectionRequests,
                            CriticalConnectionRequests = criticalConnectionRequests,
                            DaysUntilRequestIdle       = opportunity.ConnectionType.DaysUntilRequestIdle,
                            CanEdit                    = canEdit,
                            IsFollowed                 = followedOpportunityIds.Contains(opportunity.Id)
                        };

                        // If the user is limited requests with specific campus(es) set the list, otherwise leave it to be null
                        opportunitySummary.CampusSpecificConnector = campusSpecificConnector;
                        opportunitySummary.ConnectorCampusIds      = campusIds.Distinct().ToList();

                        connectionTypeSummary.Opportunities.Add(opportunitySummary);
                    }
                }
            }

            // Get a list of all the authorized opportunity ids
            var allOpportunities = SummaryState.SelectMany(s => s.Opportunities).Select(o => o.Id).Distinct().ToList();

            // Get all the active and past-due future followup request ids, and include the campus id and personid of connector
            var activeRequestsQry = new ConnectionRequestService(rockContext)
                                    .Queryable().AsNoTracking()
                                    .Where(r =>
                                           allOpportunities.Contains(r.ConnectionOpportunityId) &&
                                           (r.ConnectionState == ConnectionState.Active ||
                                            (r.ConnectionState == ConnectionState.FutureFollowUp && r.FollowupDate.HasValue && r.FollowupDate.Value < midnightToday)))
                                    .Select(r => new
            {
                r.Id,
                r.ConnectionOpportunityId,
                r.CampusId,
                ConnectorPersonId = r.ConnectorPersonAlias != null ? r.ConnectorPersonAlias.PersonId : -1
            });

            if (cpCampusFilter.SelectedCampusId.HasValue)
            {
                activeRequestsQry = activeRequestsQry.Where(a => a.CampusId.HasValue && a.CampusId == cpCampusFilter.SelectedCampusId);
            }

            var activeRequests = activeRequestsQry.ToList();

            // Based on the active requests, set additional properties for each opportunity
            foreach (var opportunity in SummaryState.SelectMany(s => s.Opportunities))
            {
                // Get the active requests for this opportunity that user is authorized to view (based on campus connector)
                var opportunityRequests = activeRequests
                                          .Where(r =>
                                                 r.ConnectionOpportunityId == opportunity.Id &&
                                                 (
                                                     !opportunity.CampusSpecificConnector ||
                                                     (r.CampusId.HasValue && opportunity.ConnectorCampusIds.Contains(r.CampusId.Value))
                                                 ))
                                          .ToList();

                // The active requests assigned to the current person
                opportunity.AssignedToYouConnectionRequests = opportunityRequests.Where(r => r.ConnectorPersonId == CurrentPersonId).Select(a => a.Id).ToList();

                // The active requests that are unassigned
                opportunity.UnassignedConnectionRequests = opportunityRequests.Where(r => r.ConnectorPersonId == -1).Select(a => a.Id).ToList();

                // Flag indicating if current user is connector for any of the active types
                opportunity.HasActiveRequestsForConnector = opportunityRequests.Any(r => r.ConnectorPersonId == CurrentPersonId);

                // Total number of requests for opportunity/campus/connector
                opportunity.TotalRequests = opportunityRequests.Count();
            }

            //Set the Idle tooltip
            var           connectionTypes = opportunities.Where(o => allOpportunities.Contains(o.Id)).Select(o => o.ConnectionType).Distinct().ToList();
            StringBuilder sb = new StringBuilder();

            if (connectionTypes.Select(t => t.DaysUntilRequestIdle).Distinct().Count() == 1)
            {
                sb.Append(String.Format("Idle (no activity in {0} days)", connectionTypes.Select(t => t.DaysUntilRequestIdle).Distinct().First()));
            }
            else
            {
                sb.Append("Idle (no activity in several days)<br/><ul class='list-unstyled'>");
                foreach (var connectionType in connectionTypes)
                {
                    sb.Append(String.Format("<li>{0}: {1} days</li>", connectionType.Name, connectionType.DaysUntilRequestIdle));
                }
                sb.Append("</ul>");
            }

            var statusTemplate    = GetAttributeValue(AttributeKey.StatusTemplate);
            var statusMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage);

            statusMergeFields.Add("ConnectionOpportunities", allOpportunities);
            statusMergeFields.Add("ConnectionTypes", connectionTypes);
            statusMergeFields.Add("IdleTooltip", sb.ToString().EncodeHtml());
            lStatusBarContent.Text = statusTemplate.ResolveMergeFields(statusMergeFields);
            BindSummaryData();
        }
        protected void gRequests_Delete( object sender, RowEventArgs e )
        {
            using ( RockContext rockContext = new RockContext() )
            {
                var service = new ConnectionRequestService( rockContext );
                var connectionRequest = service.Get( e.RowKeyId );
                if ( connectionRequest != null )
                {
                    string errorMessage;
                    if ( !service.CanDelete( connectionRequest, out errorMessage ) )
                    {
                        mdGridWarning.Show( errorMessage, ModalAlertType.Information );
                        return;
                    }

                    rockContext.WrapTransaction( () =>
                    {
                        new ConnectionRequestActivityService( rockContext ).DeleteRange( connectionRequest.ConnectionRequestActivities );
                        service.Delete( connectionRequest );
                        rockContext.SaveChanges();
                    } );
                }
            }

            BindGrid();
        }