protected Person GetPersonFromForm(string formId)
        {
            AttributeValueService attributeValueService = new AttributeValueService(rockContext);
            PersonService personService = new PersonService(rockContext);
            PersonAliasService personAliasService = new PersonAliasService(rockContext);

            var formAttribute = attributeValueService.Queryable().FirstOrDefault(a => a.Value == formId);
            var person = personService.Queryable().FirstOrDefault(p => p.Id == formAttribute.EntityId);

            return person;
        }
        /// <summary>
        /// Builds an expression for an attribute field
        /// </summary>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="entityField">The property.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public Expression GetAttributeExpression( IService serviceInstance, ParameterExpression parameterExpression, EntityField entityField, List<string> values )
        {
            ComparisonType comparisonType = ComparisonType.EqualTo;

            var service = new AttributeValueService( (RockContext)serviceInstance.Context );
            var attributeValues = service.Queryable().Where( v =>
                v.Attribute.Guid == entityField.AttributeGuid &&
                v.EntityId.HasValue &&
                v.Value != string.Empty );

            ParameterExpression attributeValueParameterExpression = Expression.Parameter( typeof( AttributeValue ), "v" );
            var filterExpression = entityField.FieldType.Field.AttributeFilterExpression( entityField.FieldConfig, values, attributeValueParameterExpression );
            if ( filterExpression != null )
            {
                attributeValues = attributeValues.Where( attributeValueParameterExpression, filterExpression, null );
            }

            IQueryable<int> ids = attributeValues.Select( v => v.EntityId.Value );

            if ( ids != null )
            {
                MemberExpression propertyExpression = Expression.Property( parameterExpression, "Id" );
                ConstantExpression idsExpression = Expression.Constant( ids.AsQueryable(), typeof( IQueryable<int> ) );
                Expression expression = Expression.Call( typeof( Queryable ), "Contains", new Type[] { typeof( int ) }, idsExpression, propertyExpression );
                if ( comparisonType == ComparisonType.NotEqualTo ||
                    comparisonType == ComparisonType.DoesNotContain ||
                    comparisonType == ComparisonType.IsBlank )
                {
                    return Expression.Not( expression );
                }
                else
                {
                    return expression;
                }
            }

            return null;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            var shapePageReference = new Rock.Web.PageReference(GetAttributeValue("SHAPEAssessmentPage"));
            var discPageReference = new Rock.Web.PageReference(GetAttributeValue("DISCAssessmentPage"));

            if (!string.IsNullOrWhiteSpace(PageParameter("FormId")))
                {
                    //Load the person based on the FormId
                    var personInUrl = PageParameter("FormId");
                    SelectedPerson = GetPersonFromForm(personInUrl);
                    PersonEncodedKey = SelectedPerson.UrlEncodedKey;
                }

                else if (!string.IsNullOrWhiteSpace(PageParameter("PersonId")))
                {
                    //Load the person based on the PersonId
                    SelectedPerson = GetPersonFromId(PageParameter("PersonId"));
                    PersonEncodedKey = SelectedPerson.UrlEncodedKey;
                 }

                else if (CurrentPerson != null)
                {
                    //Load the person based on the currently logged in person
                    SelectedPerson = CurrentPerson;
                    PersonEncodedKey = SelectedPerson.UrlEncodedKey;
                }

                else
                {
                    //Show Error Message
                    nbNoPerson.Visible = true;
                    Response.Redirect(shapePageReference.BuildUrl(), true);
                    return;
                }

            // Load the attributes

            AttributeValueService attributeValueService = new AttributeValueService(rockContext);
            DefinedValueService definedValueService = new DefinedValueService(rockContext);

            string spiritualGift1 = "";
            string spiritualGift2 = "";
            string spiritualGift3 = "";
            string spiritualGift4 = "";
            string heartCategories = "";
            string heartCauses = "";
            string heartPassion = "";
            string ability1 = "";
            string ability2 = "";
            string people = "";
            string places = "";
            string events = "";

            var spiritualGift1AttributeValue =
                attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "SpiritualGift1" && a.EntityId == SelectedPerson.Id);

            // Redirect if they haven't taken the Assessment
            if (spiritualGift1AttributeValue == null)
            {
                Response.Redirect(shapePageReference.BuildUrl(), true);
            }

            else
            {
                var spiritualGift2AttributeValue =
              attributeValueService
                  .Queryable()
                  .FirstOrDefault(a => a.Attribute.Key == "SpiritualGift2" && a.EntityId == SelectedPerson.Id);

                var spiritualGift3AttributeValue =
              attributeValueService
                  .Queryable()
                  .FirstOrDefault(a => a.Attribute.Key == "SpiritualGift3" && a.EntityId == SelectedPerson.Id);

                var spiritualGift4AttributeValue =
              attributeValueService
                  .Queryable()
                  .FirstOrDefault(a => a.Attribute.Key == "SpiritualGift4" && a.EntityId == SelectedPerson.Id);

                var ability1AttributeValue =
                    attributeValueService
                        .Queryable().FirstOrDefault(a => a.Attribute.Key == "Ability1" && a.EntityId == SelectedPerson.Id);

                var ability2AttributeValue =
                    attributeValueService
                        .Queryable().FirstOrDefault(a => a.Attribute.Key == "Ability2" && a.EntityId == SelectedPerson.Id);

                var peopleAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "SHAPEPeople" && a.EntityId == SelectedPerson.Id);

                var placesAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "SHAPEPlaces" && a.EntityId == SelectedPerson.Id);

                var eventsAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "SHAPEEvents" && a.EntityId == SelectedPerson.Id);

                var heartCategoriesAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "HeartCategories" && a.EntityId == SelectedPerson.Id);

                var heartCausesAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "HeartCauses" && a.EntityId == SelectedPerson.Id);

                var heartPassionAttributeValue = attributeValueService
                    .Queryable()
                    .FirstOrDefault(a => a.Attribute.Key == "HeartPassion" && a.EntityId == SelectedPerson.Id);

                if (spiritualGift1AttributeValue.Value != null) spiritualGift1 = spiritualGift1AttributeValue.Value;
                if (spiritualGift2AttributeValue.Value != null) spiritualGift2 = spiritualGift2AttributeValue.Value;
                if (spiritualGift3AttributeValue.Value != null) spiritualGift3 = spiritualGift3AttributeValue.Value;
                if (spiritualGift4AttributeValue.Value != null) spiritualGift4 = spiritualGift4AttributeValue.Value;
                if (heartCategoriesAttributeValue.Value != null) heartCategories = heartCategoriesAttributeValue.Value;
                if (heartCausesAttributeValue.Value != null) heartCauses = heartCausesAttributeValue.Value;
                if (heartPassionAttributeValue.Value != null) heartPassion = heartPassionAttributeValue.Value;
                if (ability1AttributeValue.Value != null) ability1 = ability1AttributeValue.Value;
                if (ability2AttributeValue.Value != null) ability2 = ability2AttributeValue.Value;
                if (peopleAttributeValue.Value != null) people = peopleAttributeValue.Value;
                if (placesAttributeValue.Value != null) places = placesAttributeValue.Value;
                if (eventsAttributeValue.Value != null) events = eventsAttributeValue.Value;

                string spiritualGift1Guid;
                string spiritualGift2Guid;
                string spiritualGift3Guid;
                string spiritualGift4Guid;
                string ability1Guid;
                string ability2Guid;

                // Check to see if there are already values saved as an ID.  If so, convert them to GUID
                if (spiritualGift1.ToString().Length < 5)
                {
                    if (spiritualGift1 != null) SpiritualGift1 = Int32.Parse(spiritualGift1);
                    if (spiritualGift2 != null) SpiritualGift2 = Int32.Parse(spiritualGift2);
                    if (spiritualGift3 != null) SpiritualGift3 = Int32.Parse(spiritualGift3);
                    if (spiritualGift4 != null) SpiritualGift4 = Int32.Parse(spiritualGift4);
                    if (ability1 != null) Ability1 = Int32.Parse(ability1);
                    if (ability2 != null) Ability2 = Int32.Parse(ability2);

                    var intsOfGifts =
                        definedValueService.GetByIds(new List<int>
                        {
                            SpiritualGift1,
                            SpiritualGift2,
                            SpiritualGift3,
                            SpiritualGift4,
                            Ability1,
                            Ability2
                        });

                    spiritualGift1Guid = intsOfGifts.ToList()[SpiritualGift1].Guid.ToString();
                    spiritualGift2Guid = intsOfGifts.ToList()[SpiritualGift2].Guid.ToString();
                    spiritualGift3Guid = intsOfGifts.ToList()[SpiritualGift3].Guid.ToString();
                    spiritualGift4Guid = intsOfGifts.ToList()[SpiritualGift4].Guid.ToString();
                    ability1Guid = intsOfGifts.ToList()[Ability1].Guid.ToString();
                    ability2Guid = intsOfGifts.ToList()[Ability2].Guid.ToString();
                }
                else
                {
                    spiritualGift1Guid = spiritualGift1;
                    spiritualGift2Guid = spiritualGift2;
                    spiritualGift3Guid = spiritualGift3;
                    spiritualGift4Guid = spiritualGift4;
                    ability1Guid = ability1;
                    ability2Guid = ability2;
                }

                // Get all of the data about the assiciated gifts and ability categories
                var shapeGift1Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(spiritualGift1Guid) }).FirstOrDefault();
                var shapeGift2Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(spiritualGift2Guid) }).FirstOrDefault();
                var shapeGift3Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(spiritualGift3Guid) }).FirstOrDefault();
                var shapeGift4Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(spiritualGift4Guid) }).FirstOrDefault();
                var ability1Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(ability1Guid) }).FirstOrDefault();
                var ability2Object = definedValueService.GetListByGuids(new List<Guid> { new Guid(ability2Guid) }).FirstOrDefault();

                shapeGift1Object.LoadAttributes();
                shapeGift2Object.LoadAttributes();
                shapeGift3Object.LoadAttributes();
                shapeGift4Object.LoadAttributes();
                ability1Object.LoadAttributes();
                ability2Object.LoadAttributes();

                // Get heart choices Values from Guids
                string heartCategoriesString = "";
                if (!heartCategories.IsNullOrWhiteSpace())
                {
                    string[] heartCategoryArray = heartCategories.Split(',');
                    foreach (string category in heartCategoryArray)
                    {
                        var definedValueObject =
                            definedValueService.Queryable().FirstOrDefault(a => a.Guid == new Guid(category));

                        if (category.Equals(heartCategoryArray.Last()))
                        {
                            heartCategoriesString += definedValueObject.Value;
                        }
                        else
                        {
                            heartCategoriesString += definedValueObject.Value + ", ";
                        }
                    }

                }

                // Get Volunteer Opportunities

                string gift1AssociatedVolunteerOpportunities =
                    shapeGift1Object.GetAttributeValue("AssociatedVolunteerOpportunities");
                string gift2AssociatedVolunteerOpportunities =
                    shapeGift2Object.GetAttributeValue("AssociatedVolunteerOpportunities");
                string gift3AssociatedVolunteerOpportunities =
                    shapeGift3Object.GetAttributeValue("AssociatedVolunteerOpportunities");
                string gift4AssociatedVolunteerOpportunities =
                    shapeGift4Object.GetAttributeValue("AssociatedVolunteerOpportunities");

                string allAssociatedVolunteerOpportunities = gift1AssociatedVolunteerOpportunities + "," +
                                                             gift2AssociatedVolunteerOpportunities + "," +
                                                             gift3AssociatedVolunteerOpportunities + "," +
                                                             gift4AssociatedVolunteerOpportunities;

                if (allAssociatedVolunteerOpportunities != ",,,")
                {
                    List<int> associatedVolunteerOpportunitiesList =
                        allAssociatedVolunteerOpportunities.Split(',').Select(t => int.Parse(t)).ToList();
                    Dictionary<int, int> VolunteerOpportunities = new Dictionary<int, int>();

                    var i = 0;
                    var q = from x in associatedVolunteerOpportunitiesList
                            group x by x
                        into g
                            let count = g.Count()
                            orderby count descending
                            select new { Value = g.Key, Count = count };
                    foreach (var x in q)
                    {
                        VolunteerOpportunities.Add(i, x.Value);
                        i++;
                    }

                    ConnectionOpportunityService connectionOpportunityService = new ConnectionOpportunityService(rockContext);
                    List<ConnectionOpportunity> connectionOpportunityList = new List<ConnectionOpportunity>();

                    foreach (KeyValuePair<int, int> entry in VolunteerOpportunities.Take(4))
                    {
                        var connection = connectionOpportunityService.GetByIds(new List<int> { entry.Value }).FirstOrDefault();

                        // Only display connection if it is marked Active
                        if (connection.IsActive == true)
                        {
                            connectionOpportunityList.Add(connection);
                        }

                    }

                    rpVolunteerOpportunities.DataSource = connectionOpportunityList;
                    rpVolunteerOpportunities.DataBind();
                }

                //Get DISC Info

                DiscService.AssessmentResults savedScores = DiscService.LoadSavedAssessmentResults(SelectedPerson);

                if (!string.IsNullOrWhiteSpace(savedScores.PersonalityType))
                {
                    ShowResults(savedScores);
                    DISCResults.Visible = true;
                    NoDISCResults.Visible = false;

                }
                else
                {
                    discPageReference.Parameters = new System.Collections.Generic.Dictionary<string, string>();
                    discPageReference.Parameters.Add("rckipid", SelectedPerson.UrlEncodedKey);
                    Response.Redirect(discPageReference.BuildUrl(), true);
                }

                // Build the UI

                lbPersonName.Text = SelectedPerson.FullName;

                lbGift1Title.Text = shapeGift1Object.Value;
                lbGift1BodyHTML.Text = shapeGift1Object.GetAttributeValue("HTMLDescription");

                lbGift2Title.Text = shapeGift2Object.Value;
                lbGift2BodyHTML.Text = shapeGift2Object.GetAttributeValue("HTMLDescription");

                lbGift3Title.Text = shapeGift3Object.Value;
                lbGift3BodyHTML.Text = shapeGift3Object.GetAttributeValue("HTMLDescription");

                lbGift4Title.Text = shapeGift4Object.Value;
                lbGift4BodyHTML.Text = shapeGift4Object.GetAttributeValue("HTMLDescription");

                lbAbility1Title.Text = ability1Object.Value;
                lbAbility1BodyHTML.Text = ability1Object.GetAttributeValue("HTMLDescription");

                lbAbility2Title.Text = ability2Object.Value;
                lbAbility2BodyHTML.Text = ability2Object.GetAttributeValue("HTMLDescription");

                lbPeople.Text = people;
                lbPlaces.Text = places;
                lbEvents.Text = events;

                lbHeartCategories.Text = heartCategoriesString;
                lbHeartCauses.Text = heartCauses;
                lbHeartPassion.Text = heartPassion;

                if (spiritualGift1AttributeValue.ModifiedDateTime != null)
                {
                    lbAssessmentDate.Text = spiritualGift1AttributeValue.ModifiedDateTime.Value.ToShortDateString();
                }
                else
                {
                    lbAssessmentDate.Text = spiritualGift1AttributeValue.CreatedDateTime.Value.ToShortDateString();
                }

                // Show create account panel if this person doesn't have an account
                if (SelectedPerson.Users.Count == 0)
                {
                    pnlAccount.Visible = true;
                }

            }
        }
Exemple #4
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void ShowResults()
        {
            // Get the group types that we're interested in
            Guid? groupTypeGuid = GetAttributeValue( "GroupType" ).AsGuidOrNull();
            if ( !groupTypeGuid.HasValue )
            {
                ShowError( "A valid Group Type is required." );
                return;
            }

            gGroups.Columns[1].Visible = GetAttributeValue( "ShowDescription" ).AsBoolean();
            gGroups.Columns[2].Visible = GetAttributeValue( "ShowSchedule" ).AsBoolean();
            gGroups.Columns[3].Visible = GetAttributeValue( "ShowCount" ).AsBoolean();
            gGroups.Columns[4].Visible = GetAttributeValue( "ShowAge" ).AsBoolean();

            bool showProximity = GetAttributeValue( "ShowProximity" ).AsBoolean();
            gGroups.Columns[5].Visible = showProximity;  // Distance

            // Get query of groups of the selected group type
            var rockContext = new RockContext();
            var groupService = new GroupService( rockContext );
            var groupQry = groupService
                .Queryable( "GroupLocations.Location" )
                .Where( g => g.IsActive && g.GroupType.Guid.Equals( groupTypeGuid.Value ) && g.IsPublic );

            var groupParameterExpression = groupService.ParameterExpression;
            var schedulePropertyExpression = Expression.Property( groupParameterExpression, "Schedule" );

            var dowFilterControl = phFilterControls.FindControl( "filter_dow" );
            if ( dowFilterControl != null )
            {
                var field = FieldTypeCache.Read( Rock.SystemGuid.FieldType.DAY_OF_WEEK ).Field;

                var filterValues = field.GetFilterValues( dowFilterControl, null, Rock.Reporting.FilterMode.SimpleFilter );
                var expression = field.PropertyFilterExpression( null, filterValues, schedulePropertyExpression, "WeeklyDayOfWeek", typeof( DayOfWeek? ) );
                groupQry = groupQry.Where( groupParameterExpression, expression, null );
            }

            var timeFilterControl = phFilterControls.FindControl( "filter_time" );
            if ( timeFilterControl != null )
            {
                var field = FieldTypeCache.Read( Rock.SystemGuid.FieldType.TIME ).Field;

                var filterValues = field.GetFilterValues( timeFilterControl, null, Rock.Reporting.FilterMode.SimpleFilter );
                var expression = field.PropertyFilterExpression( null, filterValues, schedulePropertyExpression, "WeeklyTimeOfDay", typeof( TimeSpan? ) );
                groupQry = groupQry.Where( groupParameterExpression, expression, null );
            }

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

                foreach ( var attribute in AttributeFilters )
                {
                    var filterControl = phFilterControls.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 );

                            groupQry = groupQry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                        }
                    }
                }
            }

            List<GroupLocation> fences = null;
            List<Group> groups = null;

            // Run query to get list of matching groups
            SortProperty sortProperty = gGroups.SortProperty;
            if ( sortProperty != null )
            {
                groups = groupQry.Sort( sortProperty ).ToList();
            }
            else
            {
                groups = groupQry.OrderBy( g => g.Name ).ToList();
            }

            int? fenceGroupTypeId = GetGroupTypeId( GetAttributeValue( "GeofencedGroupType" ).AsGuidOrNull() );
            bool showMap = GetAttributeValue( "ShowMap" ).AsBoolean();
            bool showFences = showMap && GetAttributeValue( "ShowFence" ).AsBoolean();

            var distances = new Dictionary<int, double>();

            // If we care where these groups are located...
            if ( fenceGroupTypeId.HasValue || showMap || showProximity )
            {
                // Get the location for the address entered
                Location personLocation = null;
                if ( fenceGroupTypeId.HasValue || showProximity )
                {
                    personLocation = new LocationService( rockContext )
                        .Get( acAddress.Street1, acAddress.Street2, acAddress.City,
                            acAddress.State, acAddress.PostalCode, acAddress.Country );
                }

                // If showing a map, and person's location was found, save a mapitem for this location
                FinderMapItem personMapItem = null;
                if ( showMap && personLocation != null && personLocation.GeoPoint != null )
                {
                    var infoWindow = string.Format( @"
            <div style='width:250px'>
            <div class='clearfix'>
            <strong>Your Location</strong>
            <br/>{0}
            </div>
            </div>
            ", personLocation.FormattedHtmlAddress );

                    personMapItem = new FinderMapItem( personLocation );
                    personMapItem.Name = "Your Location";
                    personMapItem.InfoWindow = HttpUtility.HtmlEncode( infoWindow.Replace( Environment.NewLine, string.Empty ).Replace( "\n", string.Empty ).Replace( "\t", string.Empty ) );
                }

                // Get the locations, and optionally calculate the distance for each of the groups
                var groupLocations = new List<GroupLocation>();
                foreach ( var group in groups )
                {
                    foreach ( var groupLocation in group.GroupLocations
                        .Where( gl => gl.Location.GeoPoint != null ) )
                    {
                        groupLocations.Add( groupLocation );

                        if ( showProximity && personLocation != null && personLocation.GeoPoint != null )
                        {
                            double meters = groupLocation.Location.GeoPoint.Distance( personLocation.GeoPoint ) ?? 0.0D;
                            double miles = meters * Location.MilesPerMeter;

                            // If this group already has a distance calculated, see if this location is closer and if so, use it instead
                            if ( distances.ContainsKey( group.Id ) )
                            {
                                if ( distances[group.Id] < miles )
                                {
                                    distances[group.Id] = miles;
                                }
                            }
                            else
                            {
                                distances.Add( group.Id, miles );
                            }
                        }
                    }
                }

                // If groups should be limited by a geofence
                var fenceMapItems = new List<MapItem>();
                if ( fenceGroupTypeId.HasValue )
                {
                    fences = new List<GroupLocation>();
                    if ( personLocation != null && personLocation.GeoPoint != null )
                    {
                        fences = new GroupLocationService( rockContext )
                            .Queryable( "Group,Location" )
                            .Where( gl =>
                                gl.Group.GroupTypeId == fenceGroupTypeId &&
                                gl.Location.GeoFence != null &&
                                personLocation.GeoPoint.Intersects( gl.Location.GeoFence ) )
                            .ToList();
                    }

                    // Limit the group locations to only those locations inside one of the fences
                    groupLocations = groupLocations
                        .Where( gl =>
                            fences.Any( f => gl.Location.GeoPoint.Intersects( f.Location.GeoFence ) ) )
                        .ToList();

                    // Limit the groups to the those that still contain a valid location
                    groups = groups
                        .Where( g =>
                            groupLocations.Any( gl => gl.GroupId == g.Id ) )
                        .ToList();

                    // If the map and fences should be displayed, create a map item for each fence
                    if ( showMap && showFences )
                    {
                        foreach ( var fence in fences )
                        {
                            var mapItem = new FinderMapItem( fence.Location );
                            mapItem.EntityTypeId = EntityTypeCache.Read( "Rock.Model.Group" ).Id;
                            mapItem.EntityId = fence.GroupId;
                            mapItem.Name = fence.Group.Name;
                            fenceMapItems.Add( mapItem );
                        }
                    }
                }

                // if not sorting by ColumnClick and SortByDistance, then sort the groups by distance
                if ( gGroups.SortProperty == null && GetAttributeValue( "SortByDistance" ).AsBoolean() )
                {
                    // only show groups with a known location, and sort those by distance
                    groups = groups.Where( a => distances.Select( b => b.Key ).Contains( a.Id ) ).ToList();
                    groups = groups.OrderBy( a => distances[a.Id] ).ThenBy( a => a.Name ).ToList();
                }

                // if limiting by PageSize, limit to the top X groups
                int? pageSize = ddlPageSize.SelectedValue.AsIntegerOrNull();
                if ( pageSize.HasValue && pageSize > 0 )
                {
                    groups = groups.Take( pageSize.Value ).ToList();
                }

                // If a map is to be shown
                if ( showMap && groups.Any() )
                {

                    Template template = Template.Parse( GetAttributeValue( "MapInfo" ) );

                    bool showDebug = UserCanEdit && GetAttributeValue( "MapInfoDebug" ).AsBoolean();
                    lMapInfoDebug.Visible = showDebug;

                    // Add mapitems for all the remaining valid group locations
                    var groupMapItems = new List<MapItem>();
                    foreach ( var gl in groupLocations )
                    {
                        var group = groups.Where( g => g.Id == gl.GroupId ).FirstOrDefault();
                        if ( group != null )
                        {
                            // Resolve info window lava template
                            var linkedPageParams = new Dictionary<string, string> { { "GroupId", group.Id.ToString() } };
                            var mergeFields = new Dictionary<string, object>();
                            mergeFields.Add( "Group", gl.Group );
                            mergeFields.Add( "Location", gl.Location );

                            Dictionary<string, object> linkedPages = new Dictionary<string, object>();
                            linkedPages.Add( "GroupDetailPage", LinkedPageRoute( "GroupDetailPage" ) );

                            if ( _targetPersonGuid != Guid.Empty )
                            {
                                linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", _urlParms ) );
                            }
                            else
                            {
                                linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", null ) );
                            }

                            mergeFields.Add( "LinkedPages", linkedPages );

                            // add collection of allowed security actions
                            Dictionary<string, object> securityActions = new Dictionary<string, object>();
                            securityActions.Add( "View", group.IsAuthorized( Authorization.VIEW, CurrentPerson ) );
                            securityActions.Add( "Edit", group.IsAuthorized( Authorization.EDIT, CurrentPerson ) );
                            securityActions.Add( "Administrate", group.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ) );
                            mergeFields.Add( "AllowedActions", securityActions );

                            string infoWindow = template.Render( Hash.FromDictionary( mergeFields ) );

                            if ( showDebug )
                            {
                                lMapInfoDebug.Text = mergeFields.lavaDebugInfo( null, "<span class='label label-info'>Lava used for the map window.</span>", "" );
                                showDebug = false;
                            }

                            // Add a map item for group
                            var mapItem = new FinderMapItem( gl.Location );
                            mapItem.EntityTypeId = EntityTypeCache.Read( "Rock.Model.Group" ).Id;
                            mapItem.EntityId = group.Id;
                            mapItem.Name = group.Name;
                            mapItem.InfoWindow = HttpUtility.HtmlEncode( infoWindow.Replace( Environment.NewLine, string.Empty ).Replace( "\n", string.Empty ).Replace( "\t", string.Empty ) );
                            groupMapItems.Add( mapItem );
                        }
                    }

                    // Show the map
                    Map( personMapItem, fenceMapItems, groupMapItems );
                    pnlMap.Visible = true;
                }
                else
                {
                    pnlMap.Visible = false;
                }
            }
            else
            {
                pnlMap.Visible = false;
            }

            // Should a lava output be displayed
            if ( GetAttributeValue( "ShowLavaOutput" ).AsBoolean() )
            {
                string template = GetAttributeValue( "LavaOutput" );

                var mergeFields = new Dictionary<string, object>();
                if ( fences != null )
                {
                    mergeFields.Add( "Fences", fences.Select( f => f.Group ).ToList() );
                }
                else
                {
                    mergeFields.Add( "Fences", new Dictionary<string, object>() );
                }

                mergeFields.Add( "Groups", groups );

                Dictionary<string, object> linkedPages = new Dictionary<string, object>();
                linkedPages.Add( "GroupDetailPage", LinkedPageUrl( "GroupDetailPage", null ) );

                if ( _targetPersonGuid != Guid.Empty )
                {
                    linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", _urlParms ) );
                }
                else
                {
                    linkedPages.Add( "RegisterPage", LinkedPageUrl( "RegisterPage", null ) );
                }

                mergeFields.Add( "LinkedPages", linkedPages );

                lLavaOverview.Text = template.ResolveMergeFields( mergeFields );

                bool showDebug = UserCanEdit && GetAttributeValue( "LavaOutputDebug" ).AsBoolean();
                lLavaOutputDebug.Visible = showDebug;
                if ( showDebug )
                {
                    lLavaOutputDebug.Text = mergeFields.lavaDebugInfo( null, "<span class='label label-info'>Lava used for the summary info.</span>" );
                }

                pnlLavaOutput.Visible = true;
            }
            else
            {
                pnlLavaOutput.Visible = false;
            }

            // Should a grid be displayed
            if ( GetAttributeValue( "ShowGrid" ).AsBoolean() )
            {
                pnlGrid.Visible = true;

                // Save the groups into the grid's object list since it is not being bound to actual group objects
                gGroups.ObjectList = new Dictionary<string, object>();
                groups.ForEach( g => gGroups.ObjectList.Add( g.Id.ToString(), g ) );

                // Bind the grid
                gGroups.DataSource = groups.Select( g =>
                {
                    var qryMembers = new GroupMemberService( rockContext ).Queryable().Where( a => a.GroupId == g.Id );
                    var groupType = GroupTypeCache.Read( g.GroupTypeId );

                    return new
                    {
                        Id = g.Id,
                        Name = g.Name,
                        GroupTypeName = groupType.Name,
                        GroupOrder = g.Order,
                        GroupTypeOrder = groupType.Order,
                        Description = g.Description,
                        IsSystem = g.IsSystem,
                        IsActive = g.IsActive,
                        GroupRole = string.Empty,
                        DateAdded = DateTime.MinValue,
                        Schedule = g.Schedule,
                        MemberCount = qryMembers.Count(),
                        AverageAge = Math.Round( qryMembers.Select( m => m.Person.BirthDate ).ToList().Select( a => Person.GetAge( a ) ).Average() ?? 0.0D ),
                        Distance = distances.Where( d => d.Key == g.Id )
                            .Select( d => d.Value ).FirstOrDefault()
                    };
                } ).ToList();
                gGroups.DataBind();
            }
            else
            {
                pnlGrid.Visible = false;
            }

            // Show the results
            pnlResults.Visible = true;
        }
Exemple #5
0
        /// <summary>
        /// Builds an expression for an attribute field
        /// </summary>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="entityField">The property.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static Expression GetAttributeExpression( IService serviceInstance, ParameterExpression parameterExpression, EntityField entityField, List<string> values )
        {
            var service = new AttributeValueService( (RockContext)serviceInstance.Context );

            var attributeValues = service.Queryable().Where( v =>
                v.EntityId.HasValue &&
                v.Value != string.Empty );

            if ( entityField.AttributeGuid.HasValue )
            {
                attributeValues = attributeValues.Where( v => v.Attribute.Guid == entityField.AttributeGuid );
            }
            else
            {
                attributeValues = attributeValues.Where( v => v.Attribute.Key == entityField.Name && v.Attribute.FieldTypeId == entityField.FieldType.Id );
            }

            ParameterExpression attributeValueParameterExpression = Expression.Parameter( typeof( AttributeValue ), "v" );

            // Determine the appropriate comparison type to use for this Expression.
            // Attribute Value records only exist for Entities that have a value specified for the Attribute.
            // Therefore, if the specified comparison works by excluding certain values we must invert our filter logic:
            // first we find the Attribute Values that match those values and then we exclude the associated Entities from the result set.
            var comparisonType = ComparisonType.EqualTo;
            ComparisonType evaluatedComparisonType = comparisonType;

            if ( values.Count >= 2 )
            {
                string comparisonValue = values[0];
                if ( comparisonValue != "0" )
                {
                    comparisonType = comparisonValue.ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );
                }

                switch ( comparisonType )
                {
                    case ComparisonType.DoesNotContain:
                        evaluatedComparisonType = ComparisonType.Contains;
                        break;
                    case ComparisonType.IsBlank:
                        evaluatedComparisonType = ComparisonType.IsNotBlank;
                        break;
                    case ComparisonType.LessThan:
                        evaluatedComparisonType = ComparisonType.GreaterThanOrEqualTo;
                        break;
                    case ComparisonType.LessThanOrEqualTo:
                        evaluatedComparisonType = ComparisonType.GreaterThan;
                        break;
                    case ComparisonType.NotEqualTo:
                        evaluatedComparisonType = ComparisonType.EqualTo;
                        break;
                    default:
                        evaluatedComparisonType = comparisonType;
                        break;
                }

                values[0] = evaluatedComparisonType.ToString();
            }

            var filterExpression = entityField.FieldType.Field.AttributeFilterExpression( entityField.FieldConfig, values, attributeValueParameterExpression );
            if ( filterExpression != null )
            {
                attributeValues = attributeValues.Where( attributeValueParameterExpression, filterExpression, null );
            }

            IQueryable<int> ids = attributeValues.Select( v => v.EntityId.Value );

            MemberExpression propertyExpression = Expression.Property( parameterExpression, "Id" );
            ConstantExpression idsExpression = Expression.Constant( ids.AsQueryable(), typeof( IQueryable<int> ) );
            Expression expression = Expression.Call( typeof( Queryable ), "Contains", new Type[] { typeof( int ) }, idsExpression, propertyExpression );

            // If we have used an inverted comparison type for the evaluation, invert the Expression so that it excludes the matching Entities.
            if ( comparisonType != evaluatedComparisonType )
            {
                return Expression.Not( expression );
            }
            else
            {
                return expression;
            }
        }
        private void GetData()
        {
            var rockContext = new RockContext();
            var itemService = new ContentChannelItemService(rockContext);

            int personId = CurrentPerson != null ? CurrentPerson.Id : 0;

            // Get all of the content channels
            var allChannels = new ContentChannelService( rockContext ).Queryable( "ContentChannelType" )
                .OrderBy( w => w.Name )
                .ToList();

            // Create variable for storing authorized channels and the count of active items
            var channelCounts = new Dictionary<int, int>();
            foreach ( var channel in allChannels )
            {
                if ( channel.IsAuthorized( Authorization.VIEW, CurrentPerson))
                {
                    channelCounts.Add( channel.Id, 0);
                }
            }

            // Get the pending approval item counts for each channel (if the channel requires approval)
            itemService.Queryable()
                .Where( i =>
                    channelCounts.Keys.Contains( i.ContentChannelId ) &&
                    i.Status == ContentChannelItemStatus.PendingApproval && i.ContentChannel.RequiresApproval )
                .GroupBy( i => i.ContentChannelId )
                .Select( i => new {
                    Id = i.Key,
                    Count = i.Count()
                })
                .ToList()
                .ForEach( i => channelCounts[i.Id] = i.Count );

            // Create a query to return channel, the count of items, and the selected class
            var qry = allChannels
                .Where( c => channelCounts.Keys.Contains( c.Id ) )
                .Select( c => new
                {
                    Channel = c,
                    Count = channelCounts[c.Id],
                    Class = ( SelectedChannelId.HasValue && SelectedChannelId.Value == c.Id ) ? "active" : ""
                } );

            // If displaying active only, update query to exclude those content channels without any items
            if ( tglStatus.Checked )
            {
                qry = qry.Where( c => c.Count > 0 );
            }

            var contentChannels = qry.ToList();

            rptChannels.DataSource = contentChannels;
            rptChannels.DataBind();

            ContentChannel selectedChannel = null;
            if ( SelectedChannelId.HasValue )
            {
                selectedChannel = allChannels
                    .Where( w =>
                        w.Id == SelectedChannelId.Value &&
                        channelCounts.Keys.Contains( SelectedChannelId.Value ) )
                    .FirstOrDefault();
            }

            if ( selectedChannel != null && contentChannels.Count > 0 )
            {
                // show the content item panel
                divItemPanel.Visible = true;

                BindAttributes( selectedChannel );
                AddDynamicControls( selectedChannel );

                var itemQry = itemService.Queryable()
                    .Where( i => i.ContentChannelId == selectedChannel.Id );

                var drp = new DateRangePicker();
                drp.DelimitedValues = gfFilter.GetUserPreference( "Date Range" );
                if ( drp.LowerValue.HasValue )
                {
                    if ( selectedChannel.ContentChannelType.DateRangeType == ContentChannelDateType.SingleDate )
                    {
                        itemQry = itemQry.Where( i => i.StartDateTime >= drp.LowerValue.Value );
                    }
                    else
                    {
                        itemQry = itemQry.Where( i => i.ExpireDateTime.HasValue && i.ExpireDateTime.Value >= drp.LowerValue.Value );
                    }
                }
                if ( drp.UpperValue.HasValue )
                {
                    DateTime upperDate = drp.UpperValue.Value.Date.AddDays( 1 );
                    itemQry = itemQry.Where( i => i.StartDateTime <= upperDate );
                }

                var status = gfFilter.GetUserPreference( "Status" ).ConvertToEnumOrNull<ContentChannelItemStatus>();
                if ( status.HasValue )
                {
                    itemQry = itemQry.Where( i => i.Status == status );
                }

                string title = gfFilter.GetUserPreference( "Title" );
                if (!string.IsNullOrWhiteSpace(title))
                {
                    itemQry = itemQry.Where( i => i.Title.Contains( title ) );
                }

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

                    foreach ( var attribute in AvailableAttributes )
                    {
                        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 );

                                itemQry = itemQry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }

                var items = new List<ContentChannelItem>();
                foreach ( var item in itemQry.ToList() )
                {
                    if ( item.IsAuthorized( Rock.Security.Authorization.VIEW, CurrentPerson ) )
                    {
                        items.Add( item );
                    }
                }

                SortProperty sortProperty = gContentChannelItems.SortProperty;
                if ( sortProperty != null )
                {
                    items = items.AsQueryable().Sort( sortProperty ).ToList();
                }
                else
                {
                    items = items.OrderByDescending( p => p.StartDateTime ).ToList();
                }

                gContentChannelItems.ObjectList = new Dictionary<string, object>();
                items.ForEach( i => gContentChannelItems.ObjectList.Add( i.Id.ToString(), i ) );

                gContentChannelItems.DataSource = items.Select( i => new
                {
                    i.Id,
                    i.Guid,
                    i.Title,
                    i.StartDateTime,
                    i.ExpireDateTime,
                    i.Priority,
                    Status = DisplayStatus( i.Status ),
                    Occurrences = i.EventItemOccurrences.Any()
                } ).ToList();
                gContentChannelItems.DataBind();

                lContentChannelItems.Text = selectedChannel.Name + " Items";
            }
            else
            {
                divItemPanel.Visible = false;
            }
        }
        /// <summary>
        /// Updates the list.
        /// </summary>
        private void UpdateList()
        {
            using ( var rockContext = new RockContext() )
            {
                var searchSelections = new Dictionary<string, string>();

                var connectionTypeId = GetAttributeValue( "ConnectionTypeId" ).AsInteger();
                var connectionType = new ConnectionTypeService( rockContext ).Get( connectionTypeId );
                var connectionOpportunityService = new ConnectionOpportunityService( rockContext );

                var qrySearch = connectionOpportunityService.Queryable().Where( a => a.ConnectionTypeId == connectionTypeId && a.IsActive == true ).ToList();

                if ( GetAttributeValue( "DisplayNameFilter" ).AsBoolean() )
                {
                    if ( !string.IsNullOrWhiteSpace( tbSearchName.Text ) )
                    {
                        searchSelections.Add( "tbSearchName", 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();
                    }
                }

                if ( GetAttributeValue( "DisplayCampusFilter" ).AsBoolean() )
                {
                    var searchCampuses = cblCampus.SelectedValuesAsInt;
                    if ( searchCampuses.Count > 0 )
                    {
                        searchSelections.Add( "cblCampus", searchCampuses.AsDelimited("|") );
                        qrySearch = qrySearch.Where( o => o.ConnectionOpportunityCampuses.Any( c => searchCampuses.Contains( c.CampusId ) ) ).ToList();
                    }
                }

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            string filterControlId = "filter_" + attribute.Id.ToString();
                            var filterControl = phAttributeFilters.FindControl( filterControlId );
                            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 )
                                {
                                    searchSelections.Add( filterControlId, filterValues.ToJson() );
                                    var attributeValues = attributeValueService
                                        .Queryable()
                                        .Where( v => v.Attribute.Id == attribute.Id );

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

                                    qrySearch = qrySearch.Where( o => attributeValues.Select( v => v.EntityId ).Contains( o.Id ) ).ToList();
                                }
                            }
                        }
                    }
                }

                string sessionKey = string.Format( "ConnectionSearch_{0}", this.BlockId );
                Session[sessionKey] = searchSelections;

                var opportunities = qrySearch.OrderBy( s => s.PublicName ).ToList();

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

                var pageReference = new PageReference( GetAttributeValue( "DetailPage" ), null );
                mergeFields.Add( "DetailPage", BuildDetailPageUrl(pageReference.BuildUrl()) );

                lOutput.Text = GetAttributeValue( "LavaTemplate" ).ResolveMergeFields( mergeFields );

                if ( GetAttributeValue( "SetPageTitle" ).AsBoolean() )
                {
                    string pageTitle = "Connection";
                    RockPage.PageTitle = pageTitle;
                    RockPage.BrowserTitle = String.Format( "{0} | {1}", pageTitle, RockPage.Site.Name );
                    RockPage.Header.Title = String.Format( "{0} | {1}", pageTitle, RockPage.Site.Name );
                }

                // show debug info
                if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) )
                {
                    lDebug.Visible = true;
                    lDebug.Text = mergeFields.lavaDebugInfo();
                }
            }
        }
        /// <summary>
        /// Job that will run quick SQL queries on a schedule.
        /// 
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute( IJobExecutionContext context )
        {
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            Guid? entryWorkflowType = dataMap.GetString( "EraEntryWorkflow" ).AsGuidOrNull();
            Guid? exitWorkflowType = dataMap.GetString( "EraExitWorkflow" ).AsGuidOrNull();
            bool updateVisitDates = dataMap.GetBooleanValue( "SetVisitDates" );
            var groupTypeList = dataMap.GetString( "GroupTypes" );

            // configuration
            //

            // giving
            int exitGivingCount = 1;

            // attendance
            int exitAttendanceCountShort = 1;
            int exitAttendanceCountLong = 8;

            // get era dataset from stored proc
            var resultContext = new RockContext();

            var eraAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_CURRENTLY_AN_ERA.AsGuid() );
            var eraStartAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_START_DATE.AsGuid() );
            var eraEndAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_END_DATE.AsGuid() );

            resultContext.Database.CommandTimeout = 3600;

            var results = resultContext.Database.SqlQuery<EraResult>( "spCrm_FamilyAnalyticsEraDataset" ).ToList();

            int personEntityTypeId = EntityTypeCache.Read( "Rock.Model.Person" ).Id;
            int attributeEntityTypeId = EntityTypeCache.Read( "Rock.Model.Attribute" ).Id;
            int eraAttributeId = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_CURRENTLY_AN_ERA.AsGuid() ).Id;
            int personAnalyticsCategoryId = CategoryCache.Read( SystemGuid.Category.HISTORY_PERSON_ANALYTICS.AsGuid() ).Id;

            foreach (var result in results )
            {
                // create new rock context for each family (https://weblog.west-wind.com/posts/2014/Dec/21/Gotcha-Entity-Framework-gets-slow-in-long-Iteration-Loops)
                RockContext updateContext = new RockContext();
                var attributeValueService = new AttributeValueService( updateContext );
                var historyService = new HistoryService( updateContext );

                // if era ensure it still meets requirements
                if ( result.IsEra )
                {
                    if (result.ExitGiftCountDuration < exitGivingCount && result.ExitAttendanceCountDurationShort < exitAttendanceCountShort && result.ExitAttendanceCountDurationLong < exitAttendanceCountLong )
                    {
                        // exit era (delete attribute value from each person in family)
                        var family = new GroupService( updateContext ).Queryable( "Members, Members.Person" ).AsNoTracking().Where( m => m.Id == result.FamilyId ).FirstOrDefault();

                        if ( family != null ) {
                            foreach ( var person in family.Members.Select( m => m.Person ) ) {

                                // remove the era flag
                                var eraAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id ).FirstOrDefault();
                                if ( eraAttributeValue != null )
                                {
                                    attributeValueService.Delete( eraAttributeValue );
                                }

                                // set end date
                                var eraEndAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id ).FirstOrDefault();
                                if ( eraEndAttributeValue == null )
                                {
                                    eraEndAttributeValue = new AttributeValue();
                                    eraEndAttributeValue.EntityId = person.Id;
                                    eraEndAttributeValue.AttributeId = eraEndAttribute.Id;
                                    attributeValueService.Add( eraEndAttributeValue );
                                }
                                eraEndAttributeValue.Value = RockDateTime.Now.ToString();

                                // add a history record
                                if ( personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0 )
                                {
                                    History historyRecord = new History();
                                    historyService.Add( historyRecord );
                                    historyRecord.EntityTypeId = personEntityTypeId;
                                    historyRecord.EntityId = person.Id;
                                    historyRecord.CreatedDateTime = RockDateTime.Now;
                                    historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId;
                                    historyRecord.Caption = "eRA";
                                    historyRecord.Summary = "Exited eRA Status";
                                    historyRecord.Verb = "EXITED";
                                    historyRecord.RelatedEntityTypeId = attributeEntityTypeId;
                                    historyRecord.RelatedEntityId = eraAttributeId;
                                    historyRecord.CategoryId = personAnalyticsCategoryId;
                                }

                                updateContext.SaveChanges();
                            }

                            // launch exit workflow
                            if ( exitWorkflowType.HasValue )
                            {
                                LaunchWorkflow( exitWorkflowType.Value, family );
                            }
                        }
                    }
                }
                else
                {
                    // entered era
                    var family = new GroupService( updateContext ).Queryable( "Members" ).AsNoTracking().Where( m => m.Id == result.FamilyId ).FirstOrDefault();

                    if ( family != null )
                    {
                        foreach ( var person in family.Members.Select( m => m.Person ) )
                        {
                            // set era attribute to true
                            var eraAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id ).FirstOrDefault();
                            if ( eraAttributeValue == null )
                            {
                                eraAttributeValue = new AttributeValue();
                                eraAttributeValue.EntityId = person.Id;
                                eraAttributeValue.AttributeId = eraAttribute.Id;
                                attributeValueService.Add( eraAttributeValue );
                            }
                            eraAttributeValue.Value = bool.TrueString;

                            // add start date
                            var eraStartAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraStartAttribute.Id && v.EntityId == person.Id ).FirstOrDefault();
                            if (eraStartAttributeValue == null )
                            {
                                eraStartAttributeValue = new AttributeValue();
                                eraStartAttributeValue.EntityId = person.Id;
                                eraStartAttributeValue.AttributeId = eraStartAttribute.Id;
                                attributeValueService.Add( eraStartAttributeValue );
                            }
                            eraStartAttributeValue.Value = RockDateTime.Now.ToString();

                            // delete end date if it exists
                            var eraEndAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id ).FirstOrDefault();
                            if ( eraEndAttributeValue != null )
                            {
                                attributeValueService.Delete( eraEndAttributeValue );
                            }

                            // add a history record
                            if ( personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0 )
                            {
                                History historyRecord = new History();
                                historyService.Add( historyRecord );
                                historyRecord.EntityTypeId = personEntityTypeId;
                                historyRecord.EntityId = person.Id;
                                historyRecord.CreatedDateTime = RockDateTime.Now;
                                historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId;
                                historyRecord.Caption = "eRA";
                                historyRecord.Summary = "Entered eRA Status";
                                historyRecord.Verb = "ENTERED";
                                historyRecord.RelatedEntityTypeId = attributeEntityTypeId;
                                historyRecord.RelatedEntityId = eraAttributeId;
                                historyRecord.CategoryId = personAnalyticsCategoryId;
                            }

                            updateContext.SaveChanges();
                        }

                        // launch entry workflow
                        if ( entryWorkflowType.HasValue )
                        {
                            LaunchWorkflow( entryWorkflowType.Value, family );
                        }
                    }
                }

                // update stats
            }

            // load giving attributes
            resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsGiving" );

            // load attendance attributes
            resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsAttendance" );

            // process history for group types
            if (!string.IsNullOrWhiteSpace( groupTypeList ) )
            {
                string[] groupTypeGuids = groupTypeList.Split( ',' );

                var inactiveRecordValue = DefinedValueCache.Read( SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE );

                var groupTypeEntityTypeId = EntityTypeCache.Read( "Rock.Model.GroupType" ).Id;

                foreach ( var groupTypeGuid in groupTypeGuids )
                {
                    var groupType = GroupTypeCache.Read( groupTypeGuid.AsGuid() );

                    if ( groupType != null )
                    {
                        // if the person is in a group of that type and the last history record for that group type isn't START write a start
                        RockContext rockContext = new RockContext();

                        // get history for this group type
                        var historyRecords = new HistoryService( rockContext ).Queryable()
                                            .Where( h =>
                                                 h.EntityTypeId == personEntityTypeId
                                                 && h.RelatedEntityTypeId == groupTypeEntityTypeId
                                                 && h.RelatedEntityId == groupType.Id
                                             )
                                             .GroupBy( h => h.EntityId )
                                             .Select( g => g.OrderByDescending( h => h.CreatedDateTime ).Select( h => new { h.EntityId, h.Verb } ).FirstOrDefault() )
                                             .ToList();

                        // get group member information
                        var groupMemberInfo = new GroupMemberService( rockContext ).Queryable()
                                            .Where( m =>
                                                 m.Group.GroupTypeId == groupType.Id
                                                 && m.GroupMemberStatus == GroupMemberStatus.Active
                                                 && m.Group.IsActive
                                                 //&& m.Person.RecordStatusValueId != inactiveRecordValue.Id
                                             )
                                             .GroupBy( m => m.PersonId )
                                             .Select( g => g.OrderBy( m => m.CreatedDateTime ).Select( m => new { m.PersonId, m.CreatedDateTime, PersonAliasId = m.Person.Aliases.Select( p => p.Id ).FirstOrDefault() } ).FirstOrDefault() )
                                             .ToList();

                        var needsStartDate = groupMemberInfo.Where( m => !historyRecords.Any( h => h.EntityId == m.PersonId && h.Verb == "STARTED" ) );

                        foreach ( var startItem in needsStartDate )
                        {
                            using ( RockContext updateContext = new RockContext() )
                            {
                                var historyService = new HistoryService( updateContext );
                                History history = new History();
                                historyService.Add( history );
                                history.EntityTypeId = personEntityTypeId;
                                history.EntityId = startItem.PersonId;
                                history.RelatedEntityTypeId = groupTypeEntityTypeId;
                                history.RelatedEntityId = groupType.Id;
                                history.Caption = groupType.Name;
                                history.Summary = "Started Membership in Group Of Type";
                                history.Verb = "STARTED";
                                history.CreatedDateTime = startItem.CreatedDateTime;
                                history.CreatedByPersonAliasId = startItem.PersonAliasId;
                                history.CategoryId = personAnalyticsCategoryId;

                                updateContext.SaveChanges();
                            }
                        }

                        var needsStoppedDate = historyRecords.Where( h => h.Verb == "STARTED" && !groupMemberInfo.Any( m => m.PersonId == h.EntityId ) );

                        foreach ( var stopItem in needsStoppedDate )
                        {
                            using ( RockContext updateContext = new RockContext() )
                            {
                                var person = new PersonService( updateContext ).Get( stopItem.EntityId );

                                if ( person != null )
                                {
                                    var historyService = new HistoryService( updateContext );
                                    History history = new History();
                                    historyService.Add( history );
                                    history.EntityTypeId = personEntityTypeId;
                                    history.EntityId = person.Id;
                                    history.RelatedEntityTypeId = groupTypeEntityTypeId;
                                    history.RelatedEntityId = groupType.Id;
                                    history.Caption = groupType.Name;
                                    history.Summary = "Stopped Membership in Group Of Type";
                                    history.Verb = "STOPPED";
                                    history.CreatedDateTime = RockDateTime.Now;
                                    history.CreatedByPersonAliasId = person.PrimaryAliasId;
                                    history.CategoryId = personAnalyticsCategoryId;

                                    updateContext.SaveChanges();
                                }
                            }
                        }
                    }
                }

            }

            // process visit dates
            if ( updateVisitDates )
            {
                resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsUpdateVisitDates" );
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            phSummary.Controls.Clear();
            rFilter.Visible = true;
            gList.Visible = true;
            RockContext rockContext = new RockContext();
            BenevolenceRequestService benevolenceRequestService = new BenevolenceRequestService( rockContext );
            var qry = benevolenceRequestService.Queryable( "BenevolenceResults,RequestedByPersonAlias,RequestedByPersonAlias.Person,CaseWorkerPersonAlias,CaseWorkerPersonAlias.Person" );

            // Filter by Start Date
            DateTime? startDate = drpDate.LowerValue;
            if ( startDate != null )
            {
                qry = qry.Where( b => b.RequestDateTime >= startDate );
            }

            // Filter by End Date
            DateTime? endDate = drpDate.UpperValue;
            if ( endDate != null )
            {
                qry = qry.Where( b => b.RequestDateTime <= endDate );
            }

            // Filter by Campus
            if ( cpCampus.SelectedCampusId.HasValue )
            {
                qry = qry.Where( b => b.CampusId == cpCampus.SelectedCampusId );
            }

            if ( TargetPerson != null )
            {
                // show benevolence request for the target person and also for their family members
                var qryFamilyMembers = TargetPerson.GetFamilyMembers( true, rockContext );
                qry = qry.Where( a => a.RequestedByPersonAliasId.HasValue && qryFamilyMembers.Any( b => b.PersonId == a.RequestedByPersonAlias.PersonId ) );
            }
            else
            {
                // Filter by First Name
                string firstName = tbFirstName.Text;
                if ( !string.IsNullOrWhiteSpace( firstName ) )
                {
                    qry = qry.Where( b => b.FirstName.StartsWith( firstName ) );
                }

                // Filter by Last Name
                string lastName = tbLastName.Text;
                if ( !string.IsNullOrWhiteSpace( lastName ) )
                {
                    qry = qry.Where( b => b.LastName.StartsWith( lastName ) );
                }
            }

            // Filter by Government Id
            string governmentId = tbGovernmentId.Text;
            if ( !string.IsNullOrWhiteSpace( governmentId ) )
            {
                qry = qry.Where( b => b.GovernmentId.StartsWith( governmentId ) );
            }

            // Filter by Case Worker
            int? caseWorkerPersonAliasId = ddlCaseWorker.SelectedItem.Value.AsIntegerOrNull();
            if ( caseWorkerPersonAliasId != null )
            {
                qry = qry.Where( b => b.CaseWorkerPersonAliasId == caseWorkerPersonAliasId );
            }

            // Filter by Result
            int? resultTypeValueId = ddlResult.SelectedItem.Value.AsIntegerOrNull();
            if ( resultTypeValueId != null )
            {
                qry = qry.Where( b => b.BenevolenceResults.Where( r => r.ResultTypeValueId == resultTypeValueId ).Count() > 0 );
            }

            // Filter by Request Status
            int? requestStatusValueId = ddlStatus.SelectedItem.Value.AsIntegerOrNull();
            if ( requestStatusValueId != null )
            {
                qry = qry.Where( b => b.RequestStatusValueId == requestStatusValueId );
            }

            SortProperty sortProperty = gList.SortProperty;
            if ( sortProperty != null )
            {
                if ( sortProperty.Property == "TotalAmount" )
                {
                    if ( sortProperty.Direction == SortDirection.Descending )
                    {
                        qry = qry.OrderByDescending( a => a.BenevolenceResults.Sum( b => b.Amount ) );
                    }
                    else
                    {
                        qry = qry.OrderBy( a => a.BenevolenceResults.Sum( b => b.Amount ) );
                    }
                }
                else
                {
                    qry = qry.Sort( sortProperty );
                }
            }
            else
            {
                qry = qry.OrderByDescending( a => a.RequestDateTime ).ThenByDescending( a => a.Id );
            }

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

                foreach ( var attribute in AvailableAttributes )
                {
                    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 );

                            qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                        }
                    }
                }
            }

            gList.DataSource = qry.ToList();
            gList.DataBind();

            // Builds the Totals section
            var definedTypeCache = DefinedTypeCache.Read( new Guid( Rock.SystemGuid.DefinedType.BENEVOLENCE_RESULT_TYPE ) );
            Dictionary<string, decimal> resultTotals = new Dictionary<string, decimal>();
            decimal grandTotal = 0;
            foreach ( BenevolenceRequest request in qry.ToList() )
            {
                foreach ( BenevolenceResult result in request.BenevolenceResults )
                {
                    if ( result.Amount != null )
                    {
                        if ( resultTotals.ContainsKey( result.ResultTypeValue.Value ) )
                        {
                            resultTotals[result.ResultTypeValue.Value] += result.Amount.Value;
                        }
                        else
                        {
                            resultTotals.Add( result.ResultTypeValue.Value, result.Amount.Value );
                        }

                        grandTotal += result.Amount.Value;
                    }
                }
            }

            foreach ( KeyValuePair<string, decimal> keyValuePair in resultTotals )
            {
                phSummary.Controls.Add( new LiteralControl( string.Format( "<div class='row'><div class='col-xs-8'>{0}: </div><div class='col-xs-4 text-right'>{1}{2:#,##0.00}</div></div>", keyValuePair.Key, GlobalAttributesCache.Value( "CurrencySymbol" ), keyValuePair.Value ) ) );
            }

            phSummary.Controls.Add( new LiteralControl( string.Format( "<div class='row'><div class='col-xs-8'><b>Total: </div><div class='col-xs-4 text-right'>{0}{1:#,##0.00}</b></div></div>", GlobalAttributesCache.Value( "CurrencySymbol" ), grandTotal ) ) );
        }
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGroupMembersGrid( bool isExporting = false )
        {
            if ( _group != null )
            {
                pnlGroupMembers.Visible = true;

                lHeading.Text = string.Format( "{0} {1}", _group.GroupType.GroupTerm, _group.GroupType.GroupMemberTerm.Pluralize() );

                if ( _group.GroupType.Roles.Any() )
                {
                    nbRoleWarning.Visible = false;
                    rFilter.Visible = true;
                    gGroupMembers.Visible = true;

                    var rockContext = new RockContext();

                    if ( _group != null &&
                        _group.RequiredSignatureDocumentTemplateId.HasValue )
                    {
                        Signers = new SignatureDocumentService( rockContext )
                            .Queryable().AsNoTracking()
                            .Where( d =>
                                d.SignatureDocumentTemplateId == _group.RequiredSignatureDocumentTemplateId.Value &&
                                d.Status == SignatureDocumentStatus.Signed &&
                                d.BinaryFileId.HasValue &&
                                d.AppliesToPersonAlias != null )
                            .OrderByDescending( d => d.LastStatusDate )
                            .Select( d => d.AppliesToPersonAlias.PersonId )
                            .ToList();
                    }

                    GroupMemberService groupMemberService = new GroupMemberService( rockContext );
                    var qry = groupMemberService.Queryable( "Person,GroupRole", true ).AsNoTracking()
                        .Where( m => m.GroupId == _group.Id );

                    // Filter by First Name
                    string firstName = tbFirstName.Text;
                    if ( !string.IsNullOrWhiteSpace( firstName ) )
                    {
                        qry = qry.Where( m =>
                            m.Person.FirstName.StartsWith( firstName ) ||
                            m.Person.NickName.StartsWith( firstName ) );
                    }

                    // Filter by Last Name
                    string lastName = tbLastName.Text;
                    if ( !string.IsNullOrWhiteSpace( lastName ) )
                    {
                        qry = qry.Where( m => m.Person.LastName.StartsWith( lastName ) );
                    }

                    // Filter by role
                    var validGroupTypeRoles = _group.GroupType.Roles.Select( r => r.Id ).ToList();
                    var roles = new List<int>();
                    foreach ( var roleId in cblRole.SelectedValues.AsIntegerList() )
                    {
                        if ( validGroupTypeRoles.Contains( roleId ) )
                        {
                            roles.Add( roleId );
                        }
                    }

                    if ( roles.Any() )
                    {
                        qry = qry.Where( m => roles.Contains( m.GroupRoleId ) );
                    }

                    // Filter by Group Member Status
                    var statuses = new List<GroupMemberStatus>();
                    foreach ( string status in cblGroupMemberStatus.SelectedValues )
                    {
                        if ( !string.IsNullOrWhiteSpace( status ) )
                        {
                            statuses.Add( status.ConvertToEnum<GroupMemberStatus>() );
                        }
                    }

                    if ( statuses.Any() )
                    {
                        qry = qry.Where( m => statuses.Contains( m.GroupMemberStatus ) );
                    }

                    var genders = new List<Gender>();
                    foreach ( var item in cblGenderFilter.SelectedValues )
                    {
                        var gender = item.ConvertToEnum<Gender>();
                        genders.Add( gender );
                    }

                    if ( genders.Any() )
                    {
                        qry = qry.Where( m => genders.Contains( m.Person.Gender ) );
                    }

                    // Filter by Campus
                    if ( cpCampusFilter.SelectedCampusId.HasValue )
                    {
                        Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY );
                        int campusId = cpCampusFilter.SelectedCampusId.Value;
                        var qryFamilyMembersForCampus = new GroupMemberService( rockContext ).Queryable().Where( a => a.Group.GroupType.Guid == familyGuid && a.Group.CampusId == campusId );
                        qry = qry.Where( a => qryFamilyMembersForCampus.Any( f => f.PersonId == a.PersonId ) );
                    }

                    // Filter by signed documents
                    if ( Signers != null )
                    {
                        if ( ddlSignedDocument.SelectedValue.AsBooleanOrNull() == true )
                        {
                            qry = qry.Where( m => Signers.Contains( m.PersonId ) );
                        }
                        else if ( ddlSignedDocument.SelectedValue.AsBooleanOrNull() == false )
                        {
                            qry = qry.Where( m => !Signers.Contains( m.PersonId ) );
                        }
                    }

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            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 );

                                    qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                                }
                            }
                        }
                    }

                    _inactiveStatus = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE );

                    SortProperty sortProperty = gGroupMembers.SortProperty;

                    bool hasGroupRequirements = new GroupRequirementService( rockContext ).Queryable().Where( a => a.GroupId == _group.Id ).Any();

                    // If there are group requirements that that member doesn't meet, show an icon in the grid
                    bool includeWarnings = false;
                    var groupMemberIdsThatLackGroupRequirements = new GroupService( rockContext ).GroupMembersNotMeetingRequirements( _group.Id, includeWarnings ).Select( a => a.Key.Id );

                    List<GroupMember> groupMembersList = null;
                    if ( sortProperty != null && sortProperty.Property != "FirstAttended" && sortProperty.Property != "LastAttended" )
                    {
                        groupMembersList = qry.Sort( sortProperty ).ToList();
                    }
                    else
                    {
                        groupMembersList = qry.OrderBy( a => a.GroupRole.Order ).ThenBy( a => a.Person.LastName ).ThenBy( a => a.Person.FirstName ).ToList();
                    }

                    // If there is a required signed document that member has not signed, show an icon in the grid
                    var personIdsThatHaventSigned = new List<int>();
                    if ( Signers != null )
                    {
                        var memberPersonIds = groupMembersList.Select( m => m.PersonId ).ToList();
                        personIdsThatHaventSigned = memberPersonIds.Where( i => !Signers.Contains( i ) ).ToList();
                    }

                    // Since we're not binding to actual group member list, but are using AttributeField columns,
                    // we need to save the group members into the grid's object list
                    gGroupMembers.ObjectList = new Dictionary<string, object>();
                    groupMembersList.ForEach( m => gGroupMembers.ObjectList.Add( m.Id.ToString(), m ) );
                    gGroupMembers.EntityTypeId = EntityTypeCache.Read( Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid() ).Id;

                    var homePhoneType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME );
                    var cellPhoneType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE );

                    // If exporting to Excel, the selectAll option will be true, and home location should be calculated
                    var homeLocations = new Dictionary<int, Location>();
                    if ( isExporting )
                    {
                        foreach ( var m in groupMembersList )
                        {
                            homeLocations.Add( m.Id, m.Person.GetHomeLocation( rockContext ) );
                        }
                    }

                    var groupMemberIds = groupMembersList.Select( m => m.Id ).ToList();

                    // Get all the group members with any associated registrations
                    _groupMembersWithRegistrations = new RegistrationRegistrantService( rockContext )
                        .Queryable().AsNoTracking()
                        .Where( r =>
                            r.Registration != null &&
                            r.Registration.RegistrationInstance != null &&
                            r.GroupMemberId.HasValue &&
                            groupMemberIds.Contains( r.GroupMemberId.Value ) )
                        .ToList()
                        .GroupBy( r => r.GroupMemberId.Value )
                        .Select( g => new
                        {
                            GroupMemberId = g.Key,
                            Registrations = g.ToList()
                                .Select( r => new
                                {
                                    Id = r.Registration.Id,
                                    Name = r.Registration.RegistrationInstance.Name
                                } ).Distinct()
                                .ToDictionary( r => r.Id, r => r.Name )
                        } )
                        .ToDictionary( r => r.GroupMemberId, r => r.Registrations );

                    var registrationField = gGroupMembers.ColumnsOfType<RockTemplateFieldUnselected>().FirstOrDefault();
                    if ( registrationField != null )
                    {
                        registrationField.Visible = _groupMembersWithRegistrations.Any();
                    }

                    var connectionStatusField = gGroupMembers.ColumnsOfType<DefinedValueField>().FirstOrDefault( a => a.DataField == "ConnectionStatusValueId" );
                    if ( connectionStatusField != null )
                    {
                        connectionStatusField.Visible = _group.GroupType.ShowConnectionStatus;
                    }

                    string photoFormat = "<div class=\"photo-icon photo-round photo-round-xs pull-left margin-r-sm js-person-popover\" personid=\"{0}\" data-original=\"{1}&w=50\" style=\"background-image: url( '{2}' ); background-size: cover; background-repeat: no-repeat;\"></div>";

                    var attendanceFirstLast = new Dictionary<int, DateRange>();
                    bool showAttendance = GetAttributeValue( "ShowAttendance" ).AsBoolean() && _group.GroupType.TakesAttendance;
                    gGroupMembers.ColumnsOfType<DateField>().First( a => a.DataField == "FirstAttended" ).Visible = showAttendance;
                    gGroupMembers.ColumnsOfType<DateField>().First( a => a.DataField == "LastAttended" ).Visible = showAttendance;
                    if ( showAttendance )
                    {
                        foreach ( var attendance in new AttendanceService( rockContext )
                            .Queryable().AsNoTracking()
                            .Where( a =>
                                a.GroupId.HasValue && a.GroupId.Value == _group.Id &&
                                a.DidAttend.HasValue && a.DidAttend.Value )
                            .GroupBy( a => a.PersonAlias.PersonId )
                            .Select( g => new
                            {
                                PersonId = g.Key,
                                FirstAttended = g.Min( a => a.StartDateTime ),
                                LastAttended = g.Max( a => a.StartDateTime )
                            } )
                            .ToList() )
                        {
                            attendanceFirstLast.Add( attendance.PersonId, new DateRange( attendance.FirstAttended, attendance.LastAttended ) );
                        }
                    }

                    var dataSource = groupMembersList.Select( m => new
                    {
                        m.Id,
                        m.Guid,
                        m.PersonId,
                        m.Person.NickName,
                        m.Person.LastName,
                        Name =
                        ( isExporting ? m.Person.LastName + ", " + m.Person.NickName : string.Format( photoFormat, m.PersonId, m.Person.PhotoUrl, ResolveUrl( "~/Assets/Images/person-no-photo-male.svg" ) ) +
                            m.Person.NickName + " " + m.Person.LastName
                            + ( ( hasGroupRequirements && groupMemberIdsThatLackGroupRequirements.Contains( m.Id ) )
                                ? " <i class='fa fa-exclamation-triangle text-warning'></i>"
                                : string.Empty )
                            + ( !string.IsNullOrEmpty( m.Note )
                                ? " <i class='fa fa-file-text-o text-info'></i>"
                                : string.Empty )
                            + ((personIdsThatHaventSigned.Contains( m.PersonId ))
                                ? " <i class='fa fa-pencil-square-o text-danger'></i>"
                                : string.Empty)),
                        m.Person.BirthDate,
                        m.Person.Age,
                        m.Person.ConnectionStatusValueId,
                        m.DateTimeAdded,
                        FirstAttended = attendanceFirstLast.Where( a => a.Key == m.PersonId ).Select( a => a.Value.Start ).FirstOrDefault(),
                        LastAttended = attendanceFirstLast.Where( a => a.Key == m.PersonId ).Select( a => a.Value.End ).FirstOrDefault(),
                        Email = m.Person.Email,
                        HomePhone = isExporting && homePhoneType != null ?
                            m.Person.PhoneNumbers
                                .Where( p => p.NumberTypeValueId.HasValue && p.NumberTypeValueId.Value == homePhoneType.Id )
                                .Select( p => p.NumberFormatted )
                                .FirstOrDefault() : string.Empty,
                        CellPhone = isExporting && cellPhoneType != null ?
                            m.Person.PhoneNumbers
                                .Where( p => p.NumberTypeValueId.HasValue && p.NumberTypeValueId.Value == cellPhoneType.Id )
                                .Select( p => p.NumberFormatted )
                                .FirstOrDefault() : string.Empty,
                        HomeAddress = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ?
                            homeLocations[m.Id].FormattedAddress : string.Empty,
                        Latitude = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ?
                            homeLocations[m.Id].Latitude : (double?)null,
                        Longitude = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ?
                            homeLocations[m.Id].Longitude : (double?)null,
                        GroupRole = m.GroupRole.Name,
                        m.GroupMemberStatus,
                        RecordStatusValueId = m.Person.RecordStatusValueId,
                        IsDeceased = m.Person.IsDeceased
                    } ).ToList();

                    if ( sortProperty != null )
                    {
                        if ( sortProperty.Property == "FirstAttended" )
                        {
                            if ( sortProperty.Direction == SortDirection.Descending )
                            {
                                dataSource = dataSource.OrderByDescending( a => a.FirstAttended ?? DateTime.MinValue ).ToList();
                            }
                            else
                            {
                                dataSource = dataSource.OrderBy( a => a.FirstAttended ?? DateTime.MinValue ).ToList();
                            }
                        }

                        if ( sortProperty.Property == "LastAttended" )
                        {
                            if ( sortProperty.Direction == SortDirection.Descending )
                            {
                                dataSource = dataSource.OrderByDescending( a => a.LastAttended ?? DateTime.MinValue ).ToList();
                            }
                            else
                            {
                                dataSource = dataSource.OrderBy( a => a.LastAttended ?? DateTime.MinValue ).ToList();
                            }
                        }
                    }

                    gGroupMembers.DataSource = dataSource;
                    gGroupMembers.DataBind();
                }
                else
                {
                    nbRoleWarning.Text = string.Format(
                        "{0} cannot be added to this {1} because the '{2}' group type does not have any roles defined.",
                        _group.GroupType.GroupMemberTerm.Pluralize(),
                        _group.GroupType.GroupTerm,
                        _group.GroupType.Name );

                    nbRoleWarning.Visible = true;
                    rFilter.Visible = false;
                    gGroupMembers.Visible = false;
                }
            }
            else
            {
                pnlGroupMembers.Visible = false;
            }
        }
        /// <summary>
        /// Processes the confirmation.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        private bool ProcessConfirmation( out string errorMessage )
        {
            var rockContext = new RockContext();
            if ( string.IsNullOrWhiteSpace( TransactionCode ) )
            {
                GatewayComponent gateway = null;
                var financialGateway = hfPaymentTab.Value == "ACH" ? _achGateway : _ccGateway;
                if ( financialGateway != null )
                {
                    gateway = financialGateway.GetGatewayComponent();
                }

                if ( gateway == null )
                {
                    errorMessage = "There was a problem creating the payment gateway information";
                    return false;
                }

                Person person = GetPerson( true );
                if ( person == null )
                {
                    errorMessage = "There was a problem creating the person information";
                    return false;
                }

                if ( !person.PrimaryAliasId.HasValue )
                {
                    errorMessage = "There was a problem creating the person's primary alias";
                    return false;
                }

                PaymentInfo paymentInfo = GetPaymentInfo();
                if ( paymentInfo == null )
                {
                    errorMessage = "There was a problem creating the payment information";
                    return false;
                }
                else
                {
                    paymentInfo.FirstName = person.FirstName;
                    paymentInfo.LastName = person.LastName;
                }

                if ( paymentInfo.CreditCardTypeValue != null )
                {
                    CreditCardTypeValueId = paymentInfo.CreditCardTypeValue.Id;
                }

                if ( _showCommmentEntry )
                {
                    paymentInfo.Comment1 = !string.IsNullOrWhiteSpace( GetAttributeValue( "PaymentComment" ) ) ? string.Format( "{0}: {1}", GetAttributeValue( "PaymentComment" ), txtCommentEntry.Text ) : txtCommentEntry.Text;
                }
                else
                {
                    paymentInfo.Comment1 = GetAttributeValue( "PaymentComment" );
                }

                PaymentSchedule schedule = GetSchedule();
                if ( schedule != null )
                {
                    schedule.PersonId = person.Id;

                    var scheduledTransaction = gateway.AddScheduledPayment( financialGateway, schedule, paymentInfo, out errorMessage );
                    if ( scheduledTransaction != null )
                    {
                        scheduledTransaction.TransactionFrequencyValueId = schedule.TransactionFrequencyValue.Id;
                        scheduledTransaction.AuthorizedPersonAliasId = person.PrimaryAliasId.Value;
                        scheduledTransaction.FinancialGatewayId = financialGateway.Id;

                        if ( scheduledTransaction.FinancialPaymentDetail == null )
                        {
                            scheduledTransaction.FinancialPaymentDetail = new FinancialPaymentDetail();
                        }
                        scheduledTransaction.FinancialPaymentDetail.SetFromPaymentInfo( paymentInfo, gateway, rockContext );

                        var changeSummary = new StringBuilder();
                        changeSummary.AppendFormat( "{0} starting {1}", schedule.TransactionFrequencyValue.Value, schedule.StartDate.ToShortDateString() );
                        changeSummary.AppendLine();
                        changeSummary.Append( paymentInfo.CurrencyTypeValue.Value );
                        if ( paymentInfo.CreditCardTypeValue != null )
                        {
                            changeSummary.AppendFormat( " - {0}", paymentInfo.CreditCardTypeValue.Value );
                        }
                        changeSummary.AppendFormat( " {0}", paymentInfo.MaskedNumber );
                        changeSummary.AppendLine();

                        foreach ( var account in SelectedAccounts.Where( a => a.Amount > 0 ) )
                        {
                            var transactionDetail = new FinancialScheduledTransactionDetail();
                            transactionDetail.Amount = account.Amount;
                            transactionDetail.AccountId = account.Id;
                            scheduledTransaction.ScheduledTransactionDetails.Add( transactionDetail );
                            changeSummary.AppendFormat( "{0}: {1}", account.Name, account.Amount.FormatAsCurrency() );
                            changeSummary.AppendLine();
                        }

                        var transactionService = new FinancialScheduledTransactionService( rockContext );
                        transactionService.Add( scheduledTransaction );
                        rockContext.SaveChanges();

                        // Add a note about the change
                        var noteType = NoteTypeCache.Read( Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid() );
                        if ( noteType != null )
                        {
                            var noteService = new NoteService( rockContext );
                            var note = new Note();
                            note.NoteTypeId = noteType.Id;
                            note.EntityId = scheduledTransaction.Id;
                            note.Caption = "Created Transaction";
                            note.Text = changeSummary.ToString();
                            noteService.Add( note );
                        }
                        rockContext.SaveChanges();

                        ScheduleId = scheduledTransaction.GatewayScheduleId;
                        TransactionCode = scheduledTransaction.TransactionCode;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    var transaction = gateway.Charge( financialGateway, paymentInfo, out errorMessage );
                    if ( transaction != null )
                    {
                        var txnChanges = new List<string>();
                        txnChanges.Add( "Created Transaction" );

                        History.EvaluateChange( txnChanges, "Transaction Code", string.Empty, transaction.TransactionCode );

                        transaction.AuthorizedPersonAliasId = person.PrimaryAliasId;
                        History.EvaluateChange( txnChanges, "Person", string.Empty, person.FullName );

                        transaction.TransactionDateTime = RockDateTime.Now;
                        History.EvaluateChange( txnChanges, "Date/Time", null, transaction.TransactionDateTime );

                        transaction.FinancialGatewayId = financialGateway.Id;
                        History.EvaluateChange( txnChanges, "Gateway", string.Empty, financialGateway.Name );

                        var txnType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION ) );
                        transaction.TransactionTypeValueId = txnType.Id;
                        History.EvaluateChange( txnChanges, "Type", string.Empty, txnType.Value );

                        if ( transaction.FinancialPaymentDetail == null )
                        {
                            transaction.FinancialPaymentDetail = new FinancialPaymentDetail();
                        }
                        transaction.FinancialPaymentDetail.SetFromPaymentInfo( paymentInfo, gateway, rockContext, txnChanges );

                        Guid sourceGuid = Guid.Empty;
                        if ( Guid.TryParse( GetAttributeValue( "Source" ), out sourceGuid ) )
                        {
                            var source = DefinedValueCache.Read( sourceGuid );
                            if ( source != null )
                            {
                                transaction.SourceTypeValueId = source.Id;
                                History.EvaluateChange( txnChanges, "Source", string.Empty, source.Value );
                            }
                        }

                        foreach ( var account in SelectedAccounts.Where( a => a.Amount > 0 ) )
                        {
                            var transactionDetail = new FinancialTransactionDetail();
                            transactionDetail.Amount = account.Amount;
                            transactionDetail.AccountId = account.Id;
                            transaction.TransactionDetails.Add( transactionDetail );
                            History.EvaluateChange( txnChanges, account.Name, 0.0M.FormatAsCurrency(), transactionDetail.Amount.FormatAsCurrency() );
                        }

                        var batchService = new FinancialBatchService( rockContext );

                        // Get the batch
                        var batch = batchService.Get(
                            GetAttributeValue( "BatchNamePrefix" ),
                            paymentInfo.CurrencyTypeValue,
                            paymentInfo.CreditCardTypeValue,
                            transaction.TransactionDateTime.Value,
                            financialGateway.GetBatchTimeOffset() );

                        var batchChanges = new List<string>();

                        if ( batch.Id == 0 )
                        {
                            batchChanges.Add( "Generated the batch" );
                            History.EvaluateChange( batchChanges, "Batch Name", string.Empty, batch.Name );
                            History.EvaluateChange( batchChanges, "Status", null, batch.Status );
                            History.EvaluateChange( batchChanges, "Start Date/Time", null, batch.BatchStartDateTime );
                            History.EvaluateChange( batchChanges, "End Date/Time", null, batch.BatchEndDateTime );
                        }

                        decimal newControlAmount = batch.ControlAmount + transaction.TotalAmount;
                        History.EvaluateChange( batchChanges, "Control Amount", batch.ControlAmount.FormatAsCurrency(), newControlAmount.FormatAsCurrency() );
                        batch.ControlAmount = newControlAmount;

                        transaction.BatchId = batch.Id;
                        batch.Transactions.Add( transaction );

                        rockContext.SaveChanges();

                        HistoryService.SaveChanges(
                            rockContext,
                            typeof( FinancialBatch ),
                            Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                            batch.Id,
                            batchChanges
                        );

                        HistoryService.SaveChanges(
                            rockContext,
                            typeof( FinancialBatch ),
                            Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(),
                            batch.Id,
                            txnChanges,
                            person.FullName,
                            typeof( FinancialTransaction ),
                            transaction.Id
                        );

                        SendReceipt( transaction.Id );

                        TransactionCode = transaction.TransactionCode;
                    }
                    else
                    {
                        return false;
                    }
                }

                tdTransactionCodeReceipt.Description = TransactionCode;
                tdTransactionCodeReceipt.Visible = !string.IsNullOrWhiteSpace( TransactionCode );

                tdScheduleId.Description = ScheduleId;
                tdScheduleId.Visible = !string.IsNullOrWhiteSpace( ScheduleId );

                tdNameReceipt.Description = paymentInfo.FullName;
                tdPhoneReceipt.Description = paymentInfo.Phone;
                tdEmailReceipt.Description = paymentInfo.Email;
                tdAddressReceipt.Description = string.Format( "{0} {1}, {2} {3}", paymentInfo.Street1, paymentInfo.City, paymentInfo.State, paymentInfo.PostalCode );

                rptAccountListReceipt.DataSource = SelectedAccounts.Where( a => a.Amount != 0 );
                rptAccountListReceipt.DataBind();

                tdTotalReceipt.Description = paymentInfo.Amount.ToString( "C" );

                tdPaymentMethodReceipt.Description = paymentInfo.CurrencyTypeValue.Description;
                tdAccountNumberReceipt.Description = paymentInfo.MaskedNumber;
                tdWhenReceipt.Description = schedule != null ? schedule.ToString() : "Today";

                // If there was a transaction code returned and this was not already created from a previous saved account,
                // show the option to save the account.
                if ( !( paymentInfo is ReferencePaymentInfo ) && !string.IsNullOrWhiteSpace( TransactionCode ) && gateway.SupportsSavedAccount( paymentInfo.CurrencyTypeValue ) )
                {
                    cbSaveAccount.Visible = true;
                    pnlSaveAccount.Visible = true;
                    txtSaveAccount.Visible = true;

                    // If current person does not have a login, have them create a username and password
                    phCreateLogin.Visible = !new UserLoginService( rockContext ).GetByPersonId( person.Id ).Any();
                }
                else if ( !new UserLoginService( rockContext ).GetByPersonId( person.Id ).Any() )
                {
                    pnlSaveAccount.Visible = true;
                    phCreateLogin.Visible = true;
                    cbSaveAccount.Visible = false;
                    txtSaveAccount.Visible = false;
                }
                else
                {
                    pnlSaveAccount.Visible = false;
                }

                if ( PageParameter( "argsd" ) == "1" )
                {
                    var rc = new RockContext();
                    var ats = new AttributeService( rc );
                    var argsd = ats.Queryable().Where( x => x.Key == "AutomatedRecurringGiftSetupDate" ).FirstOrDefault();
                    if ( argsd == null )
                    {
                        argsd = new Rock.Model.Attribute();
                        argsd.FieldTypeId = 85;
                        argsd.EntityTypeId = 15;
                        argsd.Key = "AutomatedRecurringGiftSetupDate";
                        argsd.Name = "Automated Recurring Gift Setup Date";
                        argsd.Guid = Guid.NewGuid();
                        argsd.CreatedDateTime = argsd.ModifiedDateTime = DateTime.Now;
                        ats.Add( argsd );
                        rc.SaveChanges();
                        rc = new RockContext();
                        ats = new AttributeService( rc );
                        argsd = ats.Queryable().Where( x => x.Key == "AutomatedRecurringGiftSetupDate" ).FirstOrDefault();
                    }
                    if ( argsd != null )
                    {
                        var atvs = new AttributeValueService( rc );
                        var argsdVal = atvs.Queryable().Where( x => x.AttributeId == argsd.Id && x.EntityId == person.Id ).FirstOrDefault();
                        if ( argsdVal == null )
                        {
                            argsdVal = new Rock.Model.AttributeValue();
                            argsdVal.AttributeId = argsd.Id;
                            argsdVal.EntityId = person.Id;
                            argsdVal.Value = DateTime.Now.ToString( "o" );
                            argsdVal.Guid = Guid.NewGuid();
                            argsdVal.CreatedDateTime = argsdVal.ModifiedDateTime = DateTime.Now;

                            atvs.Add( argsdVal );
                            rc.SaveChanges();
                        }
                        else
                        {
                            argsdVal.Value = DateTime.Now.ToString( "o" );
                            rc.SaveChanges();
                        }
                    }
                }
                return true;
            }
            else
            {
                pnlDupWarning.Visible = true;
                divActions.Visible = false;
                errorMessage = string.Empty;
                return false;
            }
        }
        /// <summary>
        /// Maps the Individual Giftedness.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        private void MapIndividualGiftedness( IQueryable<Row> tableData )
        {
            var lookupContext = new RockContext();
            var attributeService = new AttributeService( lookupContext );

            int rank1Id = attributeService.Queryable().Where( a => a.Key == "Rank1" ).FirstOrDefault().Id;
            int rank2Id = attributeService.Queryable().Where( a => a.Key == "Rank2" ).FirstOrDefault().Id;
            int rank3Id = attributeService.Queryable().Where( a => a.Key == "Rank3" ).FirstOrDefault().Id;
            int rank4Id = attributeService.Queryable().Where( a => a.Key == "Rank4" ).FirstOrDefault().Id;

            int completed = 0;
            int totalRows = tableData.Count();
            int percentage = ( totalRows - 1 ) / 100 + 1;
            ReportProgress( 0, string.Format( "Verifying Giftedness Program import ({0:N0} found).", totalRows ) );

            var newAttributeValueList = new List<AttributeValue>();

            foreach ( var row in tableData )
            {
                int? individualId = row["Individual_ID"] as int?;
                int personId = (int)GetPersonAliasId( individualId );
                var newAttributeValue = new AttributeValue();
                int? rank = row["Rank"] as int?;
                int rankId = 0;

                //not everyone has all 4 ranks, some are missing the fourth and that was causing it to run in the below if condition and try to create a duplicate record.
                if ( rank == 1 ) { rankId = rank1Id; }
                if ( rank == 2 ) { rankId = rank2Id; }
                if ( rank == 3 ) { rankId = rank3Id; }
                if ( rank == 4 ) { rankId = rank4Id; }

                if ( personId != 0 && rankId != 0 )
                {
                    var attributeValueService = new AttributeValueService( lookupContext );

                    //checks if they are in the database already or if there is a record currently in the newAttributeValueList
                    if ( attributeValueService.Queryable().Where( a => a.AttributeId == rankId && a.EntityId == personId ).FirstOrDefault() == null && newAttributeValueList.Find(a => a.AttributeId == rankId && a.EntityId == personId) == null )
                    {

                        DateTime? assessmentDate = row["AssessmentDate"] as DateTime?;
                        int? giftAttributeId = row["GiftAttributeID"] as int?;
                        string giftAttributeIdString = Convert.ToString( giftAttributeId );

                        var definedValueService = new DefinedValueService( lookupContext );

                        newAttributeValue.IsSystem = false;
                        newAttributeValue.EntityId = personId;

                        if ( rank == 1 ) { newAttributeValue.AttributeId = rank1Id; }
                        if ( rank == 2 ) { newAttributeValue.AttributeId = rank2Id; }
                        if ( rank == 3 ) { newAttributeValue.AttributeId = rank3Id; }
                        if ( rank == 4 ) { newAttributeValue.AttributeId = rank4Id; }

                        newAttributeValue.Value = Convert.ToString( definedValueService.Queryable().Where( a => a.ForeignId == giftAttributeIdString ).FirstOrDefault().Guid );
                        newAttributeValue.CreatedDateTime = assessmentDate;

                        newAttributeValueList.Add( newAttributeValue );
                        completed++;
                    }
                }
                if ( newAttributeValueList.Any() )
                {
                    if ( completed % percentage < 1 )
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress( percentComplete, string.Format( "{0:N0} spiritual gifts imported ({1}% complete).", completed, percentComplete ) );
                    }
                    else if ( completed % ReportingNumber < 1 )
                    {
                        var rockContext = new RockContext();
                        rockContext.WrapTransaction( () =>
                        {
                            rockContext.Configuration.AutoDetectChangesEnabled = false;
                            rockContext.AttributeValues.AddRange( newAttributeValueList );
                            rockContext.SaveChanges( DisableAudit );
                            newAttributeValueList.Clear();
                        } );
                        ReportPartialProgress();
                    }
                }
            }

            if ( newAttributeValueList.Any() )
            {
                var rockContext = new RockContext();
                rockContext.WrapTransaction( () =>
                {
                    rockContext.Configuration.AutoDetectChangesEnabled = false;
                    rockContext.AttributeValues.AddRange( newAttributeValueList );
                    rockContext.SaveChanges( DisableAudit );
                } );
            }

            ReportProgress( 100, string.Format( "Finished individual gifts import: {0:N0} spiritual gifts imported.", completed ) );
        }
Exemple #13
0
        /// <summary>
        /// Binds the event calendar items grid.
        /// </summary>
        protected void BindConnectionOpportunitiesGrid()
        {
            if ( _connectionType != null )
            {
                pnlConnectionOpportunities.Visible = true;

                rFilter.Visible = true;
                gConnectionOpportunities.Visible = true;

                var rockContext = new RockContext();

                ConnectionOpportunityService connectionOpportunityService = new ConnectionOpportunityService( rockContext );
                var qry = connectionOpportunityService.Queryable()
                    .Where( o => o.ConnectionTypeId == _connectionType.Id );

                // Filter by Active Only
                if ( cbActive.Checked )
                {
                    qry = qry.Where( o => o.IsActive );
                }

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

                    foreach ( var attribute in AvailableAttributes )
                    {
                        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 );

                                qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }
                SortProperty sortProperty = gConnectionOpportunities.SortProperty;

                List<ConnectionOpportunity> connectionOpportunities = null;
                if ( sortProperty != null )
                {
                    connectionOpportunities = qry.Sort( sortProperty ).ToList();
                }
                else
                {
                    connectionOpportunities = qry.ToList().OrderByDescending( a => a.Name ).ToList();
                }

                gConnectionOpportunities.ObjectList = new Dictionary<string, object>();
                connectionOpportunities.ForEach( m => gConnectionOpportunities.ObjectList.Add( m.Id.ToString(), m ) );
                gConnectionOpportunities.EntityTypeId = EntityTypeCache.Read( "Rock.Model.ConnectionOpportunity" ).Id;

                gConnectionOpportunities.DataSource = connectionOpportunities.Select( o => new
                {
                    o.Id,
                    o.Guid,
                    Name = o.Name,
                    GroupType = o.GroupType.Name,
                    Active = o.IsActive ? "<span class='label label-success'>Active</span>" : "<span class='label label-campus'>Inactive</span>"

                } ).ToList();

                gConnectionOpportunities.DataBind();
            }
            else
            {
                pnlConnectionOpportunities.Visible = false;
            }
        }
        void lvAttributeValues_ItemInserting( object sender, ListViewInsertEventArgs e )
        {
            PlaceHolder phInsertValue = lvAttributeValues.InsertItem.FindControl( "phInsertValue" ) as PlaceHolder;
            if ( phInsertValue != null && phInsertValue.Controls.Count == 1 )
            {
                string value = _attribute.FieldType.Field.GetEditValue( phInsertValue.Controls[0], _attribute.QualifierValues );

                var attributeValueService = new AttributeValueService();
                var attributeValue = new AttributeValue();
                attributeValue.AttributeId = _attribute.Id;
                attributeValue.EntityId = _model.Id;
                attributeValue.Value = value;

                int? maxOrder = attributeValueService.Queryable().
                    Where( a => a.AttributeId == attributeValue.AttributeId &&
                        a.EntityId == attributeValue.EntityId).
                    Select( a => ( int? )a.Order ).Max();

                attributeValue.Order = maxOrder.HasValue ? maxOrder.Value + 1 : 0;

                attributeValueService.Add( attributeValue, _currentPersonId);
                attributeValueService.Save( attributeValue, _currentPersonId );
                _model.LoadAttributes();
            }

            lvAttributeValues.EditIndex = -1;
            BindData();
        }
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGroupMembersGrid()
        {
            if ( _group != null )
            {
                pnlGroupMembers.Visible = true;

                lHeading.Text = string.Format( "{0} {1}", _group.GroupType.GroupTerm, _group.GroupType.GroupMemberTerm.Pluralize() );

                if ( _group.GroupType.Roles.Any() )
                {
                    nbRoleWarning.Visible = false;
                    rFilter.Visible = true;
                    gGroupMembers.Visible = true;

                    var rockContext = new RockContext();

                    GroupMemberService groupMemberService = new GroupMemberService( rockContext );
                    var qry = groupMemberService.Queryable( "Person,GroupRole", true )
                        .Where( m => m.GroupId == _group.Id );

                    // Filter by First Name
                    string firstName = tbFirstName.Text;
                    if ( !string.IsNullOrWhiteSpace( firstName ) )
                    {
                        qry = qry.Where( m => m.Person.FirstName.StartsWith( firstName ) );
                    }

                    // Filter by Last Name
                    string lastName = tbLastName.Text;
                    if ( !string.IsNullOrWhiteSpace( lastName ) )
                    {
                        qry = qry.Where( m => m.Person.LastName.StartsWith( lastName ) );
                    }

                    // Filter by role
                    var validGroupTypeRoles = _group.GroupType.Roles.Select( r => r.Id ).ToList();
                    var roles = new List<int>();
                    foreach ( string role in cblRole.SelectedValues )
                    {
                        if ( !string.IsNullOrWhiteSpace( role ) )
                        {
                            int roleId = int.MinValue;
                            if ( int.TryParse( role, out roleId ) && validGroupTypeRoles.Contains( roleId ) )
                            {
                                roles.Add( roleId );
                            }
                        }
                    }
                    if ( roles.Any() )
                    {
                        qry = qry.Where( m => roles.Contains( m.GroupRoleId ) );
                    }

                    // Filter by Status
                    var statuses = new List<GroupMemberStatus>();
                    foreach ( string status in cblStatus.SelectedValues )
                    {
                        if ( !string.IsNullOrWhiteSpace( status ) )
                        {
                            statuses.Add( status.ConvertToEnum<GroupMemberStatus>() );
                        }
                    }
                    if ( statuses.Any() )
                    {
                        qry = qry.Where( m => statuses.Contains( m.GroupMemberStatus ) );
                    }

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            var filterControl = phAttributeFilters.FindControl( "filter_" + attribute.Id.ToString() );
                            if ( filterControl != null )
                            {
                                var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues );
                                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 );

                                    qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                                }
                            }
                        }
                    }

                    _inactiveStatus = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE );

                    SortProperty sortProperty = gGroupMembers.SortProperty;

                    List<GroupMember> groupMembers = null;

                    if ( sortProperty != null )
                    {
                        groupMembers = qry.Sort( sortProperty ).ToList();
                    }
                    else
                    {
                        groupMembers = qry.OrderBy( a => a.GroupRole.Order ).ThenBy( a => a.Person.LastName ).ThenBy( a => a.Person.FirstName ).ToList();
                    }

                    // Since we're not binding to actual group member list, but are using AttributeField columns,
                    // we need to save the workflows into the grid's object list
                    gGroupMembers.ObjectList = new Dictionary<string, object>();
                    groupMembers.ForEach( m => gGroupMembers.ObjectList.Add( m.Id.ToString(), m ) );

                    gGroupMembers.DataSource = groupMembers.Select( m => new
                    {
                        m.Id,
                        m.Guid,
                        m.PersonId,
                        Name = m.Person.NickName + " " + m.Person.LastName,
                        GroupRole = m.GroupRole.Name,
                        m.GroupMemberStatus
                    } ).ToList();

                    gGroupMembers.DataBind();
                }
                else
                {
                    nbRoleWarning.Text = string.Format(
                        "{0} cannot be added to this {1} because the '{2}' group type does not have any roles defined.",
                        _group.GroupType.GroupMemberTerm.Pluralize(),
                        _group.GroupType.GroupTerm,
                        _group.GroupType.Name );

                    nbRoleWarning.Visible = true;
                    rFilter.Visible = false;
                    gGroupMembers.Visible = false;
                }
            }
            else
            {
                pnlGroupMembers.Visible = false;
            }
        }
        /// <summary>
        /// Gets the settings.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        private List<AttributeValue> GetSettings( RockContext rockContext )
        {
            var pmmEntityType = EntityTypeCache.Read( typeof( Rock.Security.BackgroundCheck.ProtectMyMinistry ) );
            if ( pmmEntityType != null )
            {
                var service = new AttributeValueService( rockContext );
                return service.Queryable( "Attribute" )
                    .Where( v => v.Attribute.EntityTypeId == pmmEntityType.Id )
                    .ToList();
            }

            return null;
        }
Exemple #17
0
        /// <summary>
        /// Loads the <see cref="P:IHasAttributes.Attributes" /> and <see cref="P:IHasAttributes.AttributeValues" /> of any <see cref="IHasAttributes" /> object
        /// </summary>
        /// <param name="entity">The item.</param>
        /// <param name="rockContext">The rock context.</param>
        public static void LoadAttributes( Rock.Attribute.IHasAttributes entity, RockContext rockContext )
        {
            if ( entity != null )
            {
                Dictionary<string, PropertyInfo> properties = new Dictionary<string, PropertyInfo>();

                Type entityType = entity.GetType();
                if ( entityType.Namespace == "System.Data.Entity.DynamicProxies" )
                    entityType = entityType.BaseType;

                rockContext = rockContext ?? new RockContext();

                // Check for group type attributes
                var groupTypeIds = new List<int>();
                if ( entity is GroupMember || entity is Group || entity is GroupType )
                {
                    // Can't use GroupTypeCache here since it loads attributes and would result in a recursive stack overflow situation
                    var groupTypeService = new GroupTypeService( rockContext );
                    GroupType groupType = null;

                    if ( entity is GroupMember )
                    {
                        var group = ( (GroupMember)entity ).Group ?? new GroupService( rockContext )
                            .Queryable().AsNoTracking().FirstOrDefault(g => g.Id == ( (GroupMember)entity ).GroupId );
                        if ( group != null )
                        {
                            groupType = group.GroupType ?? groupTypeService
                                .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == group.GroupTypeId );
                        }
                    }
                    else if ( entity is Group )
                    {
                        groupType = ( (Group)entity ).GroupType ?? groupTypeService
                            .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( (Group)entity ).GroupTypeId );
                    }
                    else
                    {
                        groupType = ( (GroupType)entity );
                    }

                    while ( groupType != null )
                    {
                        groupTypeIds.Insert( 0, groupType.Id );

                        // Check for inherited group type id's
                        if ( groupType.InheritedGroupTypeId.HasValue )
                        {
                            groupType = groupType.InheritedGroupType ?? groupTypeService
                                .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( groupType.InheritedGroupTypeId ?? 0 ) );
                        }
                        else
                        {
                            groupType = null;
                        }
                    }

                }

                foreach ( PropertyInfo propertyInfo in entityType.GetProperties() )
                    properties.Add( propertyInfo.Name.ToLower(), propertyInfo );

                Rock.Model.AttributeService attributeService = new Rock.Model.AttributeService( rockContext );
                Rock.Model.AttributeValueService attributeValueService = new Rock.Model.AttributeValueService( rockContext );

                var inheritedAttributes = new Dictionary<int, List<Rock.Web.Cache.AttributeCache>>();
                if ( groupTypeIds.Any() )
                {
                    groupTypeIds.ForEach( g => inheritedAttributes.Add( g, new List<Rock.Web.Cache.AttributeCache>() ) );
                }
                else
                {
                    inheritedAttributes.Add( 0, new List<Rock.Web.Cache.AttributeCache>() );
                }

                var attributes = new List<Rock.Web.Cache.AttributeCache>();

                // Get all the attributes that apply to this entity type and this entity's properties match any attribute qualifiers
                var entityTypeCache = Rock.Web.Cache.EntityTypeCache.Read( entityType);
                if ( entityTypeCache != null )
                {
                    int entityTypeId = entityTypeCache.Id;
                    foreach ( var attribute in attributeService.Queryable()
                        .AsNoTracking()
                        .Where( a => a.EntityTypeId == entityTypeCache.Id )
                        .Select( a => new
                        {
                            a.Id,
                            a.EntityTypeQualifierColumn,
                            a.EntityTypeQualifierValue
                        }
                        ) )
                    {
                        // group type ids exist (entity is either GroupMember, Group, or GroupType) and qualifier is for a group type id
                        if ( groupTypeIds.Any() && (
                                ( entity is GroupMember && string.Compare( attribute.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) ||
                                ( entity is Group && string.Compare( attribute.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) ||
                                ( entity is GroupType && string.Compare( attribute.EntityTypeQualifierColumn, "Id", true ) == 0 ) ) )
                        {
                            int groupTypeIdValue = int.MinValue;
                            if ( int.TryParse( attribute.EntityTypeQualifierValue, out groupTypeIdValue ) && groupTypeIds.Contains( groupTypeIdValue ) )
                            {
                                inheritedAttributes[groupTypeIdValue].Add( Rock.Web.Cache.AttributeCache.Read( attribute.Id ) );
                            }
                        }

                        else if ( string.IsNullOrEmpty( attribute.EntityTypeQualifierColumn ) ||
                            ( properties.ContainsKey( attribute.EntityTypeQualifierColumn.ToLower() ) &&
                            ( string.IsNullOrEmpty( attribute.EntityTypeQualifierValue ) ||
                            ( properties[attribute.EntityTypeQualifierColumn.ToLower()].GetValue( entity, null ) ?? "" ).ToString() == attribute.EntityTypeQualifierValue ) ) )
                        {
                            attributes.Add( Rock.Web.Cache.AttributeCache.Read( attribute.Id ) );
                        }
                    }
                }

                var allAttributes = new List<Rock.Web.Cache.AttributeCache>();

                foreach ( var attributeGroup in inheritedAttributes )
                {
                    foreach ( var attribute in attributeGroup.Value )
                    {
                        allAttributes.Add( attribute );
                    }
                }
                foreach ( var attribute in attributes )
                {
                    allAttributes.Add( attribute );
                }

                var attributeValues = new Dictionary<string, Rock.Model.AttributeValue>();

                if ( allAttributes.Any() )
                {
                    foreach ( var attribute in allAttributes )
                    {
                        // Add a placeholder for this item's value for each attribute
                        attributeValues.Add( attribute.Key, null );
                    }

                    // If loading attributes for a saved item, read the item's value(s) for each attribute 
                    if ( !entityTypeCache.IsEntity || entity.Id != 0 )
                    {
                        List<int> attributeIds = allAttributes.Select( a => a.Id ).ToList();
                        foreach ( var attributeValue in attributeValueService.Queryable().AsNoTracking()
                            .Where( v => v.EntityId == entity.Id && attributeIds.Contains( v.AttributeId ) ) )
                        {
                            var attributeKey = AttributeCache.Read( attributeValue.AttributeId ).Key;
                            attributeValues[attributeKey] = attributeValue.Clone( false ) as Rock.Model.AttributeValue;
                        }
                    }

                    // Look for any attributes that don't have a value and create a default value entry
                    foreach ( var attribute in allAttributes )
                    {
                        if ( attributeValues[attribute.Key] == null )
                        {
                            var attributeValue = new Rock.Model.AttributeValue();
                            attributeValue.AttributeId = attribute.Id;
                            if ( entity.AttributeValueDefaults != null && entity.AttributeValueDefaults.ContainsKey( attribute.Name ) )
                            {
                                attributeValue.Value = entity.AttributeValueDefaults[attribute.Name];
                            }
                            else
                            {
                                attributeValue.Value = attribute.DefaultValue;
                            }
                            attributeValues[attribute.Key] = attributeValue;
                        }
                        else
                        {
                            if ( !String.IsNullOrWhiteSpace( attribute.DefaultValue ) &&
                                String.IsNullOrWhiteSpace( attributeValues[attribute.Key].Value ) )
                            {
                                attributeValues[attribute.Key].Value = attribute.DefaultValue;
                            }
                        }
                    }
                }

                entity.Attributes = new Dictionary<string, Web.Cache.AttributeCache>();
                allAttributes.ForEach( a => entity.Attributes.Add( a.Key, a ) );

                entity.AttributeValues = attributeValues;
            }
        }
        private List<ContentChannelItem> GetItems( RockContext rockContext, ContentChannel selectedChannel, out bool isFiltered )
        {
            isFiltered = false;

            var items = new List<ContentChannelItem>();

            var itemQry = new ContentChannelItemService( rockContext ).Queryable()
                .Where( i => i.ContentChannelId == selectedChannel.Id );

            var drp = new DateRangePicker();
            drp.DelimitedValues = gfFilter.GetUserPreference( "Date Range" );
            if ( drp.LowerValue.HasValue )
            {
                isFiltered = true;
                if ( selectedChannel.ContentChannelType.DateRangeType == ContentChannelDateType.SingleDate )
                {
                    itemQry = itemQry.Where( i => i.StartDateTime >= drp.LowerValue.Value );
                }
                else
                {
                    itemQry = itemQry.Where( i => i.ExpireDateTime.HasValue && i.ExpireDateTime.Value >= drp.LowerValue.Value );
                }
            }
            if ( drp.UpperValue.HasValue )
            {
                isFiltered = true;
                DateTime upperDate = drp.UpperValue.Value.Date.AddDays( 1 );
                itemQry = itemQry.Where( i => i.StartDateTime <= upperDate );
            }

            var status = gfFilter.GetUserPreference( "Status" ).ConvertToEnumOrNull<ContentChannelItemStatus>();
            if ( status.HasValue )
            {
                isFiltered = true;
                itemQry = itemQry.Where( i => i.Status == status );
            }

            string title = gfFilter.GetUserPreference( "Title" );
            if ( !string.IsNullOrWhiteSpace( title ) )
            {
                isFiltered = true;
                itemQry = itemQry.Where( i => i.Title.Contains( title ) );
            }

            int? personId = gfFilter.GetUserPreference( "Created By" ).AsIntegerOrNull();
            if ( personId.HasValue && personId.Value != 0 )
            {
                isFiltered = true;
                itemQry = itemQry.Where( i => i.CreatedByPersonAlias.PersonId == personId );
            }

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

                foreach ( var attribute in AvailableAttributes )
                {
                    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 );

                            isFiltered = true;
                            itemQry = itemQry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                        }
                    }
                }
            }

            foreach ( var item in itemQry.ToList() )
            {
                if ( item.IsAuthorized( Rock.Security.Authorization.VIEW, CurrentPerson ) )
                {
                    items.Add( item );
                }
                else
                {
                    isFiltered = true;
                }
            }

            if ( selectedChannel.ItemsManuallyOrdered && !isFiltered )
            {
                return items.OrderBy( i => i.Order ).ToList();
            }
            else
            {
                return items;
            }
        }
Exemple #19
0
        /// <summary>
        /// This method takes the attribute values of the original blocks, and creates copies of them that point to the copied blocks. 
        /// In addition, any block attribute value pointing to a page in the original page tree is now updated to point to the
        /// corresponding page in the copied page tree.
        /// </summary>
        /// <param name="pageGuidDictionary">The dictionary containing the original page guids and the corresponding copied page guids.</param>
        /// <param name="blockGuidDictionary">The dictionary containing the original block guids and the corresponding copied block guids.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="currentPersonAliasId">The current person alias identifier.</param>
        private void GenerateBlockAttributeValues( Dictionary<Guid, Guid> pageGuidDictionary, Dictionary<Guid, Guid> blockGuidDictionary, RockContext rockContext, int? currentPersonAliasId = null )
        {
            var attributeValueService = new AttributeValueService( rockContext );
            var pageService = new PageService( rockContext );
            var blockService = new BlockService( rockContext );
            var pageGuid = Rock.SystemGuid.EntityType.PAGE.AsGuid();
            var blockGuid = Rock.SystemGuid.EntityType.BLOCK.AsGuid();

            Dictionary<Guid, int> blockIntDictionary = blockService.Queryable()
                .Where( p => blockGuidDictionary.Keys.Contains( p.Guid ) || blockGuidDictionary.Values.Contains( p.Guid ) )
                .ToDictionary( p => p.Guid, p => p.Id );

            var attributeValues = attributeValueService.Queryable().Where( a =>
                a.Attribute.EntityType.Guid == blockGuid && blockIntDictionary.Values.Contains( a.EntityId.Value ) )
                .ToList();

            foreach ( var attributeValue in attributeValues )
            {
                var newAttributeValue = attributeValue.Clone( false );
                newAttributeValue.CreatedByPersonAlias = null;
                newAttributeValue.CreatedByPersonAliasId = currentPersonAliasId;
                newAttributeValue.CreatedDateTime = RockDateTime.Now;
                newAttributeValue.ModifiedByPersonAlias = null;
                newAttributeValue.ModifiedByPersonAliasId = currentPersonAliasId;
                newAttributeValue.ModifiedDateTime = RockDateTime.Now;
                newAttributeValue.Id = 0;
                newAttributeValue.Guid = Guid.NewGuid();
                newAttributeValue.EntityId = blockIntDictionary[blockGuidDictionary[blockIntDictionary.Where( d => d.Value == attributeValue.EntityId.Value ).FirstOrDefault().Key]];

                if ( attributeValue.Attribute.FieldType.Guid == Rock.SystemGuid.FieldType.PAGE_REFERENCE.AsGuid() )
                {
                    if ( pageGuidDictionary.ContainsKey( attributeValue.Value.AsGuid() ) )
                    {
                        newAttributeValue.Value = pageGuidDictionary[attributeValue.Value.AsGuid()].ToString();
                    }
                }

                attributeValueService.Add( newAttributeValue );
            }

            rockContext.SaveChanges();
        }
Exemple #20
0
        /// <summary>
        /// Loads the <see cref="P:IHasAttributes.Attributes" /> and <see cref="P:IHasAttributes.AttributeValues" /> of any <see cref="IHasAttributes" /> object
        /// </summary>
        /// <param name="entity">The item.</param>
        /// <param name="rockContext">The rock context.</param>
        public static void LoadAttributes(Rock.Attribute.IHasAttributes entity, RockContext rockContext)
        {
            if (entity != null)
            {
                Dictionary <string, PropertyInfo> properties = new Dictionary <string, PropertyInfo>();

                Type entityType = entity.GetType();
                if (entityType.Namespace == "System.Data.Entity.DynamicProxies")
                {
                    entityType = entityType.BaseType;
                }

                rockContext = rockContext ?? new RockContext();

                // Check for group type attributes
                var groupTypeIds = new List <int>();
                if (entity is GroupMember || entity is Group || entity is GroupType)
                {
                    // Can't use GroupTypeCache here since it loads attributes and would result in a recursive stack overflow situation
                    var       groupTypeService = new GroupTypeService(rockContext);
                    GroupType groupType        = null;

                    if (entity is GroupMember)
                    {
                        var group = ((GroupMember)entity).Group ?? new GroupService(rockContext)
                                    .Queryable().AsNoTracking().FirstOrDefault(g => g.Id == ((GroupMember)entity).GroupId);
                        if (group != null)
                        {
                            groupType = group.GroupType ?? groupTypeService
                                        .Queryable().AsNoTracking().FirstOrDefault(t => t.Id == group.GroupTypeId);
                        }
                    }
                    else if (entity is Group)
                    {
                        groupType = ((Group)entity).GroupType ?? groupTypeService
                                    .Queryable().AsNoTracking().FirstOrDefault(t => t.Id == ((Group)entity).GroupTypeId);
                    }
                    else
                    {
                        groupType = ((GroupType)entity);
                    }

                    while (groupType != null)
                    {
                        groupTypeIds.Insert(0, groupType.Id);

                        // Check for inherited group type id's
                        if (groupType.InheritedGroupTypeId.HasValue)
                        {
                            groupType = groupType.InheritedGroupType ?? groupTypeService
                                        .Queryable().AsNoTracking().FirstOrDefault(t => t.Id == (groupType.InheritedGroupTypeId ?? 0));
                        }
                        else
                        {
                            groupType = null;
                        }
                    }
                }

                foreach (PropertyInfo propertyInfo in entityType.GetProperties())
                {
                    properties.Add(propertyInfo.Name.ToLower(), propertyInfo);
                }

                Rock.Model.AttributeService      attributeService      = new Rock.Model.AttributeService(rockContext);
                Rock.Model.AttributeValueService attributeValueService = new Rock.Model.AttributeValueService(rockContext);

                var inheritedAttributes = new Dictionary <int, List <Rock.Web.Cache.AttributeCache> >();
                if (groupTypeIds.Any())
                {
                    groupTypeIds.ForEach(g => inheritedAttributes.Add(g, new List <Rock.Web.Cache.AttributeCache>()));
                }
                else
                {
                    inheritedAttributes.Add(0, new List <Rock.Web.Cache.AttributeCache>());
                }

                var attributes = new List <Rock.Web.Cache.AttributeCache>();

                // Get all the attributes that apply to this entity type and this entity's properties match any attribute qualifiers
                var entityTypeCache = Rock.Web.Cache.EntityTypeCache.Read(entityType);
                if (entityTypeCache != null)
                {
                    int entityTypeId = entityTypeCache.Id;
                    foreach (var attribute in attributeService.Queryable()
                             .AsNoTracking()
                             .Where(a => a.EntityTypeId == entityTypeCache.Id)
                             .Select(a => new
                    {
                        a.Id,
                        a.EntityTypeQualifierColumn,
                        a.EntityTypeQualifierValue
                    }
                                     ))
                    {
                        // group type ids exist (entity is either GroupMember, Group, or GroupType) and qualifier is for a group type id
                        if (groupTypeIds.Any() && (
                                (entity is GroupMember && string.Compare(attribute.EntityTypeQualifierColumn, "GroupTypeId", true) == 0) ||
                                (entity is Group && string.Compare(attribute.EntityTypeQualifierColumn, "GroupTypeId", true) == 0) ||
                                (entity is GroupType && string.Compare(attribute.EntityTypeQualifierColumn, "Id", true) == 0)))
                        {
                            int groupTypeIdValue = int.MinValue;
                            if (int.TryParse(attribute.EntityTypeQualifierValue, out groupTypeIdValue) && groupTypeIds.Contains(groupTypeIdValue))
                            {
                                inheritedAttributes[groupTypeIdValue].Add(Rock.Web.Cache.AttributeCache.Read(attribute.Id));
                            }
                        }

                        else if (string.IsNullOrEmpty(attribute.EntityTypeQualifierColumn) ||
                                 (properties.ContainsKey(attribute.EntityTypeQualifierColumn.ToLower()) &&
                                  (string.IsNullOrEmpty(attribute.EntityTypeQualifierValue) ||
                                   (properties[attribute.EntityTypeQualifierColumn.ToLower()].GetValue(entity, null) ?? "").ToString() == attribute.EntityTypeQualifierValue)))
                        {
                            attributes.Add(Rock.Web.Cache.AttributeCache.Read(attribute.Id));
                        }
                    }
                }

                var allAttributes = new List <Rock.Web.Cache.AttributeCache>();

                foreach (var attributeGroup in inheritedAttributes)
                {
                    foreach (var attribute in attributeGroup.Value)
                    {
                        allAttributes.Add(attribute);
                    }
                }
                foreach (var attribute in attributes)
                {
                    allAttributes.Add(attribute);
                }

                var attributeValues = new Dictionary <string, Rock.Model.AttributeValue>();

                if (allAttributes.Any())
                {
                    foreach (var attribute in allAttributes)
                    {
                        // Add a placeholder for this item's value for each attribute
                        attributeValues.Add(attribute.Key, null);
                    }

                    // If loading attributes for a saved item, read the item's value(s) for each attribute
                    if (!entityTypeCache.IsEntity || entity.Id != 0)
                    {
                        List <int> attributeIds = allAttributes.Select(a => a.Id).ToList();
                        foreach (var attributeValue in attributeValueService.Queryable().AsNoTracking()
                                 .Where(v => v.EntityId == entity.Id && attributeIds.Contains(v.AttributeId)))
                        {
                            var attributeKey = AttributeCache.Read(attributeValue.AttributeId).Key;
                            attributeValues[attributeKey] = attributeValue.Clone(false) as Rock.Model.AttributeValue;
                        }
                    }

                    // Look for any attributes that don't have a value and create a default value entry
                    foreach (var attribute in allAttributes)
                    {
                        if (attributeValues[attribute.Key] == null)
                        {
                            var attributeValue = new Rock.Model.AttributeValue();
                            attributeValue.AttributeId = attribute.Id;
                            if (entity.AttributeValueDefaults != null && entity.AttributeValueDefaults.ContainsKey(attribute.Name))
                            {
                                attributeValue.Value = entity.AttributeValueDefaults[attribute.Name];
                            }
                            else
                            {
                                attributeValue.Value = attribute.DefaultValue;
                            }
                            attributeValues[attribute.Key] = attributeValue;
                        }
                        else
                        {
                            if (!String.IsNullOrWhiteSpace(attribute.DefaultValue) &&
                                String.IsNullOrWhiteSpace(attributeValues[attribute.Key].Value))
                            {
                                attributeValues[attribute.Key].Value = attribute.DefaultValue;
                            }
                        }
                    }
                }

                entity.Attributes = new Dictionary <string, Web.Cache.AttributeCache>();
                allAttributes.ForEach(a => entity.Attributes.Add(a.Key, a));

                entity.AttributeValues = attributeValues;
            }
        }
Exemple #21
0
        /// <summary>
        /// Binds the registrants grid.
        /// </summary>
        private void BindRegistrantsGrid()
        {
            int? instanceId = hfRegistrationInstanceId.Value.AsIntegerOrNull();
            if ( instanceId.HasValue )
            {
                using ( var rockContext = new RockContext() )
                {
                    // Start query for registrants
                    var qry = new RegistrationRegistrantService( rockContext )
                        .Queryable( "PersonAlias.Person.PhoneNumbers.NumberTypeValue,Fees.RegistrationTemplateFee,GroupMember.Group" ).AsNoTracking()
                        .Where( r =>
                            r.Registration.RegistrationInstanceId == instanceId.Value &&
                            r.PersonAlias != null &&
                            r.PersonAlias.Person != null );

                    // Filter by daterange
                    if ( drpRegistrantDateRange.LowerValue.HasValue )
                    {
                        qry = qry.Where( r =>
                            r.CreatedDateTime.HasValue &&
                            r.CreatedDateTime.Value >= drpRegistrantDateRange.LowerValue.Value );
                    }
                    if ( drpRegistrantDateRange.UpperValue.HasValue )
                    {
                        qry = qry.Where( r =>
                            r.CreatedDateTime.HasValue &&
                            r.CreatedDateTime.Value <= drpRegistrantDateRange.UpperValue.Value );
                    }

                    // Filter by first name
                    if ( !string.IsNullOrWhiteSpace( tbRegistrantFirstName.Text ) )
                    {
                        string rfname = tbRegistrantFirstName.Text;
                        qry = qry.Where( r =>
                            r.PersonAlias.Person.NickName.StartsWith( rfname ) ||
                            r.PersonAlias.Person.FirstName.StartsWith( rfname ) );
                    }

                    // Filter by last name
                    if ( !string.IsNullOrWhiteSpace( tbRegistrantLastName.Text ) )
                    {
                        string rlname = tbRegistrantLastName.Text;
                        qry = qry.Where( r =>
                            r.PersonAlias.Person.LastName.StartsWith( rlname ) );
                    }

                    bool preloadCampusValues = false;
                    var registrantAttributes = new List<AttributeCache>();
                    var personAttributes = new List<AttributeCache>();
                    var groupMemberAttributes = new List<AttributeCache>();
                    var registrantAttributeIds = new List<int>();
                    var personAttributesIds = new List<int>();
                    var groupMemberAttributesIds = new List<int>();

                    if ( RegistrantFields != null )
                    {
                        // Filter by any selected
                        foreach ( var personFieldType in RegistrantFields
                            .Where( f =>
                                f.FieldSource == RegistrationFieldSource.PersonField &&
                                f.PersonFieldType.HasValue )
                            .Select( f => f.PersonFieldType.Value ) )
                        {
                            switch ( personFieldType )
                            {
                                case RegistrationPersonFieldType.Campus:
                                    {
                                        preloadCampusValues = true;

                                        var ddlCampus = phRegistrantFormFieldFilters.FindControl( "ddlCampus" ) as RockDropDownList;
                                        if ( ddlCampus != null )
                                        {
                                            var campusId = ddlCampus.SelectedValue.AsIntegerOrNull();
                                            if ( campusId.HasValue )
                                            {
                                                var familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();
                                                qry = qry.Where( r =>
                                                    r.PersonAlias.Person.Members.Any( m =>
                                                        m.Group.GroupType.Guid == familyGroupTypeGuid &&
                                                        m.Group.CampusId.HasValue &&
                                                        m.Group.CampusId.Value == campusId ) );
                                            }
                                        }

                                        break;
                                    }

                                case RegistrationPersonFieldType.Email:
                                    {
                                        var tbEmailFilter = phRegistrantFormFieldFilters.FindControl( "tbEmailFilter" ) as RockTextBox;
                                        if ( tbEmailFilter != null && !string.IsNullOrWhiteSpace( tbEmailFilter.Text ) )
                                        {
                                            qry = qry.Where( r =>
                                                r.PersonAlias.Person.Email != null &&
                                                r.PersonAlias.Person.Email.Contains( tbEmailFilter.Text ) );
                                        }

                                        break;
                                    }

                                case RegistrationPersonFieldType.Birthdate:
                                    {
                                        var drpBirthdateFilter = phRegistrantFormFieldFilters.FindControl( "drpBirthdateFilter" ) as DateRangePicker;
                                        if ( drpBirthdateFilter != null )
                                        {
                                            if ( drpBirthdateFilter.LowerValue.HasValue )
                                            {
                                                qry = qry.Where( r =>
                                                    r.PersonAlias.Person.BirthDate.HasValue &&
                                                    r.PersonAlias.Person.BirthDate.Value >= drpBirthdateFilter.LowerValue.Value );
                                            }
                                            if ( drpBirthdateFilter.UpperValue.HasValue )
                                            {
                                                qry = qry.Where( r =>
                                                    r.PersonAlias.Person.BirthDate.HasValue &&
                                                    r.PersonAlias.Person.BirthDate.Value <= drpBirthdateFilter.UpperValue.Value );
                                            }
                                        }
                                        break;
                                    }

                                case RegistrationPersonFieldType.Gender:
                                    {
                                        var ddlGenderFilter = phRegistrantFormFieldFilters.FindControl( "ddlGenderFilter" ) as RockDropDownList;
                                        if ( ddlGenderFilter != null )
                                        {
                                            var gender = ddlGenderFilter.SelectedValue.ConvertToEnumOrNull<Gender>();
                                            if ( gender.HasValue )
                                            {
                                                qry = qry.Where( r =>
                                                    r.PersonAlias.Person.Gender == gender );
                                            }
                                        }

                                        break;
                                    }

                                case RegistrationPersonFieldType.MaritalStatus:
                                    {
                                        var ddlMaritalStatusFilter = phRegistrantFormFieldFilters.FindControl( "ddlMaritalStatusFilter" ) as RockDropDownList;
                                        if ( ddlMaritalStatusFilter != null )
                                        {
                                            var maritalStatusId = ddlMaritalStatusFilter.SelectedValue.AsIntegerOrNull();
                                            if ( maritalStatusId.HasValue )
                                            {
                                                qry = qry.Where( r =>
                                                    r.PersonAlias.Person.MaritalStatusValueId.HasValue &&
                                                    r.PersonAlias.Person.MaritalStatusValueId.Value == maritalStatusId.Value );
                                            }
                                        }

                                        break;
                                    }
                                case RegistrationPersonFieldType.MobilePhone:
                                    {
                                        var tbPhoneFilter = phRegistrantFormFieldFilters.FindControl( "tbPhoneFilter" ) as RockTextBox;
                                        if ( tbPhoneFilter != null && !string.IsNullOrWhiteSpace( tbPhoneFilter.Text ) )
                                        {
                                            string numericPhone = tbPhoneFilter.Text.AsNumeric();

                                            qry = qry.Where( r =>
                                                r.PersonAlias.Person.PhoneNumbers != null &&
                                                r.PersonAlias.Person.PhoneNumbers.Any( n => n.Number.Contains( numericPhone ) ) );
                                        }

                                        break;
                                    }
                            }
                        }

                        // Get all the registrant attributes selected to be on grid
                        registrantAttributes = RegistrantFields
                            .Where( f =>
                                f.Attribute != null &&
                                f.FieldSource == RegistrationFieldSource.RegistrationAttribute )
                            .Select( f => f.Attribute )
                            .ToList();
                        registrantAttributeIds = registrantAttributes.Select( a => a.Id ).Distinct().ToList();

                        // Filter query by any configured registrant attribute filters
                        if ( registrantAttributes != null && registrantAttributes.Any() )
                        {
                            var attributeValueService = new AttributeValueService( rockContext );
                            var parameterExpression = attributeValueService.ParameterExpression;
                            foreach ( var attribute in registrantAttributes )
                            {
                                var filterControl = phRegistrantFormFieldFilters.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 );
                                        qry = qry
                                            .Where( r => attributeValues.Select( v => v.EntityId ).Contains( r.Id ) );
                                    }
                                }
                            }
                        }

                        // Get all the person attributes selected to be on grid
                        personAttributes = RegistrantFields
                            .Where( f =>
                                f.Attribute != null &&
                                f.FieldSource == RegistrationFieldSource.PersonAttribute )
                            .Select( f => f.Attribute )
                            .ToList();
                        personAttributesIds = personAttributes.Select( a => a.Id ).Distinct().ToList();

                        // Filter query by any configured person attribute filters
                        if ( personAttributes != null && personAttributes.Any() )
                        {
                            var attributeValueService = new AttributeValueService( rockContext );
                            var parameterExpression = attributeValueService.ParameterExpression;
                            foreach ( var attribute in personAttributes )
                            {
                                var filterControl = phRegistrantFormFieldFilters.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 );
                                        qry = qry
                                            .Where( r => attributeValues.Select( v => v.EntityId ).Contains( r.PersonAlias.PersonId ) );
                                    }
                                }
                            }
                        }

                        // Get all the group member attributes selected to be on grid
                        groupMemberAttributes = RegistrantFields
                            .Where( f =>
                                f.Attribute != null &&
                                f.FieldSource == RegistrationFieldSource.GroupMemberAttribute )
                            .Select( f => f.Attribute )
                            .ToList();
                        groupMemberAttributesIds = groupMemberAttributes.Select( a => a.Id ).Distinct().ToList();

                        // Filter query by any configured person attribute filters
                        if ( groupMemberAttributes != null && groupMemberAttributes.Any() )
                        {
                            var attributeValueService = new AttributeValueService( rockContext );
                            var parameterExpression = attributeValueService.ParameterExpression;
                            foreach ( var attribute in groupMemberAttributes )
                            {
                                var filterControl = phRegistrantFormFieldFilters.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 );
                                        qry = qry
                                            .Where( r => r.GroupMemberId.HasValue &&
                                            attributeValues.Select( v => v.EntityId ).Contains( r.GroupMemberId.Value ) );
                                    }
                                }
                            }
                        }
                    }

                    // Sort the query
                    IOrderedQueryable<RegistrationRegistrant> orderedQry = null;
                    SortProperty sortProperty = gRegistrants.SortProperty;
                    if ( sortProperty != null )
                    {
                        orderedQry = qry.Sort( sortProperty );
                    }
                    else
                    {
                        orderedQry = qry
                            .OrderBy( r => r.PersonAlias.Person.LastName )
                            .ThenBy( r => r.PersonAlias.Person.NickName );
                    }

                    // Set the grids LinqDataSource which will run query and set results for current page
                    gRegistrants.SetLinqDataSource<RegistrationRegistrant>( orderedQry );

                    if ( RegistrantFields != null )
                    {
                        // Get the query results for the current page
                        var currentPageRegistrants = gRegistrants.DataSource as List<RegistrationRegistrant>;
                        if ( currentPageRegistrants != null )
                        {
                            // Get all the registrant ids in current page of query results
                            var registrantIds = currentPageRegistrants
                                .Select( r => r.Id )
                                .Distinct()
                                .ToList();

                            // Get all the person ids in current page of query results
                            var personIds = currentPageRegistrants
                                .Select( r => r.PersonAlias.PersonId )
                                .Distinct()
                                .ToList();

                            // Get all the group member ids and the group id in current page of query results
                            var groupMemberIds = new List<int>();
                            GroupLinks = new Dictionary<int,string>();
                            foreach( var groupMember in currentPageRegistrants
                                .Where( m =>
                                    m.GroupMember != null &&
                                    m.GroupMember.Group != null )
                                .Select( m => m.GroupMember ) )
                            {
                                groupMemberIds.Add( groupMember.Id );
                                GroupLinks.AddOrIgnore( groupMember.GroupId,
                                    string.Format( "<a href='{0}'>{1}</a>",
                                        LinkedPageUrl( "GroupDetailPage", new Dictionary<string, string> { { "GroupId", groupMember.GroupId.ToString() } } ),
                                        groupMember.Group.Name ) );
                            }

                            // If the campus column was selected to be displayed on grid, preload all the people's
                            // campuses so that the databind does not need to query each row
                            if ( preloadCampusValues )
                            {
                                PersonCampusIds = new Dictionary<int, List<int>>();

                                Guid familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();
                                foreach ( var personCampusList in new GroupMemberService( rockContext )
                                    .Queryable().AsNoTracking()
                                    .Where( m =>
                                        m.Group.GroupType.Guid == familyGroupTypeGuid &&
                                        personIds.Contains( m.PersonId ) )
                                    .GroupBy( m => m.PersonId )
                                    .Select( m => new
                                    {
                                        PersonId = m.Key,
                                        CampusIds = m
                                            .Where( g => g.Group.CampusId.HasValue )
                                            .Select( g => g.Group.CampusId.Value )
                                            .ToList()
                                    } ) )
                                {
                                    PersonCampusIds.Add( personCampusList.PersonId, personCampusList.CampusIds );
                                }
                            }

                            // If there are any attributes that were selected to be displayed, we're going
                            // to try and read all attribute values in one query and then put them into a
                            // custom grid ObjectList property so that the AttributeField columns don't need
                            // to do the LoadAttributes and querying of values for each row/column
                            if ( personAttributesIds.Any() || groupMemberAttributesIds.Any() || registrantAttributeIds.Any() )
                            {

                                // Query the attribute values for all rows and attributes
                                var attributeValues = new AttributeValueService( rockContext )
                                    .Queryable( "Attribute" ).AsNoTracking()
                                    .Where( v =>
                                        v.EntityId.HasValue &&
                                        (
                                            (
                                                personAttributesIds.Contains( v.AttributeId ) &&
                                                personIds.Contains( v.EntityId.Value )
                                            ) ||
                                            (
                                                groupMemberAttributesIds.Contains( v.AttributeId ) &&
                                                groupMemberIds.Contains( v.EntityId.Value )
                                            ) ||
                                            (
                                                registrantAttributeIds.Contains( v.AttributeId ) &&
                                                registrantIds.Contains( v.EntityId.Value )
                                            )
                                        )
                                    )
                                    .ToList();

                                // Get the attributes to add to each row's object
                                var attributes = new Dictionary<string, AttributeCache>();
                                RegistrantFields
                                        .Where( f => f.Attribute != null )
                                        .Select( f => f.Attribute )
                                        .ToList()
                                    .ForEach( a => attributes
                                        .Add( a.Id.ToString() + a.Key, a ) );

                                // Initialize the grid's object list
                                gRegistrants.ObjectList = new Dictionary<string, object>();

                                // Loop through each of the current page's registrants and build an attribute
                                // field object for storing attributes and the values for each of the registrants
                                foreach ( var registrant in currentPageRegistrants )
                                {
                                    // Create a row attribute object
                                    var attributeFieldObject = new AttributeFieldObject();

                                    // Add the attributes to the attribute object
                                    attributeFieldObject.Attributes = attributes;

                                    // Add any person attribute values to object
                                    attributeValues
                                        .Where( v =>
                                            personAttributesIds.Contains( v.AttributeId ) &&
                                            v.EntityId.Value == registrant.PersonAlias.PersonId )
                                        .ToList()
                                        .ForEach( v => attributeFieldObject.AttributeValues
                                            .Add( v.AttributeId.ToString() + v.Attribute.Key, v ) );

                                    // Add any group member attribute values to object
                                    if ( registrant.GroupMemberId.HasValue )
                                    {
                                        attributeValues
                                            .Where( v =>
                                                groupMemberAttributesIds.Contains( v.AttributeId ) &&
                                                v.EntityId.Value == registrant.GroupMemberId.Value )
                                            .ToList()
                                            .ForEach( v => attributeFieldObject.AttributeValues
                                                .Add( v.AttributeId.ToString() + v.Attribute.Key, v ) );
                                    }

                                    // Add any registrant attribute values to object
                                    attributeValues
                                        .Where( v =>
                                            registrantAttributeIds.Contains( v.AttributeId ) &&
                                            v.EntityId.Value == registrant.PersonAlias.PersonId )
                                        .ToList()
                                        .ForEach( v => attributeFieldObject.AttributeValues
                                            .Add( v.AttributeId.ToString() + v.Attribute.Key, v ) );

                                    // Add row attribute object to grid's object list
                                    gRegistrants.ObjectList.Add( registrant.Id.ToString(), attributeFieldObject );
                                }
                            }
                        }
                    }

                    gRegistrants.DataBind();
                }
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            if ( _workflowType != null )
            {
                pnlWorkflowList.Visible = true;

                var rockContext = new RockContext();
                var workflowService = new WorkflowService( rockContext );

                var qry = workflowService
                    .Queryable( "Activities.ActivityType,InitiatorPersonAlias.Person" ).AsNoTracking()
                    .Where( w => w.WorkflowTypeId.Equals( _workflowType.Id ) );

                // Activated Date Range Filter
                if ( drpActivated.LowerValue.HasValue )
                {
                    qry = qry.Where( w => w.ActivatedDateTime >= drpActivated.LowerValue.Value );
                }
                if ( drpActivated.UpperValue.HasValue )
                {
                    DateTime upperDate = drpActivated.UpperValue.Value.Date.AddDays( 1 );
                    qry = qry.Where( w => w.ActivatedDateTime.Value < upperDate );
                }

                // State Filter
                List<string> states = cblState.SelectedValues;
                if ( states.Count == 1 )    // Don't filter if none or both options are selected
                {
                    if ( states[0] == "Active" )
                    {
                        qry = qry.Where( w => !w.CompletedDateTime.HasValue );
                    }
                    else
                    {
                        qry = qry.Where( w => w.CompletedDateTime.HasValue );
                    }
                }

                // Completed Date Range Filter
                if ( drpCompleted.LowerValue.HasValue )
                {
                    qry = qry.Where( w => w.CompletedDateTime.HasValue && w.CompletedDateTime.Value >= drpCompleted.LowerValue.Value );
                }
                if ( drpCompleted.UpperValue.HasValue )
                {
                    DateTime upperDate = drpCompleted.UpperValue.Value.Date.AddDays( 1 );
                    qry = qry.Where( w => w.CompletedDateTime.HasValue && w.CompletedDateTime.Value < upperDate );
                }

                string name = tbName.Text;
                if ( !string.IsNullOrWhiteSpace( name ) )
                {
                    qry = qry.Where( w => w.Name.StartsWith( name ) );
                }

                int? personId = ppInitiator.SelectedValue;
                if ( personId.HasValue )
                {
                    qry = qry.Where( w => w.InitiatorPersonAlias.PersonId == personId.Value );
                }

                string status = tbStatus.Text;
                if ( !string.IsNullOrWhiteSpace( status ) )
                {
                    qry = qry.Where( w => w.Status.StartsWith( status ) );
                }

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

                    foreach ( var attribute in AvailableAttributes )
                    {
                        var filterControl = phAttributeFilters.FindControl( "filter_" + attribute.Id.ToString() );
                        if ( filterControl != null )
                        {
                            var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues );
                            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 );

                                qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }

                List<Workflow> workflows = null;

                var sortProperty = gWorkflows.SortProperty;
                if ( sortProperty != null )
                {
                    if ( sortProperty.Property == "Initiator" )
                    {
                        if ( sortProperty.Direction == SortDirection.Ascending )
                        {
                            workflows = qry
                                .OrderBy( w => w.InitiatorPersonAlias.Person.LastName )
                                .ThenBy( w => w.InitiatorPersonAlias.Person.NickName )
                                .ToList();
                        }
                        else
                        {
                            workflows = qry
                                .OrderByDescending( w => w.InitiatorPersonAlias.Person.LastName )
                                .ThenByDescending( w => w.InitiatorPersonAlias.Person.NickName )
                                .ToList();
                        }
                    }
                    else
                    {
                        workflows = qry.Sort( sortProperty ).ToList();
                    }
                }
                else
                {
                    workflows = qry.OrderByDescending( s => s.CreatedDateTime ).ToList();
                }

                // Since we're not binding to actual workflow list, but are using AttributeField columns,
                // we need to save the workflows into the grid's object list
                gWorkflows.ObjectList = new Dictionary<string, object>();
                workflows.ForEach( w => gWorkflows.ObjectList.Add( w.Id.ToString(), w ) );

                gWorkflows.DataSource = workflows.Select( w => new
                {
                    w.Id,
                    w.Name,
                    Initiator = ( w.InitiatorPersonAlias != null ? w.InitiatorPersonAlias.Person.FullName : "" ),
                    Activities = w.ActiveActivities.Select( a => a.ActivityType.Name ).ToList().AsDelimited( "<br/>" ),
                    w.CreatedDateTime,
                    Status = string.Format( "<span class='label label-info'>{0}</span>", w.Status ),
                    State = ( w.CompletedDateTime.HasValue ? "<span class='label label-default'>Completed</span>" : "<span class='label label-success'>Active</span>" )
                } ).ToList();
                gWorkflows.DataBind();
            }
            else
            {
                pnlWorkflowList.Visible = false;
            }
        }
        /// <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();
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Updates the list.
        /// </summary>
        private void UpdateList()
        {
            using ( var rockContext = new RockContext() )
            {
                var connectionType = new ConnectionTypeService( rockContext ).Get( GetAttributeValue( "ConnectionTypeId" ).AsInteger() );
                var qrySearch = connectionType.ConnectionOpportunities.ToList();

                if ( GetAttributeValue( "DisplayNameFilter" ).AsBoolean() )
                {
                    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();
                    }
                }

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

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            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( o => attributeValues.Select( v => v.EntityId ).Contains( o.Id ) ).ToList();
                                }
                            }
                        }
                    }
                }

                var opportunitySummaries = new List<OpportunitySummary>();
                foreach ( var opportunity in qrySearch )
                {
                    opportunitySummaries.Add( new OpportunitySummary
                    {
                        IconCssClass = opportunity.IconCssClass,
                        Name = opportunity.PublicName,
                        PhotoUrl = opportunity.PhotoUrl,
                        Description = opportunity.Description.ScrubHtmlAndConvertCrLfToBr(),
                        Id = opportunity.Id
                    } );
                }

                var opportunities = opportunitySummaries
                    .OrderBy( e => e.Name )
                    .ToList();

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

                var pageReference = new PageReference( GetAttributeValue( "DetailPage" ), null );
                mergeFields.Add( "DetailPage", pageReference.BuildUrl() );

                lOutput.Text = GetAttributeValue( "LavaTemplate" ).ResolveMergeFields( mergeFields );

                if ( GetAttributeValue( "SetPageTitle" ).AsBoolean() )
                {
                    string pageTitle = "Connection";
                    RockPage.PageTitle = pageTitle;
                    RockPage.BrowserTitle = String.Format( "{0} | {1}", pageTitle, RockPage.Site.Name );
                    RockPage.Header.Title = String.Format( "{0} | {1}", pageTitle, RockPage.Site.Name );
                }

                // show debug info
                if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) )
                {
                    lDebug.Visible = true;
                    lDebug.Text = mergeFields.lavaDebugInfo();
                }
            }
        }
Exemple #25
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGroupMembersGrid()
        {
            if ( _group != null )
            {
                pnlGroupMembers.Visible = true;

                lHeading.Text = string.Format( "{0} {1}", _group.GroupType.GroupTerm, _group.GroupType.GroupMemberTerm.Pluralize() );

                if ( _group.GroupType.Roles.Any() )
                {
                    nbRoleWarning.Visible = false;
                    rFilter.Visible = true;
                    gGroupMembers.Visible = true;

                    var rockContext = new RockContext();

                    GroupMemberService groupMemberService = new GroupMemberService( rockContext );
                    var qry = groupMemberService.Queryable( "Person,GroupRole", true ).AsNoTracking()
                        .Where( m => m.GroupId == _group.Id );

                    // Filter by First Name
                    string firstName = tbFirstName.Text;
                    if ( !string.IsNullOrWhiteSpace( firstName ) )
                    {
                        qry = qry.Where( m => m.Person.FirstName.StartsWith( firstName ) );
                    }

                    // Filter by Last Name
                    string lastName = tbLastName.Text;
                    if ( !string.IsNullOrWhiteSpace( lastName ) )
                    {
                        qry = qry.Where( m => m.Person.LastName.StartsWith( lastName ) );
                    }

                    // Filter by role
                    var validGroupTypeRoles = _group.GroupType.Roles.Select( r => r.Id ).ToList();
                    var roles = new List<int>();
                    foreach ( string role in cblRole.SelectedValues )
                    {
                        if ( !string.IsNullOrWhiteSpace( role ) )
                        {
                            int roleId = int.MinValue;
                            if ( int.TryParse( role, out roleId ) && validGroupTypeRoles.Contains( roleId ) )
                            {
                                roles.Add( roleId );
                            }
                        }
                    }

                    if ( roles.Any() )
                    {
                        qry = qry.Where( m => roles.Contains( m.GroupRoleId ) );
                    }

                    // Filter by Status
                    var statuses = new List<GroupMemberStatus>();
                    foreach ( string status in cblStatus.SelectedValues )
                    {
                        if ( !string.IsNullOrWhiteSpace( status ) )
                        {
                            statuses.Add( status.ConvertToEnum<GroupMemberStatus>() );
                        }
                    }

                    if ( statuses.Any() )
                    {
                        qry = qry.Where( m => statuses.Contains( m.GroupMemberStatus ) );
                    }

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            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 );

                                    qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                                }
                            }
                        }
                    }

                    _inactiveStatus = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE );

                    SortProperty sortProperty = gGroupMembers.SortProperty;

                    bool hasGroupRequirements = new GroupRequirementService( rockContext ).Queryable().Where( a => a.GroupId == _group.Id ).Any();

                    // If there are group requirements that that member doesn't meet, show an icon in the grid
                    bool includeWarnings = false;
                    var groupMemberIdsThatLackGroupRequirements = new GroupService( rockContext ).GroupMembersNotMeetingRequirements( _group.Id, includeWarnings ).Select( a => a.Key.Id );

                    List<GroupMember> groupMembersList = null;

                    if ( sortProperty != null )
                    {
                        groupMembersList = qry.Sort( sortProperty ).ToList();
                    }
                    else
                    {
                        groupMembersList = qry.OrderBy( a => a.GroupRole.Order ).ThenBy( a => a.Person.LastName ).ThenBy( a => a.Person.FirstName ).ToList();
                    }

                    // Since we're not binding to actual group member list, but are using AttributeField columns,
                    // we need to save the workflows into the grid's object list
                    gGroupMembers.ObjectList = new Dictionary<string, object>();
                    groupMembersList.ForEach( m => gGroupMembers.ObjectList.Add( m.Id.ToString(), m ) );
                    gGroupMembers.EntityTypeId = EntityTypeCache.Read( Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid() ).Id;

                    gGroupMembers.DataSource = groupMembersList.Select( m => new
                    {
                        m.Id,
                        m.Guid,
                        m.PersonId,
                        Name = m.Person.NickName + " " + m.Person.LastName
                            + ( hasGroupRequirements && groupMemberIdsThatLackGroupRequirements.Contains( m.Id )
                                ? " <i class='fa fa-exclamation-triangle text-warning'></i>"
                                : string.Empty )
                            + ( !string.IsNullOrEmpty( m.Note )
                            ? " <i class='fa fa-file-text-o text-info'></i>"
                            : string.Empty ),
                        GroupRole = m.GroupRole.Name,
                        m.GroupMemberStatus,
                        RecordStatusValueId = m.Person.RecordStatusValueId,
                        IsDeceased = m.Person.IsDeceased
                    } ).ToList();

                    gGroupMembers.DataBind();
                }
                else
                {
                    nbRoleWarning.Text = string.Format(
                        "{0} cannot be added to this {1} because the '{2}' group type does not have any roles defined.",
                        _group.GroupType.GroupMemberTerm.Pluralize(),
                        _group.GroupType.GroupTerm,
                        _group.GroupType.Name );

                    nbRoleWarning.Visible = true;
                    rFilter.Visible = false;
                    gGroupMembers.Visible = false;
                }
            }
            else
            {
                pnlGroupMembers.Visible = false;
            }
        }
        /// <summary>
        /// Binds the event calendar items grid.
        /// </summary>
        protected void BindEventCalendarItemsGrid()
        {
            if ( _eventCalendar != null )
            {
                pnlEventCalendarItems.Visible = true;

                var rockContext = new RockContext();

                EventCalendarItemService eventCalendarItemService = new EventCalendarItemService( rockContext );
                var qry = eventCalendarItemService
                    .Queryable( "EventCalendar,EventItem.EventItemAudiences,EventItem.EventItemOccurrences.Schedule" )
                    .Where( m =>
                        m.EventItem != null &&
                        m.EventCalendarId == _eventCalendar.Id );

                // Filter by Status
                string statusFilter = ddlStatus.SelectedValue;
                if ( statusFilter == "Active" )
                {
                    qry = qry
                        .Where( m => m.EventItem.IsActive );
                }
                else if ( statusFilter == "Inactive" )
                {
                    qry = qry
                        .Where( m => !m.EventItem.IsActive );
                }

                // Filter by Approval Status
                string approvalStatusFilter = ddlApprovalStatus.SelectedValue;
                if ( approvalStatusFilter == "Approved" )
                {
                    qry = qry
                        .Where( m => m.EventItem.IsApproved );
                }
                else if ( approvalStatusFilter == "Not Approved" )
                {
                    qry = qry
                        .Where( m => !m.EventItem.IsApproved );
                }

                // Filter by Campus
                List<int> campusIds = cblCampus.SelectedValuesAsInt;
                if ( campusIds.Any() )
                {
                    qry = qry
                        .Where( i =>
                            i.EventItem.EventItemOccurrences
                                .Any( c =>
                                    !c.CampusId.HasValue ||
                                    campusIds.Contains( c.CampusId.Value ) ) );
                }

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

                    foreach ( var attribute in AvailableAttributes )
                    {
                        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 );

                                qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }

                // Filter by Audience
                List<int> audiences = cblAudience.SelectedValuesAsInt;
                if ( audiences.Any() )
                {
                    qry = qry.Where( i => i.EventItem.EventItemAudiences
                        .Any( c => audiences.Contains( c.DefinedValueId ) ) );
                }

                SortProperty sortProperty = gEventCalendarItems.SortProperty;

                // Sort and query db
                List<EventCalendarItem> eventCalendarItems = null;
                if ( sortProperty != null )
                {
                    // If sorting on date, wait until after checking to see if date range was specified
                    if ( sortProperty.Property == "Date" )
                    {
                        eventCalendarItems = qry.ToList();
                    }
                    else
                    {
                        eventCalendarItems = qry.Sort( sortProperty ).ToList();
                    }
                }
                else
                {
                    eventCalendarItems = qry.OrderBy( a => a.EventItem.Name ).ToList();
                }

                // Now that items have been loaded and ordered from db, calculate the next start date for each item
                var calendarItemsWithDates = eventCalendarItems
                    .Select( i => new EventCalendarItemWithDates
                    {
                        EventCalendarItem = i,
                        NextStartDateTime = i.EventItem.NextStartDateTime,
                    } )
                    .ToList();

                var dateCol = gEventCalendarItems.Columns.OfType<BoundField>().Where( c => c.DataField == "Date" ).FirstOrDefault();

                // if a date range was specified, need to get all dates for items and filter based on any that have an occurrence withing the date range
                DateTime? lowerDateRange = drpDate.LowerValue;
                DateTime? upperDateRange = drpDate.UpperValue;
                if ( lowerDateRange.HasValue || upperDateRange.HasValue )
                {
                    // If only one value was included, default the other to be a years difference
                    lowerDateRange = lowerDateRange ?? upperDateRange.Value.AddYears( -1 ).AddDays( 1 );
                    upperDateRange = upperDateRange ?? lowerDateRange.Value.AddYears( 1 ).AddDays( -1 );

                    // Get the start datetimes within the selected date range
                    calendarItemsWithDates.ForEach( i => i.StartDateTimes = i.EventCalendarItem.EventItem.GetStartTimes( lowerDateRange.Value, upperDateRange.Value.AddDays( 1 ) ) );

                    // Filter out calendar items with no dates within range
                    calendarItemsWithDates = calendarItemsWithDates.Where( i => i.StartDateTimes.Any() ).ToList();

                    // Update the Next Start Date to be the next date in range instead
                    dateCol.HeaderText = "Next Date In Range";
                    calendarItemsWithDates.ForEach( i => i.NextStartDateTime = i.StartDateTimes.Min() );
                }
                else
                {
                    dateCol.HeaderText = "Next Start Date";
                }

                // Now sort on date if that is what was selected
                if ( sortProperty != null && sortProperty.Property == "Date" )
                {
                    if ( sortProperty.Direction == SortDirection.Ascending )
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderBy( a => a.NextStartDateTime ).ToList();
                    }
                    else
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderByDescending( a => a.NextStartDateTime ).ToList();
                    }
                }

                // Save the calendar items to the grid's objectlist
                gEventCalendarItems.ObjectList = new Dictionary<string, object>();
                calendarItemsWithDates.ForEach( i => gEventCalendarItems.ObjectList.Add( i.EventCalendarItem.EventItem.Id.ToString(), i.EventCalendarItem ) );
                gEventCalendarItems.EntityTypeId = EntityTypeCache.Read( "Rock.Model.EventCalendarItem" ).Id;

                gEventCalendarItems.DataSource = calendarItemsWithDates.Select( i => new
                {
                    Id = i.EventCalendarItem.EventItem.Id,
                    Guid = i.EventCalendarItem.EventItem.Guid,
                    Date = i.NextStartDateTime.HasValue ? i.NextStartDateTime.Value.ToShortDateString() : "N/A",
                    Name = i.EventCalendarItem.EventItem.Name,
                    Occurrences = campusIds.Any() ?
                        i.EventCalendarItem.EventItem.EventItemOccurrences.Where( c => !c.CampusId.HasValue || campusIds.Contains( c.CampusId.Value ) ).Count() :
                        i.EventCalendarItem.EventItem.EventItemOccurrences.Count(),
                    Calendar = i.EventCalendarItem.EventItem.EventCalendarItems.ToList().Select( c => c.EventCalendar.Name ).ToList().AsDelimited( "<br>" ),
                    Audience = i.EventCalendarItem.EventItem.EventItemAudiences.ToList().Select( a => a.DefinedValue.Value ).ToList().AsDelimited( "<br>" ),
                    Status = i.EventCalendarItem.EventItem.IsActive ? "<span class='label label-success'>Active</span>" : "<span class='label label-default'>Inactive</span>",
                    ApprovalStatus = i.EventCalendarItem.EventItem.IsApproved ? "<span class='label label-info'>Approved</span>" : "<span class='label label-warning'>Not Approved</span>"
                } ).ToList();

                gEventCalendarItems.DataBind();
            }
            else
            {
                pnlEventCalendarItems.Visible = false;
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            if ( _workflowType != null )
            {
                pnlWorkflowList.Visible = true;

                if ( _workflowType != null )
                {
                    var rockContext = new RockContext();
                    var workflowService = new WorkflowService( rockContext );

                    var qry = workflowService
                        .Queryable( "Activities.ActivityType,InitiatorPersonAlias.Person" ).AsNoTracking()
                        .Where( w => w.WorkflowTypeId.Equals( _workflowType.Id ) );

                    // Activated Date Range Filter
                    if ( drpActivated.LowerValue.HasValue )
                    {
                        qry = qry.Where( w => w.ActivatedDateTime >= drpActivated.LowerValue.Value );
                    }
                    if ( drpActivated.UpperValue.HasValue )
                    {
                        DateTime upperDate = drpActivated.UpperValue.Value.Date.AddDays( 1 );
                        qry = qry.Where( w => w.ActivatedDateTime.Value < upperDate );
                    }

                    // State Filter
                    List<string> states = cblState.SelectedValues;
                    if ( states.Count == 1 )    // Don't filter if none or both options are selected
                    {
                        if ( states[0] == "Active" )
                        {
                            qry = qry.Where( w => !w.CompletedDateTime.HasValue );
                        }
                        else
                        {
                            qry = qry.Where( w => w.CompletedDateTime.HasValue );
                        }
                    }

                    // Completed Date Range Filter
                    if ( drpCompleted.LowerValue.HasValue )
                    {
                        qry = qry.Where( w => w.CompletedDateTime.HasValue && w.CompletedDateTime.Value >= drpCompleted.LowerValue.Value );
                    }
                    if ( drpCompleted.UpperValue.HasValue )
                    {
                        DateTime upperDate = drpCompleted.UpperValue.Value.Date.AddDays( 1 );
                        qry = qry.Where( w => w.CompletedDateTime.HasValue && w.CompletedDateTime.Value < upperDate );
                    }

                    string name = tbName.Text;
                    if ( !string.IsNullOrWhiteSpace( name ) )
                    {
                        qry = qry.Where( w => w.Name.StartsWith( name ) );
                    }

                    int? personId = ppInitiator.SelectedValue;
                    if ( personId.HasValue )
                    {
                        qry = qry.Where( w => w.InitiatorPersonAlias.PersonId == personId.Value );
                    }

                    string status = tbStatus.Text;
                    if ( !string.IsNullOrWhiteSpace( status ) )
                    {
                        qry = qry.Where( w => w.Status.StartsWith( status ) );
                    }

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

                        foreach ( var attribute in AvailableAttributes )
                        {
                            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 );

                                    qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                                }
                            }
                        }
                    }

                    IQueryable<Workflow> workflows = null;

                    var sortProperty = gWorkflows.SortProperty;
                    if ( sortProperty != null )
                    {
                        if ( sortProperty.Property == "Initiator" )
                        {
                            if ( sortProperty.Direction == SortDirection.Ascending )
                            {
                                workflows = qry
                                    .OrderBy( w => w.InitiatorPersonAlias.Person.LastName )
                                    .ThenBy( w => w.InitiatorPersonAlias.Person.NickName );
                            }
                            else
                            {
                                workflows = qry
                                    .OrderByDescending( w => w.InitiatorPersonAlias.Person.LastName )
                                    .ThenByDescending( w => w.InitiatorPersonAlias.Person.NickName );
                            }
                        }
                        else
                        {
                            workflows = qry.Sort( sortProperty );
                        }
                    }
                    else
                    {
                        workflows = qry.OrderByDescending( s => s.CreatedDateTime );
                    }

                    // Since we're not binding to actual workflow list, but are using AttributeField columns,
                    // we need to save the workflows into the grid's object list
                    var workflowObjectQry = workflows;
                    if ( gWorkflows.AllowPaging )
                    {
                        workflowObjectQry = workflowObjectQry.Skip( gWorkflows.PageIndex * gWorkflows.PageSize ).Take( gWorkflows.PageSize );
                    }

                    gWorkflows.ObjectList = workflowObjectQry.ToList().ToDictionary( k => k.Id.ToString(), v => v as object );

                    gWorkflows.EntityTypeId = EntityTypeCache.Read<Workflow>().Id;
                    var qryGrid = workflows.Select( w => new
                    {
                        w.Id,
                        w.Name,
                        Initiator = w.InitiatorPersonAlias.Person,
                        Activities = w.Activities.Where( a => a.ActivatedDateTime.HasValue && !a.CompletedDateTime.HasValue ).OrderBy( a => a.ActivityType.Order ).Select( a => a.ActivityType.Name ),
                        w.CreatedDateTime,
                        Status = w.Status,
                        IsCompleted = w.CompletedDateTime.HasValue
                    } );

                    gWorkflows.SetLinqDataSource( qryGrid );
                    gWorkflows.DataBind();
                }
                else
                {
                    pnlWorkflowList.Visible = false;
                }
            }
        }
Exemple #28
0
        /// <summary>
        /// Builds an expression for an attribute field
        /// </summary>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="property">The property.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public Expression GetAttributeExpression( IService serviceInstance, ParameterExpression parameterExpression, EntityField property, List<string> values )
        {
            IEnumerable<int> ids = null;

            ComparisonType comparisonType = ComparisonType.EqualTo;

            var service = new AttributeValueService( (RockContext)serviceInstance.Context );
            var attributeValues = service.Queryable().Where( v =>
                v.Attribute.Guid == property.AttributeGuid &&
                v.EntityId.HasValue &&
                v.Value != string.Empty ).ToList();

            switch ( property.FilterFieldType )
            {
                case SystemGuid.FieldType.DATE:

                    if ( values.Count == 2 )
                    {
                        comparisonType = values[0].ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );

                        if ( !( ComparisonType.IsBlank | ComparisonType.IsNotBlank ).HasFlag( comparisonType ) )
                        {
                            DateTime dateValue = values[1].AsDateTime() ?? DateTime.MinValue;
                            switch ( comparisonType )
                            {
                                case ComparisonType.EqualTo:
                                case ComparisonType.NotEqualTo:
                                    ids = attributeValues.Where( v => dateValue.CompareTo( Convert.ToDateTime( v.Value ) ) == 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThan:
                                    ids = attributeValues.Where( v => dateValue.CompareTo( Convert.ToDateTime( v.Value ) ) <= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThanOrEqualTo:
                                    ids = attributeValues.Where( v => dateValue.CompareTo( Convert.ToDateTime( v.Value ) ) < 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThan:
                                    ids = attributeValues.Where( v => dateValue.CompareTo( Convert.ToDateTime( v.Value ) ) >= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThanOrEqualTo:
                                    ids = attributeValues.Where( v => dateValue.CompareTo( Convert.ToDateTime( v.Value ) ) > 0 ).Select( v => v.EntityId.Value );
                                    break;
                            }
                        }
                        else
                        {
                            ids = attributeValues.Select( v => v.EntityId.Value );
                        }
                    }

                    break;

                case SystemGuid.FieldType.TIME:

                    if ( values.Count == 2 )
                    {
                        comparisonType = values[0].ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );

                        if ( !( ComparisonType.IsBlank | ComparisonType.IsNotBlank ).HasFlag( comparisonType ) )
                        {
                            TimeSpan timeValue = values[1].AsTimeSpan() ?? TimeSpan.MinValue;
                            switch ( comparisonType )
                            {
                                case ComparisonType.EqualTo:
                                case ComparisonType.NotEqualTo:
                                    ids = attributeValues.Where( v => timeValue.CompareTo( v.Value.AsTimeSpan() ) == 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThan:
                                    ids = attributeValues.Where( v => timeValue.CompareTo( v.Value.AsTimeSpan() ) <= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThanOrEqualTo:
                                    ids = attributeValues.Where( v => timeValue.CompareTo( v.Value.AsTimeSpan() ) < 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThan:
                                    ids = attributeValues.Where( v => timeValue.CompareTo( v.Value.AsTimeSpan() ) >= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThanOrEqualTo:
                                    ids = attributeValues.Where( v => timeValue.CompareTo( v.Value.AsTimeSpan() ) > 0 ).Select( v => v.EntityId.Value );
                                    break;
                            }
                        }
                        else
                        {
                            ids = attributeValues.Select( v => v.EntityId.Value );
                        }
                    }

                    break;
                
                case SystemGuid.FieldType.DECIMAL:
                case SystemGuid.FieldType.INTEGER:

                    if ( values.Count == 2 )
                    {
                        comparisonType = values[0].ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );

                        if ( !( ComparisonType.IsBlank | ComparisonType.IsNotBlank ).HasFlag( comparisonType ) )
                        {
                            double numericValue = values[1].AsDoubleOrNull() ?? int.MinValue;
                            switch ( comparisonType )
                            {
                                case ComparisonType.EqualTo:
                                case ComparisonType.NotEqualTo:
                                    ids = attributeValues.Where( v => numericValue.CompareTo( v.Value.AsDouble() ) == 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThan:
                                    ids = attributeValues.Where( v => numericValue.CompareTo( v.Value.AsDouble() ) <= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.GreaterThanOrEqualTo:
                                    ids = attributeValues.Where( v => numericValue.CompareTo( v.Value.AsDouble() ) < 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThan:
                                    ids = attributeValues.Where( v => numericValue.CompareTo( v.Value.AsDouble() ) >= 0 ).Select( v => v.EntityId.Value );
                                    break;
                                case ComparisonType.LessThanOrEqualTo:
                                    ids = attributeValues.Where( v => numericValue.CompareTo( v.Value.AsDouble() ) > 0 ).Select( v => v.EntityId.Value );
                                    break;
                            }
                        }
                        else
                        {
                            ids = attributeValues.Select( v => v.EntityId.Value );
                        }
                    }

                    break;

                case SystemGuid.FieldType.TEXT:

                    if ( values.Count == 2 )
                    {
                        comparisonType = values[0].ConvertToEnum<ComparisonType>( ComparisonType.EqualTo );

                        switch ( comparisonType )
                        {
                            case ComparisonType.Contains:
                            case ComparisonType.DoesNotContain:
                                ids = attributeValues.Where( v => v.Value.ToUpper().Contains( values[1].ToUpper() ) ).Select( v => v.EntityId.Value );
                                break;
                            case ComparisonType.EqualTo:
                            case ComparisonType.NotEqualTo:
                                ids = attributeValues.Where( v => v.Value.Equals( values[1], StringComparison.CurrentCultureIgnoreCase ) ).Select( v => v.EntityId.Value );
                                break;
                            case ComparisonType.IsBlank:
                            case ComparisonType.IsNotBlank:
                                ids = attributeValues.Select( v => v.EntityId.Value );
                                break;
                            case ComparisonType.StartsWith:
                                ids = attributeValues.Where( v => v.Value.StartsWith( values[1], StringComparison.CurrentCultureIgnoreCase ) ).Select( v => v.EntityId.Value );
                                break;
                            case ComparisonType.EndsWith:
                                ids = attributeValues.Where( v => v.Value.EndsWith( values[1], StringComparison.CurrentCultureIgnoreCase ) ).Select( v => v.EntityId.Value );
                                break;
                        }
                    }

                    break;

                case SystemGuid.FieldType.DAY_OF_WEEK:
                case SystemGuid.FieldType.SINGLE_SELECT:

                    if ( values.Count == 1 )
                    {
                        ids = attributeValues.Where( v => v.Value == values[0] ).Select( v => v.EntityId.Value );
                    }

                    break;

                case SystemGuid.FieldType.MULTI_SELECT:

                    if ( values.Count == 1 )
                    {
                        List<string> selectedValues = JsonConvert.DeserializeObject<List<string>>( values[0] );
                        ids = attributeValues.Where( v => selectedValues.Contains( v.Value ) ).Select( v => v.EntityId.Value );
                    }

                    break;
            }

            if ( ids != null )
            {
                MemberExpression propertyExpression = Expression.Property( parameterExpression, "Id" );
                ConstantExpression idsExpression = Expression.Constant( ids.AsQueryable(), typeof( IQueryable<int> ) );
                Expression expression = Expression.Call( typeof( Queryable ), "Contains", new Type[] { typeof( int ) }, idsExpression, propertyExpression );
                if ( comparisonType == ComparisonType.NotEqualTo ||
                    comparisonType == ComparisonType.DoesNotContain ||
                    comparisonType == ComparisonType.IsBlank )
                {
                    return Expression.Not( expression );
                }
                else
                {
                    return expression;
                }
            }

            return null;
        }
        /// <summary>
        /// Binds the event calendar items grid.
        /// </summary>
        protected void BindConnectionOpportunitiesGrid()
        {
            if ( _connectionType != null )
            {
                pnlConnectionOpportunities.Visible = true;

                rFilter.Visible = true;
                gConnectionOpportunities.Visible = true;

                var rockContext = new RockContext();

                ConnectionOpportunityService connectionOpportunityService = new ConnectionOpportunityService( rockContext );
                var qry = connectionOpportunityService.Queryable()
                    .Where( o => o.ConnectionTypeId == _connectionType.Id );

                // Filter by Active Only
                if ( cbActive.Checked )
                {
                    qry = qry.Where( o => o.IsActive );
                }

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

                    foreach ( var attribute in AvailableAttributes )
                    {
                        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 );

                                qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }
                SortProperty sortProperty = gConnectionOpportunities.SortProperty;

                List<ConnectionOpportunity> connectionOpportunities = null;
                if ( sortProperty != null )
                {
                    connectionOpportunities = qry.Sort( sortProperty ).ToList();
                }
                else
                {
                    connectionOpportunities = qry.ToList().OrderBy( a => a.Name ).ToList();
                }

                gConnectionOpportunities.DataSource = connectionOpportunities;
                gConnectionOpportunities.DataBind();
            }
            else
            {
                pnlConnectionOpportunities.Visible = false;
            }
        }
Exemple #30
0
        /// <summary>
        /// Loads the <see cref="P:IHasAttributes.Attributes" /> and <see cref="P:IHasAttributes.AttributeValues" /> of any <see cref="IHasAttributes" /> object
        /// </summary>
        /// <param name="entity">The item.</param>
        /// <param name="rockContext">The rock context.</param>
        public static void LoadAttributes( Rock.Attribute.IHasAttributes entity, RockContext rockContext )
        {
            if ( entity != null )
            {
                Dictionary<string, PropertyInfo> properties = new Dictionary<string, PropertyInfo>();

                Type entityType = entity.GetType();
                if ( entityType.IsDynamicProxyType() )
                {
                    entityType = entityType.BaseType;
                }

                rockContext = rockContext ?? new RockContext();

                // Event item's will load attributes for child calendar items. Use this to store the child values.
                var altEntityIds = new List<int>();

                // Check for group type attributes
                var groupTypeIds = new List<int>();
                if ( entity is GroupMember || entity is Group || entity is GroupType )
                {
                    // Can't use GroupTypeCache here since it loads attributes and would result in a recursive stack overflow situation
                    var groupTypeService = new GroupTypeService( rockContext );
                    GroupType groupType = null;

                    if ( entity is GroupMember )
                    {
                        var group = ( (GroupMember)entity ).Group ?? new GroupService( rockContext )
                            .Queryable().AsNoTracking().FirstOrDefault(g => g.Id == ( (GroupMember)entity ).GroupId );
                        if ( group != null )
                        {
                            groupType = group.GroupType ?? groupTypeService
                                .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == group.GroupTypeId );
                        }
                    }
                    else if ( entity is Group )
                    {
                        groupType = ( (Group)entity ).GroupType ?? groupTypeService
                            .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( (Group)entity ).GroupTypeId );
                    }
                    else
                    {
                        groupType = ( (GroupType)entity );
                    }

                    while ( groupType != null )
                    {
                        groupTypeIds.Insert( 0, groupType.Id );

                        // Check for inherited group type id's
                        if ( groupType.InheritedGroupTypeId.HasValue )
                        {
                            groupType = groupType.InheritedGroupType ?? groupTypeService
                                .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( groupType.InheritedGroupTypeId ?? 0 ) );
                        }
                        else
                        {
                            groupType = null;
                        }
                    }

                }

                // Check for registration template type attributes
                int? registrationTemplateId = null;
                if ( entity is RegistrationRegistrant )
                {
                    RegistrationInstance registrationInstance = null;
                    var registration = ( (RegistrationRegistrant)entity ).Registration ?? new RegistrationService( rockContext )
                        .Queryable().AsNoTracking().FirstOrDefault( r => r.Id == ( (RegistrationRegistrant)entity ).RegistrationId );
                    if ( registration != null )
                    {
                        registrationInstance = registration.RegistrationInstance ?? new RegistrationInstanceService( rockContext )
                            .Queryable().AsNoTracking().FirstOrDefault( r => r.Id == registration.RegistrationInstanceId );
                        if ( registrationInstance != null )
                        {
                            registrationTemplateId = registrationInstance.RegistrationTemplateId;
                        }
                    }
                }

                // Get the calendar ids for any event items
                var calendarIds = new List<int>();
                if ( entity is EventItem )
                {
                    var calendarItems = ( (EventItem)entity ).EventCalendarItems.ToList() ?? new EventCalendarItemService( rockContext )
                        .Queryable().AsNoTracking().Where( c => c.EventItemId == ( (EventItem)entity ).Id ).ToList();
                    calendarIds = calendarItems.Select( c => c.EventCalendarId ).ToList();
                    altEntityIds = calendarItems.Select( c => c.Id ).ToList();
                }

                foreach ( PropertyInfo propertyInfo in entityType.GetProperties() )
                    properties.Add( propertyInfo.Name.ToLower(), propertyInfo );

                Rock.Model.AttributeService attributeService = new Rock.Model.AttributeService( rockContext );
                Rock.Model.AttributeValueService attributeValueService = new Rock.Model.AttributeValueService( rockContext );

                var inheritedAttributes = new Dictionary<int, List<Rock.Web.Cache.AttributeCache>>();
                if ( groupTypeIds.Any() )
                {
                    groupTypeIds.ForEach( g => inheritedAttributes.Add( g, new List<Rock.Web.Cache.AttributeCache>() ) );
                }
                else if ( calendarIds.Any() )
                {
                    calendarIds.ForEach( c => inheritedAttributes.Add( c, new List<Rock.Web.Cache.AttributeCache>() ) );
                }
                else
                {
                    inheritedAttributes.Add( 0, new List<Rock.Web.Cache.AttributeCache>() );
                }

                // Check for any calendar item attributes that event item inherits
                if ( calendarIds.Any() )
                {
                    var calendarItemEntityType = EntityTypeCache.Read( typeof( EventCalendarItem ) );
                    if ( calendarItemEntityType != null )
                    {
                        foreach ( var calendarItemEntityAttributes in AttributeCache
                            .GetByEntity( calendarItemEntityType.Id )
                            .Where( a =>
                                a.EntityTypeQualifierColumn == "EventCalendarId" &&
                                calendarIds.Contains( a.EntityTypeQualifierValue.AsInteger() ) ) )
                        {
                            foreach ( var attributeId in calendarItemEntityAttributes.AttributeIds )
                            {
                                inheritedAttributes[calendarItemEntityAttributes.EntityTypeQualifierValue.AsInteger()].Add(
                                    AttributeCache.Read( attributeId ) );
                            }
                        }
                    }
                }

                var attributes = new List<Rock.Web.Cache.AttributeCache>();

                // Get all the attributes that apply to this entity type and this entity's properties match any attribute qualifiers
                var entityTypeCache = Rock.Web.Cache.EntityTypeCache.Read( entityType);
                if ( entityTypeCache != null )
                {
                    int entityTypeId = entityTypeCache.Id;
                    foreach ( var entityAttributes in AttributeCache.GetByEntity( entityTypeCache.Id ) )
                    {
                        // group type ids exist (entity is either GroupMember, Group, or GroupType) and qualifier is for a group type id
                        if ( groupTypeIds.Any() && (
                                ( entity is GroupMember && string.Compare( entityAttributes.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) ||
                                ( entity is Group && string.Compare( entityAttributes.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) ||
                                ( entity is GroupType && string.Compare( entityAttributes.EntityTypeQualifierColumn, "Id", true ) == 0 ) ) )
                        {
                            int groupTypeIdValue = int.MinValue;
                            if ( int.TryParse( entityAttributes.EntityTypeQualifierValue, out groupTypeIdValue ) && groupTypeIds.Contains( groupTypeIdValue ) )
                            {
                                foreach( int attributeId in entityAttributes.AttributeIds )
                                {
                                    inheritedAttributes[groupTypeIdValue].Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) );
                                }
                            }
                        }

                        // Registrant attribute ( by RegistrationTemplateId )
                        else if ( entity is RegistrationRegistrant &&
                            registrationTemplateId.HasValue &&
                            entityAttributes.EntityTypeQualifierValue.AsInteger() == registrationTemplateId.Value )
                        {
                            foreach ( int attributeId in entityAttributes.AttributeIds )
                            {
                                attributes.Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) );
                            }
                        }

                        else if ( string.IsNullOrEmpty( entityAttributes.EntityTypeQualifierColumn ) ||
                            ( properties.ContainsKey( entityAttributes.EntityTypeQualifierColumn.ToLower() ) &&
                            ( string.IsNullOrEmpty( entityAttributes.EntityTypeQualifierValue ) ||
                            ( properties[entityAttributes.EntityTypeQualifierColumn.ToLower()].GetValue( entity, null ) ?? "" ).ToString() == entityAttributes.EntityTypeQualifierValue ) ) )
                        {
                            foreach( int attributeId in entityAttributes.AttributeIds )
                            {
                                attributes.Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) );
                            }
                        }
                    }
                }

                var allAttributes = new List<Rock.Web.Cache.AttributeCache>();

                foreach ( var attributeGroup in inheritedAttributes )
                {
                    foreach ( var attribute in attributeGroup.Value )
                    {
                        allAttributes.Add( attribute );
                    }
                }
                foreach ( var attribute in attributes )
                {
                    allAttributes.Add( attribute );
                }

                var attributeValues = new Dictionary<string, AttributeValueCache>();

                if ( allAttributes.Any() )
                {
                    foreach ( var attribute in allAttributes )
                    {
                        // Add a placeholder for this item's value for each attribute
                        attributeValues.AddOrIgnore( attribute.Key, null );
                    }

                    // If loading attributes for a saved item, read the item's value(s) for each attribute
                    if ( !entityTypeCache.IsEntity || entity.Id != 0 )
                    {
                        List<int> attributeIds = allAttributes.Select( a => a.Id ).ToList();
                        foreach ( var attributeValue in attributeValueService.Queryable().AsNoTracking()
                            .Where( v =>
                                v.EntityId.HasValue &&
                                ( v.EntityId.Value == entity.Id || altEntityIds.Contains( v.EntityId.Value ) )
                                && attributeIds.Contains( v.AttributeId ) ) )
                        {
                            var attributeKey = AttributeCache.Read( attributeValue.AttributeId ).Key;
                            attributeValues[attributeKey] = new AttributeValueCache( attributeValue );
                        }
                    }

                    // Look for any attributes that don't have a value and create a default value entry
                    foreach ( var attribute in allAttributes )
                    {
                        if ( attributeValues[attribute.Key] == null )
                        {
                            var attributeValue = new AttributeValueCache();
                            attributeValue.AttributeId = attribute.Id;
                            if ( entity.AttributeValueDefaults != null && entity.AttributeValueDefaults.ContainsKey( attribute.Name ) )
                            {
                                attributeValue.Value = entity.AttributeValueDefaults[attribute.Name];
                            }
                            else
                            {
                                attributeValue.Value = attribute.DefaultValue;
                            }
                            attributeValues[attribute.Key] = attributeValue;
                        }
                        else
                        {
                            if ( !String.IsNullOrWhiteSpace( attribute.DefaultValue ) &&
                                String.IsNullOrWhiteSpace( attributeValues[attribute.Key].Value ) )
                            {
                                attributeValues[attribute.Key].Value = attribute.DefaultValue;
                            }
                        }
                    }
                }

                entity.Attributes = new Dictionary<string, Web.Cache.AttributeCache>();
                allAttributes.ForEach( a => entity.Attributes.AddOrIgnore( a.Key, a ) );

                entity.AttributeValues = attributeValues;
            }
        }