/// <summary> /// Binds the group members grid. /// </summary> protected void BindGroupMembersGrid() { var rockContext = new RockContext(); int groupId = hfGroupId.Value.AsInteger(); 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 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) { fundingRemaining = null; } else if (fundingRemaining < 0) { fundingRemaining = 0.00M; } return(new { groupMember.Id, PersonId = groupMember.PersonId, DateTimeAdded = groupMember.DateTimeAdded, groupMember.Person.FullName, groupMember.Person.Gender, FundingRemaining = fundingRemaining, GroupRoleName = a.GroupRole.Name }); }).ToList(); gGroupMembers.DataSource = groupMemberList; gGroupMembers.DataBind(); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection) { if (selection.IsNotNullOrWhiteSpace()) { var ebPersonFieldType = FieldTypeCache.Get(EBGuid.FieldType.EVENTBRITE_PERSON.AsGuid()); var ebPersonAttribute = new AttributeService(( RockContext )serviceInstance.Context).GetByFieldTypeId(ebPersonFieldType.Id).FirstOrDefault(); if (ebPersonAttribute != null) { var qry = new GroupMemberService(( RockContext )serviceInstance.Context).Queryable() .WhereAttributeValue(( RockContext )serviceInstance.Context, a => a.Attribute.Key == ebPersonAttribute.Key && a.Value != null && a.Value != "" && a.Value.Contains("^")); var groupMemberIds = new List <int>(); foreach (var groupMember in qry.ToList()) { if (groupMember.Attributes == null) { groupMember.LoadAttributes(); } var attributeVal = groupMember.GetAttributeValue(ebPersonAttribute.Key); if (attributeVal.IsNotNullOrWhiteSpace()) { var containsValue = attributeVal.Split(new char[] { '^' })[1].Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries).Contains(selection); if (containsValue) { groupMemberIds.Add(groupMember.Id); } } } qry = qry.Where(gm => groupMemberIds.Contains(gm.Id)); Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.GroupMember>(qry, parameterExpression, "gm"); return(extractedFilterExpression); } } return(null); }
/// <summary> /// Job that will sync groups. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; try { int notificationsSent = 0; int errorsEncountered = 0; int pendingMembersCount = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString("GroupType").AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString("NotificationEmail").AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString("GroupRoleFilter").AsGuidOrNull(); int? pendingAge = dataMap.GetString("PendingAge").AsIntegerOrNull(); bool includePreviouslyNotificed = dataMap.GetString("IncludePreviouslyNotified").AsBoolean(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (!systemEmailGuid.HasValue || systemEmailGuid == Guid.Empty) { context.Result = "Job failed. Unable to find System Email"; throw new Exception("No system email found."); } systemEmail = emailService.Get(systemEmailGuid.Value); // get group members if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty) { context.Result = "Job failed. Unable to find group type"; throw new Exception("No group type found"); } var qry = new GroupMemberService(rockContext).Queryable("Person, Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qry = qry.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } if (pendingAge.HasValue && pendingAge.Value > 0) { var ageDate = RockDateTime.Now.AddDays(pendingAge.Value * -1); qry = qry.Where(m => m.ModifiedDateTime > ageDate); } var pendingGroupMembers = qry.ToList(); var groups = pendingGroupMembers.GroupBy(m => m.Group); var errorList = new List <string>(); foreach (var groupKey in groups) { var group = groupKey.Key; // get list of pending people var qryPendingIndividuals = group.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var pendingIndividuals = qryPendingIndividuals.Select(m => m.Person).ToList(); if (!pendingIndividuals.Any()) { continue; } // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty); if (!groupLeaders.Any()) { errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader"); continue; } var recipients = new List <RecipientData>(); foreach (var leader in groupLeaders) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("PendingIndividuals", pendingIndividuals); mergeFields.Add("Group", group); mergeFields.Add("ParentGroup", group.ParentGroup); mergeFields.Add("Person", leader.Person); recipients.Add(new RecipientData(leader.Person.Email, mergeFields)); } var errorMessages = new List <string>(); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); emailMessage.Send(out errorMessages); errorsEncountered += errorMessages.Count; errorList.AddRange(errorMessages); // be conservative: only mark as notified if we are sure the email didn't fail if (errorMessages.Any()) { continue; } notificationsSent += recipients.Count(); // mark pending members as notified as we go in case the job fails var notifiedPersonIds = pendingIndividuals.Select(p => p.Id); foreach (var pendingGroupMember in pendingGroupMembers.Where(m => m.IsNotified == false && notifiedPersonIds.Contains(m.PersonId))) { pendingGroupMember.IsNotified = true; } rockContext.SaveChanges(); } context.Result = string.Format("Sent {0} emails to leaders for {1} pending individuals. {2} errors encountered.", notificationsSent, pendingMembersCount, errorsEncountered); if (errorList.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors: "); errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errors = sb.ToString(); context.Result += errors; throw new Exception(errors); } } catch (Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var errors = new List <string>(); var rockContext = new RockContext(); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("NotificationEmailTemplate").AsGuidOrNull(); if (systemEmailGuid.HasValue) { var selectedGroupTypes = new List <Guid>(); if (!string.IsNullOrWhiteSpace(dataMap.GetString("GroupTypes"))) { selectedGroupTypes = dataMap.GetString("GroupTypes").Split(',').Select(Guid.Parse).ToList(); } var notificationOption = dataMap.GetString("NotifyParentLeaders").ConvertToEnum <NotificationOption>(NotificationOption.None); var accountAbilityGroupGuid = dataMap.GetString("AccountabilityGroup").AsGuid(); var groupRequirementsQry = new GroupRequirementService(rockContext).Queryable(); // get groups matching of the types provided GroupService groupService = new GroupService(rockContext); var groups = groupService.Queryable().AsNoTracking() .Where(g => selectedGroupTypes.Contains(g.GroupType.Guid) && g.IsActive == true && groupRequirementsQry.Any(a => (a.GroupId.HasValue && a.GroupId == g.Id) || (a.GroupTypeId.HasValue && a.GroupTypeId == g.GroupTypeId))); foreach (var group in groups) { // check for members that don't meet requirements var groupMembersWithIssues = groupService.GroupMembersNotMeetingRequirements(group, true); if (groupMembersWithIssues.Count > 0) { // add issues to issue list GroupsMissingRequirements groupMissingRequirements = new GroupsMissingRequirements(); groupMissingRequirements.Id = group.Id; groupMissingRequirements.Name = group.Name; if (group.GroupType != null) { groupMissingRequirements.GroupTypeId = group.GroupTypeId; groupMissingRequirements.GroupTypeName = group.GroupType.Name; } groupMissingRequirements.AncestorPathName = groupService.GroupAncestorPathName(group.Id); // get list of the group leaders groupMissingRequirements.Leaders = group.Members .Where(m => m.GroupRole.ReceiveRequirementsNotifications) .Select(m => new GroupMemberResult { Id = m.Id, PersonId = m.PersonId, FullName = m.Person.FullName }) .ToList(); List <GroupMembersMissingRequirements> groupMembers = new List <GroupMembersMissingRequirements>(); foreach (var groupMemberIssue in groupMembersWithIssues) { GroupMembersMissingRequirements groupMember = new GroupMembersMissingRequirements(); groupMember.FullName = groupMemberIssue.Key.Person.FullName; groupMember.Id = groupMemberIssue.Key.Id; groupMember.PersonId = groupMemberIssue.Key.PersonId; groupMember.GroupMemberRole = groupMemberIssue.Key.GroupRole.Name; List <MissingRequirement> missingRequirements = new List <MissingRequirement>(); foreach (var issue in groupMemberIssue.Value) { MissingRequirement missingRequirement = new MissingRequirement(); missingRequirement.Id = issue.Key.GroupRequirement.GroupRequirementType.Id; missingRequirement.Name = issue.Key.GroupRequirement.GroupRequirementType.Name; missingRequirement.Status = issue.Key.MeetsGroupRequirement; missingRequirement.OccurrenceDate = issue.Value; switch (issue.Key.MeetsGroupRequirement) { case MeetsGroupRequirement.Meets: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.PositiveLabel; break; case MeetsGroupRequirement.MeetsWithWarning: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.WarningLabel; break; case MeetsGroupRequirement.NotMet: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.NegativeLabel; break; } missingRequirements.Add(missingRequirement); } groupMember.MissingRequirements = missingRequirements; groupMembers.Add(groupMember); } groupMissingRequirements.GroupMembersMissingRequirements = groupMembers; _groupsMissingRequriements.Add(groupMissingRequirements); // add leaders as people to notify foreach (var leader in group.Members.Where(m => m.GroupRole.ReceiveRequirementsNotifications)) { NotificationItem notification = new NotificationItem(); notification.GroupId = group.Id; notification.Person = leader.Person; _notificationList.Add(notification); } // notify parents if (notificationOption != NotificationOption.None) { var parentLeaders = new GroupMemberService(rockContext).Queryable("Person").AsNoTracking() .Where(m => m.GroupRole.ReceiveRequirementsNotifications); if (notificationOption == NotificationOption.DirectParent) { // just the parent group parentLeaders = parentLeaders.Where(m => m.GroupId == group.ParentGroupId); } else { // all parents in the hierarchy var parentIds = groupService.GetAllAncestorIds(group.Id); parentLeaders = parentLeaders.Where(m => parentIds.Contains(m.GroupId)); } foreach (var parentLeader in parentLeaders.ToList()) { NotificationItem parentNotification = new NotificationItem(); parentNotification.Person = parentLeader.Person; parentNotification.GroupId = group.Id; _notificationList.Add(parentNotification); } } } } // send out notifications int recipients = 0; var notificationRecipients = _notificationList.GroupBy(p => p.Person.Id).ToList(); foreach (var recipientId in notificationRecipients) { var recipient = _notificationList.Where(n => n.Person.Id == recipientId.Key).Select(n => n.Person).FirstOrDefault(); if (!recipient.IsEmailActive || recipient.Email.IsNullOrWhiteSpace() || recipient.EmailPreference == EmailPreference.DoNotEmail) { continue; } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Person", recipient); var notificationGroupIds = _notificationList .Where(n => n.Person.Id == recipient.Id) .Select(n => n.GroupId) .ToList(); var missingRequirements = _groupsMissingRequriements.Where(g => notificationGroupIds.Contains(g.Id)).ToList(); mergeFields.Add("GroupsMissingRequirements", missingRequirements); var emailMessage = new RockEmailMessage(systemEmailGuid.Value); emailMessage.AddRecipient(new RecipientData(recipient.Email, mergeFields)); var emailErrors = new List <string>(); emailMessage.Send(out emailErrors); errors.AddRange(emailErrors); recipients++; } // add accountability group members if (!accountAbilityGroupGuid.IsEmpty()) { var accountabilityGroupMembers = new GroupMemberService(rockContext).Queryable().AsNoTracking() .Where(m => m.Group.Guid == accountAbilityGroupGuid) .Select(m => m.Person); var emailMessage = new RockEmailMessage(systemEmailGuid.Value); foreach (var person in accountabilityGroupMembers) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Person", person); mergeFields.Add("GroupsMissingRequirements", _groupsMissingRequriements); emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields)); recipients++; } var emailErrors = new List <string>(); emailMessage.Send(out emailErrors); errors.AddRange(emailErrors); } context.Result = string.Format("{0} requirement notification {1} sent", recipients, "email".PluralizeIf(recipients != 1)); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append(string.Format("{0} Errors: ", errors.Count())); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; var exception = new Exception(errorMessage); HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(exception, context2); throw exception; } } else { context.Result = "Warning: No NotificationEmailTemplate found"; } }
private void ListGroups() { RockContext rockContext = new RockContext(); var qry = new GroupMemberService(rockContext) .Queryable("Group"); var parentGroupGuid = GetAttributeValue("ParentGroup").AsGuidOrNull(); if (parentGroupGuid != null) { var availableGroupIds = (List <int>)GetCacheItem("GroupListPersonalizedLava:" + parentGroupGuid.ToString()); if (availableGroupIds == null) { var parentGroup = new GroupService(rockContext).Get(parentGroupGuid ?? new Guid()); if (parentGroup != null) { availableGroupIds = GetChildGroups(parentGroup).Select(g => g.Id).ToList(); } else { availableGroupIds = new List <int>(); } var cacheLength = GetAttributeValue("CacheDuration").AsInteger(); string cacheTags = GetAttributeValue("CacheTags") ?? string.Empty; AddCacheItem("GroupListPersonalizedLava:" + parentGroupGuid.ToString(), availableGroupIds, cacheLength, cacheTags); } qry = qry.Where(m => availableGroupIds.Contains(m.GroupId)); } qry = qry.Where(m => m.PersonId == CurrentPersonId && m.GroupMemberStatus == GroupMemberStatus.Active); if (_hideInactive) { qry = qry.Where(m => m.Group.IsActive == true && !m.Group.IsArchived); } List <Guid> includeGroupTypeGuids = GetAttributeValue("IncludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList(); if (includeGroupTypeGuids.Count > 0) { qry = qry.Where(t => includeGroupTypeGuids.Contains(t.Group.GroupType.Guid)); } List <Guid> excludeGroupTypeGuids = GetAttributeValue("ExcludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList(); if (excludeGroupTypeGuids.Count > 0) { qry = qry.Where(t => !excludeGroupTypeGuids.Contains(t.Group.GroupType.Guid)); } var groups = new List <GroupInvolvementSummary>(); foreach (var groupMember in qry.ToList()) { if (groupMember.Group.IsAuthorized(Authorization.VIEW, CurrentPerson)) { groups.Add(new GroupInvolvementSummary { Group = groupMember.Group, Role = groupMember.GroupRole.Name, IsLeader = groupMember.GroupRole.IsLeader, GroupType = groupMember.Group.GroupType.Name }); } } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); mergeFields.Add("Groups", groups); Dictionary <string, object> linkedPages = new Dictionary <string, object>(); linkedPages.Add("DetailPage", LinkedPageRoute("DetailPage")); mergeFields.Add("LinkedPages", linkedPages); if (this.GetAttributeValue("DisplayInactiveGroups").AsBoolean()) { mergeFields.Add("ShowInactive", this.GetAttributeValue("DisplayInactiveGroups")); mergeFields.Add("InitialActive", this.GetAttributeValue("InitialActiveSetting")); mergeFields.Add("InactiveParameter", this.GetAttributeValue("InactiveParameterName")); } string template = GetAttributeValue("LavaTemplate"); lContent.Text = template.ResolveMergeFields(mergeFields); }
/// <summary> /// Unsubscribes the person from any lists that were selected. /// </summary> /// <returns>true if they were actually unsubscribed from something or false otherwise.</returns> private bool UnsubscribeFromLists() { if (_person == null) { return(false); } if (!cblUnsubscribeFromLists.SelectedValuesAsInt.Any()) { nbUnsubscribeSuccessMessage.NotificationBoxType = NotificationBoxType.Warning; nbUnsubscribeSuccessMessage.Text = "Please select the lists that you want to unsubscribe from."; nbUnsubscribeSuccessMessage.Visible = true; return(false); } List <Group> unsubscribedGroups = new List <Group>(); var rockContext = new RockContext(); foreach (var communicationListId in cblUnsubscribeFromLists.SelectedValuesAsInt) { // normally there would be at most 1 group member record for the person, but just in case, mark them all inactive var groupMemberRecordsForPerson = new GroupMemberService(rockContext).Queryable().Include(a => a.Group).Where(a => a.GroupId == communicationListId && a.PersonId == _person.Id); foreach (var groupMember in groupMemberRecordsForPerson.ToList()) { groupMember.GroupMemberStatus = GroupMemberStatus.Inactive; if (groupMember.Note.IsNullOrWhiteSpace()) { groupMember.Note = "Unsubscribed"; } unsubscribedGroups.Add(groupMember.Group); rockContext.SaveChanges(); } // if they selected the CommunicationList associated with the CommunicationId from the Url, log an 'Unsubscribe' Interaction if (_communication != null && _communication.ListGroupId.HasValue && communicationListId == _communication.ListGroupId) { var communicationRecipient = _communication.GetRecipientsQry(rockContext).Where(a => a.PersonAlias.PersonId == _person.Id).FirstOrDefault(); if (communicationRecipient != null) { var interactionService = new InteractionService(rockContext); InteractionComponent interactionComponent = new InteractionComponentService(rockContext) .GetComponentByEntityId(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid(), _communication.Id, _communication.Subject); rockContext.SaveChanges(); var ipAddress = GetClientIpAddress(); var userAgent = Request.UserAgent ?? ""; UAParser.ClientInfo client = UAParser.Parser.GetDefault().Parse(userAgent); var clientOs = client.OS.ToString(); var clientBrowser = client.UA.ToString(); var clientType = InteractionDeviceType.GetClientType(userAgent); interactionService.AddInteraction(interactionComponent.Id, communicationRecipient.Id, "Unsubscribe", "", communicationRecipient.PersonAliasId, RockDateTime.Now, clientBrowser, clientOs, clientType, userAgent, ipAddress, null); rockContext.SaveChanges(); } } } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); int?communicationId = PageParameter(PageParameterKey.CommunicationId).AsIntegerOrNull(); if (_communication != null) { mergeFields.Add("Communication", _communication); } mergeFields.Add("UnsubscribedGroups", unsubscribedGroups); nbUnsubscribeSuccessMessage.NotificationBoxType = NotificationBoxType.Success; nbUnsubscribeSuccessMessage.Text = GetAttributeValue(AttributeKey.UnsubscribeSuccessText).ResolveMergeFields(mergeFields); nbUnsubscribeSuccessMessage.Visible = true; return(true); }
private void ListGroups() { RockContext rockContext = new RockContext(); var qry = new GroupMemberService(rockContext) .Queryable("Group") .Where(m => m.PersonId == CurrentPersonId && m.GroupMemberStatus == GroupMemberStatus.Active && m.Group.IsActive == true); List <Guid> includeGroupTypeGuids = GetAttributeValue("IncludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList(); if (includeGroupTypeGuids.Count > 0) { qry = qry.Where(t => includeGroupTypeGuids.Contains(t.Group.GroupType.Guid)); } List <Guid> excludeGroupTypeGuids = GetAttributeValue("ExcludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList(); if (excludeGroupTypeGuids.Count > 0) { qry = qry.Where(t => !excludeGroupTypeGuids.Contains(t.Group.GroupType.Guid)); } var groups = new List <GroupInvolvementSummary>(); foreach (var groupMember in qry.ToList()) { if (groupMember.Group.IsAuthorized(Authorization.VIEW, CurrentPerson)) { groups.Add(new GroupInvolvementSummary { Group = groupMember.Group, Role = groupMember.GroupRole.Name, IsLeader = groupMember.GroupRole.IsLeader, GroupType = groupMember.Group.GroupType.Name }); } } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); mergeFields.Add("Groups", groups); Dictionary <string, object> linkedPages = new Dictionary <string, object>(); linkedPages.Add("DetailPage", LinkedPageRoute("DetailPage")); mergeFields.Add("LinkedPages", linkedPages); string template = GetAttributeValue("LavaTemplate"); // show debug info bool enableDebug = GetAttributeValue("EnableDebug").AsBoolean(); if (enableDebug && IsUserAuthorized(Authorization.EDIT)) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } lContent.Text = template.ResolveMergeFields(mergeFields); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); Guid? groupGuid = null; Person person = null; string attributeValue = string.Empty; Guid groupRoleGuid = Guid.Empty; string attributeKey = string.Empty; // get the group attribute Guid groupAttributeGuid = GetAttributeValue(action, "Group").AsGuid(); if (!groupAttributeGuid.IsEmpty()) { groupGuid = action.GetWorkflowAttributeValue(groupAttributeGuid).AsGuidOrNull(); if (!groupGuid.HasValue) { errorMessages.Add("The group could not be found!"); } } // get person alias guid Guid personAliasGuid = Guid.Empty; string personAttribute = GetAttributeValue(action, "Person"); Guid guid = personAttribute.AsGuid(); if (!guid.IsEmpty()) { var attribute = AttributeCache.Get(guid, rockContext); if (attribute != null) { string value = action.GetWorkflowAttributeValue(guid); personAliasGuid = value.AsGuid(); } if (personAliasGuid != Guid.Empty) { person = new PersonAliasService(rockContext).Queryable().AsNoTracking() .Where(p => p.Guid.Equals(personAliasGuid)) .Select(p => p.Person) .FirstOrDefault(); } else { errorMessages.Add("The person could not be found in the attribute!"); } } // get group member attribute value attributeValue = GetAttributeValue(action, "AttributeValue"); guid = attributeValue.AsGuid(); if (guid.IsEmpty()) { attributeValue = attributeValue.ResolveMergeFields(GetMergeFields(action)); } else { var workflowAttributeValue = action.GetWorkflowAttributeValue(guid); if (workflowAttributeValue != null) { attributeValue = workflowAttributeValue; } } // get optional role filter groupRoleGuid = GetAttributeValue(action, "GroupRoleFilter").AsGuid(); // get attribute key attributeKey = GetAttributeValue(action, "GroupMemberAttributeKey").Replace(" ", ""); // set attribute if (groupGuid.HasValue && person != null) { var qry = new GroupMemberService(rockContext).Queryable() .Where(m => m.Group.Guid == groupGuid && m.PersonId == person.Id); if (groupRoleGuid != Guid.Empty) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleGuid); } foreach (var groupMember in qry.ToList()) { groupMember.LoadAttributes(rockContext); if (groupMember.Attributes.ContainsKey(attributeKey)) { var attribute = groupMember.Attributes[attributeKey]; Rock.Attribute.Helper.SaveAttributeValue(groupMember, attribute, attributeValue, rockContext); } else { action.AddLogEntry(string.Format("The group member attribute {0} does not exist!", attributeKey)); break; } } } errorMessages.ForEach(m => action.AddLogEntry(m, true)); return(true); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var exceptionMsgs = new List <string>(); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? groupGuid = dataMap.GetString("EligibleFollowers").AsGuidOrNull(); Guid? systemEmailGuid = dataMap.GetString("EmailTemplate").AsGuidOrNull(); int followingSuggestionsEmailsSent = 0; int followingSuggestionsSuggestionsTotal = 0; if (groupGuid.HasValue && systemEmailGuid.HasValue) { using (var rockContext = new RockContext()) { var followingService = new FollowingService(rockContext); // The people who are eligible to get following suggestions based on the group type setting for this job var eligiblePersonIds = new GroupMemberService(rockContext) .Queryable().AsNoTracking() .Where(m => m.Group != null && m.Group.Guid.Equals(groupGuid.Value) && m.GroupMemberStatus == GroupMemberStatus.Active && m.Person != null && m.Person.Email != null && m.Person.Email != "") .Select(m => m.PersonId) .Distinct(); // check to see if there are any event types that require notification var followerPersonIds = new List <int>(); if (new FollowingEventTypeService(rockContext) .Queryable().AsNoTracking() .Any(e => e.IsNoticeRequired)) { // if so, include all eligible people followerPersonIds = eligiblePersonIds.ToList(); } else { // if not, filter the list of eligible people down to only those that actually have subscribed to one or more following events followerPersonIds = new FollowingEventSubscriptionService(rockContext) .Queryable().AsNoTracking() .Where(f => eligiblePersonIds.Contains(f.PersonAlias.PersonId)) .Select(f => f.PersonAlias.PersonId) .Distinct() .ToList(); } if (followerPersonIds.Any()) { // Get the primary person alias id for each of the followers var primaryAliasIds = new Dictionary <int, int>(); new PersonAliasService(rockContext) .Queryable().AsNoTracking() .Where(a => followerPersonIds.Contains(a.PersonId) && a.PersonId == a.AliasPersonId) .ToList() .ForEach(a => primaryAliasIds.AddOrIgnore(a.PersonId, a.Id)); // Get current date/time. var timestamp = RockDateTime.Now; var suggestionTypes = new FollowingSuggestionTypeService(rockContext) .Queryable().AsNoTracking() .Where(s => s.IsActive) .OrderBy(s => s.Name) .ToList(); var components = new Dictionary <int, SuggestionComponent>(); var suggestedEntities = new Dictionary <int, Dictionary <int, IEntity> >(); foreach (var suggestionType in suggestionTypes) { try { // Get the suggestion type component var suggestionComponent = suggestionType.GetSuggestionComponent(); if (suggestionComponent != null) { components.Add(suggestionType.Id, suggestionComponent); // Get the entitytype for this suggestion type var suggestionEntityType = EntityTypeCache.Read(suggestionComponent.FollowedType); if (suggestionEntityType != null) { var entityIds = new List <int>(); // Call the components method to return all of it's suggestions var personEntitySuggestions = suggestionComponent.GetSuggestions(suggestionType, followerPersonIds); // If any suggestions were returned by the component if (personEntitySuggestions.Any()) { int entityTypeId = suggestionEntityType.Id; string reasonNote = suggestionType.ReasonNote; // Get the existing followings for any of the followers var existingFollowings = new Dictionary <int, List <int> >(); foreach (var following in followingService.Queryable("PersonAlias").AsNoTracking() .Where(f => f.EntityTypeId == entityTypeId && followerPersonIds.Contains(f.PersonAlias.PersonId))) { existingFollowings.AddOrIgnore(following.PersonAlias.PersonId, new List <int>()); existingFollowings[following.PersonAlias.PersonId].Add(following.EntityId); } // Loop through each follower foreach (var followerPersonId in personEntitySuggestions .Select(s => s.PersonId) .Distinct()) { using (var suggestionContext = new RockContext()) { var followingSuggestedService = new FollowingSuggestedService(suggestionContext); // Read all the existing suggestions for this type and the returned followers var existingSuggestions = followingSuggestedService .Queryable("PersonAlias") .Where(s => s.SuggestionTypeId == suggestionType.Id && s.PersonAlias.PersonId == followerPersonId) .ToList(); // Look through the returned suggestions foreach (var followedEntityId in personEntitySuggestions .Where(s => s.PersonId == followerPersonId) .Select(s => s.EntityId)) { // Make sure person isn't already following this entity if (!existingFollowings.ContainsKey(followerPersonId) || !existingFollowings[followerPersonId].Contains(followedEntityId)) { // If this person had a primary alias id if (primaryAliasIds.ContainsKey(followerPersonId)) { entityIds.Add(followedEntityId); // Look for existing suggestion for this person and entity var suggestion = existingSuggestions .Where(s => s.EntityId == followedEntityId) .OrderByDescending(s => s.StatusChangedDateTime) .FirstOrDefault(); // If not found, add one if (suggestion == null) { suggestion = new FollowingSuggested(); suggestion.EntityTypeId = entityTypeId; suggestion.EntityId = followedEntityId; suggestion.PersonAliasId = primaryAliasIds[followerPersonId]; suggestion.SuggestionTypeId = suggestionType.Id; suggestion.Status = FollowingSuggestedStatus.PendingNotification; suggestion.StatusChangedDateTime = timestamp; followingSuggestedService.Add(suggestion); } else { // If found, and it has not been ignored, and it's time to promote again, update the promote date if (suggestion.Status != FollowingSuggestedStatus.Ignored && ( !suggestionType.ReminderDays.HasValue || !suggestion.LastPromotedDateTime.HasValue || suggestion.LastPromotedDateTime.Value.AddDays(suggestionType.ReminderDays.Value) <= timestamp )) { if (suggestion.Status != FollowingSuggestedStatus.PendingNotification) { suggestion.StatusChangedDateTime = timestamp; suggestion.Status = FollowingSuggestedStatus.PendingNotification; } } } } } } // Save the suggestions for this type suggestionContext.SaveChanges(); } } } // If any entities are being suggested for this type, query database for them and save to dictionary if (entityIds.Any()) { if (suggestionEntityType.AssemblyName != null) { // get the actual type of what is being followed Type entityType = suggestionEntityType.GetEntityType(); if (entityType != null) { // Get generic queryable method and query all the entities that are being followed Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); Rock.Data.IService serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { rockContext }) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; var entityList = entityQry.AsNoTracking().Where(q => entityIds.Contains(q.Id)).ToList(); if (entityList != null && entityList.Any()) { var entities = new Dictionary <int, IEntity>(); entityList.ForEach(e => entities.Add(e.Id, e)); suggestedEntities.Add(suggestionType.Id, entities); } } } } } } } catch (Exception ex) { exceptionMsgs.Add(string.Format("An exception occurred calculating suggestions for the '{0}' suggestion type:{1} {2}", suggestionType.Name, Environment.NewLine, ex.Messages().AsDelimited(Environment.NewLine + " "))); ExceptionLogService.LogException(ex, System.Web.HttpContext.Current); } } var allSuggestions = new FollowingSuggestedService(rockContext) .Queryable("PersonAlias") .Where(s => s.Status == FollowingSuggestedStatus.PendingNotification) .ToList(); var suggestionPersonIds = allSuggestions .Where(s => followerPersonIds.Contains(s.PersonAlias.PersonId)) .Select(s => s.PersonAlias.PersonId) .Distinct() .ToList(); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); foreach (var person in new PersonService(rockContext) .Queryable().AsNoTracking() .Where(p => suggestionPersonIds.Contains(p.Id)) .ToList()) { try { var personSuggestionNotices = new List <FollowingSuggestionNotices>(); foreach (var suggestionType in suggestionTypes) { var component = components.ContainsKey(suggestionType.Id) ? components[suggestionType.Id] : null; if (component != null && suggestedEntities.ContainsKey(suggestionType.Id)) { var entities = new List <IEntity>(); foreach (var suggestion in allSuggestions .Where(s => s.PersonAlias.PersonId == person.Id && s.SuggestionTypeId == suggestionType.Id) .ToList()) { if (suggestedEntities[suggestionType.Id].ContainsKey(suggestion.EntityId)) { entities.Add(suggestedEntities[suggestionType.Id][suggestion.EntityId]); suggestion.LastPromotedDateTime = timestamp; suggestion.Status = FollowingSuggestedStatus.Suggested; } } var notices = new List <string>(); foreach (var entity in component.SortEntities(entities)) { notices.Add(component.FormatEntityNotification(suggestionType, entity)); } if (notices.Any()) { personSuggestionNotices.Add(new FollowingSuggestionNotices(suggestionType, notices)); } } } if (personSuggestionNotices.Any()) { // Send the notice var recipients = new List <RecipientData>(); var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", person); mergeFields.Add("Suggestions", personSuggestionNotices.OrderBy(s => s.SuggestionType.Order).ToList()); recipients.Add(new RecipientData(person.Email, mergeFields)); Email.Send(systemEmailGuid.Value, recipients, appRoot); followingSuggestionsEmailsSent += recipients.Count(); followingSuggestionsSuggestionsTotal += personSuggestionNotices.Count(); } rockContext.SaveChanges(); } catch (Exception ex) { exceptionMsgs.Add(string.Format("An exception occurred sending suggestions to '{0}':{1} {2}", person.FullName, Environment.NewLine, ex.Messages().AsDelimited(Environment.NewLine + " "))); ExceptionLogService.LogException(ex, System.Web.HttpContext.Current); } } } } } context.Result = string.Format("A total of {0} following suggestions sent to {1} people", followingSuggestionsSuggestionsTotal, followingSuggestionsEmailsSent); if (exceptionMsgs.Any()) { throw new Exception("One or more exceptions occurred calculating suggestions..." + Environment.NewLine + exceptionMsgs.AsDelimited(Environment.NewLine)); } }
/// <summary> /// Binds the data. /// </summary> private void BindData() { if (Person != null && Person.Id > 0) { if (ownerRoleGuid != Guid.Empty) { using (var rockContext = new RockContext()) { var memberService = new GroupMemberService(rockContext); var group = memberService.Queryable(true) .Where(m => m.PersonId == Person.Id && m.GroupRole.Guid == ownerRoleGuid) .Select(m => m.Group) .FirstOrDefault(); if (group == null && GetAttributeValue("CreateGroup").AsBoolean()) { var role = new GroupTypeRoleService(rockContext).Get(ownerRoleGuid); if (role != null && role.GroupTypeId.HasValue) { var groupService = new GroupService(rockContext); group = new Group(); group.Name = role.GroupType.Name; group.GroupTypeId = role.GroupTypeId.Value; groupService.Add(group); rockContext.SaveChanges(); var groupMember = new GroupMember(); groupMember.PersonId = Person.Id; groupMember.GroupRoleId = role.Id; groupMember.GroupId = group.Id; group.Members.Add(groupMember); rockContext.SaveChanges(); group = groupService.Get(group.Id); } } if (group != null) { lGroupName.Text = group.Name.Pluralize(); lGroupTypeIcon.Text = string.Format("<i class='{0}'></i>", group.GroupType.IconCssClass); lGroupTypeIcon.Visible = !string.IsNullOrWhiteSpace(group.GroupType.IconCssClass); phEditActions.Visible = group.IsAuthorized(Authorization.EDIT, CurrentPerson); if (group.IsAuthorized(Authorization.VIEW, CurrentPerson)) { int?maxRelationshipsToDisplay = this.GetAttributeValue("MaxRelationshipsToDisplay").AsIntegerOrNull(); IQueryable <GroupMember> qryGroupMembers = new GroupMemberService(rockContext).GetByGroupId(group.Id, true) .Where(m => m.PersonId != Person.Id) .OrderBy(m => m.Person.LastName) .ThenBy(m => m.Person.FirstName); if (maxRelationshipsToDisplay.HasValue) { qryGroupMembers = qryGroupMembers.Take(maxRelationshipsToDisplay.Value); } rGroupMembers.DataSource = qryGroupMembers.ToList(); rGroupMembers.DataBind(); } else { lAccessWarning.Text = string.Format("<div class='alert alert-info'>You do not have security rights to view {0}.", group.Name.Pluralize()); } } else { lGroupName.Text = this.BlockCache.Name; } } } } }
/// <summary> /// Job that will sync groups. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; try { int notificationsSent = 0; int pendingMembersCount = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString("GroupType").AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString("NotificationEmail").AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString("GroupRoleFilter").AsGuidOrNull(); int? pendingAge = dataMap.GetString("PendingAge").AsIntegerOrNull(); bool includePreviouslyNotificed = dataMap.GetString("IncludePreviouslyNotified").AsBoolean(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { // no email specified, so nothing to do return; } // get group members if (groupTypeGuid.HasValue && groupTypeGuid != Guid.Empty) { var qry = new GroupMemberService(rockContext).Queryable("Person, Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qry = qry.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } if (pendingAge.HasValue && pendingAge.Value > 0) { var ageDate = RockDateTime.Now.AddDays(pendingAge.Value * -1); qry = qry.Where(m => m.ModifiedDateTime > ageDate); } var pendingGroupMembers = qry.ToList(); var groups = pendingGroupMembers.GroupBy(m => m.Group); foreach (var groupKey in groups) { var group = groupKey.Key; // get list of pending people var qryPendingIndividuals = group.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Pending); if (!includePreviouslyNotificed) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.IsNotified == false); } if (groupRoleFilterGuid.HasValue) { qryPendingIndividuals = qryPendingIndividuals.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var pendingIndividuals = qryPendingIndividuals.Select(m => m.Person).ToList(); // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("PublicApplicationRoot"); var recipients = new List <RecipientData>(); foreach (var leader in groupLeaders.Where(l => l.Person != null && l.Person.Email != "")) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("PendingIndividuals", pendingIndividuals); mergeFields.Add("Group", group); mergeFields.Add("ParentGroup", group.ParentGroup); mergeFields.Add("Person", leader.Person); recipients.Add(new RecipientData(leader.Person.Email, mergeFields)); } if (pendingIndividuals.Count() > 0) { var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); emailMessage.Send(); notificationsSent += recipients.Count(); } // mark pending members as notified as we go in case the job fails var notifiedPersonIds = pendingIndividuals.Select(p => p.Id); foreach (var pendingGroupMember in pendingGroupMembers.Where(m => m.IsNotified == false && notifiedPersonIds.Contains(m.PersonId))) { pendingGroupMember.IsNotified = true; } rockContext.SaveChanges(); } } context.Result = string.Format("Sent {0} emails to leaders for {1} pending individuals", notificationsSent, pendingMembersCount); } catch (System.Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
private List <MedicalItem> GetMedicalItems() { RockContext rockContext = new RockContext(); GroupService groupService = new GroupService(rockContext); var groupIdStrings = GetAttributeValue("GroupIds").SplitDelimitedValues(); var groupIds = new List <int>(); foreach (var id in groupIdStrings) { groupIds.Add(id.AsInteger()); } var groups = groupService.GetByIds(groupIds); var groupTypeIds = groups.ToList().Select(g => g.GroupTypeId.ToString()).Distinct(); var groupEntityid = EntityTypeCache.GetId <Rock.Model.GroupMember>(); var key = GetAttributeValue("MedicationMatrixKey"); AttributeService attributeService = new AttributeService(rockContext); List <int> attributeIds = attributeService.Queryable() .Where(a => (groupIdStrings.Contains(a.EntityTypeQualifierValue) || groupTypeIds.Contains(a.EntityTypeQualifierValue)) && a.Key == key && a.EntityTypeId == groupEntityid) .Select(a => a.Id).ToList(); if (attributeIds == null) { nbAlert.Visible = true; nbAlert.Text = "Medication attribute not found"; return(null); } List <int> filterAttributeIds = null; var filterAttributeKey = GetAttributeValue("GroupMemberAttributeFilter"); if (!string.IsNullOrWhiteSpace(filterAttributeKey)) { filterAttributeIds = attributeService.Queryable() .Where(a => (groupIdStrings.Contains(a.EntityTypeQualifierValue) || groupTypeIds.Contains(a.EntityTypeQualifierValue)) && a.Key == filterAttributeKey && a.EntityTypeId == groupEntityid) .Select(a => a.Id).ToList(); } var attributeMatrixItemEntityId = EntityTypeCache.GetId <AttributeMatrixItem>(); AttributeValueService attributeValueService = new AttributeValueService(rockContext); AttributeMatrixService attributeMatrixService = new AttributeMatrixService(rockContext); AttributeMatrixItemService attributeMatrixItemService = new AttributeMatrixItemService(rockContext); HistoryService historyService = new HistoryService(rockContext); var qry = new GroupMemberService(rockContext).Queryable() .Join( attributeValueService.Queryable().Where(av => attributeIds.Contains(av.AttributeId)), m => m.Id, av => av.EntityId.Value, (m, av) => new { Member = m, AttributeValue = av.Value } ) .Join( attributeMatrixService.Queryable(), m => m.AttributeValue, am => am.Guid.ToString(), (m, am) => new { Member = m.Member, AttributeMatrix = am } ) .Join( attributeMatrixItemService.Queryable(), m => m.AttributeMatrix.Id, ami => ami.AttributeMatrixId, (m, ami) => new { Member = m.Member, AttributeMatrixItem = ami, TemplateId = ami.AttributeMatrix.AttributeMatrixTemplateId } ) .Join( attributeService.Queryable(), m => new { TemplateIdString = m.TemplateId.ToString(), EntityTypeId = attributeMatrixItemEntityId }, a => new { TemplateIdString = a.EntityTypeQualifierValue, EntityTypeId = a.EntityTypeId }, (m, a) => new { Member = m.Member, AttributeMatrixItem = m.AttributeMatrixItem, Attribute = a } ) .Join( attributeValueService.Queryable(), m => new { EntityId = m.AttributeMatrixItem.Id, AttributeId = m.Attribute.Id }, av => new { EntityId = av.EntityId ?? 0, AttributeId = av.AttributeId }, (m, av) => new { Member = m.Member, Attribute = m.Attribute, AttributeValue = av, MatrixItemId = m.AttributeMatrixItem.Id, FilterValue = "" } ). Where(obj => groupIds.Contains(obj.Member.GroupId)); if (filterAttributeIds != null && pnlAttribute.Visible && !string.IsNullOrWhiteSpace(ddlAttribute.SelectedValue)) { var filterValue = ddlAttribute.SelectedValue; qry = qry .Join( attributeValueService.Queryable().Where(av => filterAttributeIds.Contains(av.AttributeId)), m => new { Id = m.Member.Id, Value = filterValue }, av => new { Id = av.EntityId ?? 0, Value = av.Value }, (m, av) => new { Member = m.Member, Attribute = m.Attribute, AttributeValue = m.AttributeValue, MatrixItemId = m.MatrixItemId, FilterValue = av.Value }); } var members = qry.ToList().GroupBy(a => a.Member).ToList(); var firstDay = (dpDate.SelectedDate ?? Rock.RockDateTime.Today).Date; var nextday = firstDay.AddDays(1); var personIds = members.Select(m => m.Key.PersonId); var attributeMatrixEntityTypeId = EntityTypeCache.GetId <AttributeMatrixItem>().Value; var historyItems = historyService.Queryable() .Where(h => personIds.Contains(h.EntityId)) .Where(h => h.RelatedEntityTypeId == attributeMatrixEntityTypeId) .Where(h => h.CreatedDateTime >= firstDay && h.CreatedDateTime < nextday) .ToList(); foreach (var member in members) { if (!string.IsNullOrWhiteSpace(tbName.Text) && !member.Key.Person.FullName.ToLower().Contains(tbName.Text.ToLower()) && !member.Key.Person.FullNameReversed.ToLower().Contains(tbName.Text.ToLower())) { continue; } var medicines = member.GroupBy(m => m.MatrixItemId); foreach (var medicine in medicines) { var scheduleAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Schedule"); var schedules = scheduleAtt.AttributeValue.Value.SplitDelimitedValues(); foreach (var schedule in schedules) { if (ddlSchedule.SelectedValue != "" && ddlSchedule.SelectedValue.AsGuid() != schedule.AsGuid()) { continue; } var medicalItem = new MedicalItem() { Person = member.Key.Person.FullNameReversed, GroupMemberId = member.Key.Id, GroupMember = member.FirstOrDefault().Member, PersonId = member.Key.Person.Id, FilterAttribute = member.FirstOrDefault().FilterValue }; if (!string.IsNullOrWhiteSpace(schedule)) { var dv = DefinedValueCache.Read(schedule.AsGuid()); if (dv != null) { medicalItem.Schedule = dv.Value; medicalItem.ScheduleGuid = dv.Guid; } } var medAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Medication"); if (medAtt != null) { medicalItem.Medication = medAtt.AttributeValue.Value; } var instructionAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Instructions"); if (instructionAtt != null) { medicalItem.Instructions = instructionAtt.AttributeValue.Value; } medicalItem.Key = string.Format("{0}|{1}|{2}", medicalItem.PersonId, medicine.Key, medicalItem.ScheduleGuid); var history = historyItems.Where(h => h.EntityId == medicalItem.PersonId && h.RelatedEntityId == medicine.Key && (string.IsNullOrWhiteSpace(h.RelatedData) || h.RelatedData.AsGuid() == medicalItem.ScheduleGuid)); if (history.Any()) { medicalItem.Distributed = true; medicalItem.History = string.Join("<br>", history.Select(h => h.Summary)); } medicalItems.Add(medicalItem); } } } SortProperty sortProperty = gGrid.SortProperty; if (sortProperty != null) { if (sortProperty.Property == "Person") { if (sortProperty.Direction == SortDirection.Ascending) { medicalItems = medicalItems.OrderBy(mi => mi.Person).ToList(); } else { medicalItems = medicalItems.OrderByDescending(mi => mi.Person).ToList(); } } } else { medicalItems = medicalItems.OrderBy(mi => mi.Person).ToList(); gGrid.SortProperty = new SortProperty() { Property = "Person" }; } return(medicalItems); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("NotificationEmailTemplate").AsGuidOrNull(); if (systemEmailGuid.HasValue) { var selectedGroupTypes = new List <Guid>(); if (!string.IsNullOrWhiteSpace(dataMap.GetString("GroupTypes"))) { selectedGroupTypes = dataMap.GetString("GroupTypes").Split(',').Select(Guid.Parse).ToList(); } var excludedGroupRoleIds = new List <int>(); if (!string.IsNullOrWhiteSpace(dataMap.GetString("ExcludedGroupRoleIds"))) { excludedGroupRoleIds = dataMap.GetString("ExcludedGroupRoleIds").Split(',').Select(int.Parse).ToList(); } var notificationOption = dataMap.GetString("NotifyParentLeaders").ConvertToEnum <NotificationOption>(NotificationOption.None); var accountAbilityGroupGuid = dataMap.GetString("AccountabilityGroup").AsGuid(); // get groups matching of the types provided GroupService groupService = new GroupService(rockContext); var groups = groupService.Queryable().AsNoTracking() .Where(g => selectedGroupTypes.Contains(g.GroupType.Guid) && g.IsActive == true && g.GroupRequirements.Any()); foreach (var group in groups) { // check for members that don't meet requirements var groupMembersWithIssues = groupService.GroupMembersNotMeetingRequirements(group.Id, true); if (groupMembersWithIssues.Count > 0) { // add issues to issue list GroupsMissingRequirements groupMissingRequirements = new GroupsMissingRequirements(); groupMissingRequirements.Id = group.Id; groupMissingRequirements.Name = group.Name; if (group.GroupType != null) { groupMissingRequirements.GroupTypeId = group.GroupTypeId; groupMissingRequirements.GroupTypeName = group.GroupType.Name; } groupMissingRequirements.AncestorPathName = groupService.GroupAncestorPathName(group.Id); // get list of the group leaders groupMissingRequirements.Leaders = group.Members .Where(m => m.GroupRole.IsLeader == true && !excludedGroupRoleIds.Contains(m.GroupRoleId)) .Select(m => new GroupMemberResult { Id = m.Id, PersonId = m.PersonId, FullName = m.Person.FullName }) .ToList(); List <GroupMembersMissingRequirements> groupMembers = new List <GroupMembersMissingRequirements>(); foreach (var groupMemberIssue in groupMembersWithIssues) { GroupMembersMissingRequirements groupMember = new GroupMembersMissingRequirements(); groupMember.FullName = groupMemberIssue.Key.Person.FullName; groupMember.Id = groupMemberIssue.Key.Id; groupMember.PersonId = groupMemberIssue.Key.PersonId; groupMember.GroupMemberRole = groupMemberIssue.Key.GroupRole.Name; List <MissingRequirement> missingRequirements = new List <MissingRequirement>(); foreach (var issue in groupMemberIssue.Value) { MissingRequirement missingRequirement = new MissingRequirement(); missingRequirement.Id = issue.Key.GroupRequirement.GroupRequirementType.Id; missingRequirement.Name = issue.Key.GroupRequirement.GroupRequirementType.Name; missingRequirement.Status = issue.Key.MeetsGroupRequirement; missingRequirement.OccurrenceDate = issue.Value; switch (issue.Key.MeetsGroupRequirement) { case MeetsGroupRequirement.Meets: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.PositiveLabel; break; case MeetsGroupRequirement.MeetsWithWarning: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.WarningLabel; break; case MeetsGroupRequirement.NotMet: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.NegativeLabel; break; } missingRequirements.Add(missingRequirement); } groupMember.MissingRequirements = missingRequirements; groupMembers.Add(groupMember); } groupMissingRequirements.GroupMembersMissingRequirements = groupMembers; _groupsMissingRequriements.Add(groupMissingRequirements); // add leaders as people to notify foreach (var leader in group.Members.Where(m => m.GroupRole.IsLeader == true && !excludedGroupRoleIds.Contains(m.GroupRoleId))) { NotificationItem notification = new NotificationItem(); notification.GroupId = group.Id; notification.Person = leader.Person; _notificationList.Add(notification); // notify parents if (notificationOption != NotificationOption.None) { var parentLeaders = new GroupMemberService(rockContext).Queryable("Person").AsNoTracking() .Where(m => m.GroupRole.IsLeader && !excludedGroupRoleIds.Contains(m.GroupRoleId)); if (notificationOption == NotificationOption.DirectParent) { // just the parent group parentLeaders = parentLeaders.Where(m => m.GroupId == group.ParentGroupId); } else { // all parents in the heirarchy var parentIds = groupService.GetAllAncestorIds(group.Id); parentLeaders = parentLeaders.Where(m => parentIds.Contains(m.GroupId)); } foreach (var parentLeader in parentLeaders.ToList()) { NotificationItem parentNotification = new NotificationItem(); parentNotification.Person = parentLeader.Person; parentNotification.GroupId = group.Id; _notificationList.Add(parentNotification); } } } } } // send out notificatons var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); var recipients = new List <RecipientData>(); var notificationRecipients = _notificationList.GroupBy(p => p.Person.Id).ToList(); foreach (var recipientId in notificationRecipients) { var recipient = _notificationList.Where(n => n.Person.Id == recipientId.Key).Select(n => n.Person).FirstOrDefault(); var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", recipient); var notificationGroupIds = _notificationList .Where(n => n.Person.Id == recipient.Id) .Select(n => n.GroupId) .ToList(); var missingRequirements = _groupsMissingRequriements.Where(g => notificationGroupIds.Contains(g.Id)).ToList(); mergeFields.Add("GroupsMissingRequirements", missingRequirements); var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(null); globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value)); recipients.Add(new RecipientData(recipient.Email, mergeFields)); Email.Send(systemEmailGuid.Value, recipients, appRoot); recipients.Clear(); } // add accountability group members if (!accountAbilityGroupGuid.IsEmpty()) { var accountabilityGroupMembers = new GroupMemberService(rockContext).Queryable().AsNoTracking() .Where(m => m.Group.Guid == accountAbilityGroupGuid) .Select(m => m.Person); foreach (var person in accountabilityGroupMembers) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", person); mergeFields.Add("GroupsMissingRequirements", _groupsMissingRequriements); var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(null); globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value)); recipients.Add(new RecipientData(person.Email, mergeFields)); } } Email.Send(systemEmailGuid.Value, recipients, appRoot); } }
/// <summary> /// Binds the data. /// </summary> private void BindData() { ShowRole = GetAttributeValue("ShowRole").AsBoolean(); if (person != null && person.Id > 0) { if (ownerRoleGuid != Guid.Empty) { using (var rockContext = new RockContext()) { var memberService = new GroupMemberService(rockContext); var group = memberService.Queryable(true) .Where(m => m.PersonId == person.Id && m.GroupRole.Guid == ownerRoleGuid) .Select(m => m.Group) .FirstOrDefault(); if (group != null) { lGroupName.Text = group.Name.Pluralize(); lGroupTypeIcon.Text = string.Format("<i class='{0}'></i>", group.GroupType.IconCssClass); lGroupTypeIcon.Visible = !string.IsNullOrWhiteSpace(group.GroupType.IconCssClass); if (group.IsAuthorized(Authorization.VIEW, CurrentPerson)) { int?maxRelationshipsToDisplay = this.GetAttributeValue("MaxRelationshipsToDisplay").AsIntegerOrNull(); var roles = new List <int>(); if (canCheckInOnly) { foreach (var role in new GroupTypeRoleService(rockContext) .Queryable().AsNoTracking() .Where(r => r.GroupType.Guid.Equals(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS)))) { role.LoadAttributes(rockContext); if (role.Attributes.ContainsKey("CanCheckin")) { bool canCheckIn = false; if (bool.TryParse(role.GetAttributeValue("CanCheckin"), out canCheckIn) && canCheckIn) { roles.Add(role.Id); } } if (role.Attributes.ContainsKey("InverseRelationship")) { var inverseRoleGuid = role.GetAttributeValue("InverseRelationship").AsGuidOrNull(); if (inverseRoleGuid != null) { var groupTypeRole = new GroupTypeRoleService(rockContext) .Queryable().AsNoTracking() .FirstOrDefault(r => r.Guid.Equals(( Guid )inverseRoleGuid)); if (groupTypeRole != null) { groupTypeRole.LoadAttributes(rockContext); if (groupTypeRole.Attributes.ContainsKey("CanCheckin")) { bool canCheckIn = false; if (bool.TryParse(groupTypeRole.GetAttributeValue("CanCheckin"), out canCheckIn) && canCheckIn) { roles.Add(role.Id); } } } } } } } else { foreach (var role in new GroupTypeRoleService(rockContext) .Queryable().AsNoTracking() .Where(r => r.GroupType.Guid.Equals(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS)))) { roles.Add(role.Id); } } IQueryable <GroupMember> qryGroupMembers = new GroupMemberService(rockContext).GetByGroupId(group.Id, true) .Where(m => m.PersonId != person.Id) .Where(m => roles.Contains(m.GroupRoleId)) .OrderBy(m => m.Person.LastName) .ThenBy(m => m.Person.FirstName); if (maxRelationshipsToDisplay.HasValue) { qryGroupMembers = qryGroupMembers.Take(maxRelationshipsToDisplay.Value); } rGroupMembers.ItemDataBound += rptrMembers_ItemDataBound; rGroupMembers.DataSource = qryGroupMembers.ToList(); rGroupMembers.DataBind(); } else { lAccessWarning.Text = string.Format("<div class='alert alert-info'>You do not have security rights to view {0}.", group.Name.Pluralize()); } } } } } }
/// <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(); }