/// <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); }
/// <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()); }
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>"; } } }
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(); }
/// <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(); } } }