/// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            var kciSmallGroupGuid = SystemGuid.GroupType.CELL_GROUP.AsGuid();
            // TODO Change
            var attributeId = 1;

            var leaderAttributes = new AttributeValueService(context)
                                   .Queryable()
                                   .Where(av => av.AttributeId == attributeId);

            var personService = new PersonService(context).Queryable();

            var lineLeaderQuery = new PersonService(context)
                                  .Queryable()
                                  .Select(p => leaderAttributes
                                          .Where(a => a.EntityId == p.Id)
                                          .Select(a => personService
                                                  .AsQueryable()
                                                  .FirstOrDefault(q => q.Id == a.ValueAsPersonId)
                                                  .FullName
                                                  )
                                          );

            var selectLineLeaderExpression = SelectExpressionExtractor.Extract(lineLeaderQuery, entityIdProperty, "p");

            return(selectLineLeaderExpression);
        }
示例#2
0
        /// <summary>
        /// Gets the services.
        /// </summary>
        /// <returns></returns>
        private List <Schedule> GetServices(CampusCache campus = null)
        {
            var services = new List <Schedule>();

            if (!string.IsNullOrWhiteSpace(GetAttributeValue("ScheduleCategories")))
            {
                List <Guid> categoryGuids       = GetAttributeValue("ScheduleCategories").Split(',').Select(g => g.AsGuid()).ToList();
                string      campusAttributeGuid = GetAttributeValue("CampusAttribute");

                DateTime?weekend = bddlWeekend.SelectedValue.AsDateTime();
                using (var rockContext = new RockContext())
                {
                    var attributeValueQry = new AttributeValueService(rockContext).Queryable();
                    foreach (Guid categoryGuid in categoryGuids)
                    {
                        var scheduleCategory = CategoryCache.Read(categoryGuid);
                        if (scheduleCategory != null && campus != null)
                        {
                            var schedules = new ScheduleService(rockContext)
                                            .Queryable().AsNoTracking()
                                            .Where(s => s.CategoryId == scheduleCategory.Id)
                                            .Join(
                                attributeValueQry.Where(av => av.Attribute.Guid.ToString() == campusAttributeGuid &&
                                                        av.Value.Contains(campus.Guid.ToString())),
                                p => p.Id,
                                av => av.EntityId,
                                (p, av) => new { Schedule = p, Value = av.Value });
                            // Check to see if the event was applicable the week for which we are entering data
                            foreach (var schedule in schedules)
                            {
                                var occurrences = ScheduleICalHelper.GetOccurrences(schedule.Schedule.GetCalenderEvent(), weekend.Value.Date.AddDays(-6), weekend.Value.Date.AddDays(1));
                                if (occurrences.Count > 0)
                                {
                                    services.Add(schedule.Schedule);
                                }
                            }
                        }
                        else if (scheduleCategory != null)
                        {
                            foreach (var schedule in new ScheduleService(rockContext)
                                     .Queryable().AsNoTracking()
                                     .Where(s =>
                                            s.CategoryId.HasValue &&
                                            s.CategoryId.Value == scheduleCategory.Id)
                                     .OrderBy(s => s.Name))
                            {
                                services.Add(schedule);
                            }
                        }
                    }
                }
            }
            return(services.OrderBy(s => s.NextStartDateTime.HasValue?s.NextStartDateTime.Value.Ticks : s.EffectiveEndDate.HasValue?s.EffectiveEndDate.Value.Ticks: 0).ToList());
        }
示例#3
0
        private void Map()
        {
            string mapStylingFormat = @"
                        <style>
                            #map_wrapper {{
                                height: {0}px;
                            }}

                            #map_canvas {{
                                width: 100%;
                                height: 100%;
                                border-radius: var(--border-radius-base);
                            }}
                        </style>";

            lMapStyling.Text = string.Format(mapStylingFormat, GetAttributeValue("MapHeight"));

            string settingGroupTypeId     = GetAttributeValue("GroupType");
            string queryStringGroupTypeId = PageParameter("GroupTypeId");

            if ((string.IsNullOrWhiteSpace(settingGroupTypeId) && string.IsNullOrWhiteSpace(queryStringGroupTypeId)))
            {
                pnlMap.Visible = false;
                lMessages.Text = "<div class='alert alert-warning'><strong>Group Mapper</strong> Please configure a group type to display as a block setting or pass a GroupTypeId as a query parameter.</div>";
            }
            else
            {
                var rockContext = new RockContext();

                pnlMap.Visible = true;

                int groupsMapped    = 0;
                int groupsWithNoGeo = 0;

                StringBuilder sbGroupJson       = new StringBuilder();
                StringBuilder sbGroupsWithNoGeo = new StringBuilder();

                Guid?groupType   = null;
                int  groupTypeId = -1;

                if (!string.IsNullOrWhiteSpace(settingGroupTypeId))
                {
                    groupType = new Guid(settingGroupTypeId);
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(queryStringGroupTypeId) && Int32.TryParse(queryStringGroupTypeId, out groupTypeId))
                    {
                        groupType = new GroupTypeService(rockContext).Get(groupTypeId).Guid;
                    }
                }

                if (groupType != null)
                {
                    Template      template     = null;
                    ILavaTemplate lavaTemplate = null;

                    if (LavaService.RockLiquidIsEnabled)
                    {
                        if (GetAttributeValue("ShowMapInfoWindow").AsBoolean())
                        {
                            template = Template.Parse(GetAttributeValue("InfoWindowContents").Trim());

                            LavaHelper.VerifyParseTemplateForCurrentEngine(GetAttributeValue("InfoWindowContents").Trim());
                        }
                        else
                        {
                            template = Template.Parse(string.Empty);
                        }
                    }
                    else
                    {
                        string templateContent;

                        if (GetAttributeValue("ShowMapInfoWindow").AsBoolean())
                        {
                            templateContent = GetAttributeValue("InfoWindowContents").Trim();
                        }
                        else
                        {
                            templateContent = string.Empty;
                        }

                        var parseResult = LavaService.ParseTemplate(templateContent);

                        lavaTemplate = parseResult.Template;
                    }

                    var groupPageRef = new PageReference(GetAttributeValue("GroupDetailPage"));

                    // create group detail link for use in map's info window
                    var personPageParams = new Dictionary <string, string>();
                    personPageParams.Add("PersonId", string.Empty);
                    var personProfilePage = LinkedPageUrl("PersonProfilePage", personPageParams);

                    var groupEntityType = EntityTypeCache.Get(typeof(Group));
                    var dynamicGroups   = new List <dynamic>();


                    // Create query to get attribute values for selected attribute keys.
                    var attributeKeys   = GetAttributeValue("Attributes").SplitDelimitedValues().ToList();
                    var attributeValues = new AttributeValueService(rockContext).Queryable("Attribute")
                                          .Where(v =>
                                                 v.Attribute.EntityTypeId == groupEntityType.Id &&
                                                 attributeKeys.Contains(v.Attribute.Key));

                    GroupService groupService = new GroupService(rockContext);
                    var          groups       = groupService.Queryable()
                                                .Where(g => g.GroupType.Guid == groupType)
                                                .Select(g => new
                    {
                        Group           = g,
                        GroupId         = g.Id,
                        GroupName       = g.Name,
                        GroupGuid       = g.Guid,
                        GroupMemberTerm = g.GroupType.GroupMemberTerm,
                        GroupCampus     = g.Campus.Name,
                        IsActive        = g.IsActive,
                        GroupLocation   = g.GroupLocations
                                          .Where(l => l.Location.GeoPoint != null)
                                          .Select(l => new
                        {
                            l.Location.Street1,
                            l.Location.Street2,
                            l.Location.City,
                            l.Location.State,
                            PostalCode = l.Location.PostalCode,
                            Latitude   = l.Location.GeoPoint.Latitude,
                            Longitude  = l.Location.GeoPoint.Longitude,
                            Name       = l.GroupLocationTypeValue.Value
                        }).FirstOrDefault(),
                        GroupMembers    = g.Members,
                        AttributeValues = attributeValues
                                          .Where(v => v.EntityId == g.Id)
                    });


                    if (GetAttributeValue("IncludeInactiveGroups").AsBoolean() == false)
                    {
                        groups = groups.Where(g => g.IsActive == true);
                    }

                    // Create dynamic object to include attribute values
                    foreach (var group in groups)
                    {
                        dynamic dynGroup = new ExpandoObject();
                        dynGroup.GroupId   = group.GroupId;
                        dynGroup.GroupName = group.GroupName;

                        // create group detail link for use in map's info window
                        if (groupPageRef.PageId > 0)
                        {
                            var groupPageParams = new Dictionary <string, string>();
                            groupPageParams.Add("GroupId", group.GroupId.ToString());
                            groupPageRef.Parameters  = groupPageParams;
                            dynGroup.GroupDetailPage = groupPageRef.BuildUrl();
                        }
                        else
                        {
                            dynGroup.GroupDetailPage = string.Empty;
                        }

                        dynGroup.PersonProfilePage = personProfilePage;
                        dynGroup.GroupMemberTerm   = group.GroupMemberTerm;
                        dynGroup.GroupCampus       = group.GroupCampus;
                        dynGroup.GroupLocation     = group.GroupLocation;

                        var groupAttributes = new List <dynamic>();
                        foreach (AttributeValue value in group.AttributeValues)
                        {
                            var attrCache     = AttributeCache.Get(value.AttributeId);
                            var dictAttribute = new Dictionary <string, object>();
                            dictAttribute.Add("Key", attrCache.Key);
                            dictAttribute.Add("Name", attrCache.Name);

                            if (attrCache != null)
                            {
                                dictAttribute.Add("Value", attrCache.FieldType.Field.FormatValueAsHtml(null, attrCache.EntityTypeId, group.GroupId, value.Value, attrCache.QualifierValues, false));
                            }
                            else
                            {
                                dictAttribute.Add("Value", value.Value);
                            }

                            groupAttributes.Add(dictAttribute);
                        }

                        dynGroup.Attributes = groupAttributes;

                        var groupMembers = new List <dynamic>();
                        foreach (GroupMember member in group.GroupMembers)
                        {
                            var dictMember = new Dictionary <string, object>();
                            dictMember.Add("Id", member.Person.Id);
                            dictMember.Add("GuidP", member.Person.Guid);
                            dictMember.Add("NickName", member.Person.NickName);
                            dictMember.Add("LastName", member.Person.LastName);
                            dictMember.Add("RoleName", member.GroupRole.Name);
                            dictMember.Add("Email", member.Person.Email);
                            dictMember.Add("PhotoGuid", member.Person.Photo != null ? member.Person.Photo.Guid : Guid.Empty);

                            var phoneTypes = new List <dynamic>();
                            foreach (PhoneNumber p in member.Person.PhoneNumbers)
                            {
                                var dictPhoneNumber = new Dictionary <string, object>();
                                dictPhoneNumber.Add("Name", p.NumberTypeValue.Value);
                                dictPhoneNumber.Add("Number", p.ToString());
                                phoneTypes.Add(dictPhoneNumber);
                            }

                            dictMember.Add("PhoneTypes", phoneTypes);

                            groupMembers.Add(dictMember);
                        }

                        dynGroup.GroupMembers = groupMembers;

                        dynamicGroups.Add(dynGroup);
                    }

                    foreach (var group in dynamicGroups)
                    {
                        if (group.GroupLocation != null && group.GroupLocation.Latitude != null)
                        {
                            groupsMapped++;
                            var groupDict = group as IDictionary <string, object>;

                            string infoWindow;

                            if (LavaService.RockLiquidIsEnabled)
                            {
                                infoWindow = template.Render(Hash.FromDictionary(groupDict)).Replace("\n", string.Empty);
                            }
                            else
                            {
                                var result = LavaService.RenderTemplate(lavaTemplate, groupDict);

                                infoWindow = result.Text;

                                if (!result.HasErrors)
                                {
                                    infoWindow = infoWindow.Replace("\n", string.Empty);
                                }
                            }

                            sbGroupJson.Append(string.Format(
                                                   @"{{ ""name"":""{0}"" , ""latitude"":""{1}"", ""longitude"":""{2}"", ""infowindow"":""{3}"" }},",
                                                   HttpUtility.HtmlEncode(group.GroupName),
                                                   group.GroupLocation.Latitude,
                                                   group.GroupLocation.Longitude,
                                                   HttpUtility.HtmlEncode(infoWindow)));
                        }
                        else
                        {
                            groupsWithNoGeo++;

                            if (!string.IsNullOrWhiteSpace(group.GroupDetailPage))
                            {
                                sbGroupsWithNoGeo.Append(string.Format(@"<li><a href='{0}'>{1}</a></li>", group.GroupDetailPage, group.GroupName));
                            }
                            else
                            {
                                sbGroupsWithNoGeo.Append(string.Format(@"<li>{0}</li>", group.GroupName));
                            }
                        }
                    }

                    string groupJson = sbGroupJson.ToString();

                    // remove last comma
                    if (groupJson.Length > 0)
                    {
                        groupJson = groupJson.Substring(0, groupJson.Length - 1);
                    }

                    // add styling to map
                    string styleCode   = "null";
                    string markerColor = "FE7569";

                    DefinedValueCache dvcMapStyle = DefinedValueCache.Get(GetAttributeValue("MapStyle").AsGuid());
                    if (dvcMapStyle != null)
                    {
                        styleCode = dvcMapStyle.GetAttributeValue("DynamicMapStyle");
                        var colors = dvcMapStyle.GetAttributeValue("Colors").Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                        if (colors.Any())
                        {
                            markerColor = colors.First().Replace("#", "");
                        }
                    }

                    // write script to page
                    string mapScriptFormat = @" <script>
                                                Sys.Application.add_load(function () {{
                                                    var groupData = JSON.parse('{{ ""groups"" : [ {0} ]}}');
                                                    var showInfoWindow = {1};
                                                    var mapStyle = {2};
                                                    var pinColor = '{3}';

                                                    var pinImage = {{
                                                        path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
                                                        fillColor: '#' + pinColor,
                                                        fillOpacity: 1,
                                                        strokeColor: '#000',
                                                        strokeWeight: 1,
                                                        scale: 1,
                                                        labelOrigin: new google.maps.Point(0,-28)
                                                    }};

                                                    initializeMap();

                                                    function initializeMap() {{
                                                        console.log(mapStyle);
                                                        var map;
                                                        var bounds = new google.maps.LatLngBounds();
                                                        var mapOptions = {{
                                                            mapTypeId: 'roadmap',
                                                            styles: mapStyle
                                                        }};

                                                        // Display a map on the page
                                                        map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
                                                        map.setTilt(45);

                                                        // Display multiple markers on a map
                                                        if (showInfoWindow) {{
                                                            var infoWindow = new google.maps.InfoWindow(), marker, i;
                                                        }}

                                                        // Loop through our array of markers & place each one on the map
                                                        $.each(groupData.groups, function (i, group) {{

                                                            var position = new google.maps.LatLng(group.latitude, group.longitude);
                                                            bounds.extend(position);

                                                            marker = new google.maps.Marker({{
                                                                position: position,
                                                                map: map,
                                                                title: htmlDecode(group.name),
                                                                icon: pinImage,
                                                                label: String.fromCharCode(9679)
                                                            }});

                                                            // Allow each marker to have an info window
                                                            if (showInfoWindow) {{
                                                                google.maps.event.addListener(marker, 'click', (function (marker, i) {{
                                                                    return function () {{
                                                                        infoWindow.setContent(htmlDecode(groupData.groups[i].infowindow));
                                                                        infoWindow.open(map, marker);
                                                                    }}
                                                                }})(marker, i));
                                                            }}

                                                            map.fitBounds(bounds);

                                                        }});

                                                        // Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
                                                        var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function (event) {{
                                                            google.maps.event.removeListener(boundsListener);
                                                        }});
                                                    }}

                                                    function htmlDecode(input) {{
                                                        var e = document.createElement('div');
                                                        e.innerHTML = input;
                                                        return e.childNodes.length === 0 ? """" : e.childNodes[0].nodeValue;
                                                    }}
                                                }});
                                            </script>";

                    string mapScript = string.Format(
                        mapScriptFormat,
                        groupJson,
                        GetAttributeValue("ShowMapInfoWindow").AsBoolean().ToString().ToLower(),
                        styleCode,
                        markerColor);

                    ScriptManager.RegisterStartupScript(pnlMap, pnlMap.GetType(), "group-mapper-script", mapScript, false);

                    if (groupsMapped == 0)
                    {
                        pnlMap.Visible = false;
                        lMessages.Text = @" <p>
                                                <div class='alert alert-warning fade in'>No groups were able to be mapped. You may want to check your configuration.</div>
                                        </p>";
                    }
                    else
                    {
                        // output any warnings
                        if (groupsWithNoGeo > 0)
                        {
                            string messagesFormat = @" <p>
                                                <div class='alert alert-warning fade in'>Some groups could not be mapped.
                                                    <button type='button' class='close' data-dismiss='alert' aria-hidden='true'><i class='fa fa-times'></i></button>
                                                    <small><a data-toggle='collapse' data-parent='#accordion' href='#map-error-details'>Show Details</a></small>
                                                    <div id='map-error-details' class='collapse'>
                                                        <p class='margin-t-sm'>
                                                            <strong>Groups That Could Not Be Mapped</strong>
                                                            <ul>
                                                                {0}
                                                            </ul>
                                                        </p>
                                                    </div>
                                                </div>
                                            </p>";
                            lMessages.Text = string.Format(messagesFormat, sbGroupsWithNoGeo.ToString());
                        }
                    }
                }
                else
                {
                    pnlMap.Visible = false;
                    lMessages.Text = "<div class='alert alert-warning'><strong>Group Mapper</strong> Please configure a group type to display and a location type to use.</div>";
                }
            }
        }
示例#4
0
        public StatementGeneratorRecipientResult GetStatementGeneratorRecipientResult(int groupId, int?personId, Guid?locationGuid, [FromBody] StatementGeneratorOptions options)
        {
            if (options == null)
            {
                throw new Exception("StatementGenerationOption options must be specified");
            }

            if (options.LayoutDefinedValueGuid == null)
            {
                throw new Exception("LayoutDefinedValueGuid option must be specified");
            }

            var result = new StatementGeneratorRecipientResult();

            result.GroupId  = groupId;
            result.PersonId = personId;

            using (var rockContext = new RockContext())
            {
                var financialTransactionQry = this.GetFinancialTransactionQuery(options, rockContext, false);
                var financialPledgeQry      = GetFinancialPledgeQuery(options, rockContext, false);

                var    personList = new List <Person>();
                Person person     = null;
                if (personId.HasValue)
                {
                    person = new PersonService(rockContext).Queryable().Include(a => a.Aliases).Where(a => a.Id == personId.Value).FirstOrDefault();
                    personList.Add(person);
                }
                else
                {
                    // get transactions for all the persons in the specified group that have specified that group as their GivingGroup
                    GroupMemberService groupMemberService = new GroupMemberService(rockContext);
                    personList = groupMemberService.GetByGroupId(groupId).Where(a => a.Person.GivingGroupId == groupId).Select(s => s.Person).Include(a => a.Aliases).ToList();
                    person     = personList.FirstOrDefault();
                }

                if (options.ExcludeOptedOutIndividuals == true && !options.DataViewId.HasValue)
                {
                    int?doNotSendGivingStatementAttributeId = AttributeCache.Get(Rock.StatementGenerator.SystemGuid.Attribute.PERSON_DO_NOT_SEND_GIVING_STATEMENT.AsGuid())?.Id;
                    if (doNotSendGivingStatementAttributeId.HasValue)
                    {
                        var personIds         = personList.Select(a => a.Id).ToList();
                        var optedOutPersonQry = new AttributeValueService(rockContext).Queryable().Where(a => a.AttributeId == doNotSendGivingStatementAttributeId);
                        if (personIds.Count == 1)
                        {
                            int entityPersonId = personIds[0];
                            optedOutPersonQry = optedOutPersonQry.Where(a => a.EntityId == entityPersonId);
                        }
                        else
                        {
                            optedOutPersonQry = optedOutPersonQry.Where(a => personIds.Contains(a.EntityId.Value));
                        }

                        var optedOutPersonIds = optedOutPersonQry
                                                .Select(a => new
                        {
                            PersonId = a.EntityId.Value,
                            a.Value
                        }).ToList().Where(a => a.Value.AsBoolean() == true).Select(a => a.PersonId).ToList();

                        if (optedOutPersonIds.Any())
                        {
                            bool givingLeaderOptedOut = personList.Any(a => optedOutPersonIds.Contains(a.Id) && a.GivingLeaderId == a.Id);

                            var remaingPersonIds = personList.Where(a => !optedOutPersonIds.Contains(a.Id)).ToList();

                            if (givingLeaderOptedOut || !remaingPersonIds.Any())
                            {
                                // If the giving leader opted out, or if there aren't any people in the giving statement that haven't opted out, return NULL and OptedOut = true
                                result.OptedOut = true;
                                result.Html     = null;
                                return(result);
                            }
                        }
                    }
                }

                var personAliasIds = personList.SelectMany(a => a.Aliases.Select(x => x.Id)).ToList();
                if (personAliasIds.Count == 1)
                {
                    var personAliasId = personAliasIds[0];
                    financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAliasId.Value == personAliasId);
                }
                else
                {
                    financialTransactionQry = financialTransactionQry.Where(a => personAliasIds.Contains(a.AuthorizedPersonAliasId.Value));
                }

                var financialTransactionsList = financialTransactionQry
                                                .Include(a => a.FinancialPaymentDetail)
                                                .Include(a => a.FinancialPaymentDetail.CurrencyTypeValue)
                                                .Include(a => a.TransactionDetails)
                                                .Include(a => a.TransactionDetails.Select(x => x.Account))
                                                .OrderBy(a => a.TransactionDateTime).ToList();

                foreach (var financialTransaction in financialTransactionsList)
                {
                    if (options.TransactionAccountIds != null)
                    {
                        // remove any Accounts that were not included (in case there was a mix of included and not included accounts in the transaction)
                        financialTransaction.TransactionDetails = financialTransaction.TransactionDetails.Where(a => options.TransactionAccountIds.Contains(a.AccountId)).ToList();
                    }

                    financialTransaction.TransactionDetails = financialTransaction.TransactionDetails.OrderBy(a => a.Account.Order).ThenBy(a => a.Account.Name).ToList();
                }

                var lavaTemplateValue      = DefinedValueCache.Get(options.LayoutDefinedValueGuid.Value);
                var lavaTemplateLava       = lavaTemplateValue.GetAttributeValue("LavaTemplate");
                var lavaTemplateFooterLava = lavaTemplateValue.GetAttributeValue("FooterHtml");

                var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null, new Lava.CommonMergeFieldsOptions {
                    GetLegacyGlobalMergeFields = false, GetDeviceFamily = false, GetOSFamily = false, GetPageContext = false, GetPageParameters = false, GetCampuses = true, GetCurrentPerson = true
                });
                mergeFields.Add("LavaTemplate", lavaTemplateValue);

                mergeFields.Add("PersonList", personList);
                mergeFields.Add("StatementStartDate", options.StartDate);
                var humanFriendlyEndDate = options.EndDate.HasValue ? options.EndDate.Value.AddDays(-1) : RockDateTime.Now.Date;
                mergeFields.Add("StatementEndDate", humanFriendlyEndDate);

                var familyTitle = Rock.Data.RockUdfHelper.ufnCrm_GetFamilyTitle(rockContext, personId, groupId, null, false, !options.ExcludeInActiveIndividuals);

                mergeFields.Add("Salutation", familyTitle);

                Location mailingAddress;

                if (locationGuid.HasValue)
                {
                    // get the location that was specified for the recipient
                    mailingAddress = new LocationService(rockContext).Get(locationGuid.Value);
                }
                else
                {
                    // for backwards compatibility, get the first address
                    IQueryable <GroupLocation> groupLocationsQry = GetGroupLocationQuery(rockContext);
                    mailingAddress = groupLocationsQry.Where(a => a.GroupId == groupId).Select(a => a.Location).FirstOrDefault();
                }

                mergeFields.Add("MailingAddress", mailingAddress);

                if (mailingAddress != null)
                {
                    mergeFields.Add("StreetAddress1", mailingAddress.Street1);
                    mergeFields.Add("StreetAddress2", mailingAddress.Street2);
                    mergeFields.Add("City", mailingAddress.City);
                    mergeFields.Add("State", mailingAddress.State);
                    mergeFields.Add("PostalCode", mailingAddress.PostalCode);
                    mergeFields.Add("Country", mailingAddress.Country);
                }
                else
                {
                    mergeFields.Add("StreetAddress1", string.Empty);
                    mergeFields.Add("StreetAddress2", string.Empty);
                    mergeFields.Add("City", string.Empty);
                    mergeFields.Add("State", string.Empty);
                    mergeFields.Add("PostalCode", string.Empty);
                    mergeFields.Add("Country", string.Empty);
                }

                var transactionDetailListAll = financialTransactionsList.SelectMany(a => a.TransactionDetails).ToList();

                if (options.HideRefundedTransactions && transactionDetailListAll.Any(a => a.Amount < 0))
                {
                    var allRefunds = transactionDetailListAll.SelectMany(a => a.Transaction.Refunds).ToList();
                    foreach (var refund in allRefunds)
                    {
                        foreach (var refundedOriginalTransactionDetail in refund.OriginalTransaction.TransactionDetails)
                        {
                            // remove the refund's original TransactionDetails from the results
                            if (transactionDetailListAll.Contains(refundedOriginalTransactionDetail))
                            {
                                transactionDetailListAll.Remove(refundedOriginalTransactionDetail);
                                foreach (var refundDetailId in refund.FinancialTransaction.TransactionDetails.Select(a => a.Id))
                                {
                                    // remove the refund's transaction from the results
                                    var refundDetail = transactionDetailListAll.FirstOrDefault(a => a.Id == refundDetailId);
                                    if (refundDetail != null)
                                    {
                                        transactionDetailListAll.Remove(refundDetail);
                                    }
                                }
                            }
                        }
                    }
                }

                if (options.HideCorrectedTransactions && transactionDetailListAll.Any(a => a.Amount < 0))
                {
                    // Hide transactions that are corrected on the same date. Transactions that have a matching negative dollar amount on the same date and same account will not be shown.

                    // get a list of dates that have at least one negative transaction
                    var transactionsByDateList = transactionDetailListAll.GroupBy(a => a.Transaction.TransactionDateTime.Value.Date).Select(a => new
                    {
                        Date = a.Key,
                        TransactionDetails = a.ToList()
                    })
                                                 .Where(a => a.TransactionDetails.Any(x => x.Amount < 0))
                                                 .ToList();


                    foreach (var transactionsByDate in transactionsByDateList)
                    {
                        foreach (var negativeTransaction in transactionsByDate.TransactionDetails.Where(a => a.Amount < 0))
                        {
                            // find the first transaction that has an amount that matches the negative amount (on the same day and same account)
                            // and make sure the matching transaction doesn't already have a refund associated with it
                            var correctedTransactionDetail = transactionsByDate.TransactionDetails
                                                             .Where(a => (a.Amount == (-negativeTransaction.Amount) && a.AccountId == negativeTransaction.AccountId) && !a.Transaction.Refunds.Any())
                                                             .FirstOrDefault();
                            if (correctedTransactionDetail != null)
                            {
                                // if the transaction was corrected, remove it, and also remove the associated correction (the negative one) transaction
                                transactionDetailListAll.Remove(correctedTransactionDetail);
                                transactionDetailListAll.Remove(negativeTransaction);
                            }
                        }
                    }
                }

                List <FinancialTransactionDetail> transactionDetailListCash    = transactionDetailListAll;
                List <FinancialTransactionDetail> transactionDetailListNonCash = new List <FinancialTransactionDetail>();

                if (options.CurrencyTypeIdsCash != null)
                {
                    // NOTE: if there isn't a FinancialPaymentDetail record, assume it is Cash
                    transactionDetailListCash = transactionDetailListCash.Where(a =>
                                                                                (a.Transaction.FinancialPaymentDetailId == null) ||
                                                                                (a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue && options.CurrencyTypeIdsCash.Contains(a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value))).ToList();
                }

                if (options.CurrencyTypeIdsNonCash != null)
                {
                    transactionDetailListNonCash = transactionDetailListAll.Where(a =>
                                                                                  a.Transaction.FinancialPaymentDetailId.HasValue &&
                                                                                  a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue &&
                                                                                  options.CurrencyTypeIdsNonCash.Contains(a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value)).ToList();
                }

                // Add Merge Fields for Transactions for custom Statements that might want to organize the output by Transaction instead of TransactionDetail
                var transactionListCash    = transactionDetailListCash.GroupBy(a => a.Transaction).Select(a => a.Key).ToList();
                var transactionListNonCash = transactionDetailListNonCash.GroupBy(a => a.Transaction).Select(a => a.Key).ToList();
                mergeFields.Add("Transactions", transactionListCash);
                mergeFields.Add("TransactionsNonCash", transactionListNonCash);

                // Add the standard TransactionDetails and TransactionDetailsNonCash that the default Rock templates use
                mergeFields.Add("TransactionDetails", transactionDetailListCash);
                mergeFields.Add("TransactionDetailsNonCash", transactionDetailListNonCash);

                mergeFields.Add("TotalContributionAmount", transactionDetailListCash.Sum(a => a.Amount));
                mergeFields.Add("TotalContributionCount", transactionDetailListCash.Count());

                mergeFields.Add("TotalContributionAmountNonCash", transactionDetailListNonCash.Sum(a => a.Amount));
                mergeFields.Add("TotalContributionCountNonCash", transactionDetailListNonCash.Count());

                mergeFields.Add("AccountSummary", transactionDetailListCash.GroupBy(t => t.Account.Name).Select(s => new { AccountName = s.Key, Total = s.Sum(a => a.Amount), Order = s.Max(a => a.Account.Order) }).OrderBy(s => s.Order));
                mergeFields.Add("AccountSummaryNonCash", transactionDetailListNonCash.GroupBy(t => t.Account.Name).Select(s => new { AccountName = s.Key, Total = s.Sum(a => a.Amount), Order = s.Max(a => a.Account.Order) }).OrderBy(s => s.Order));

                if (options.PledgesAccountIds.Any())
                {
                    var pledgeList = financialPledgeQry
                                     .Where(p => p.PersonAliasId.HasValue && personAliasIds.Contains(p.PersonAliasId.Value))
                                     .Include(a => a.Account)
                                     .OrderBy(a => a.Account.Order)
                                     .ThenBy(a => a.Account.PublicName)
                                     .ToList();

                    var pledgeSummaryByPledgeList = pledgeList
                                                    .Select(p => new
                    {
                        p.Account,
                        Pledge = p
                    })
                                                    .ToList();

                    //// Pledges but organized by Account (in case more than one pledge goes to the same account)
                    //// NOTE: In the case of multiple pledges to the same account (just in case they accidently or intentionally had multiple pledges to the same account)
                    ////  -- Date Range
                    ////    -- StartDate: Earliest StartDate of all the pledges for that account
                    ////    -- EndDate: Lastest EndDate of all the pledges for that account
                    ////  -- Amount Pledged: Sum of all Pledges to that account
                    ////  -- Amount Given:
                    ////    --  The sum of transaction amounts to that account between
                    ////      -- Start Date: Earliest Start Date of all the pledges to that account
                    ////      -- End Date: Whatever is earlier (Statement End Date or Pledges' End Date)
                    var pledgeSummaryList = pledgeSummaryByPledgeList.GroupBy(a => a.Account).Select(a => new PledgeSummary
                    {
                        Account    = a.Key,
                        PledgeList = a.Select(x => x.Pledge).ToList()
                    }).ToList();

                    // add detailed pledge information
                    if (pledgeSummaryList.Any())
                    {
                        int statementPledgeYear = options.StartDate.Value.Year;

                        List <int> pledgeCurrencyTypeIds = null;
                        if (options.CurrencyTypeIdsCash != null)
                        {
                            pledgeCurrencyTypeIds = options.CurrencyTypeIdsCash;
                            if (options.PledgesIncludeNonCashGifts && options.CurrencyTypeIdsNonCash != null)
                            {
                                pledgeCurrencyTypeIds = options.CurrencyTypeIdsCash.Union(options.CurrencyTypeIdsNonCash).ToList();
                            }
                        }

                        foreach (var pledgeSummary in pledgeSummaryList)
                        {
                            DateTime adjustedPledgeEndDate = pledgeSummary.PledgeEndDate.Value.Date;
                            if (pledgeSummary.PledgeEndDate.Value.Date < DateTime.MaxValue.Date)
                            {
                                adjustedPledgeEndDate = pledgeSummary.PledgeEndDate.Value.Date.AddDays(1);
                            }

                            if (options.EndDate.HasValue)
                            {
                                if (adjustedPledgeEndDate > options.EndDate.Value)
                                {
                                    adjustedPledgeEndDate = options.EndDate.Value;
                                }
                            }

                            var pledgeFinancialTransactionDetailQry = new FinancialTransactionDetailService(rockContext).Queryable().Where(t =>
                                                                                                                                           t.Transaction.AuthorizedPersonAliasId.HasValue && personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value) &&
                                                                                                                                           t.Transaction.TransactionDateTime >= pledgeSummary.PledgeStartDate &&
                                                                                                                                           t.Transaction.TransactionDateTime < adjustedPledgeEndDate);

                            if (options.PledgesIncludeChildAccounts)
                            {
                                // If PledgesIncludeChildAccounts = true, we'll include transactions to those child accounts as part of the pledge (but only one level deep)
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t =>
                                                                                                                t.AccountId == pledgeSummary.AccountId
                                                                                                                ||
                                                                                                                (t.Account.ParentAccountId.HasValue && t.Account.ParentAccountId == pledgeSummary.AccountId)
                                                                                                                );
                            }
                            else
                            {
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t => t.AccountId == pledgeSummary.AccountId);
                            }

                            if (pledgeCurrencyTypeIds != null)
                            {
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t =>
                                                                                                                t.Transaction.FinancialPaymentDetailId.HasValue &&
                                                                                                                t.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue && pledgeCurrencyTypeIds.Contains(t.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value));
                            }

                            pledgeSummary.AmountGiven = pledgeFinancialTransactionDetailQry.Sum(t => ( decimal? )t.Amount) ?? 0;
                        }
                    }

                    // Pledges ( organized by each Account in case an account is used by more than one pledge )
                    mergeFields.Add("Pledges", pledgeSummaryList);
                }

                mergeFields.Add("Options", options);

                var currentPerson = this.GetPerson();
                result.Html = lavaTemplateLava.ResolveMergeFields(mergeFields, currentPerson);
                if (!string.IsNullOrEmpty(lavaTemplateFooterLava))
                {
                    result.FooterHtml = lavaTemplateFooterLava.ResolveMergeFields(mergeFields, currentPerson);
                }

                result.Html = result.Html.Trim();
            }

            return(result);
        }
        /// <summary>
        /// Maps the authorizations to an attribute.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        private void MapAuthorizations(IQueryable <Row> tableData)
        {
            var lookupContext   = new RockContext();
            var rockContext     = new RockContext();
            var categoryService = new CategoryService(lookupContext);
            var personService   = new PersonService(lookupContext);

            var noteList = new List <Note>();


            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying Authorization import ({0:N0} found).", totalRows));

            var attributeList            = new AttributeService(lookupContext).Queryable().ToList();
            int authorizationAttributeId = 0;

            if (attributeList.Find(a => a.Key == "PickupAuthorization") != null)
            {
                authorizationAttributeId = attributeList.Find(a => a.Key == "PickupAuthorization").Id;
            }

            var authorizationAttributeValueList = new List <AttributeValue>();

            authorizationAttributeValueList = new AttributeValueService(rockContext).Queryable().Where(av => av.AttributeId == authorizationAttributeId).ToList();

            int f1HouseholdIdAttributeId = attributeList.Find(a => a.Key == "F1HouseholdId").Id;

            //places all household attributes in a dictionary where the key is the personId and the houshold is the value.
            var householdDictionary = new AttributeValueService(lookupContext).Queryable()
                                      .Where(av => av.AttributeId == f1HouseholdIdAttributeId)
                                      .Select(av => new { PersonId = av.EntityId, HouseholdId = av.Value })
                                      .ToDictionary(t => t.PersonId, t => t.HouseholdId);


            foreach (var row in tableData)
            {
                //var rockContext = new RockContext();
                var categoryList = new CategoryService(rockContext).Queryable().ToList();


                //check if category exists
                //If it doesn't (though it should), it will create a new category called Authorization
                if (categoryList.Find(c => c.Name == "Childhood Information") == null)
                {
                    var entityType = new EntityTypeService(rockContext);
                    //creates if category doesn't exist
                    var newCategory = new Category();
                    newCategory.IsSystem     = false;
                    newCategory.EntityTypeId = entityType.Queryable().Where(e => e.Name == "Rock.Model.Attribute").Select(e => e.Id).FirstOrDefault();
                    newCategory.EntityTypeQualifierColumn = "EntityTypeId";
                    newCategory.EntityTypeQualifierValue  = Convert.ToString(PersonEntityTypeId);
                    newCategory.Name        = "Authorization";
                    newCategory.Description = "Contains the pickup authorization";

                    //var newCategoryContext = new RockContext();
                    //newCategoryContext.WrapTransaction( () =>
                    //{
                    //    newCategoryContext.Configuration.AutoDetectChangesEnabled = false;
                    //    newCategoryContext.Categories.Add( newCategory );
                    //    newCategoryContext.SaveChanges( DisableAudit );
                    //} );
                    rockContext.WrapTransaction(() =>
                    {
                        rockContext.Configuration.AutoDetectChangesEnabled = false;
                        rockContext.Categories.Add(newCategory);
                        rockContext.SaveChanges(DisableAudit);
                    });
                }
                attributeList = new AttributeService(lookupContext).Queryable().ToList();

                //Check if Attribute exists
                //If it doesn't it creates the attribute
                if (attributeList.Find(a => a.Key == "PickupAuthorization") == null)
                {
                    var fieldType = new FieldTypeService(rockContext);
                    //var newAttributeList = new List<Rock.Model.Attribute>();
                    var fieldTypeId = fieldType.Queryable().Where(e => e.Name == "Memo").FirstOrDefault().Id;
                    var category2   = new CategoryService(rockContext).Queryable().Where(gt => gt.Name == "Childhood Information").FirstOrDefault();
                    var category3   = new CategoryService(rockContext).Queryable().Where(gt => gt.Name == "Authorization").FirstOrDefault();

                    //Creates if attribute doesn't exist
                    //The attribute is a memo attribute
                    var newAttribute = new Rock.Model.Attribute();
                    newAttribute.Key                       = "PickupAuthorization";
                    newAttribute.Name                      = "Pickup Authorization";
                    newAttribute.FieldTypeId               = fieldTypeId;
                    newAttribute.EntityTypeId              = PersonEntityTypeId;
                    newAttribute.EntityTypeQualifierValue  = string.Empty;
                    newAttribute.EntityTypeQualifierColumn = string.Empty;
                    newAttribute.Description               = "Lists who is authorized to pickup this child along with their current phone number.";
                    newAttribute.DefaultValue              = string.Empty;
                    newAttribute.IsMultiValue              = false;
                    newAttribute.IsRequired                = false;

                    if (categoryList.Find(c => c.Name == "Childhood Information") != null)
                    {
                        newAttribute.Categories = new List <Category>();
                        newAttribute.Categories.Add(category2);
                    }
                    //If authorization category was create, this is where the attribute is set to that category.
                    else
                    {
                        newAttribute.Categories = new List <Category>();
                        newAttribute.Categories.Add(category3);    //Sets to Authorization Attribute Category.
                    }

                    //saves the attribute
                    rockContext.WrapTransaction(() =>
                    {
                        rockContext.Configuration.AutoDetectChangesEnabled = false;
                        rockContext.Attributes.Add(newAttribute);
                        rockContext.SaveChanges(DisableAudit);
                    });
                }
                //Adding to the person's attributes
                int?     householdId       = row["HouseholdID"] as int?;
                string   personName        = row["PersonName"] as string;
                DateTime?authorizationDate = row["AuthorizationDate"] as DateTime?;

                attributeList = new AttributeService(rockContext).Queryable().ToList();

                //Gets the Attribute Id for Pickup Authorization.
                authorizationAttributeId = attributeList.Find(a => a.Key == "PickupAuthorization").Id;


                //since F1 authorization applies to the household id and not individual I have to apply it to all members in that household.
                //Value in F1 is a text entry and not a person select. Discuss with staff that we need to break away from this and start using known relationships for authorization
                foreach (var household in householdDictionary.Where(h => h.Value == Convert.ToString(householdId)))
                {
                    //checks if a record already exists in the list

                    if (authorizationAttributeValueList.Find(a => a.AttributeId == authorizationAttributeId && a.EntityId == household.Key) == null)
                    {
                        var person = new PersonService(rockContext).Queryable().Where(p => p.Id == household.Key).FirstOrDefault();

                        //trying to keep from adding this attribute to adult records
                        if (person != null && (person.Age <= 18 || person.Age == null))
                        {
                            //creates new attribute record if it does not exist.
                            var newAuthorizationAttribute = new AttributeValue();
                            newAuthorizationAttribute.IsSystem        = false;
                            newAuthorizationAttribute.AttributeId     = authorizationAttributeId;
                            newAuthorizationAttribute.EntityId        = household.Key;     //the key is the person ID
                            newAuthorizationAttribute.Value           = personName + ", "; //text field
                            newAuthorizationAttribute.CreatedDateTime = authorizationDate;

                            //adds the new record to the list
                            authorizationAttributeValueList.Add(newAuthorizationAttribute);
                        }
                    }
                    //if a record already exists
                    else
                    {
                        //adds to the current value.
                        authorizationAttributeValueList.Find(a => a.AttributeId == authorizationAttributeId && a.EntityId == household.Key).Value = personName + ", ";
                    }
                }
                completed++;
                if (completed % percentage < 1)
                {
                    int percentComplete = completed / percentage;
                    ReportProgress(percentComplete, string.Format("{0:N0} authorizations imported ({1}% complete).", completed, percentComplete));
                }
                else if (completed % ReportingNumber < 1)
                {
                    //rockContext.WrapTransaction( () =>
                    // {
                    //     rockContext.Configuration.AutoDetectChangesEnabled = false;
                    //     rockContext.AttributeValues.AddRange( authorizationAttributeValueList );
                    //     rockContext.SaveChanges( DisableAudit );  //I get can't insert duplicate entry error
                    // } );

                    ReportPartialProgress();
                }
            }

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

            ReportProgress(100, string.Format("Finished authorization import: {0:N0} notes imported.", completed));
        }
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGroupMembersGrid()
        {
            var showGoal      = GetAttributeValue("ShowMemberFundingGoal").AsBoolean();
            var showTotal     = GetAttributeValue("ShowMemberTotalFunding").AsBoolean();
            var showRemaining = GetAttributeValue("ShowMemberFundingRemaining").AsBoolean();

            gGroupMembers.Columns[4].Visible = showGoal;
            gGroupMembers.Columns[5].Visible = showTotal;
            gGroupMembers.Columns[6].Visible = showRemaining;

            var rockContext = new RockContext();

            int groupId = hfGroupId.Value.AsInteger();
            var totalFundraisingGoal  = 0.00M;
            var totalContribution     = 0.00M;
            var totalFundingRemaining = 0.00M;
            var groupMembersQuery     = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == groupId);
            var group = new GroupService(rockContext).Get(groupId);

            group.LoadAttributes(rockContext);
            var defaultIndividualFundRaisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();

            groupMembersQuery = groupMembersQuery.Sort(gGroupMembers.SortProperty ?? new SortProperty {
                Property = "Person.LastName, Person.NickName"
            });

            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();
            var entityTypeIdPerson      = EntityTypeCache.GetId <Rock.Model.Person>();

            var groupMemberList = groupMembersQuery.ToList().Select(a =>
            {
                var groupMember = a;
                groupMember.LoadAttributes(rockContext);

                var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                        .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                               d.EntityId == groupMember.Id)
                                        .Sum(d => ( decimal? )d.Amount) ?? 0.00M;

                var individualFundraisingGoal          = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                bool disablePublicContributionRequests = groupMember.GetAttributeValue("DisablePublicContributionRequests").AsBoolean();
                if (!individualFundraisingGoal.HasValue)
                {
                    individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                }

                var fundingRemaining = individualFundraisingGoal - contributionTotal;
                if (disablePublicContributionRequests || !showRemaining)
                {
                    fundingRemaining = null;
                }
                else if (fundingRemaining < 0)
                {
                    fundingRemaining = 0.00M;
                }

                totalFundraisingGoal  += (individualFundraisingGoal != null ? ( decimal )individualFundraisingGoal : 0);
                totalContribution     += contributionTotal;
                totalFundingRemaining += (fundingRemaining != null ? ( decimal )fundingRemaining : 0);

                if (!showGoal)
                {
                    individualFundraisingGoal = null;
                    totalFundraisingGoal      = 0.00M;
                }

                if (!showTotal)
                {
                    contributionTotal = 0.00M;
                    totalContribution = 0.00M;
                }

                return(new
                {
                    groupMember.Id,
                    PersonId = groupMember.PersonId,
                    DateTimeAdded = groupMember.DateTimeAdded,
                    groupMember.Person.FullName,
                    groupMember.Person.Gender,
                    FundingRemaining = fundingRemaining,
                    GroupRoleName = a.GroupRole.Name,
                    FundingGoal = individualFundraisingGoal,
                    TotalFunding = contributionTotal,
                    Email = groupMember.Person.Email
                });
            }).ToList();

            _groupTotals.Add("TotalFundraisingGoal", totalFundraisingGoal);
            _groupTotals.Add("TotalContribution", totalContribution);
            _groupTotals.Add("TotalFundingRemaining", totalFundingRemaining);

            //
            // Attributes
            //

            BindAttributes(group);
            AddDynamicControls(group);

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

            // Get all the group member ids and the group id in current page of query results
            var groupMemberIds = new List <int>();

            foreach (var groupMember in groupMemberList
                     .Select(m => m))
            {
                groupMemberIds.Add(groupMember.Id);
            }

            var groupMemberAttributesIds = new List <int>();

            foreach (var gma in AvailableAttributes.Where(a => a.EntityTypeId == entityTypeIdGroupMember))
            {
                groupMemberAttributesIds.Add(gma.Id);
            }

            var personAttributesIds = new List <int>();

            foreach (var pa in AvailableAttributes.Where(a => a.EntityTypeId == entityTypeIdPerson))
            {
                personAttributesIds.Add(pa.Id);
            }

            // 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

            // 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)
                                             )
                                         )
                                         )
                                  .ToList();

            // Get the attributes to add to each row's object
            BindAttributes(group);
            var attributes = new Dictionary <string, AttributeCache>();

            AvailableAttributes.ForEach(a => attributes
                                        .Add(a.Id.ToString() + a.Key, a));

            // Initialize the grid's object list
            gGroupMembers.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 gm in groupMemberList)
            {
                // 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 == gm.PersonId)
                .ToList()
                .ForEach(v => attributeFieldObject.AttributeValues
                         .Add(v.AttributeId.ToString() + v.Attribute.Key, new AttributeValueCache(v)));

                // Add any group member attribute values to object
                attributeValues
                .Where(v =>
                       groupMemberAttributesIds.Contains(v.AttributeId) &&
                       v.EntityId.Value == gm.Id)
                .ToList()
                .ForEach(v => attributeFieldObject.AttributeValues
                         .Add(v.AttributeId.ToString() + v.Attribute.Key, new AttributeValueCache(v)));

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

            gGroupMembers.DataSource = groupMemberList;
            gGroupMembers.DataBind();
        }
示例#7
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        /// <remarks>Multiple methods depend on the GroupMember object type</remarks>
        /// <param name="isExporting">if set to <c>true</c> [is exporting].</param>
        protected void BindGroupMembersGrid(bool isExporting = false)
        {
            if (_group != null && _group.GroupType.Roles.Any())
            {
                pnlGroupMembers.Visible = true;

                using (var rockContext = new RockContext())
                {
                    // Start query for group members
                    var qry = new GroupMemberService(rockContext)
                              .Queryable("Person,GroupRole", true)
                              .Where(m => m.GroupId == _group.Id && m.Person != null);

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

                    // increase the timeout just in case. A complex filter on the grid might slow things down
                    rockContext.Database.CommandTimeout = 180;

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

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

                    var groupAttributes = GetGroupAttributes();
                    if (groupAttributes.Any())
                    {
                        // Get the query results for the current page
                        var currentGroupMembers = pnlGroupMembers.DataSource as List <GroupMember>;
                        if (currentGroupMembers != null)
                        {
                            // Get all the person ids in current page of query results
                            var personIds = currentGroupMembers
                                            .Select(r => r.PersonId)
                                            .Distinct()
                                            .ToList();

                            var groupMemberIds = currentGroupMembers
                                                 .Select(r => r.Id)
                                                 .Distinct()
                                                 .ToList();

                            var groupMemberAttributesIds = groupAttributes.Select(a => a.Id).Distinct().ToList();

                            // 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 (groupMemberAttributesIds.Any())
                            {
                                // Query the attribute values for all rows and attributes
                                var attributeValues = new AttributeValueService(rockContext)
                                                      .Queryable("Attribute").AsNoTracking()
                                                      .Where(v =>
                                                             v.EntityId.HasValue &&
                                                             groupMemberAttributesIds.Contains(v.AttributeId) &&
                                                             groupMemberIds.Contains(v.EntityId.Value)
                                                             )
                                                      .ToList();

                                // Get the attributes to add to each row's object
                                var attributes = new Dictionary <string, AttributeCache>();
                                groupAttributes.ForEach(a =>
                                                        attributes.Add(a.Id + a.Key, a));

                                // Initialize the grid's object list
                                pnlGroupMembers.ObjectList   = new Dictionary <string, object>();
                                pnlGroupMembers.EntityTypeId = EntityTypeCache.Get(Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid()).Id;

                                // Loop through each of the current group's members and build an attribute
                                // field object for storing attributes and the values for each of the members
                                foreach (var groupMember in currentGroupMembers)
                                {
                                    // Create a row attribute object
                                    var attributeFieldObject = new AttributeFieldObject
                                    {
                                        // Add the attributes to the attribute object
                                        Attributes = attributes
                                    };

                                    // Add any group member attribute values to object
                                    if (groupMember.Id > 0)
                                    {
                                        attributeValues
                                        .Where(v =>
                                               groupMemberAttributesIds.Contains(v.AttributeId) &&
                                               v.EntityId.Value == groupMember.Id)
                                        .ToList()
                                        .ForEach(v => attributeFieldObject.AttributeValues
                                                 .Add(v.AttributeId + v.Attribute.Key, new AttributeValueCache(v)));
                                    }

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

                    pnlGroupMembers.DataBind();
                }
            }
        }