public GroupAncestorPathName ( int groupId ) : string | ||
groupId | int | The group identifier. |
리턴 | string |
/// <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( "PublicApplicationRoot" ); 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 = 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 ); 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 = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); mergeFields.Add( "Person", person ); mergeFields.Add( "GroupsMissingRequirements", _groupsMissingRequriements ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); } } Email.Send( systemEmailGuid.Value, recipients, appRoot ); context.Result = string.Format( "{0} requirement notification {1} sent", recipients.Count, "email".PluralizeIf( recipients.Count() != 1 ) ); } else { context.Result = "Warning: No NotificationEmailTemplate found"; } }
/// <summary> /// Adds the group controls. /// </summary> /// <param name="group">The group.</param> /// <param name="checkBoxList">The check box list.</param> /// <param name="service">The service.</param> /// <param name="showGroupAncestry">if set to <c>true</c> [show group ancestry].</param> private void AddGroupControls( Group group, RockCheckBoxList checkBoxList, GroupService service, bool showGroupAncestry ) { // Only show groups that actually have a schedule if ( group != null ) { if ( group.ScheduleId.HasValue || group.GroupLocations.Any( l => l.Schedules.Any() ) ) { string displayName = showGroupAncestry ? service.GroupAncestorPathName( group.Id ) : group.Name; checkBoxList.Items.Add( new ListItem( displayName, group.Id.ToString() ) ); } if ( group.Groups != null ) { foreach ( var childGroup in group.Groups .OrderBy( a => a.Order ) .ThenBy( a => a.Name ) .ToList() ) { AddGroupControls( childGroup, checkBoxList, service, showGroupAncestry ); } } } }
/// <summary> /// Binds the grid. /// </summary> protected void BindGrid() { AddScheduleColumns(); var rockContext = new RockContext(); var groupLocationService = new GroupLocationService( rockContext ); var groupTypeService = new GroupTypeService( rockContext ); var groupService = new GroupService( rockContext ); IEnumerable<GroupTypePath> groupPaths = new List<GroupTypePath>(); var groupLocationQry = groupLocationService.Queryable(); List<int> currentAndDescendantGroupTypeIds = new List<int>(); var currentGroupTypeIds = this.CurrentGroupTypeIds.ToList(); currentAndDescendantGroupTypeIds.AddRange( currentGroupTypeIds ); foreach ( var templateGroupType in groupTypeService.Queryable().Where( a => currentGroupTypeIds.Contains( a.Id ) ) ) { foreach ( var childGroupType in groupTypeService.GetChildGroupTypes( templateGroupType.Id ) ) { currentAndDescendantGroupTypeIds.Add( childGroupType.Id ); currentAndDescendantGroupTypeIds.AddRange( groupTypeService.GetAllAssociatedDescendents( childGroupType.Id ).Select( a => a.Id ).ToList() ); } } groupLocationQry = groupLocationQry.Where( a => currentAndDescendantGroupTypeIds.Contains( a.Group.GroupTypeId ) ); groupLocationQry = groupLocationQry.OrderBy( a => a.Group.Name ).ThenBy( a => a.Location.Name ); List<int> currentDeviceLocationIdList = this.GetGroupTypesLocations( rockContext ).Select( a => a.Id ).Distinct().ToList(); var qryList = groupLocationQry .Where( a => currentDeviceLocationIdList.Contains( a.LocationId ) ) .Select( a => new { GroupLocationId = a.Id, a.Location, GroupId = a.GroupId, GroupName = a.Group.Name, ScheduleIdList = a.Schedules.Select( s => s.Id ), GroupTypeId = a.Group.GroupTypeId } ).ToList(); var locationService = new LocationService( rockContext ); // put stuff in a datatable so we can dynamically have columns for each Schedule DataTable dataTable = new DataTable(); dataTable.Columns.Add( "GroupLocationId" ); dataTable.Columns.Add( "GroupId" ); dataTable.Columns.Add( "GroupName" ); dataTable.Columns.Add( "GroupPath" ); dataTable.Columns.Add( "LocationName" ); dataTable.Columns.Add( "LocationPath" ); foreach ( var field in gGroupLocationSchedule.Columns.OfType<CheckBoxEditableField>() ) { dataTable.Columns.Add( field.DataField, typeof( bool ) ); } var locationPaths = new Dictionary<int, string>(); foreach ( var row in qryList ) { DataRow dataRow = dataTable.NewRow(); dataRow["GroupLocationId"] = row.GroupLocationId; dataRow["GroupName"] = groupService.GroupAncestorPathName( row.GroupId ); dataRow["GroupPath"] = groupPaths.Where( gt => gt.GroupTypeId == row.GroupTypeId ).Select( gt => gt.Path ).FirstOrDefault(); dataRow["LocationName"] = row.Location.Name; if ( row.Location.ParentLocationId.HasValue ) { int locationId = row.Location.ParentLocationId.Value; if ( !locationPaths.ContainsKey( locationId ) ) { var locationNames = new List<string>(); var parentLocation = locationService.Get( locationId ); while ( parentLocation != null ) { locationNames.Add( parentLocation.Name ); parentLocation = parentLocation.ParentLocation; } if ( locationNames.Any() ) { locationNames.Reverse(); locationPaths.Add( locationId, locationNames.AsDelimited( " > " ) ); } else { locationPaths.Add( locationId, string.Empty ); } } dataRow["LocationPath"] = locationPaths[locationId]; } foreach ( var field in gGroupLocationSchedule.Columns.OfType<CheckBoxEditableField>() ) { int scheduleId = int.Parse( field.DataField.Replace( "scheduleField_", string.Empty ) ); dataRow[field.DataField] = row.ScheduleIdList.Any( a => a == scheduleId ); } dataTable.Rows.Add( dataRow ); } gGroupLocationSchedule.EntityTypeId = EntityTypeCache.Read<GroupLocation>().Id; gGroupLocationSchedule.DataSource = dataTable; gGroupLocationSchedule.DataBind(); }
/// <summary> /// Binds the grid. /// </summary> protected void BindGrid() { AddScheduleColumns(); var rockContext = new RockContext(); var groupLocationService = new GroupLocationService( rockContext ); var groupTypeService = new GroupTypeService( rockContext ); var groupService = new GroupService( rockContext ); IEnumerable<GroupTypePath> groupPaths = new List<GroupTypePath>(); var groupLocationQry = groupLocationService.Queryable(); int groupTypeId; // if this page has a PageParam for groupTypeId use that to limit which groupTypeId to see. Otherwise, use the groupTypeId specified in the filter int? groupTypeIdPageParam = this.PageParameter( "groupTypeId" ).AsIntegerOrNull(); if ( groupTypeIdPageParam.HasValue ) { groupTypeId = groupTypeIdPageParam ?? Rock.Constants.All.Id; } else { groupTypeId = ddlGroupType.SelectedValueAsInt() ?? Rock.Constants.All.Id; } if ( groupTypeId != Rock.Constants.All.Id ) { var descendantGroupTypeIds = groupTypeService.GetAllAssociatedDescendents( groupTypeId ).Select( a => a.Id ); // filter to groups that either are of the GroupType or are of a GroupType that has the selected GroupType as a parent (ancestor) groupLocationQry = groupLocationQry.Where( a => a.Group.GroupType.Id == groupTypeId || descendantGroupTypeIds.Contains( a.Group.GroupTypeId ) ); groupPaths = groupTypeService.GetAllAssociatedDescendentsPath( groupTypeId ); } else { // if no specific GroupType is specified, show all GroupTypes with GroupTypePurpose of Checkin Template and their descendents (since this blocktype is specifically for Checkin) int groupTypePurposeCheckInTemplateId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE ) ).Id; List<int> descendantGroupTypeIds = new List<int>(); foreach ( var templateGroupType in groupTypeService.Queryable().Where( a => a.GroupTypePurposeValueId == groupTypePurposeCheckInTemplateId ) ) { foreach ( var childGroupType in groupTypeService.GetChildGroupTypes( templateGroupType.Id ) ) { descendantGroupTypeIds.Add( childGroupType.Id ); descendantGroupTypeIds.AddRange( groupTypeService.GetAllAssociatedDescendents( childGroupType.Id ).Select( a => a.Id ).ToList() ); } } groupLocationQry = groupLocationQry.Where( a => descendantGroupTypeIds.Contains( a.Group.GroupTypeId ) ); } if ( gGroupLocationSchedule.SortProperty != null ) { groupLocationQry = groupLocationQry.Sort( gGroupLocationSchedule.SortProperty ); } else { groupLocationQry = groupLocationQry.OrderBy( a => a.Group.Name ).ThenBy( a => a.Location.Name ); } var qryList = groupLocationQry .Where( a => a.Location != null ) .Select( a => new { GroupLocationId = a.Id, a.Location, GroupId = a.GroupId, GroupName = a.Group.Name, ScheduleIdList = a.Schedules.Select( s => s.Id ), GroupTypeId = a.Group.GroupTypeId } ).ToList(); var locationService = new LocationService( rockContext ); int parentLocationId = pkrParentLocation.SelectedValueAsInt() ?? Rock.Constants.All.Id; if ( parentLocationId != Rock.Constants.All.Id ) { var currentAndDescendantLocationIds = new List<int>(); currentAndDescendantLocationIds.Add( parentLocationId ); currentAndDescendantLocationIds.AddRange( locationService.GetAllDescendents( parentLocationId ).Select( a => a.Id ) ); qryList = qryList.Where( a => currentAndDescendantLocationIds.Contains( a.Location.Id ) ).ToList(); } // put stuff in a datatable so we can dynamically have columns for each Schedule DataTable dataTable = new DataTable(); dataTable.Columns.Add( "GroupLocationId" ); dataTable.Columns.Add( "GroupId" ); dataTable.Columns.Add( "GroupName" ); dataTable.Columns.Add( "GroupPath" ); dataTable.Columns.Add( "LocationName" ); dataTable.Columns.Add( "LocationPath" ); foreach ( var field in gGroupLocationSchedule.Columns.OfType<CheckBoxEditableField>() ) { dataTable.Columns.Add( field.DataField, typeof( bool ) ); } var locationPaths = new Dictionary<int, string>(); foreach ( var row in qryList ) { DataRow dataRow = dataTable.NewRow(); dataRow["GroupLocationId"] = row.GroupLocationId; dataRow["GroupName"] = groupService.GroupAncestorPathName( row.GroupId ); dataRow["GroupPath"] = groupPaths.Where( gt => gt.GroupTypeId == row.GroupTypeId ).Select( gt => gt.Path ).FirstOrDefault(); dataRow["LocationName"] = row.Location.Name; if ( row.Location.ParentLocationId.HasValue ) { int locationId = row.Location.ParentLocationId.Value; if ( !locationPaths.ContainsKey( locationId ) ) { var locationNames = new List<string>(); var parentLocation = locationService.Get( locationId ); while ( parentLocation != null ) { locationNames.Add( parentLocation.Name ); parentLocation = parentLocation.ParentLocation; } if ( locationNames.Any() ) { locationNames.Reverse(); locationPaths.Add( locationId, locationNames.AsDelimited( " > " ) ); } else { locationPaths.Add( locationId, string.Empty ); } } dataRow["LocationPath"] = locationPaths[locationId]; } foreach ( var field in gGroupLocationSchedule.Columns.OfType<CheckBoxEditableField>() ) { int scheduleId = int.Parse( field.DataField.Replace( "scheduleField_", string.Empty ) ); dataRow[field.DataField] = row.ScheduleIdList.Any( a => a == scheduleId ); } dataTable.Rows.Add( dataRow ); } gGroupLocationSchedule.EntityTypeId = EntityTypeCache.Read<GroupLocation>().Id; gGroupLocationSchedule.DataSource = dataTable; gGroupLocationSchedule.DataBind(); }