/// <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();
        }
        /// <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();
        }
Beispiel #3
0
        /// <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);
                    }

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

                    // 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
                opportunity.ActiveCount = opportunityRequests.Count();

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

            BindSummaryData();
        }
        /// <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();
        }
Beispiel #5
0
        /// <summary>
        /// Gets the summary data.
        /// </summary>
        private void GetSummaryData()
        {
            SummaryState = new List<ConnectionTypeSummary>();

            var rockContext = new RockContext();

            // Loop through every opportunity
            foreach ( var opportunity in new ConnectionOpportunityService( rockContext )
                .Queryable().AsNoTracking() )
            {
                // 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 );
                    }

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

                    // 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
                opportunity.ActiveCount = opportunityRequests.Count();

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

            BindSummaryData();
        }